]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/detail/signals_common.hpp
major boost update
[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 #include <boost/type_traits/conversion_traits.hpp>
20 #include <boost/ref.hpp>
21
22 namespace boost {
23   namespace signals {
24     namespace detail {
25       // The unusable class is a placeholder for unused function arguments
26       // It is also completely unusable except that it constructable from
27       // anything. This helps compilers without partial specialization
28       // handle slots returning void.  
29       struct unusable {
30         unusable() {}
31       };
32
33       // Determine the result type of a slot call
34       template<typename R>
35       struct slot_result_type {
36         typedef R type;
37       };
38
39       template<>
40       struct slot_result_type<void> {
41         typedef unusable type;
42       };
43
44       // Determine if the given type T is a signal
45       class signal_base;
46
47       template<typename T>
48       struct is_signal {
49         BOOST_STATIC_CONSTANT(bool, 
50           value = (is_convertible<T*, signal_base*>::value));
51       };
52
53       /*
54        * The IF implementation is temporary code. When a Boost metaprogramming
55        * library is introduced, Boost.Signals will use it instead. 
56        */
57       namespace intimate {
58         struct SelectThen 
59         {       
60           template<typename Then, typename Else>
61           struct Result
62           {       
63             typedef Then type;
64           };
65         };
66  
67         struct SelectElse
68         {
69           template<typename Then, typename Else>
70           struct Result
71           { 
72             typedef Else type;
73           };
74         };
75  
76         template<bool Condition>
77         struct Selector
78         {
79           typedef SelectThen type;
80         };
81  
82         template<>
83         struct Selector<false>
84         {
85           typedef SelectElse type;
86         };
87       } // end namespace intimate 
88  
89       template<bool Condition, typename Then, typename Else>
90       struct IF
91       {
92         typedef typename intimate::Selector<Condition>::type select;
93         typedef typename select::template Result<Then,Else>::type type;
94       };
95
96       // Determine if the incoming argument is a reference_wrapper
97 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
98       template<typename T>
99       struct is_ref
100       {
101         BOOST_STATIC_CONSTANT(bool, value = false); 
102       };
103
104       template<typename T>
105       struct is_ref<reference_wrapper<T> >
106       {
107         BOOST_STATIC_CONSTANT(bool, value = true);
108       };
109 #else // no partial specialization
110       typedef char yes_type;
111       typedef double no_type;
112       
113       no_type is_ref_tester(...);
114
115       template<typename T>
116       yes_type is_ref_tester(reference_wrapper<T>*);
117
118       template<typename T>
119       struct is_ref
120       {
121         static T* t;
122         BOOST_STATIC_CONSTANT(bool, 
123           value = (sizeof(is_ref_tester(t)) == sizeof(yes_type)));
124       };
125 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
126
127       // A slot can be a signal, a reference to a function object, or a 
128       // function object.
129       struct signal_tag {};
130       struct reference_tag {};
131       struct value_tag {};
132
133       // Classify the given slot as a signal, a reference-to-slot, or a 
134       // standard slot
135       template<typename S>
136       class get_slot_tag {
137         typedef typename IF<(is_signal<S>::value),
138                             signal_tag,
139                             value_tag>::type signal_or_value;
140
141       public:   
142         typedef typename IF<(is_ref<S>::value),
143                             reference_tag,
144                             signal_or_value>::type type;
145       };
146
147       // Forward declaration needed in lots of places
148       class signal_base_impl;
149       class bound_objects_visitor;
150       class slot_base;
151     } // end namespace detail
152   } // end namespace signals
153 } // end namespace boost
154
155 #endif // BOOST_SIGNALS_COMMON_HEADER