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_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 template<typename Signature, typename SlotFunction> class slot; 26 27 // slot class template. 28 template<BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS), 29 typename SlotFunction = BOOST_SIGNALS2_FUNCTION_N_DECL(BOOST_SIGNALS2_NUM_ARGS)> 30 class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); 31 32 template<BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)> 33 class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION 34 : public slot_base, public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(R) 35 36 { 37 public: 38 template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction> 39 friend class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS); 40 41 typedef SlotFunction slot_function_type; 42 typedef R result_type; 43 typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type; 44 45 #ifdef BOOST_NO_VARIADIC_TEMPLATES 46 47 // typedef Tn argn_type; 48 #define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \ 49 typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type); 50 BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~) 51 #undef BOOST_SIGNALS2_MISC_STATEMENT 52 #if BOOST_SIGNALS2_NUM_ARGS == 1 53 typedef arg1_type argument_type; 54 #elif BOOST_SIGNALS2_NUM_ARGS == 2 55 typedef arg1_type first_argument_type; 56 typedef arg2_type second_argument_type; 57 #endif 58 59 template<unsigned n> class arg : public 60 detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) 61 <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS) 62 BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)> 63 {}; 64 65 BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS); 66 67 #else // BOOST_NO_VARIADIC_TEMPLATES 68 69 template<unsigned n> class arg 70 { 71 public: 72 typedef typename detail::variadic_arg_type<n, Args...>::type type; 73 }; 74 BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args)); 75 76 #endif // BOOST_NO_VARIADIC_TEMPLATES 77 78 template<typename F> 79 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const F& f) 80 { 81 init_slot_function(f); 82 } 83 // copy constructors 84 #ifdef BOOST_NO_VARIADIC_TEMPLATES 85 template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction> 86 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) 87 <BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS, Other), OtherSlotFunction> &other_slot): 88 slot_base(other_slot), _slot_function(other_slot._slot_function) 89 { 90 } 91 #endif 92 template<typename Signature, typename OtherSlotFunction> 93 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot): 94 slot_base(other_slot), _slot_function(other_slot._slot_function) 95 { 96 } 97 // bind syntactic sugar 98 BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS 99 // invocation 100 R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) 101 { 102 locked_container_type locked_objects = lock(); 103 return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); 104 } 105 R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const 106 { 107 locked_container_type locked_objects = lock(); 108 return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS)); 109 } 110 // tracking 111 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked) { 112 _tracked_objects.push_back(tracked); 113 return *this; 114 } 115 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const signal_base &signal) 116 { 117 track_signal(signal); 118 return *this; 119 } 120 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const slot_base &slot) 121 { 122 tracked_container_type::const_iterator it; 123 for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it) 124 { 125 _tracked_objects.push_back(*it); 126 } 127 return *this; 128 } 129 template<typename ForeignWeakPtr> 130 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked, 131 typename weak_ptr_traits<ForeignWeakPtr>::shared_type * /*SFINAE*/ = 0) 132 { 133 _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked)); 134 return *this; 135 } 136 template<typename ForeignSharedPtr> 137 BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked, 138 typename shared_ptr_traits<ForeignSharedPtr>::weak_type * /*SFINAE*/ = 0) 139 { 140 _tracked_objects.push_back 141 ( 142 detail::foreign_void_weak_ptr 143 ( 144 typename shared_ptr_traits<ForeignSharedPtr>::weak_type(tracked) 145 ) 146 ); 147 return *this; 148 } 149 150 const slot_function_type& slot_function() const {return _slot_function;} 151 slot_function_type& slot_function() {return _slot_function;} 152 private: 153 template<typename F> 154 void init_slot_function(const F& f) 155 { 156 _slot_function = detail::get_invocable_slot(f, detail::tag_type(f)); 157 signals2::detail::tracked_objects_visitor visitor(this); 158 boost::visit_each(visitor, f); 159 } 160 161 SlotFunction _slot_function; 162 }; 163 164 #ifdef BOOST_NO_VARIADIC_TEMPLATES 165 namespace detail 166 { 167 template<unsigned arity, typename Signature, typename SlotFunction> 168 class slotN; 169 // partial template specialization 170 template<typename Signature, typename SlotFunction> 171 class slotN<BOOST_SIGNALS2_NUM_ARGS, Signature, SlotFunction> 172 { 173 public: 174 typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)< 175 BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature), 176 SlotFunction> type; 177 }; 178 } 179 #endif 180 } // end namespace signals2 181 } // end namespace boost 182 183 #undef BOOST_SIGNALS2_NUM_ARGS 184