/Src/Dependencies/Boost/boost/signals2/detail/slot_template.hpp

http://hadesmem.googlecode.com/ · C++ Header · 183 lines · 145 code · 22 blank · 16 comment · 4 complexity · a8cd47e4cba3c56e11df1e1eaf133fc9 MD5 · raw file

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