1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/signals/signal_template.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,410 @@
1.4 +// Boost.Signals library
1.5 +
1.6 +// Copyright Douglas Gregor 2001-2004. Use, modification and
1.7 +// distribution is subject to the Boost Software License, Version
1.8 +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.9 +// http://www.boost.org/LICENSE_1_0.txt)
1.10 +
1.11 +// For more information, see http://www.boost.org
1.12 +
1.13 +// This file intentionally does not have include guards, because it is meant
1.14 +// to be included multiple times (one for each signalN class). The
1.15 +// BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED macro merely serves to
1.16 +// suppress reinclusion of the files that this header depends on.
1.17 +
1.18 +#ifndef BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED
1.19 +#define BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED
1.20 +# include <boost/config.hpp>
1.21 +# include <boost/signals/connection.hpp>
1.22 +# include <boost/utility.hpp>
1.23 +# include <boost/ref.hpp>
1.24 +# include <boost/signals/slot.hpp>
1.25 +# include <boost/last_value.hpp>
1.26 +# include <boost/signals/detail/signal_base.hpp>
1.27 +# include <boost/signals/detail/slot_call_iterator.hpp>
1.28 +# include <boost/mpl/bool.hpp>
1.29 +# include <boost/type_traits/is_convertible.hpp>
1.30 +# include <cassert>
1.31 +# include <functional>
1.32 +# include <memory>
1.33 +#endif // !BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED
1.34 +
1.35 +#ifdef BOOST_HAS_ABI_HEADERS
1.36 +# include BOOST_ABI_PREFIX
1.37 +#endif
1.38 +
1.39 +// Include the appropriate functionN header
1.40 +#define BOOST_SIGNAL_FUNCTION_N_HEADER BOOST_JOIN(<boost/function/function,BOOST_SIGNALS_NUM_ARGS.hpp>)
1.41 +#include BOOST_SIGNAL_FUNCTION_N_HEADER
1.42 +
1.43 +// Determine if a comma should follow a listing of the arguments/parameters
1.44 +#if BOOST_SIGNALS_NUM_ARGS == 0
1.45 +# define BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.46 +#else
1.47 +# define BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS ,
1.48 +#endif // BOOST_SIGNALS_NUM_ARGS > 0
1.49 +
1.50 +// Define class names used
1.51 +#define BOOST_SIGNALS_SIGNAL BOOST_JOIN(signal,BOOST_SIGNALS_NUM_ARGS)
1.52 +#define BOOST_SIGNALS_FUNCTION BOOST_JOIN(function,BOOST_SIGNALS_NUM_ARGS)
1.53 +#define BOOST_SIGNALS_ARGS_STRUCT BOOST_JOIN(args,BOOST_SIGNALS_NUM_ARGS)
1.54 +#define BOOST_SIGNALS_CALL_BOUND BOOST_JOIN(call_bound,BOOST_SIGNALS_NUM_ARGS)
1.55 +
1.56 +// Define commonly-used instantiations
1.57 +#define BOOST_SIGNALS_ARGS_STRUCT_INST \
1.58 + BOOST_SIGNALS_NAMESPACE::detail::BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS>
1.59 +
1.60 +namespace boost {
1.61 + namespace BOOST_SIGNALS_NAMESPACE {
1.62 + namespace detail {
1.63 + // Holds the arguments for a bound slot call in a single place
1.64 + template<BOOST_SIGNALS_TEMPLATE_PARMS
1.65 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.66 + typename Dummy = int>
1.67 + struct BOOST_SIGNALS_ARGS_STRUCT {
1.68 + BOOST_SIGNALS_ARGS_STRUCT(BOOST_SIGNALS_COPY_PARMS)
1.69 + BOOST_SIGNALS_INIT_ARGS
1.70 + {
1.71 + }
1.72 +
1.73 + BOOST_SIGNALS_ARGS_AS_MEMBERS
1.74 + };
1.75 +
1.76 + // Function object that calls the function object given to it, passing
1.77 + // the bound arguments along to that underlying function object
1.78 + template<typename R>
1.79 + struct BOOST_SIGNALS_CALL_BOUND {
1.80 + template<BOOST_SIGNALS_TEMPLATE_PARMS
1.81 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.82 + typename F>
1.83 + struct caller {
1.84 + typedef BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS>*
1.85 + args_type;
1.86 +
1.87 + args_type args;
1.88 +
1.89 + typedef R result_type;
1.90 +
1.91 + caller() {}
1.92 + caller(args_type a) : args(a) {}
1.93 +
1.94 + template<typename Pair>
1.95 + R operator()(const Pair& slot) const
1.96 + {
1.97 + F* target = const_cast<F*>(unsafe_any_cast<F>(&slot.second));
1.98 + return (*target)(BOOST_SIGNALS_BOUND_ARGS);
1.99 + }
1.100 + };
1.101 + };
1.102 +
1.103 + template<>
1.104 + struct BOOST_SIGNALS_CALL_BOUND<void> {
1.105 + template<BOOST_SIGNALS_TEMPLATE_PARMS
1.106 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.107 + typename F>
1.108 + struct caller {
1.109 + typedef BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS>*
1.110 + args_type;
1.111 +
1.112 + args_type args;
1.113 +
1.114 + typedef unusable result_type;
1.115 +
1.116 + caller(args_type a) : args(a) {}
1.117 +
1.118 + template<typename Pair>
1.119 + unusable operator()(const Pair& slot) const
1.120 + {
1.121 + F* target = const_cast<F*>(unsafe_any_cast<F>(&slot.second));
1.122 + (*target)(BOOST_SIGNALS_BOUND_ARGS);
1.123 + return unusable();
1.124 + }
1.125 + };
1.126 + };
1.127 + } // namespace detail
1.128 + } // namespace BOOST_SIGNALS_NAMESPACE
1.129 +
1.130 + // The actual signalN class
1.131 + template<
1.132 + typename R,
1.133 + BOOST_SIGNALS_TEMPLATE_PARMS
1.134 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.135 + typename Combiner = last_value<R>,
1.136 + typename Group = int,
1.137 + typename GroupCompare = std::less<Group>,
1.138 + typename SlotFunction = BOOST_SIGNALS_FUNCTION<
1.139 + R BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.140 + BOOST_SIGNALS_TEMPLATE_ARGS>
1.141 + >
1.142 + class BOOST_SIGNALS_SIGNAL :
1.143 + public BOOST_SIGNALS_NAMESPACE::detail::signal_base, // management of slot list
1.144 + public BOOST_SIGNALS_NAMESPACE::trackable // signals are trackable
1.145 + {
1.146 + public:
1.147 + // The slot function type
1.148 + typedef SlotFunction slot_function_type;
1.149 +
1.150 + // Result type of a slot
1.151 + typedef typename BOOST_SIGNALS_NAMESPACE::detail::slot_result_type<R>::type
1.152 + slot_result_type;
1.153 +
1.154 + // Argument types
1.155 + BOOST_SIGNALS_ARG_TYPES
1.156 +
1.157 +#if BOOST_SIGNALS_NUM_ARGS == 1
1.158 + typedef T1 argument_type;
1.159 +#elif BOOST_SIGNALS_NUM_ARGS == 2
1.160 + typedef T1 first_argument_type;
1.161 + typedef T2 second_argument_type;
1.162 +#endif
1.163 +
1.164 + private:
1.165 + // The real slot name comparison object type
1.166 + typedef BOOST_SIGNALS_NAMESPACE::detail::group_bridge_compare<GroupCompare, Group>
1.167 + real_group_compare_type;
1.168 +
1.169 + // The function object passed to the slot call iterator that will call
1.170 + // the underlying slot function with its arguments bound
1.171 + typedef BOOST_SIGNALS_NAMESPACE::detail::BOOST_SIGNALS_CALL_BOUND<R>
1.172 + outer_bound_slot_caller;
1.173 + typedef typename outer_bound_slot_caller::template
1.174 + caller<BOOST_SIGNALS_TEMPLATE_ARGS
1.175 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.176 + slot_function_type>
1.177 + call_bound_slot;
1.178 +
1.179 + public:
1.180 + // Combiner's result type
1.181 + typedef typename Combiner::result_type result_type;
1.182 +
1.183 + // Combiner type
1.184 + typedef Combiner combiner_type;
1.185 +
1.186 + // Slot type
1.187 + typedef slot<slot_function_type> slot_type;
1.188 +
1.189 + // Slot name type and comparison
1.190 + typedef Group group_type;
1.191 + typedef GroupCompare group_compare_type;
1.192 +
1.193 + typedef BOOST_SIGNALS_NAMESPACE::detail::slot_call_iterator<
1.194 + call_bound_slot, iterator> slot_call_iterator;
1.195 +
1.196 + explicit
1.197 + BOOST_SIGNALS_SIGNAL(const Combiner& c = Combiner(),
1.198 + const GroupCompare& comp = GroupCompare()) :
1.199 + BOOST_SIGNALS_NAMESPACE::detail::signal_base(real_group_compare_type(comp),
1.200 + c)
1.201 + {
1.202 + }
1.203 +
1.204 + // Connect a slot to this signal
1.205 + BOOST_SIGNALS_NAMESPACE::connection
1.206 + connect(const slot_type&,
1.207 + BOOST_SIGNALS_NAMESPACE::connect_position at
1.208 + = BOOST_SIGNALS_NAMESPACE::at_back);
1.209 +
1.210 +
1.211 + BOOST_SIGNALS_NAMESPACE::connection
1.212 + connect(const group_type&, const slot_type&,
1.213 + BOOST_SIGNALS_NAMESPACE::connect_position at
1.214 + = BOOST_SIGNALS_NAMESPACE::at_back);
1.215 +
1.216 +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
1.217 + // MSVC 6.0 and 7.0 don't handle the is_convertible test well
1.218 + void disconnect(const group_type& group)
1.219 + {
1.220 + impl->disconnect(group);
1.221 + }
1.222 +#else
1.223 + template<typename T>
1.224 + void disconnect(const T& t)
1.225 + {
1.226 + typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group;
1.227 + this->do_disconnect(t, is_group());
1.228 + }
1.229 +
1.230 + private:
1.231 + // Disconnect a named slot
1.232 + void do_disconnect(const group_type& group, mpl::bool_<true>)
1.233 + {
1.234 + impl->disconnect(group);
1.235 + }
1.236 +
1.237 + template<typename Function>
1.238 + void do_disconnect(const Function& f, mpl::bool_<false>)
1.239 + {
1.240 + // Notify the slot handling code that we are iterating through the slots
1.241 + BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl);
1.242 +
1.243 + for (iterator i = impl->slots_.begin(); i != impl->slots_.end(); ++i) {
1.244 + slot_function_type& s = *unsafe_any_cast<slot_function_type>(&i->second);
1.245 + if (s == f) i->first.disconnect();
1.246 + }
1.247 + }
1.248 +#endif
1.249 +
1.250 + public:
1.251 +
1.252 + // Emit the signal
1.253 + result_type operator()(BOOST_SIGNALS_PARMS);
1.254 + result_type operator()(BOOST_SIGNALS_PARMS) const;
1.255 +
1.256 + Combiner& combiner()
1.257 + { return *unsafe_any_cast<Combiner>(&impl->combiner_); }
1.258 +
1.259 + const Combiner& combiner() const
1.260 + { return *unsafe_any_cast<const Combiner>(&impl->combiner_); }
1.261 + };
1.262 +
1.263 + template<
1.264 + typename R,
1.265 + BOOST_SIGNALS_TEMPLATE_PARMS
1.266 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.267 + typename Combiner,
1.268 + typename Group,
1.269 + typename GroupCompare,
1.270 + typename SlotFunction
1.271 + >
1.272 + BOOST_SIGNALS_NAMESPACE::connection
1.273 + BOOST_SIGNALS_SIGNAL<
1.274 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.275 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.276 + Combiner, Group, GroupCompare, SlotFunction
1.277 + >::connect(const slot_type& in_slot,
1.278 + BOOST_SIGNALS_NAMESPACE::connect_position at)
1.279 + {
1.280 + using boost::BOOST_SIGNALS_NAMESPACE::detail::stored_group;
1.281 +
1.282 + // If the slot has been disconnected, just return a disconnected
1.283 + // connection
1.284 + if (!in_slot.is_active()) {
1.285 + return BOOST_SIGNALS_NAMESPACE::connection();
1.286 + }
1.287 +
1.288 + return impl->connect_slot(in_slot.get_slot_function(), stored_group(),
1.289 + in_slot.get_data(), at);
1.290 + }
1.291 +
1.292 + template<
1.293 + typename R,
1.294 + BOOST_SIGNALS_TEMPLATE_PARMS
1.295 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.296 + typename Combiner,
1.297 + typename Group,
1.298 + typename GroupCompare,
1.299 + typename SlotFunction
1.300 + >
1.301 + BOOST_SIGNALS_NAMESPACE::connection
1.302 + BOOST_SIGNALS_SIGNAL<
1.303 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.304 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.305 + Combiner, Group, GroupCompare, SlotFunction
1.306 + >::connect(const group_type& group,
1.307 + const slot_type& in_slot,
1.308 + BOOST_SIGNALS_NAMESPACE::connect_position at)
1.309 + {
1.310 + // If the slot has been disconnected, just return a disconnected
1.311 + // connection
1.312 + if (!in_slot.is_active()) {
1.313 + return BOOST_SIGNALS_NAMESPACE::connection();
1.314 + }
1.315 +
1.316 + return impl->connect_slot(in_slot.get_slot_function(), group,
1.317 + in_slot.get_data(), at);
1.318 + }
1.319 +
1.320 + template<
1.321 + typename R,
1.322 + BOOST_SIGNALS_TEMPLATE_PARMS
1.323 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.324 + typename Combiner,
1.325 + typename Group,
1.326 + typename GroupCompare,
1.327 + typename SlotFunction
1.328 + >
1.329 + typename BOOST_SIGNALS_SIGNAL<
1.330 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.331 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.332 + Combiner, Group, GroupCompare, SlotFunction>::result_type
1.333 + BOOST_SIGNALS_SIGNAL<
1.334 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.335 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.336 + Combiner, Group, GroupCompare, SlotFunction
1.337 + >::operator()(BOOST_SIGNALS_PARMS)
1.338 + {
1.339 + // Notify the slot handling code that we are making a call
1.340 + BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl);
1.341 +
1.342 + // Construct a function object that will call the underlying slots
1.343 + // with the given arguments.
1.344 +#if BOOST_SIGNALS_NUM_ARGS == 0
1.345 + BOOST_SIGNALS_ARGS_STRUCT_INST args;
1.346 +#else
1.347 + BOOST_SIGNALS_ARGS_STRUCT_INST args(BOOST_SIGNALS_ARGS);
1.348 +#endif // BOOST_SIGNALS_NUM_ARGS > 0
1.349 + call_bound_slot f(&args);
1.350 +
1.351 + typedef typename call_bound_slot::result_type result_type;
1.352 + optional<result_type> cache;
1.353 + // Let the combiner call the slots via a pair of input iterators
1.354 + return combiner()(slot_call_iterator(notification.impl->slots_.begin(),
1.355 + impl->slots_.end(), f, cache),
1.356 + slot_call_iterator(notification.impl->slots_.end(),
1.357 + impl->slots_.end(), f, cache));
1.358 + }
1.359 +
1.360 + template<
1.361 + typename R,
1.362 + BOOST_SIGNALS_TEMPLATE_PARMS
1.363 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.364 + typename Combiner,
1.365 + typename Group,
1.366 + typename GroupCompare,
1.367 + typename SlotFunction
1.368 + >
1.369 + typename BOOST_SIGNALS_SIGNAL<
1.370 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.371 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.372 + Combiner, Group, GroupCompare, SlotFunction>::result_type
1.373 + BOOST_SIGNALS_SIGNAL<
1.374 + R, BOOST_SIGNALS_TEMPLATE_ARGS
1.375 + BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.376 + Combiner, Group, GroupCompare, SlotFunction
1.377 + >::operator()(BOOST_SIGNALS_PARMS) const
1.378 + {
1.379 + // Notify the slot handling code that we are making a call
1.380 + BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl);
1.381 +
1.382 + // Construct a function object that will call the underlying slots
1.383 + // with the given arguments.
1.384 +#if BOOST_SIGNALS_NUM_ARGS == 0
1.385 + BOOST_SIGNALS_ARGS_STRUCT_INST args;
1.386 +#else
1.387 + BOOST_SIGNALS_ARGS_STRUCT_INST args(BOOST_SIGNALS_ARGS);
1.388 +#endif // BOOST_SIGNALS_NUM_ARGS > 0
1.389 +
1.390 + call_bound_slot f(&args);
1.391 +
1.392 + typedef typename call_bound_slot::result_type result_type;
1.393 + optional<result_type> cache;
1.394 +
1.395 + // Let the combiner call the slots via a pair of input iterators
1.396 + return combiner()(slot_call_iterator(notification.impl->slots_.begin(),
1.397 + impl->slots_.end(), f, cache),
1.398 + slot_call_iterator(notification.impl->slots_.end(),
1.399 + impl->slots_.end(), f, cache));
1.400 + }
1.401 +} // namespace boost
1.402 +
1.403 +#undef BOOST_SIGNAL_FUNCTION_N_HEADER
1.404 +#undef BOOST_SIGNALS_ARGS_STRUCT_INST
1.405 +#undef BOOST_SIGNALS_CALL_BOUND
1.406 +#undef BOOST_SIGNALS_ARGS_STRUCT
1.407 +#undef BOOST_SIGNALS_FUNCTION
1.408 +#undef BOOST_SIGNALS_SIGNAL
1.409 +#undef BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS
1.410 +
1.411 +#ifdef BOOST_HAS_ABI_HEADERS
1.412 +# include BOOST_ABI_SUFFIX
1.413 +#endif