]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/detail/signals_common.hpp
Update to latest from boost 1.34.x branch
[lyx.git] / boost / boost / signals / detail / signals_common.hpp
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 {
33         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 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
101       template<typename T>
102       struct is_ref
103       {
104         BOOST_STATIC_CONSTANT(bool, value = false);
105       };
106
107       template<typename T>
108       struct is_ref<reference_wrapper<T> >
109       {
110         BOOST_STATIC_CONSTANT(bool, value = true);
111       };
112 #else // no partial specialization
113       typedef char yes_type;
114       typedef double no_type;
115
116       no_type is_ref_tester(...);
117
118       template<typename T>
119       yes_type is_ref_tester(reference_wrapper<T>*);
120
121       template<typename T>
122       struct is_ref
123       {
124         static T* t;
125         BOOST_STATIC_CONSTANT(bool,
126           value = (sizeof(is_ref_tester(t)) == sizeof(yes_type)));
127       };
128 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
129
130       // A slot can be a signal, a reference to a function object, or a
131       // function object.
132       struct signal_tag {};
133       struct reference_tag {};
134       struct value_tag {};
135
136       // Classify the given slot as a signal, a reference-to-slot, or a
137       // standard slot
138       template<typename S>
139       class get_slot_tag {
140         typedef typename IF<(is_signal<S>::value),
141                             signal_tag,
142                             value_tag>::type signal_or_value;
143
144       public:
145         typedef typename IF<(is_ref<S>::value),
146                             reference_tag,
147                             signal_or_value>::type type;
148       };
149
150       // Forward declaration needed in lots of places
151       class signal_base_impl;
152       class bound_objects_visitor;
153       class slot_base;
154     } // end namespace detail
155   } // end namespace BOOST_SIGNALS_NAMESPACE
156 } // end namespace boost
157
158 #ifdef BOOST_HAS_ABI_HEADERS
159 #  include BOOST_ABI_SUFFIX
160 #endif
161
162 #endif // BOOST_SIGNALS_COMMON_HEADER