Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49182 - in sandbox/thread_safe_signals/trunk: boost/signals2 boost/signals2/detail libs/signals2/doc/reference libs/signals2/test
From: fmhess_at_[hidden]
Date: 2008-10-08 14:11:24


Author: fmhess
Date: 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
New Revision: 49182
URL: http://svn.boost.org/trac/boost/changeset/49182

Log:
Added extended_slot_type and connect_extended() to signal classes.

Text files modified:
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp | 267 +++++++++++++++++++++++++++++++++------
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/signals_common_macros.hpp | 9 +
   sandbox/thread_safe_signals/trunk/boost/signals2/shared_connection_block.hpp | 2
   sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp | 28 +++
   sandbox/thread_safe_signals/trunk/boost/signals2/slot.hpp | 2
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/signal_header.xml | 54 +++++++
   sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp | 48 +++++-
   sandbox/thread_safe_signals/trunk/libs/signals2/test/threading_models_test.cpp | 4
   8 files changed, 353 insertions(+), 61 deletions(-)

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -25,6 +25,7 @@
   typename Group = int, \
   typename GroupCompare = std::less<Group>, \
   typename SlotFunction = BOOST_FUNCTION_N_DECL(BOOST_SIGNALS_NUM_ARGS), \
+ typename ExtendedSlotFunction = BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(BOOST_SIGNALS_NUM_ARGS), \
   typename Mutex = signals2::mutex
 // typename R, typename T1, typename T2, ..., typename TN, typename Combiner, ...
 #define BOOST_SIGNAL_TEMPLATE_DECL \
@@ -33,11 +34,14 @@
   typename Group, \
   typename GroupCompare, \
   typename SlotFunction, \
+ typename ExtendedSlotFunction, \
   typename Mutex
-// R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, Mutex
+// R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
 #define BOOST_SIGNAL_TEMPLATE_INSTANTIATION \
   BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS), \
- Combiner, Group, GroupCompare, SlotFunction, Mutex
+ Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
+// bound_extended_slot_functionN
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N BOOST_PP_CAT(bound_extended_slot_function, BOOST_SIGNALS_NUM_ARGS)
 
 namespace boost
 {
@@ -45,6 +49,101 @@
   {
     namespace detail
     {
+// wrapper around an signalN::extended_slot_function which binds the
+// connection argument so it looks like a normal
+// signalN::slot_function
+ template<typename ExtendedSlotFunction, typename ResultType>
+ class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N
+ {
+ public:
+ BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(const ExtendedSlotFunction &fun):
+ _fun(fun), _connection(new connection)
+ {}
+ void set_connection(const connection &conn)
+ {
+ *_connection = conn;
+ }
+// typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNALS2_MISC_TEMPLATE_DECL \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(BOOST_SIGNALS_NUM_ARGS), typename T)
+// Tn & argn
+#define BOOST_SIGNALS2_FULL_REF_ARG(z, n, data) \
+ BOOST_PP_CAT(T, BOOST_PP_INC(n)) & BOOST_SIGNAL_SIGNATURE_ARG_NAME(~, n, ~)
+// T1 & arg1, T2 & arg2, ..., Tn & argn
+#define BOOST_SIGNALS2_FULL_REF_ARGS(arity) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_FULL_REF_ARG, ~)
+
+#if BOOST_SIGNALS_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_MISC_TEMPLATE_DECL>
+#endif // BOOST_SIGNALS_NUM_ARGS > 0
+ ResultType operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ return _fun(*_connection BOOST_PP_COMMA_IF(BOOST_SIGNALS_NUM_ARGS)
+ BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ // const overload
+#if BOOST_SIGNALS_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_MISC_TEMPLATE_DECL>
+#endif // BOOST_SIGNALS_NUM_ARGS > 0
+ ResultType operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ return _fun(*_connection BOOST_PP_COMMA_IF(BOOST_SIGNALS_NUM_ARGS)
+ BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ template<typename T>
+ bool operator==(const T &other) const
+ {
+ return _fun == other;
+ }
+ private:
+ BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N()
+ {}
+
+ ExtendedSlotFunction _fun;
+ boost::shared_ptr<connection> _connection;
+ };
+ // specialization for void return type
+ template<typename ExtendedSlotFunction>
+ class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N<ExtendedSlotFunction, void>
+ {
+ public:
+ BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(const ExtendedSlotFunction &fun):
+ _fun(fun), _connection(new connection)
+ {}
+ void set_connection(const connection &conn)
+ {
+ *_connection = conn;
+ }
+#if BOOST_SIGNALS_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_MISC_TEMPLATE_DECL>
+#endif // BOOST_SIGNALS_NUM_ARGS > 0
+ void operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ _fun(*_connection BOOST_PP_COMMA_IF(BOOST_SIGNALS_NUM_ARGS)
+ BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ // const overload
+#if BOOST_SIGNALS_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_MISC_TEMPLATE_DECL>
+#endif // BOOST_SIGNALS_NUM_ARGS > 0
+ void operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ _fun(*_connection BOOST_PP_COMMA_IF(BOOST_SIGNALS_NUM_ARGS)
+ BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ template<typename T>
+ bool operator==(const T &other) const
+ {
+ return _fun == other;
+ }
+ private:
+ ExtendedSlotFunction _fun;
+ boost::shared_ptr<connection> _connection;
+ };
+#undef BOOST_SIGNALS2_MISC_TEMPLATE_DECL
+#undef BOOST_SIGNALS2_FULL_REF_ARG
+#undef BOOST_SIGNALS2_FULL_REF_ARGS
+
       template<BOOST_SIGNAL_TEMPLATE_DECL>
       class BOOST_SIGNAL_IMPL_CLASS_NAME
       {
@@ -53,13 +152,20 @@
         // typedef slotN<Signature, SlotFunction> slot_type;
         typedef BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)<BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS),
           slot_function_type> slot_type;
+ typedef ExtendedSlotFunction extended_slot_function_type;
+ // typedef slotN<R, const connection &, T1, T2, ..., TN, extended_slot_function_type> extended_slot_type;
+ typedef BOOST_SLOT_CLASS_NAME(BOOST_PP_INC(BOOST_SIGNALS_NUM_ARGS))<
+ BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS),
+ extended_slot_function_type> extended_slot_type;
       private:
         class slot_invoker;
         typedef typename group_key<Group>::type group_key_type;
         typedef shared_ptr<connection_body<group_key_type, slot_type, Mutex> > connection_body_type;
         typedef grouped_list<Group, GroupCompare, connection_body_type> connection_list_type;
+ typedef BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N<extended_slot_function_type, typename extended_slot_function_type::result_type>
+ bound_extended_slot_function_type;
       public:
- typedef typename slot_function_type::result_type slot_result_type;
+ typedef typename slot_result_type_wrapper<typename slot_function_type::result_type>::type slot_result_type;
         typedef Combiner combiner_type;
         typedef typename combiner_type::result_type result_type;
         typedef Group group_type;
@@ -76,38 +182,33 @@
         connection connect(const slot_type &slot, connect_position position = at_back)
         {
           unique_lock<mutex_type> lock(_mutex);
- connection_body_type newConnectionBody =
- create_new_connection(slot);
- group_key_type group_key;
- if(position == at_back)
- {
- group_key.first = back_ungrouped_slots;
- _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
- }else
- {
- group_key.first = front_ungrouped_slots;
- _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
- }
- newConnectionBody->set_group_key(group_key);
- return connection(newConnectionBody);
+ return nolock_connect(slot, position);
         }
         connection connect(const group_type &group,
           const slot_type &slot, connect_position position = at_back)
         {
           unique_lock<Mutex> lock(_mutex);
- connection_body_type newConnectionBody =
- create_new_connection(slot);
- // update map to first connection body in group if needed
- group_key_type group_key(grouped_slots, group);
- newConnectionBody->set_group_key(group_key);
- if(position == at_back)
- {
- _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
- }else // at_front
- {
- _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
- }
- return connection(newConnectionBody);
+ return nolock_connect(group, slot, position);
+ }
+ // connect extended slot
+ connection connect_extended(const extended_slot_type &ext_slot, connect_position position = at_back)
+ {
+ unique_lock<mutex_type> lock(_mutex);
+ bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+ slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+ connection conn = nolock_connect(slot, position);
+ bound_slot.set_connection(conn);
+ return conn;
+ }
+ connection connect_extended(const group_type &group,
+ const extended_slot_type &ext_slot, connect_position position = at_back)
+ {
+ unique_lock<Mutex> lock(_mutex);
+ bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+ slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+ connection conn = nolock_connect(group, slot, position);
+ bound_slot.set_connection(conn);
+ return conn;
         }
         // disconnect slot(s)
         void disconnect_all_slots()
@@ -158,7 +259,7 @@
           }
           slot_invoker invoker BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, \
             (BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)), );
- optional<typename slot_result_type_wrapper<slot_result_type>::type > cache;
+ optional<slot_result_type> cache;
           return local_state->combiner(
             slot_call_iterator(local_state->connection_bodies.begin(), local_state->connection_bodies.end(), invoker, cache),
             slot_call_iterator(local_state->connection_bodies.end(), local_state->connection_bodies.end(), invoker, cache));
@@ -179,7 +280,7 @@
           }
           slot_invoker invoker BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, \
             (BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)), );
- optional<typename slot_result_type_wrapper<slot_result_type>::type > cache;
+ optional<slot_result_type> cache;
           return const_cast<const combiner_type&>(local_state->combiner)(
             slot_call_iterator(local_state->connection_bodies.begin(), local_state->connection_bodies.end(), invoker, cache),
             slot_call_iterator(local_state->connection_bodies.end(), local_state->connection_bodies.end(), invoker, cache));
@@ -229,7 +330,7 @@
         class slot_invoker
         {
         public:
- typedef typename slot_result_type_wrapper<slot_result_type>::type result_type;
+ typedef slot_result_type result_type;
 
           slot_invoker(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, :, )
 // argn ( argn ) ,
@@ -358,9 +459,53 @@
             if((*it)->slot.slot_function() == slot)
             {
               (*it)->nolock_disconnect();
+ }else
+ {
+ // check for wrapped extended slot
+ bound_extended_slot_function_type *fp;
+ fp = (*it)->slot.slot_function().template target<bound_extended_slot_function_type>();
+ if(fp && *fp == slot)
+ {
+ (*it)->nolock_disconnect();
+ }
             }
           }
         }
+ // connect slot
+ connection nolock_connect(const slot_type &slot, connect_position position)
+ {
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ group_key_type group_key;
+ if(position == at_back)
+ {
+ group_key.first = back_ungrouped_slots;
+ _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
+ }else
+ {
+ group_key.first = front_ungrouped_slots;
+ _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
+ }
+ newConnectionBody->set_group_key(group_key);
+ return connection(newConnectionBody);
+ }
+ connection nolock_connect(const group_type &group,
+ const slot_type &slot, connect_position position)
+ {
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ // update map to first connection body in group if needed
+ group_key_type group_key(grouped_slots, group);
+ newConnectionBody->set_group_key(group_key);
+ if(position == at_back)
+ {
+ _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
+ }else // at_front
+ {
+ _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
+ }
+ return connection(newConnectionBody);
+ }
 
         shared_ptr<invocation_state> _shared_state;
         mutable typename connection_list_type::iterator _garbage_collector_it;
@@ -376,20 +521,22 @@
     template<BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL>
     class BOOST_SIGNAL_CLASS_NAME: public signal_base
     {
+ typedef detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> impl_class;
     public:
       typedef detail::BOOST_WEAK_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> weak_signal_type;
       friend class detail::BOOST_WEAK_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>;
 
       typedef SlotFunction slot_function_type;
       // typedef slotN<Signature, SlotFunction> slot_type;
- typedef BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)<BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS),
- slot_function_type> slot_type;
- typedef typename slot_function_type::result_type slot_result_type;
+ typedef typename impl_class::slot_type slot_type;
+ typedef typename impl_class::extended_slot_function_type extended_slot_function_type;
+ typedef typename impl_class::extended_slot_type extended_slot_type;
+ typedef typename impl_class::slot_result_type slot_result_type;
       typedef Combiner combiner_type;
       typedef typename combiner_type::result_type result_type;
       typedef Group group_type;
       typedef GroupCompare group_compare_type;
- typedef typename detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>::slot_call_iterator
+ typedef typename impl_class::slot_call_iterator
         slot_call_iterator;
 // typedef Tn argn_type;
 #define BOOST_SIGNAL_MISC_STATEMENT(z, n, data) \
@@ -406,7 +553,7 @@
 
       BOOST_SIGNAL_CLASS_NAME(const combiner_type &combiner = combiner_type(),
         const group_compare_type &group_compare = group_compare_type()):
- _pimpl(new detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>(combiner, group_compare))
+ _pimpl(new impl_class(combiner, group_compare))
       {};
       virtual ~BOOST_SIGNAL_CLASS_NAME()
       {
@@ -421,6 +568,15 @@
       {
         return (*_pimpl).connect(group, slot, position);
       }
+ connection connect_extended(const extended_slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect_extended(slot, position);
+ }
+ connection connect_extended(const group_type &group,
+ const extended_slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect_extended(group, slot, position);
+ }
       void disconnect_all_slots()
       {
         (*_pimpl).disconnect_all_slots();
@@ -464,7 +620,7 @@
         return _pimpl;
       }
     private:
- shared_ptr<detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> >
+ shared_ptr<impl_class>
         _pimpl;
     };
 
@@ -476,7 +632,7 @@
       {
       public:
         typedef SlotFunction slot_function_type;
- typedef typename slot_function_type::result_type slot_result_type;
+ typedef typename slot_result_type_wrapper<typename slot_function_type::result_type>::type slot_result_type;
         typedef typename BOOST_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>::result_type
           result_type;
 
@@ -504,20 +660,42 @@
       };
 
       template<unsigned arity, typename Signature, typename Combiner,
- typename Group, typename GroupCompare, typename SlotFunction, typename Mutex>
+ typename Group, typename GroupCompare, typename SlotFunction,
+ typename ExtendedSlotFunction, typename Mutex>
       class signalN;
       // partial template specialization
       template<typename Signature, typename Combiner, typename Group,
- typename GroupCompare, typename SlotFunction, typename Mutex>
+ typename GroupCompare, typename SlotFunction,
+ typename ExtendedSlotFunction, typename Mutex>
       class signalN<BOOST_SIGNALS_NUM_ARGS, Signature, Combiner, Group,
- GroupCompare, SlotFunction, Mutex>
+ GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>
       {
       public:
         typedef BOOST_SIGNAL_CLASS_NAME<
           BOOST_SIGNAL_PORTABLE_SIGNATURE(BOOST_SIGNALS_NUM_ARGS, Signature),
           Combiner, Group,
- GroupCompare, SlotFunction, Mutex> type;
+ GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> type;
       };
+
+ template<int arity, typename Signature>
+ class extended_signature;
+ // partial template specialization
+ template<typename Signature>
+ class extended_signature<BOOST_SIGNALS_NUM_ARGS, Signature>
+ {
+ public:
+// typename function_traits<Signature>::result_type (
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type)
+#define BOOST_SIGNALS2_EXT_SIGNATURE(arity, Signature) \
+ typename function_traits<Signature>::result_type ( \
+ BOOST_PP_ENUM(arity, BOOST_SIGNAL_SIGNATURE_TO_ARGN_TYPE, Signature) )
+ typedef function<BOOST_SIGNALS2_EXT_SIGNATURE(BOOST_SIGNALS_NUM_ARGS, Signature)> function_type;
+#undef BOOST_SIGNALS2_EXT_SIGNATURE
+ };
+
     } // namespace detail
   } // namespace signals2
 } // namespace boost
@@ -529,3 +707,4 @@
 #undef BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL
 #undef BOOST_SIGNAL_TEMPLATE_DECL
 #undef BOOST_SIGNAL_TEMPLATE_INSTANTIATION
+#undef BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/detail/signals_common_macros.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/detail/signals_common_macros.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/detail/signals_common_macros.hpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -12,7 +12,7 @@
 #define BOOST_SIGNALS_COMMON_MACROS_HEADER
 
 #ifndef BOOST_SIGNALS_MAX_ARGS
-#define BOOST_SIGNALS_MAX_ARGS 10
+#define BOOST_SIGNALS_MAX_ARGS 9
 #endif
 
 // argn
@@ -40,6 +40,13 @@
 // functionN<R, T1, T2, ..., TN>
 #define BOOST_FUNCTION_N_DECL(arity) BOOST_PP_CAT(function, arity)<\
   BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(arity) >
+// R, const boost::signals2::connection&, T1, T2, ..., TN
+#define BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) \
+ R, const boost::signals2::connection& BOOST_PP_COMMA_IF(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// functionN<R, const boost::signals2::connection &, T1, T2, ..., TN>
+#define BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(arity) BOOST_PP_CAT(function, BOOST_PP_INC(arity))<\
+ BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) >
 // slotN
 #define BOOST_SLOT_CLASS_NAME(arity) BOOST_PP_CAT(slot, arity)
 // typename function_traits<Signature>::argn_type

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/shared_connection_block.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/shared_connection_block.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/shared_connection_block.hpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -22,7 +22,7 @@
     class shared_connection_block
     {
     public:
- shared_connection_block(connection &conn):
+ shared_connection_block(const connection &conn):
         _weak_connection_body(conn._weak_connection_body)
       {
         block();

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -37,6 +37,29 @@
 #include <boost/signals2/slot.hpp>
 #include <functional>
 
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<typename ResultSlot, typename SlotIn, typename SlotFunction>
+ ResultSlot replace_slot_function(const SlotIn &slot_in, const SlotFunction &fun)
+ {
+ ResultSlot slot(fun);
+ slot_base::tracked_container_type tracked_objects = slot_in.tracked_objects();
+ slot_base::tracked_container_type::const_iterator it;
+ for(it = tracked_objects.begin(); it != tracked_objects.end(); ++it)
+ {
+ slot.track(*it);
+ }
+ return slot;
+ }
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+
 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS_MAX_ARGS)
 #define BOOST_PP_FILENAME_1 <boost/signals2/detail/signal_template.hpp>
 #include BOOST_PP_ITERATE()
@@ -50,13 +73,14 @@
       typename Group = int,
       typename GroupCompare = std::less<Group>,
       typename SlotFunction = function<Signature>,
+ typename ExtendedSlotFunction = typename detail::extended_signature<function_traits<Signature>::arity, Signature>::function_type,
       typename Mutex = mutex >
     class signal: public detail::signalN<function_traits<Signature>::arity,
- Signature, Combiner, Group, GroupCompare, SlotFunction, Mutex>::type
+ Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type
     {
     private:
       typedef typename detail::signalN<boost::function_traits<Signature>::arity,
- Signature, Combiner, Group, GroupCompare, SlotFunction, Mutex>::type base_type;
+ Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type base_type;
     public:
       signal(const Combiner &combiner = Combiner(), const GroupCompare &group_compare = GroupCompare()):
         base_type(combiner, group_compare)

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/slot.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/slot.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/slot.hpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -82,7 +82,7 @@
   }
 } // end namespace boost
 
-#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS_MAX_ARGS)
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_INC(BOOST_SIGNALS_MAX_ARGS))
 #define BOOST_PP_FILENAME_1 <boost/signals2/detail/slot_template.hpp>
 #include BOOST_PP_ITERATE()
 

Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/signal_header.xml
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/signal_header.xml (original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/signal_header.xml 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -29,6 +29,9 @@
           <template-type-parameter name="SlotFunction">
             <default><classname>functionN</classname>&lt;R, T1, T2, ..., TN&gt;</default>
           </template-type-parameter>
+ <template-type-parameter name="ExtendedSlotFunction">
+ <default><classname>function</classname>&lt;R (const <classname>connection</classname> &amp;, T1, T2, ..., TN)&gt;</default>
+ </template-type-parameter>
           <template-type-parameter name="Mutex">
             <default><classname>mutex</classname></default>
           </template-type-parameter>
@@ -59,6 +62,18 @@
         <typedef name="slot_type">
           <type><classname>slotN</classname>&lt;R, T1, T2, ..., TN, SlotFunction&gt;</type>
         </typedef>
+ <typedef name="extended_slot_function_type"><type>ExtendedSlotFunction</type></typedef>
+ <typedef name="extended_slot_type">
+ <type><classname>slotN</classname>&lt;R, const <classname>connection</classname> &amp;, T1, T2, ..., TN, ExtendedSlotFunction&gt;</type>
+ <description>
+ <para>Slots of the <code>extended_slot_type</code> may be connected to the signal using the
+ <methodname>connect_extended</methodname> methods. The <code>extended_slot_type</code>
+ has an additional <classname>connection</classname> argument in its signature,
+ which gives slot functions access to their connection to the signal
+ invoking them.
+ </para>
+ </description>
+ </typedef>
         <typedef name="slot_result_type">
           <type><emphasis>unspecified</emphasis></type>
         </typedef>
@@ -165,6 +180,40 @@
             signal is calling will result in the slot being called
             immediately.</para></notes>
           </overloaded-method>
+ <overloaded-method name="connect_extended">
+ <signature>
+ <type><classname>connection</classname></type>
+ <parameter name="slot">
+ <paramtype>const extended_slot_type&amp;</paramtype>
+ </parameter>
+ <parameter name="at">
+ <paramtype>connect_position</paramtype>
+ <default>at_back</default>
+ </parameter>
+ </signature>
+
+ <signature>
+ <type><classname>connection</classname></type>
+ <parameter name="group">
+ <paramtype>const group_type&amp;</paramtype>
+ </parameter>
+ <parameter name="slot">
+ <paramtype>const extended_slot_type&amp;</paramtype>
+ </parameter>
+ <parameter name="at">
+ <paramtype>connect_position</paramtype>
+ <default>at_back</default>
+ </parameter>
+ </signature>
+ <description>
+ <para>
+ The <code>connect_extended</code> methods work the same as the <methodname>connect</methodname>
+ methods, except they take slots of type <classname>extended_slot_type</classname>.
+ This is useful if a slot needs to access the connection between it and the
+ signal invoking it, for example if it wishes to disconnect or block the connection.
+ </para>
+ </description>
+ </overloaded-method>
 
           <overloaded-method name="disconnect">
             <signature>
@@ -343,13 +392,16 @@
           <template-type-parameter name="SlotFunction">
             <default><classname>function</classname>&lt;Signature&gt;</default>
           </template-type-parameter>
+ <template-type-parameter name="ExtendedSlotFunction">
+ <default><classname>functionN</classname>&lt;R, const <classname>connection</classname> &amp;, T1, T2, ..., TN&gt;</default>
+ </template-type-parameter>
           <template-type-parameter name="Mutex">
             <default><classname>mutex</classname></default>
           </template-type-parameter>
         </template>
 
         <inherit access="public">
- <type><classname>signalN</classname>&lt;R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, Mutex&gt;</type>
+ <type><classname>signalN</classname>&lt;R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex&gt;</type>
         </inherit>
         <purpose>Safe multicast callback.</purpose>
 

Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp (original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -220,18 +220,47 @@
   BOOST_CHECK(*result == 1);
 }
 
-static void disconnecting_slot()
+template<typename ResultType>
+ ResultType disconnecting_slot(const boost::signals2::connection &conn, int)
 {
- throw boost::signals2::expired_slot();
+ conn.disconnect();
+ return ResultType();
 }
 
-static void test_slot_expired_disconnect()
+template<typename ResultType>
+ void test_extended_slot()
 {
- boost::signals2::signal0<void> sig;
- sig.connect(&disconnecting_slot);
- BOOST_CHECK(sig.num_slots() == 1);
- sig();
- BOOST_CHECK(sig.num_slots() == 0);
+ {
+ typedef boost::signals2::signal1<ResultType, int> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ slot_type myslot(&disconnecting_slot<ResultType>);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig(0);
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ { // test 0 arg signal
+ typedef boost::signals2::signal0<ResultType> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ slot_type myslot(&disconnecting_slot<ResultType>, _1, 0);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig();
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
+ // test disconnection by slot
+ {
+ typedef boost::signals2::signal1<ResultType, int> signal_type;
+ typedef typename signal_type::extended_slot_type slot_type;
+ signal_type sig;
+ slot_type myslot(&disconnecting_slot<ResultType>);
+ sig.connect_extended(myslot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig.disconnect(&disconnecting_slot<ResultType>);
+ BOOST_CHECK(sig.num_slots() == 0);
+ }
 }
 
 int
@@ -242,6 +271,7 @@
   test_signal_signal_connect();
   test_ref();
   test_default_combiner();
- test_slot_expired_disconnect();
+ test_extended_slot<void>();
+ test_extended_slot<int>();
   return 0;
 }

Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/threading_models_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/threading_models_test.cpp (original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/threading_models_test.cpp 2008-10-08 14:11:22 EDT (Wed, 08 Oct 2008)
@@ -52,10 +52,10 @@
 int test_main(int, char*[])
 {
   typedef boost::signals2::signal<void (), slot_counter, int, std::less<int>, boost::function<void ()>,
- boost::mutex> sig0_mt_type;
+ boost::function<void (const boost::signals2::connection &)>, boost::mutex> sig0_mt_type;
   simple_test<sig0_mt_type>();
   typedef boost::signals2::signal<void (), slot_counter, int, std::less<int>, boost::function<void ()>,
- boost::signals2::dummy_mutex> sig0_st_type;
+ boost::function<void (const boost::signals2::connection &)>, boost::signals2::dummy_mutex> sig0_st_type;
   simple_test<sig0_st_type>();
   return 0;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk