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