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