$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: stipe_at_[hidden]
Date: 2007-08-19 23:00:16
Author: srajko
Date: 2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
New Revision: 38773
URL: http://svn.boost.org/trac/boost/changeset/38773
Log:
add ProxyProducer concept
Added:
   sandbox/SOC/2007/signals/libs/dataflow/doc/components.qbk   (contents, props changed)
Text files modified: 
   sandbox/SOC/2007/signals/boost/dataflow/connection/consumer_map.hpp         |    19 ++                                      
   sandbox/SOC/2007/signals/boost/dataflow/detail/enable_if_defined.hpp        |     8 +                                       
   sandbox/SOC/2007/signals/boost/dataflow/signal/component/chain.hpp          |     5                                         
   sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter.hpp         |     8 +                                       
   sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter_base.hpp    |     5                                         
   sandbox/SOC/2007/signals/boost/dataflow/signal/connection/slot_selector.hpp |     9 +                                       
   sandbox/SOC/2007/signals/boost/dataflow/signal/support.hpp                  |    22 ++-                                     
   sandbox/SOC/2007/signals/boost/dataflow/support/connectable.hpp             |    24 ++-                                     
   sandbox/SOC/2007/signals/boost/dataflow/support/producer.hpp                |   228 ++++++++++++++++++++++++++++++++++++--- 
   sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk                     |    79 +++++++++++++                           
   sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk                     |     1                                         
   sandbox/SOC/2007/signals/libs/dataflow/test/test_socket.cpp                 |     8                                         
   sandbox/SOC/2007/signals/libs/dataflow/test/test_storage.cpp                |     7 +                                       
   13 files changed, 376 insertions(+), 47 deletions(-)
Modified: sandbox/SOC/2007/signals/boost/dataflow/connection/consumer_map.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/connection/consumer_map.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/connection/consumer_map.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -8,6 +8,7 @@
 
 #include <boost/dataflow/support.hpp>
 
+#include <boost/mpl/not.hpp>
 #include <boost/fusion/algorithm/iteration/for_each.hpp>
 #include <boost/fusion/sequence/container/vector.hpp>
 #include <boost/fusion/sequence/intrinsic/at_key.hpp>
@@ -15,8 +16,9 @@
 #include <boost/fusion/sequence/generation/vector_tie.hpp>
 #include <boost/fusion/sequence/view/zip_view.hpp>
 #include <boost/fusion/support/is_sequence.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 #include <boost/utility/result_of.hpp>
-#include <boost/mpl/not.hpp>
 
 namespace boost { namespace dataflow {
 
@@ -27,11 +29,22 @@
 {
     consumer_map(const T& t) : T(t) {}
     typedef fusion_map_consumer consumer_category;
-    typedef fusion_map_consumer producer_category;
+    typedef
+        typename boost::remove_const<
+            typename boost::remove_reference<
+                typename boost::fusion::result_of::front<T>::type
+            >::type
+        >::type::second_type proxy_producer_for;
+    typedef mutable_proxy_producer proxy_producer_category;
+
+    typename get_proxied_producer_type<proxy_producer_for>::type &get_proxied_producer() const
+    {
+        return boost::dataflow::get_proxied_producer(boost::fusion::front(*this).second);
+    }
 };
 
 namespace extension
-{   
+{
     // component >>= map
     template<typename ProducerTag, typename ConsumerTag>
     struct connect_impl<ProducerTag, ConsumerTag,
Modified: sandbox/SOC/2007/signals/boost/dataflow/detail/enable_if_defined.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/detail/enable_if_defined.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/detail/enable_if_defined.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -18,6 +18,14 @@
     {
         typedef Result type;
     };
+    
+    struct void_;
+    
+    template<typename T0=void_, typename T1=void_, typename T2=void_,
+        typename T3=void_, typename T4=void_, typename T5=void_>
+    struct all_of
+    {
+    };
 }
 
 } } // namespace boost::dataflow
Modified: sandbox/SOC/2007/signals/boost/dataflow/signal/component/chain.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signal/component/chain.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signal/component/chain.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -27,6 +27,7 @@
 public:
         typedef typename T::signal_type signal_type;
         typedef typename T::signature_type signature_type;
+        typedef T proxy_producer_for;
     
         chain_impl(size_t copies, T *component=NULL)
         {
@@ -52,6 +53,10 @@
         {
             return components[size-1].default_signal();
         }
+        typename boost::dataflow::get_proxied_producer_type<proxy_producer_for>::type &get_proxied_producer() const
+        {
+            return boost::dataflow::get_proxied_producer(components[size-1]);
+        }
     private:
         void initialize(size_t copies, T *component=NULL)
         {
Modified: sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -66,6 +66,7 @@
 public:
     //typedef Signature produced_type;
     //typedef boost::dataflow::signal_producer producer_category;
+    typedef boost::signal<Signature, Combiner, Group, GroupCompare> proxy_producer_for;
     
     // the signature of the output signal
         typedef Signature signature_type;
@@ -79,6 +80,9 @@
         ///	Returns the default out signal.
         signal_type &default_signal() const
         {	return out; }
+  	signal_type &get_proxied_producer() const
+	{	return out; }
+
         ///	Disconnects all slots connected to the signals::filter.
         void disconnect_all_slots() {out.disconnect_all_slots();}
 protected:
@@ -122,6 +126,7 @@
     typedef typename boost::fusion::result_of::as_vector<parameter_types>::type parameter_vector;
     typedef typename Combiner::result_type signature_type (const parameter_vector &);
     typedef typename Combiner::result_type fused_signature_type (const parameter_vector &);
+    typedef boost::signal<signature_type, Combiner, Group, GroupCompare> proxy_producer_for;
     typedef boost::signal<signature_type, Combiner, Group, GroupCompare> signal_type;
 
 //    typedef typename Combiner::result_type produced_type (const parameter_vector &);
@@ -129,6 +134,9 @@
         ///	Returns the default out signal.
         signal_type &default_signal() const
         {	return fused_out; }
+	///	Returns the default out signal.
+	signal_type &get_proxied_producer() const
+	{	return fused_out; }
         ///	Disconnects all slots connected to the signals::filter.
         void disconnect_all_slots() {fused_out.disconnect_all_slots();}
     
Modified: sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter_base.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter_base.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signal/component/filter_base.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -26,8 +26,9 @@
 #endif
 {
 public:
-    typedef boost::dataflow::signal_producer producer_category;
+//    typedef boost::dataflow::signal_producer producer_category;
     typedef boost::dataflow::signal_consumer consumer_category;
+    typedef boost::dataflow::mutable_proxy_producer proxy_producer_category;
 };
 
 } }
@@ -48,7 +49,7 @@
 /*template<class T>
 struct is_component<T, typename boost::enable_if<is_filter<T> >::type >
     : public boost::true_type { };*/
-        
+
 template<class T>
 struct get_signal<T, typename boost::enable_if<is_filter<T> >::type >
 {
Modified: sandbox/SOC/2007/signals/boost/dataflow/signal/connection/slot_selector.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signal/connection/slot_selector.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signal/connection/slot_selector.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -22,14 +22,19 @@
 {
     typedef Signature signature_type;
     typedef T class_type;
-    typedef typename boost::dataflow::signal_consumer consumer_category;
-    typedef typename boost::dataflow::signal_producer producer_category;
+    typedef boost::dataflow::signal_consumer consumer_category;
+    typedef T proxy_producer_for;
+    typedef boost::dataflow::mutable_proxy_producer proxy_producer_category;
+
     
         T &object;
         typename detail::slot_type<Signature, T>::type func;
     
         slot_selector(typename detail::slot_type<Signature, T>::type func, T &object)
                 : object(object), func(func) {}
+
+    typename boost::dataflow::get_proxied_producer_type<T>::type &get_proxied_producer() const
+    {   return boost::dataflow::get_proxied_producer(object);  }
 };
 
 /**	\brief Allows arbitrary member functions to serve as slots.
Modified: sandbox/SOC/2007/signals/boost/dataflow/signal/support.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signal/support.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signal/support.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -142,17 +142,25 @@
     };
 }
 
+/*
 template<typename T>
 struct produced_type_of<
-T,
-typename boost::enable_if<
-boost::is_base_of<
-signal_producer,
-typename producer_category_of<T>::type
->
->::type >
+    T,
+    typename boost::enable_if<
+        boost::is_base_of<
+            signal_producer,
+            typename producer_category_of<T>::type
+        >
+    >::type >
 {
     typedef typename boost::signals::detail::get_signature<typename extension::signals::get_signal_type<T>::type>::type type;
+};*/
+
+template<typename Signature, typename Combiner, typename Group, typename GroupCompare>
+struct produced_type_of<
+    boost::signal<Signature, Combiner, Group, GroupCompare> >
+{
+    typedef Signature type;
 };
 
 } } // namespace boost::dataflow
Modified: sandbox/SOC/2007/signals/boost/dataflow/support/connectable.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/support/connectable.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/support/connectable.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -35,8 +35,10 @@
     extension::connect_impl<
         typename producer_category_of<Producer>::type,
         typename consumer_category_of<Consumer>::type>
-            ::template apply<Producer,Consumer>
-                ::call(producer,consumer);
+            ::template apply<
+                typename get_proxied_producer_type<Producer>::type,
+                Consumer
+            >::call(get_proxied_producer(producer),consumer);
 }
 
 template<typename Producer, typename Consumer>
@@ -45,8 +47,10 @@
     extension::connect_impl<
         typename producer_category_of<Producer>::type,
         typename consumer_category_of<Consumer>::type>
-            ::template apply<Producer,Consumer>
-                ::call(producer,consumer);
+            ::template apply<
+                typename get_proxied_producer_type<Producer>::type,
+                Consumer
+            >::call(get_proxied_producer(producer),consumer);
 }
 
 template<typename Producer, typename Consumer>
@@ -55,8 +59,10 @@
     extension::connect_impl<
         typename producer_category_of<Producer>::type,
         typename consumer_category_of<Consumer>::type>
-            ::template apply<Producer,Consumer>
-                ::call(producer,consumer);
+            ::template apply<
+                typename get_proxied_producer_type<Producer>::type,
+                Consumer
+            >::call(get_proxied_producer(producer),consumer);
 }
 
 template<typename Producer, typename Consumer>
@@ -65,8 +71,10 @@
     extension::connect_impl<
         typename producer_category_of<Producer>::type,
         typename consumer_category_of<Consumer>::type>
-            ::template apply<Producer,Consumer>
-            ::call(producer,consumer);
+            ::template apply<
+                typename get_proxied_producer_type<Producer>::type,
+                Consumer
+            >::call(get_proxied_producer(producer),consumer);
 }
 
 } } // namespace boost::dataflow
Modified: sandbox/SOC/2007/signals/boost/dataflow/support/producer.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/support/producer.hpp	(original)
+++ sandbox/SOC/2007/signals/boost/dataflow/support/producer.hpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -7,54 +7,244 @@
 #define BOOST_DATAFLOW_SUPPORT_PRODUCER_HPP
 
 #include <boost/dataflow/detail/enable_if_defined.hpp>
+//#include <boost/dataflow/support/proxy.hpp>
 
-#include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/integral_constant.hpp>
+#include <boost/static_assert.hpp>
 
 
 namespace boost { namespace dataflow {
 
-// trait giving the producer category of a type.
 template<typename T, typename Enable=void>
-struct producer_category_of
+struct proxied_producer_of
 {
-    // Error: attempting to use T as a producer, but producer_category_of<T>
-    // has not been specialized!
-    BOOST_STATIC_ASSERT(sizeof(T)==0);
 };
 
 template<typename T>
-struct producer_category_of<T,
-typename detail::enable_if_defined<typename T::producer_category >::type >
+struct proxied_producer_of<T,
+typename detail::enable_if_defined<typename T::proxy_producer_for >::type >
 {
-    typedef typename T::producer_category type;
+    typedef typename T::proxy_producer_for type;
 };
 
-// trait determining whether a type is a producer.
+struct default_proxy_producer;
+struct mutable_proxy_producer;
+
 template<typename T, typename Enable=void>
-struct is_producer
+struct proxy_producer_category_of
+{
+    typedef default_proxy_producer type;
+};
+
+template<typename T>
+struct proxy_producer_category_of<T,
+typename detail::enable_if_defined<typename T::proxy_producer_category >::type >
+{
+    typedef typename T::proxy_producer_category type;
+};
+
+// trait determining whether a type is a producer proxy.
+template<typename T, typename Enable=void>
+struct is_proxy_producer
     : public boost::false_type {};
 
 template<typename T>
-struct is_producer<T, 
-        typename detail::enable_if_defined<typename producer_category_of<T>::type >::type >
+struct is_proxy_producer<T,
+        typename detail::enable_if_defined<
+            detail::all_of<
+                typename proxied_producer_of<T>::type,
+                typename proxy_producer_category_of<T>::type
+            >
+        >::type >
     : public boost::true_type {};
+
+template<typename T, typename Enable=void>
+struct get_proxied_producer_type
+{
+    typedef T type;
+};
+
+template<typename T>
+struct get_proxied_producer_type<T, 
+    typename boost::enable_if<is_proxy_producer<T> >::type>
+{
+    typedef
+        typename get_proxied_producer_type<
+            typename proxied_producer_of<T>::type
+        >::type type;
+};
+
+namespace extension
+{
+    template<typename ProxyProducerTag>
+    struct get_proxied_producer_impl
+    {
+        template<typename ProxyProducer>
+        struct apply
+        {
+            static void call(const ProxyProducer &)
+            {
+                // Error: get_proxied_producer_impl has not been implemented
+                // for ProxyProducerTag.
+                BOOST_STATIC_ASSERT(sizeof(ProxyProducer)==0);
+            }
+        };
+    };
+
+    template<>
+    struct get_proxied_producer_impl<default_proxy_producer>
+    {
+        template<typename ProxyProducer>
+        struct result
+        {
+            typedef typename
+                boost::dataflow::get_proxied_producer_type<ProxyProducer>::type & type;
+        };
+        
+        template<typename ProxyProducer>
+        struct result<const ProxyProducer>
+        {
+            typedef const typename
+                boost::dataflow::get_proxied_producer_type<ProxyProducer>::type & type;
+        };
+
+        template<typename ProxyProducer>
+        struct apply
+        {            
+            static typename
+            boost::dataflow::get_proxied_producer_type<ProxyProducer>::type &
+            call(ProxyProducer &t)
+            {
+                return t.get_proxied_producer();
+            }
+            static
+            const typename boost::dataflow::get_proxied_producer_type<ProxyProducer>::type &
+            call(const ProxyProducer &t)
+            {
+                return t.get_proxied_producer();
+            }
+        };
+    };
     
+    template<>
+    struct get_proxied_producer_impl<mutable_proxy_producer>
+    {
+        template<typename ProxyProducer>
+        struct result
+        {
+            typedef typename
+                boost::dataflow::get_proxied_producer_type<ProxyProducer>::type & type;
+        };
+
+        template<typename ProxyProducer>
+        struct apply
+        {
+            static
+            typename boost::dataflow::get_proxied_producer_type<ProxyProducer>::type &
+            call(const ProxyProducer &t)
+            {
+                return t.get_proxied_producer();
+            }
+        };
+    };
+
+}
+
+template<typename T>
+typename boost::disable_if<
+    is_proxy_producer<T>,
+    const T &
+>::type
+get_proxied_producer(const T &t)
+{
+    return t;
+}
+
+template<typename T>
+typename boost::disable_if<
+    is_proxy_producer<T>,
+    T &
+>::type
+get_proxied_producer(T &t)
+{
+    return t;
+}
+
+template<typename T>
+typename boost::lazy_enable_if<
+    is_proxy_producer<T>,
+    typename extension::get_proxied_producer_impl<
+        typename proxy_producer_category_of<T>::type>::template result<T>
+>::type
+get_proxied_producer(T &t)
+{
+    return extension::get_proxied_producer_impl<
+        typename proxy_producer_category_of<T>::type>::template apply<T>::call(t);
+}
+
+template<typename T>
+typename boost::lazy_enable_if<
+    is_proxy_producer<T>,
+    typename extension::get_proxied_producer_impl<
+        typename proxy_producer_category_of<T>::type>::template result<const T>
+>::type
+get_proxied_producer(const T &t)
+{
+    return extension::get_proxied_producer_impl<
+        typename proxy_producer_category_of<T>::type>::template apply<T>::call(t);
+}
+
+// trait giving the producer category of a type.
+template<typename T, typename Enable=void>
+struct producer_category_of
+{
+};
+
+template<typename T>
+struct producer_category_of<T,
+typename detail::enable_if_defined<typename T::producer_category >::type >
+{
+    typedef typename T::producer_category type;
+};
+
+template<typename T>
+struct producer_category_of<T,
+    typename boost::enable_if<is_proxy_producer<T> >::type>
+{
+    typedef
+        typename producer_category_of<
+            typename get_proxied_producer_type<T>::type
+        >::type type;
+};
+
 template<typename T, typename Enable=void>
 struct produced_type_of
 {
-    // Error: attempting to use T as a producer, but produced_type_of<T>
-    // has not been specialized!
-    BOOST_STATIC_ASSERT(sizeof(T)==0);
 };
 
 template<typename T>
-struct produced_type_of<T,
-typename detail::enable_if_defined<typename T::produced_type>::type >
+struct produced_type_of<T, typename boost::enable_if<is_proxy_producer<T> >::type>
 {
-    typedef typename T::produced_type type;
+    typedef
+        typename produced_type_of<
+            typename get_proxied_producer_type<T>::type
+        >::type type;
 };
 
+// trait determining whether a type is a producer.
+template<typename T, typename Enable=void>
+struct is_producer
+    : public boost::false_type {};
+
+template<typename T>
+struct is_producer<T, 
+        typename detail::enable_if_defined<detail::all_of<
+            typename producer_category_of<T>::type,
+            typename produced_type_of<T>::type
+        > >::type >
+    : public boost::true_type {};
+
 } } // namespace boost::dataflow
 
 #endif // BOOST_DATAFLOW_SUPPORT_PRODUCER_HPP
Added: sandbox/SOC/2007/signals/libs/dataflow/doc/components.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/components.qbk	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -0,0 +1,63 @@
+[section Components]
+
+[section producer_group]
+
+[heading Model of]
+* [ProducerConcept]
+
+[heading Description]
+
+A [producer_group] collects multiple producers in a group, so that they
+can be connected all together to a [consumer_group].  The connections
+are made element-wise, i.e, the first producer in the [producer_group] is
+connected to the first consumer in the [consumer_group], the second
+producer to the second consumer, etc. [producer_group]
+is a wrapper for [BoostFusion] sequences which allows them to be
+used in this fashion.
+
+Examples of connections between [producer_group] and [consumer_group] objects,
+as well as grouping components together using `operator&` can be seen
+in the [DataflowPhoenix] documentation.
+
+[endsect][/producer_group]
+
+[section consumer_group]
+
+[heading Model of]
+* [ProducerConcept]
+
+[heading Description]
+
+A [consumer_group] collects multiple consumers in a group, so that they
+can be connected all together to a [producer_group].  The connections
+are made element-wise, i.e, the first producer in the [producer_group] is
+connected to the first consumer in the [consumer_group], the second
+producer to the second consumer, etc. [consumer_group]
+is a wrapper for [BoostFusion] sequences which allows them to be
+used in this fashion.
+
+Examples of connections between [producer_group] and [consumer_group] objects,
+as well as grouping components together using `operator&` can be seen
+in the [DataflowPhoenix] documentation.
+
+[endsect][/consumer_group]
+
+[section consumer_map]
+
+A [consumer_map] groups together multiple consumers, keyed by type they consume.
+When a [ProducerConcept] is connected to a [consumer_map], the consumer
+whose key matches the [ProducerConcept]'s produced type will be chosen for
+the connection.
+[consumer_map] is a wrapper for [BoostFusion] maps which allows them to be
+used in this fashion.
+
+
+A [consumer_map] is used as the return type of [^[storage].send_slot()],
+which and includes the [slot_selector] for both the fused and unfused
+versions of the `send()` function.  The appropriate slot is selected when
+a connection is made, based on the [ProducerConcept]'s outgoing signal
+signature.
+
+[endsect][/consumer_map]
+
+[endsect]
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk	(original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -27,7 +27,8 @@
 [heading Components]
 
 We will call the fundamental processing elements of a dataflow program
-/components/, which have two categories:
+/components/.  A component can have a number of connectable interfaces
+(inputs\/outputs), which have two categories:
 
 * /producers/, which produce data; and
 * /consumers/, which consume data.
@@ -38,7 +39,20 @@
 that consumes data - a function that takes an argument, a functor, etc.
 
 Producers and consumers are captured more formally by the [ProducerConcept]
-and [ConsumerConcept] concepts.
+and [ConsumerConcept] concepts.  There is no concept directly corresponding to
+a component, because a component is a more abstract notion - i.e., a component
+is whatever makes sense for the design application.  Typically, though, a
+component is embedded in a class, and the different [ProducerConcept]s
+and [ConsumerConcept]s are accessible either through the class
+directly, or through its member functions and variables.
+
+[heading Proxies]
+
+It is often the case that a component delegates its [ProducerConcept] or
+[ConsumerConcept] functionality to some other element.  For example, a
+class that is a [DataflowSignals] component might delegate its
+[ProducerConcept] functionality to a member boost::signal.  It can
+do so by declaring itself a [ProxyProducerConcept] for the boost::signal.
 
 [heading Connections]
 
@@ -51,6 +65,7 @@
 
 Connectability is captured more formally by the [ConnectableConcept] concept.
 
+
 [/
 [heading Push and pull]
 
@@ -169,6 +184,66 @@
 
 [endsect][/producer]
 
+
+[section ProxyProducer]
+
+A type `PP` is a ['[ProxyProducerConcept]] if specifies the proxied producer
+type, and if objects of the proxied type can be retreived from objects of
+[ProxyProducerConcept] type.  If the proxied producer type is a valid
+[ProducerConcept], then 'PP' satisfies the [ProducerConcept] requirements
+in the same way.
+
+[heading Notation]
+The following expressions are used in this document:
+
+[variablelist
+    [[PP] [A ProxyProducer type.]]
+    [[pp] [An object of type `PP`]]
+]
+
+[heading Requirements]
+[table
+    [[Name] [Expression] [Result Type] [Semantics]]
+    [
+        [Proxy Producer Category]
+        [`proxy_producer_category_of<PP>::type`
+         [footnote `namespace boost::dataflow`]]
+        [Any type]
+        [
+            The category of the proxy producer, used for tag forwarding.
+        ]
+    ]
+    [
+        [Proxied Producer Type]
+        [`proxied_producer_of<PP>::type`
+         [footnote `namespace boost::dataflow`]]
+        [Any type]
+        [
+            The proxied producer type.
+        ]
+    ]
+    [
+        [Proxied Producer]
+        [`get_proxied_producer(pp)`
+         [footnote `namespace boost::dataflow`]]
+        []
+        [
+            Retrieves a reference to the proxied producer object.
+        ]
+    ]
+]
+
+[heading Notes]
+
+To define a new [ProxyProducerConcept] class type, it is sufficient to define
+member typedefs `proxy_producer_category` and `proxy_producer_for`,
+and member function `get_proxied_producer`.
+
+[heading Examples]
+
+[endsect][/proxyproducer]
+
+
 [section Consumer]
 
 A type `T` is a /consumer/ if it defines a consumer category.
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk	(original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -15,6 +15,7 @@
 [template ConsumerConcept[] [link dataflow.concepts.consumer [^Consumer]]]
 [template InvocableConcept[] [link dataflow.concepts.invocable [^Invocable]]]
 [template ConnectableConcept[] [link dataflow.concepts.connectable [^Connectable]]]
+[template ProxyProducerConcept[] [link dataflow.concepts.proxyproducer [^ProxyProducer]]]
 [template SignalProducerConcept[] [link dataflow.signals.concepts.signalproducer [^SignalProducer]]]
 [template SignalConsumerConcept[] [link dataflow.signals.concepts.signalconsumer [^SignalConsumer]]]
 [template PhoenixProducerConcept[] [link dataflow.concepts.phoenix.phoenixproducer [^PhoenixProducer]]]
Modified: sandbox/SOC/2007/signals/libs/dataflow/test/test_socket.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/test/test_socket.cpp	(original)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/test_socket.cpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -19,6 +19,10 @@
 //[ test_socket
 
 using namespace boost;
+namespace boost { namespace signals {
+    using boost::dataflow::operators::operator|;
+    using boost::dataflow::operators::operator>>=;
+} }
 
 mutex mutex_;
 condition cond;
@@ -29,8 +33,6 @@
 // its final signal through the socket.
 void asio_server()
 {
-    using namespace boost::dataflow::operators;
-
         // set up the socket
         asio::ip::tcp::acceptor acceptor(io_service, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 1097));
         asio::ip::tcp::socket socket(io_service);
@@ -55,8 +57,6 @@
 
 int test_main(int, char* [])
 {
-    using namespace boost::dataflow::operators;
-
         // start the server in a separate thread
         boost::mutex::scoped_lock lock(mutex_);
         boost::thread t(asio_server);
Modified: sandbox/SOC/2007/signals/libs/dataflow/test/test_storage.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/test/test_storage.cpp	(original)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/test_storage.cpp	2007-08-19 23:00:10 EDT (Sun, 19 Aug 2007)
@@ -20,6 +20,13 @@
         signals::storage<void (float), signals::unfused> floater(2.5f);
         signals::storage<void (float), signals::unfused> collector(0.0f);
 
+        typedef dataflow::proxied_producer_of<typeof(floater.send_slot())> test;
+        typedef dataflow::is_proxy_producer<typeof(floater.send_slot())> test2;
+        typedef dataflow::is_producer<typeof(floater.send_slot())> test3;
+        
+        BOOST_STATIC_ASSERT(test2::value);
+        BOOST_STATIC_ASSERT(test3::value);
+        
         // create the network (banger to floater.send, floater to collector)
         banger >>= floater.send_slot() >>= collector;