]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/detail/signals_common.hpp
update boost
[lyx.git] / boost / boost / signals / detail / signals_common.hpp
1 // Boost.Signals library
2 //
3 // Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
4 //
5 // Permission to copy, use, sell and distribute this software is granted
6 // provided this copyright notice appears in all copies.
7 // Permission to modify the code and to distribute modified code is granted
8 // provided this copyright notice appears in all copies, and a notice
9 // that the code was modified is included with the copyright notice.
10 //
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
13  
14 // For more information, see http://www.boost.org
15
16 #ifndef BOOST_SIGNALS_COMMON_HEADER
17 #define BOOST_SIGNALS_COMMON_HEADER
18
19 #ifndef BOOST_SIGNALS_NAMESPACE
20 #  define BOOST_SIGNALS_NAMESPACE signals
21 #endif
22
23 #include <boost/type_traits/conversion_traits.hpp>
24 #include <boost/ref.hpp>
25
26 namespace boost {
27   namespace BOOST_SIGNALS_NAMESPACE {
28     namespace detail {
29       // The unusable class is a placeholder for unused function arguments
30       // It is also completely unusable except that it constructable from
31       // anything. This helps compilers without partial specialization
32       // handle slots returning void.  
33       struct unusable {
34         unusable() {}
35       };
36
37       // Determine the result type of a slot call
38       template<typename R>
39       struct slot_result_type {
40         typedef R type;
41       };
42
43       template<>
44       struct slot_result_type<void> {
45         typedef unusable type;
46       };
47
48       // Determine if the given type T is a signal
49       class signal_base;
50
51       template<typename T>
52       struct is_signal {
53         BOOST_STATIC_CONSTANT(bool, 
54           value = (is_convertible<T*, signal_base*>::value));
55       };
56
57       /*
58        * The IF implementation is temporary code. When a Boost metaprogramming
59        * library is introduced, Boost.Signals will use it instead. 
60        */
61       namespace intimate {
62         struct SelectThen 
63         {       
64           template<typename Then, typename Else>
65           struct Result
66           {       
67             typedef Then type;
68           };
69         };
70  
71         struct SelectElse
72         {
73           template<typename Then, typename Else>
74           struct Result
75           { 
76             typedef Else type;
77           };
78         };
79  
80         template<bool Condition>
81         struct Selector
82         {
83           typedef SelectThen type;
84         };
85  
86         template<>
87         struct Selector<false>
88         {
89           typedef SelectElse type;
90         };
91       } // end namespace intimate 
92  
93       template<bool Condition, typename Then, typename Else>
94       struct IF
95       {
96         typedef typename intimate::Selector<Condition>::type select;
97         typedef typename select::template Result<Then,Else>::type type;
98       };
99
100       // Determine if the incoming argument is a reference_wrapper
101 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
102       template<typename T>
103       struct is_ref
104       {
105         BOOST_STATIC_CONSTANT(bool, value = false); 
106       };
107
108       template<typename T>
109       struct is_ref<reference_wrapper<T> >
110       {
111         BOOST_STATIC_CONSTANT(bool, value = true);
112       };
113 #else // no partial specialization
114       typedef char yes_type;
115       typedef double no_type;
116       
117       no_type is_ref_tester(...);
118
119       template<typename T>
120       yes_type is_ref_tester(reference_wrapper<T>*);
121
122       template<typename T>
123       struct is_ref
124       {
125         static T* t;
126         BOOST_STATIC_CONSTANT(bool, 
127           value = (sizeof(is_ref_tester(t)) == sizeof(yes_type)));
128       };
129 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
130
131       // A slot can be a signal, a reference to a function object, or a 
132       // function object.
133       struct signal_tag {};
134       struct reference_tag {};
135       struct value_tag {};
136
137       // Classify the given slot as a signal, a reference-to-slot, or a 
138       // standard slot
139       template<typename S>
140       class get_slot_tag {
141         typedef typename IF<(is_signal<S>::value),
142                             signal_tag,
143                             value_tag>::type signal_or_value;
144
145       public:   
146         typedef typename IF<(is_ref<S>::value),
147                             reference_tag,
148                             signal_or_value>::type type;
149       };
150
151       // Forward declaration needed in lots of places
152       class signal_base_impl;
153       class bound_objects_visitor;
154       class slot_base;
155     } // end namespace detail
156   } // end namespace BOOST_SIGNALS_NAMESPACE
157 } // end namespace boost
158
159 #endif // BOOST_SIGNALS_COMMON_HEADER