signals_common.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Boost.Signals library
  2. // Copyright Douglas Gregor 2001-2004. Use, modification and
  3. // distribution is subject to the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // For more information, see http://www.boost.org
  7. #ifndef BOOST_SIGNALS_COMMON_HEADER
  8. #define BOOST_SIGNALS_COMMON_HEADER
  9. #ifndef BOOST_SIGNALS_NAMESPACE
  10. # define BOOST_SIGNALS_NAMESPACE signals
  11. #endif
  12. #include <boost/type_traits/conversion_traits.hpp>
  13. #include <boost/ref.hpp>
  14. #include <boost/signals/detail/config.hpp>
  15. #ifdef BOOST_HAS_ABI_HEADERS
  16. # include BOOST_ABI_PREFIX
  17. #endif
  18. namespace boost {
  19. namespace BOOST_SIGNALS_NAMESPACE {
  20. namespace detail {
  21. // The unusable class is a placeholder for unused function arguments
  22. // It is also completely unusable except that it constructable from
  23. // anything. This helps compilers without partial specialization
  24. // handle slots returning void.
  25. struct unusable {
  26. unusable() {}
  27. };
  28. // Determine the result type of a slot call
  29. template<typename R>
  30. struct slot_result_type {
  31. typedef R type;
  32. };
  33. template<>
  34. struct slot_result_type<void> {
  35. typedef unusable type;
  36. };
  37. // Determine if the given type T is a signal
  38. class signal_base;
  39. template<typename T>
  40. struct is_signal {
  41. BOOST_STATIC_CONSTANT(bool,
  42. value = (is_convertible<T*, signal_base*>::value));
  43. };
  44. /*
  45. * The IF implementation is temporary code. When a Boost metaprogramming
  46. * library is introduced, Boost.Signals will use it instead.
  47. */
  48. namespace intimate {
  49. struct SelectThen
  50. {
  51. template<typename Then, typename Else>
  52. struct Result
  53. {
  54. typedef Then type;
  55. };
  56. };
  57. struct SelectElse
  58. {
  59. template<typename Then, typename Else>
  60. struct Result
  61. {
  62. typedef Else type;
  63. };
  64. };
  65. template<bool Condition>
  66. struct Selector
  67. {
  68. typedef SelectThen type;
  69. };
  70. template<>
  71. struct Selector<false>
  72. {
  73. typedef SelectElse type;
  74. };
  75. } // end namespace intimate
  76. template<bool Condition, typename Then, typename Else>
  77. struct IF
  78. {
  79. typedef typename intimate::Selector<Condition>::type select;
  80. typedef typename select::template Result<Then,Else>::type type;
  81. };
  82. // Determine if the incoming argument is a reference_wrapper
  83. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  84. template<typename T>
  85. struct is_ref
  86. {
  87. BOOST_STATIC_CONSTANT(bool, value = false);
  88. };
  89. template<typename T>
  90. struct is_ref<reference_wrapper<T> >
  91. {
  92. BOOST_STATIC_CONSTANT(bool, value = true);
  93. };
  94. #else // no partial specialization
  95. typedef char yes_type;
  96. typedef double no_type;
  97. no_type is_ref_tester(...);
  98. template<typename T>
  99. yes_type is_ref_tester(reference_wrapper<T>*);
  100. template<typename T>
  101. struct is_ref
  102. {
  103. static T* t;
  104. BOOST_STATIC_CONSTANT(bool,
  105. value = (sizeof(is_ref_tester(t)) == sizeof(yes_type)));
  106. };
  107. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  108. // A slot can be a signal, a reference to a function object, or a
  109. // function object.
  110. struct signal_tag {};
  111. struct reference_tag {};
  112. struct value_tag {};
  113. // Classify the given slot as a signal, a reference-to-slot, or a
  114. // standard slot
  115. template<typename S>
  116. class get_slot_tag {
  117. typedef typename IF<(is_signal<S>::value),
  118. signal_tag,
  119. value_tag>::type signal_or_value;
  120. public:
  121. typedef typename IF<(is_ref<S>::value),
  122. reference_tag,
  123. signal_or_value>::type type;
  124. };
  125. // Forward declaration needed in lots of places
  126. class signal_base_impl;
  127. class bound_objects_visitor;
  128. class slot_base;
  129. } // end namespace detail
  130. } // end namespace BOOST_SIGNALS_NAMESPACE
  131. } // end namespace boost
  132. #ifdef BOOST_HAS_ABI_HEADERS
  133. # include BOOST_ABI_SUFFIX
  134. #endif
  135. #endif // BOOST_SIGNALS_COMMON_HEADER