]> git.lyx.org Git - lyx.git/blob - boost/boost/mpl/has_xxx.hpp
update to boost 1.32.0
[lyx.git] / boost / boost / mpl / has_xxx.hpp
1
2 #ifndef BOOST_MPL_HAS_XXX_HPP_INCLUDED
3 #define BOOST_MPL_HAS_XXX_HPP_INCLUDED
4
5 // Copyright Aleksey Gurtovoy 2002-2004
6 // Copyright David Abrahams 2002-2003
7 //
8 // Distributed under the Boost Software License, Version 1.0. 
9 // (See accompanying file LICENSE_1_0.txt or copy at 
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // See http://www.boost.org/libs/mpl for documentation.
13
14 // $Source: /cvsroot/boost/boost/boost/mpl/has_xxx.hpp,v $
15 // $Date: 2004/09/03 15:56:55 $
16 // $Revision: 1.3 $
17
18 #include <boost/mpl/bool.hpp>
19 #include <boost/mpl/aux_/type_wrapper.hpp>
20 #include <boost/mpl/aux_/yes_no.hpp>
21 #include <boost/mpl/aux_/config/has_xxx.hpp>
22 #include <boost/mpl/aux_/config/msvc_typename.hpp>
23 #include <boost/mpl/aux_/config/msvc.hpp>
24 #include <boost/mpl/aux_/config/static_constant.hpp>
25 #include <boost/mpl/aux_/config/workaround.hpp>
26
27 #include <boost/preprocessor/cat.hpp>
28
29 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX)
30
31 #   if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
32
33 // agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET 
34 // newsgroup's posting by John Madsen (comp.lang.c++.moderated, 
35 // 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but 
36 // it works way more reliably than the SFINAE-based implementation
37
38 // Modified dwa 8/Oct/02 to handle reference types.
39
40 #   include <boost/mpl/if.hpp>
41 #   include <boost/mpl/bool.hpp>
42
43 namespace boost { namespace mpl { namespace aux {
44
45 struct has_xxx_tag;
46
47 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
48 template< typename U > struct msvc_incomplete_array
49 {
50     typedef char (&type)[sizeof(U) + 1];
51 };
52 #endif
53
54 template< typename T >
55 struct msvc_is_incomplete
56 {
57     // MSVC is capable of some kinds of SFINAE.  If U is an incomplete
58     // type, it won't pick the second overload
59     static char tester(...);
60
61 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
62     template< typename U >
63     static typename msvc_incomplete_array<U>::type tester(type_wrapper<U>);
64 #else
65     template< typename U >
66     static char (& tester(type_wrapper<U>) )[sizeof(U)+1];
67 #endif 
68     
69     BOOST_STATIC_CONSTANT(bool, value = 
70           sizeof(tester(type_wrapper<T>())) == 1
71         );
72 };
73
74 template<>
75 struct msvc_is_incomplete<int>
76 {
77     BOOST_STATIC_CONSTANT(bool, value = false);
78 };
79
80 }}}
81
82 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \
83 template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \
84 struct BOOST_PP_CAT(trait,_impl) : T \
85 { \
86     static boost::mpl::aux::no_tag \
87     test(void(*)(::boost::mpl::aux::has_xxx_tag)); \
88     \
89     static boost::mpl::aux::yes_tag test(...); \
90     \
91     BOOST_STATIC_CONSTANT(bool, value = \
92           sizeof(test(static_cast<void(*)(name)>(0))) \
93             != sizeof(boost::mpl::aux::no_tag) \
94         ); \
95     typedef boost::mpl::bool_<value> type; \
96 }; \
97 \
98 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
99 struct trait \
100     : boost::mpl::if_c< \
101           boost::mpl::aux::msvc_is_incomplete<T>::value \
102         , boost::mpl::bool_<false> \
103         , BOOST_PP_CAT(trait,_impl)<T> \
104         >::type \
105 { \
106 }; \
107 \
108 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \
109 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \
110 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \
111 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \
112 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \
113 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \
114 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \
115 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \
116 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \
117 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \
118 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \
119 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \
120 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \
121 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \
122 /**/
123
124 #   define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \
125 template<> struct trait<T> \
126 { \
127     BOOST_STATIC_CONSTANT(bool, value = false); \
128     typedef boost::mpl::bool_<false> type; \
129 }; \
130 /**/
131
132 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
133 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
134     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
135     BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \
136 /**/
137 #else
138 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
139     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
140 /**/
141 #endif
142
143
144 // SFINAE-based implementations below are derived from a USENET newsgroup's 
145 // posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST)
146
147 #   elif BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
148
149 // MSVC 7.1+
150
151 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
152 template< typename T > struct BOOST_PP_CAT(trait,_wrapper_); \
153 template< typename T > \
154 boost::mpl::aux::yes_tag BOOST_PP_CAT(trait,_helper_)( \
155       BOOST_PP_CAT(trait,_wrapper_)<T> const volatile* \
156     , BOOST_PP_CAT(trait,_wrapper_)<BOOST_MSVC_TYPENAME T::name>* = 0 \
157     ); \
158 \
159 boost::mpl::aux::no_tag BOOST_PP_CAT(trait,_helper_)(...); \
160 \
161 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
162 struct trait \
163 { \
164     typedef BOOST_PP_CAT(trait,_wrapper_)<T> t_; \
165     BOOST_STATIC_CONSTANT(bool, value = \
166           sizeof((BOOST_PP_CAT(trait,_helper_))(static_cast<t_*>(0))) \
167             == sizeof(boost::mpl::aux::yes_tag) \
168         ); \
169     typedef boost::mpl::bool_<value> type; \
170 }; \
171 /**/
172
173 #   else // other SFINAE-capable compilers
174
175 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
176 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
177 struct trait \
178 { \
179     struct gcc_3_2_wknd \
180     { \
181         template< typename U > \
182         static boost::mpl::aux::yes_tag test( \
183               boost::mpl::aux::type_wrapper<U> const volatile* \
184             , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
185             ); \
186     \
187         static boost::mpl::aux::no_tag test(...); \
188     }; \
189     \
190     typedef boost::mpl::aux::type_wrapper<T> t_; \
191     BOOST_STATIC_CONSTANT(bool, value = \
192           sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
193             == sizeof(boost::mpl::aux::yes_tag) \
194         ); \
195     typedef boost::mpl::bool_<value> type; \
196 }; \
197 /**/
198
199 #   endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
200
201
202 #else // BOOST_MPL_CFG_NO_HAS_XXX
203
204 // placeholder implementation
205
206 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
207 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
208 struct trait \
209 { \
210     BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
211     typedef fallback_ type; \
212 }; \
213 /**/
214
215 #endif
216
217 #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
218     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
219 /**/
220
221 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED