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