]> git.lyx.org Git - lyx.git/blob - boost/boost/mpl/has_xxx.hpp
Upgrade to boost 1.33.1
[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: 2005/06/15 10:43:23 $
16 // $Revision: 1.4 $
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 // agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE
152 // applied to partial specialization to fix some apparently random failures 
153 // (thanks to Daniel Wallin for researching this!)
154
155 namespace boost { namespace mpl { namespace aux {
156 template< typename T > struct msvc71_sfinae_helper { typedef void type; };
157 }}}
158
159 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
160 template< typename T, typename U = void > \
161 struct BOOST_PP_CAT(trait,_impl_) \
162 { \
163     BOOST_STATIC_CONSTANT(bool, value = false); \
164     typedef boost::mpl::bool_<value> type; \
165 }; \
166 \
167 template< typename T > \
168 struct BOOST_PP_CAT(trait,_impl_)< \
169       T \
170     , typename boost::mpl::aux::msvc71_sfinae_helper< typename T::name >::type \
171     > \
172 { \
173     BOOST_STATIC_CONSTANT(bool, value = true); \
174     typedef boost::mpl::bool_<value> type; \
175 }; \
176 \
177 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
178 struct trait \
179     : BOOST_PP_CAT(trait,_impl_)<T> \
180 { \
181 }; \
182 /**/
183
184 #   else // other SFINAE-capable compilers
185
186 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
187 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
188 struct trait \
189 { \
190     struct gcc_3_2_wknd \
191     { \
192         template< typename U > \
193         static boost::mpl::aux::yes_tag test( \
194               boost::mpl::aux::type_wrapper<U> const volatile* \
195             , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
196             ); \
197     \
198         static boost::mpl::aux::no_tag test(...); \
199     }; \
200     \
201     typedef boost::mpl::aux::type_wrapper<T> t_; \
202     BOOST_STATIC_CONSTANT(bool, value = \
203           sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
204             == sizeof(boost::mpl::aux::yes_tag) \
205         ); \
206     typedef boost::mpl::bool_<value> type; \
207 }; \
208 /**/
209
210 #   endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
211
212
213 #else // BOOST_MPL_CFG_NO_HAS_XXX
214
215 // placeholder implementation
216
217 #   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
218 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
219 struct trait \
220 { \
221     BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
222     typedef fallback_ type; \
223 }; \
224 /**/
225
226 #endif
227
228 #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
229     BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
230 /**/
231
232 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED