slot_template.hpp 6.9 KB

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