Line data Source code
1 : // Boost.Signals2 library 2 : 3 : // Copyright Frank Mori Hess 2007-2008. 4 : // Copyright Timmo Stange 2007. 5 : // Copyright Douglas Gregor 2001-2004. Use, modification and 6 : // distribution is subject to the Boost Software License, Version 7 : // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 8 : // http://www.boost.org/LICENSE_1_0.txt) 9 : 10 : // For more information, see http://www.boost.org 11 : 12 : // This file is included iteratively, and should not be protected from multiple inclusion 13 : 14 : #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES 15 : #define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION() 16 : #else 17 : #define BOOST_SIGNALS2_NUM_ARGS 1 18 : #endif 19 : 20 : 21 : namespace boost 22 : { 23 : namespace signals2 24 : { 25 : #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES 26 : template<typename Signature, typename SlotFunction> class slot; 27 : #else 28 : template<typename Signature, typename SlotFunction = boost::function<Signature> > 29 29777 : class slot; 30 : 31 : #if BOOST_WORKAROUND(BOOST_MSVC, <= 1900) 32 : template<typename Signature, typename SlotFunction> class slot{}; 33 : #endif 34 : #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES 35 : 36 : template<BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)> 37 : class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION 38 : : public slot_base, public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE 39 : 40 : { 41 : public: 42 : template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction> 43 : friend class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); 44 : 45 : typedef SlotFunction slot_function_type; 46 : typedef R result_type; 47 : typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type; 48 : 49 : #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES 50 : 51 : // typedef Tn argn_type; 52 : #define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \ 53 : typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type); 54 : BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~) 55 : #undef BOOST_SIGNALS2_MISC_STATEMENT 56 : #if BOOST_SIGNALS2_NUM_ARGS == 1 57 : typedef arg1_type argument_type; 58 : #elif BOOST_SIGNALS2_NUM_ARGS == 2 59 : typedef arg1_type first_argument_type; 60 : typedef arg2_type second_argument_type; 61 : #endif 62 : 63 : template<unsigned n> class arg : public 64 : detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) 65 : <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS) 66 : BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)> 67 : {}; 68 : 69 : BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS); 70 : 71 : #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES 72 : 73 : template<unsigned n> class arg 74 : { 75 : public: 76 : typedef typename detail::variadic_arg_type<n, Args...>::type type; 77 : }; 78 : BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args)); 79 : 80 : #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES 81 : 82 : template<typename F> 83 59554 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const F& f) 84 29777 : { 85 29777 : init_slot_function(f); 86 59554 : } 87 : // copy constructors 88 : #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES 89 : template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction> 90 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) 91 : <BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS, Other), OtherSlotFunction> &other_slot): 92 : slot_base(other_slot), _slot_function(other_slot._slot_function) 93 : { 94 : } 95 : #endif 96 : template<typename Signature, typename OtherSlotFunction> 97 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot): 98 : slot_base(other_slot), _slot_function(other_slot._slot_function) 99 : { 100 : } 101 : // bind syntactic sugar 102 : BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS 103 : // invocation 104 : R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) 105 : { 106 : locked_container_type locked_objects = lock(); 107 : return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); 108 : } 109 : R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const 110 : { 111 : locked_container_type locked_objects = lock(); 112 : return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); 113 : } 114 : // tracking 115 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked) { 116 : _tracked_objects.push_back(tracked); 117 : return *this; 118 : } 119 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const signal_base &signal) 120 : { 121 : track_signal(signal); 122 : return *this; 123 : } 124 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const slot_base &slot) 125 : { 126 : tracked_container_type::const_iterator it; 127 : for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it) 128 : { 129 : _tracked_objects.push_back(*it); 130 : } 131 : return *this; 132 : } 133 : template<typename ForeignWeakPtr> 134 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked, 135 : typename weak_ptr_traits<ForeignWeakPtr>::shared_type * /*SFINAE*/ = 0) 136 : { 137 : _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked)); 138 : return *this; 139 : } 140 : template<typename ForeignSharedPtr> 141 : BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked, 142 : typename shared_ptr_traits<ForeignSharedPtr>::weak_type * /*SFINAE*/ = 0) 143 : { 144 : _tracked_objects.push_back 145 : ( 146 : detail::foreign_void_weak_ptr 147 : ( 148 : typename shared_ptr_traits<ForeignSharedPtr>::weak_type(tracked) 149 : ) 150 : ); 151 : return *this; 152 : } 153 : 154 : const slot_function_type& slot_function() const {return _slot_function;} 155 375533 : slot_function_type& slot_function() {return _slot_function;} 156 : private: 157 : template<typename F> 158 29777 : void init_slot_function(const F& f) 159 : { 160 29777 : _slot_function = detail::get_invocable_slot(f, detail::tag_type(f)); 161 29777 : signals2::detail::tracked_objects_visitor visitor(this); 162 29777 : boost::visit_each(visitor, f); 163 29777 : } 164 : 165 : SlotFunction _slot_function; 166 : }; 167 : 168 : #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES 169 : namespace detail 170 : { 171 : template<unsigned arity, typename Signature, typename SlotFunction> 172 : class slotN; 173 : // partial template specialization 174 : template<typename Signature, typename SlotFunction> 175 : class slotN<BOOST_SIGNALS2_NUM_ARGS, Signature, SlotFunction> 176 : { 177 : public: 178 : typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)< 179 : BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature), 180 : SlotFunction> type; 181 : }; 182 : } 183 : #endif 184 : } // end namespace signals2 185 : } // end namespace boost 186 : 187 : #undef BOOST_SIGNALS2_NUM_ARGS