Chris@16: // Boost.Signals2 library Chris@16: Chris@16: // Copyright Frank Mori Hess 2007-2008. Chris@16: // Copyright Timmo Stange 2007. Chris@16: // Copyright Douglas Gregor 2001-2004. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // For more information, see http://www.boost.org Chris@16: Chris@16: // This file is included iteratively, and should not be protected from multiple inclusion Chris@16: Chris@16: #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: #define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION() Chris@16: #else Chris@16: #define BOOST_SIGNALS2_NUM_ARGS 1 Chris@16: #endif Chris@16: Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace signals2 Chris@16: { Chris@101: #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: template class slot; Chris@101: #else Chris@101: template > Chris@101: class slot; Chris@16: Chris@101: #if BOOST_WORKAROUND(BOOST_MSVC, <= 1900) Chris@101: template class slot{}; Chris@101: #endif Chris@101: #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: Chris@16: template Chris@16: class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION Chris@16: : public slot_base, public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(R) Chris@16: Chris@16: { Chris@16: public: Chris@16: template Chris@16: friend class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); Chris@16: Chris@16: typedef SlotFunction slot_function_type; Chris@16: typedef R result_type; Chris@16: typedef typename mpl::identity::type signature_type; Chris@16: Chris@16: #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: Chris@16: // typedef Tn argn_type; Chris@16: #define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \ Chris@16: typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type); Chris@16: BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~) Chris@16: #undef BOOST_SIGNALS2_MISC_STATEMENT Chris@16: #if BOOST_SIGNALS2_NUM_ARGS == 1 Chris@16: typedef arg1_type argument_type; Chris@16: #elif BOOST_SIGNALS2_NUM_ARGS == 2 Chris@16: typedef arg1_type first_argument_type; Chris@16: typedef arg2_type second_argument_type; Chris@16: #endif Chris@16: Chris@16: template class arg : public Chris@16: detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) Chris@16: Chris@16: {}; Chris@16: Chris@16: BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS); Chris@16: Chris@16: #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: Chris@16: template class arg Chris@16: { Chris@16: public: Chris@16: typedef typename detail::variadic_arg_type::type type; Chris@16: }; Chris@16: BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args)); Chris@16: Chris@16: #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: Chris@16: template Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const F& f) Chris@16: { Chris@16: init_slot_function(f); Chris@16: } Chris@16: // copy constructors Chris@16: #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: template Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) Chris@16: &other_slot): Chris@16: slot_base(other_slot), _slot_function(other_slot._slot_function) Chris@16: { Chris@16: } Chris@16: #endif Chris@16: template Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const slot &other_slot): Chris@16: slot_base(other_slot), _slot_function(other_slot._slot_function) Chris@16: { Chris@16: } Chris@16: // bind syntactic sugar Chris@16: BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS Chris@16: // invocation Chris@16: R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) Chris@16: { Chris@16: locked_container_type locked_objects = lock(); Chris@16: return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); Chris@16: } Chris@16: R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const Chris@16: { Chris@16: locked_container_type locked_objects = lock(); Chris@16: return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); Chris@16: } Chris@16: // tracking Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr &tracked) { Chris@16: _tracked_objects.push_back(tracked); Chris@16: return *this; Chris@16: } Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const signal_base &signal) Chris@16: { Chris@16: track_signal(signal); Chris@16: return *this; Chris@16: } Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const slot_base &slot) Chris@16: { Chris@16: tracked_container_type::const_iterator it; Chris@16: for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it) Chris@16: { Chris@16: _tracked_objects.push_back(*it); Chris@16: } Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked, Chris@16: typename weak_ptr_traits::shared_type * /*SFINAE*/ = 0) Chris@16: { Chris@16: _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked)); Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked, Chris@16: typename shared_ptr_traits::weak_type * /*SFINAE*/ = 0) Chris@16: { Chris@16: _tracked_objects.push_back Chris@16: ( Chris@16: detail::foreign_void_weak_ptr Chris@16: ( Chris@16: typename shared_ptr_traits::weak_type(tracked) Chris@16: ) Chris@16: ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: const slot_function_type& slot_function() const {return _slot_function;} Chris@16: slot_function_type& slot_function() {return _slot_function;} Chris@16: private: Chris@16: template Chris@16: void init_slot_function(const F& f) Chris@16: { Chris@16: _slot_function = detail::get_invocable_slot(f, detail::tag_type(f)); Chris@16: signals2::detail::tracked_objects_visitor visitor(this); Chris@16: boost::visit_each(visitor, f); Chris@16: } Chris@16: Chris@16: SlotFunction _slot_function; Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: class slotN; Chris@16: // partial template specialization Chris@16: template Chris@16: class slotN Chris@16: { Chris@16: public: Chris@16: typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)< Chris@16: BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature), Chris@16: SlotFunction> type; Chris@16: }; Chris@16: } Chris@16: #endif Chris@16: } // end namespace signals2 Chris@16: } // end namespace boost Chris@16: Chris@16: #undef BOOST_SIGNALS2_NUM_ARGS