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