|
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><R, T1, T2, ..., TN></default>
</template-type-parameter>
+ <template-type-parameter name="ExtendedSlotFunction">
+ <default><classname>function</classname><R (const <classname>connection</classname> &, T1, T2, ..., TN)></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><R, T1, T2, ..., TN, SlotFunction></type>
</typedef>
+ <typedef name="extended_slot_function_type"><type>ExtendedSlotFunction</type></typedef>
+ <typedef name="extended_slot_type">
+ <type><classname>slotN</classname><R, const <classname>connection</classname> &, T1, T2, ..., TN, ExtendedSlotFunction></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&</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&</paramtype>
+ </parameter>
+ <parameter name="slot">
+ <paramtype>const extended_slot_type&</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><Signature></default>
</template-type-parameter>
+ <template-type-parameter name="ExtendedSlotFunction">
+ <default><classname>functionN</classname><R, const <classname>connection</classname> &, T1, T2, ..., TN></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><R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, Mutex></type>
+ <type><classname>signalN</classname><R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex></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