blob: c88560975f53c38bb472a2e7458bb9d0165a8131 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001
Jeff Thompson3d613fd2013-10-15 15:39:04 -07002#ifndef NDNBOOST_MPL_HAS_XXX_HPP_INCLUDED
3#define NDNBOOST_MPL_HAS_XXX_HPP_INCLUDED
Jeff Thompsona28eed82013-08-22 16:21:10 -07004
5// Copyright Aleksey Gurtovoy 2002-2006
6// Copyright David Abrahams 2002-2003
7// Copyright Daniel Walker 2007
8//
9// Distributed under the Boost Software License, Version 1.0.
10// (See accompanying file LICENSE_1_0.txt or copy at
11// http://www.boost.org/LICENSE_1_0.txt)
12//
13// See http://www.boost.org/libs/mpl for documentation.
14
15// $Id: has_xxx.hpp 64146 2010-07-19 00:46:31Z djwalker $
16// $Date: 2010-07-18 17:46:31 -0700 (Sun, 18 Jul 2010) $
17// $Revision: 64146 $
18
19#include <ndnboost/mpl/bool.hpp>
20#include <ndnboost/mpl/aux_/na_spec.hpp>
21#include <ndnboost/mpl/aux_/type_wrapper.hpp>
22#include <ndnboost/mpl/aux_/yes_no.hpp>
23#include <ndnboost/mpl/aux_/config/gcc.hpp>
24#include <ndnboost/mpl/aux_/config/has_xxx.hpp>
25#include <ndnboost/mpl/aux_/config/msvc_typename.hpp>
26#include <ndnboost/mpl/aux_/config/msvc.hpp>
27#include <ndnboost/mpl/aux_/config/static_constant.hpp>
28#include <ndnboost/mpl/aux_/config/workaround.hpp>
29
30#include <ndnboost/preprocessor/array/elem.hpp>
31#include <ndnboost/preprocessor/cat.hpp>
32#include <ndnboost/preprocessor/control/if.hpp>
33#include <ndnboost/preprocessor/repetition/enum_params.hpp>
34#include <ndnboost/preprocessor/repetition/enum_trailing_params.hpp>
35
Jeff Thompson3d613fd2013-10-15 15:39:04 -070036#if NDNBOOST_WORKAROUND( __BORLANDC__, NDNBOOST_TESTED_AT(0x590) )
Jeff Thompsona28eed82013-08-22 16:21:10 -070037# include <ndnboost/type_traits/is_class.hpp>
38#endif
39
Jeff Thompson3d613fd2013-10-15 15:39:04 -070040#if !defined(NDNBOOST_MPL_CFG_NO_HAS_XXX)
Jeff Thompsona28eed82013-08-22 16:21:10 -070041
Jeff Thompson3d613fd2013-10-15 15:39:04 -070042# if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
Jeff Thompsona28eed82013-08-22 16:21:10 -070043
44// agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET
45// newsgroup's posting by John Madsen (comp.lang.c++.moderated,
46// 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but
47// it works way more reliably than the SFINAE-based implementation
48
49// Modified dwa 8/Oct/02 to handle reference types.
50
51# include <ndnboost/mpl/if.hpp>
52# include <ndnboost/mpl/bool.hpp>
53
54namespace ndnboost { namespace mpl { namespace aux {
55
56struct has_xxx_tag;
57
Jeff Thompson3d613fd2013-10-15 15:39:04 -070058#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, == 1300)
Jeff Thompsona28eed82013-08-22 16:21:10 -070059template< typename U > struct msvc_incomplete_array
60{
61 typedef char (&type)[sizeof(U) + 1];
62};
63#endif
64
65template< typename T >
66struct msvc_is_incomplete
67{
68 // MSVC is capable of some kinds of SFINAE. If U is an incomplete
69 // type, it won't pick the second overload
70 static char tester(...);
71
Jeff Thompson3d613fd2013-10-15 15:39:04 -070072#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, == 1300)
Jeff Thompsona28eed82013-08-22 16:21:10 -070073 template< typename U >
74 static typename msvc_incomplete_array<U>::type tester(type_wrapper<U>);
75#else
76 template< typename U >
77 static char (& tester(type_wrapper<U>) )[sizeof(U)+1];
78#endif
79
Jeff Thompson3d613fd2013-10-15 15:39:04 -070080 NDNBOOST_STATIC_CONSTANT(bool, value =
Jeff Thompsona28eed82013-08-22 16:21:10 -070081 sizeof(tester(type_wrapper<T>())) == 1
82 );
83};
84
85template<>
86struct msvc_is_incomplete<int>
87{
Jeff Thompson3d613fd2013-10-15 15:39:04 -070088 NDNBOOST_STATIC_CONSTANT(bool, value = false);
Jeff Thompsona28eed82013-08-22 16:21:10 -070089};
90
91}}}
92
Jeff Thompson3d613fd2013-10-15 15:39:04 -070093# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -070094template< typename T, typename name = ::ndnboost::mpl::aux::has_xxx_tag > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -070095struct NDNBOOST_PP_CAT(trait,_impl) : T \
Jeff Thompsona28eed82013-08-22 16:21:10 -070096{ \
97 static ndnboost::mpl::aux::no_tag \
98 test(void(*)(::ndnboost::mpl::aux::has_xxx_tag)); \
99 \
100 static ndnboost::mpl::aux::yes_tag test(...); \
101 \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700102 NDNBOOST_STATIC_CONSTANT(bool, value = \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700103 sizeof(test(static_cast<void(*)(name)>(0))) \
104 != sizeof(ndnboost::mpl::aux::no_tag) \
105 ); \
106 typedef ndnboost::mpl::bool_<value> type; \
107}; \
108\
109template< typename T, typename fallback_ = ndnboost::mpl::bool_<default_> > \
110struct trait \
111 : ndnboost::mpl::if_c< \
112 ndnboost::mpl::aux::msvc_is_incomplete<T>::value \
113 , ndnboost::mpl::bool_<false> \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700114 , NDNBOOST_PP_CAT(trait,_impl)<T> \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700115 >::type \
116{ \
117}; \
118\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700119NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \
120NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \
121NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \
122NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \
123NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \
124NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \
125NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \
126NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \
127NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \
128NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \
129NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \
130NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \
131NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \
132NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700133/**/
134
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700135# define NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700136template<> struct trait<T> \
137{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700138 NDNBOOST_STATIC_CONSTANT(bool, value = false); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700139 typedef ndnboost::mpl::bool_<false> type; \
140}; \
141/**/
142
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700143#if !defined(NDNBOOST_NO_INTRINSIC_WCHAR_T)
144# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
145 NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
146 NDNBOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700147/**/
148#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700149# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
150 NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700151/**/
152#endif
153
154
155// SFINAE-based implementations below are derived from a USENET newsgroup's
156// posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST)
157
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700158# elif NDNBOOST_WORKAROUND(NDNBOOST_MSVC, NDNBOOST_TESTED_AT(1400)) \
159 || NDNBOOST_WORKAROUND(__IBMCPP__, <= 700)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700160
161// MSVC 7.1+ & VACPP
162
163// agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE
164// applied to partial specialization to fix some apparently random failures
165// (thanks to Daniel Wallin for researching this!)
166
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700167# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700168template< typename T > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700169struct NDNBOOST_PP_CAT(trait, _msvc_sfinae_helper) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700170{ \
171 typedef void type; \
172};\
173\
174template< typename T, typename U = void > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700175struct NDNBOOST_PP_CAT(trait,_impl_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700176{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700177 NDNBOOST_STATIC_CONSTANT(bool, value = false); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700178 typedef ndnboost::mpl::bool_<value> type; \
179}; \
180\
181template< typename T > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700182struct NDNBOOST_PP_CAT(trait,_impl_)< \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700183 T \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700184 , typename NDNBOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700185 > \
186{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700187 NDNBOOST_STATIC_CONSTANT(bool, value = true); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700188 typedef ndnboost::mpl::bool_<value> type; \
189}; \
190\
191template< typename T, typename fallback_ = ndnboost::mpl::bool_<default_> > \
192struct trait \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700193 : NDNBOOST_PP_CAT(trait,_impl_)<T> \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700194{ \
195}; \
196/**/
197
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700198# elif NDNBOOST_WORKAROUND( __BORLANDC__, NDNBOOST_TESTED_AT(0x590) )
Jeff Thompsona28eed82013-08-22 16:21:10 -0700199
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700200# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700201template< typename T, bool IS_CLASS > \
202struct trait_tester \
203{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700204 NDNBOOST_STATIC_CONSTANT( bool, value = false ); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700205}; \
206template< typename T > \
207struct trait_tester< T, true > \
208{ \
209 struct trait_tester_impl \
210 { \
211 template < class U > \
212 static int resolve( ndnboost::mpl::aux::type_wrapper<U> const volatile * \
213 , ndnboost::mpl::aux::type_wrapper<typename U::name >* = 0 ); \
214 static char resolve( ... ); \
215 }; \
216 typedef ndnboost::mpl::aux::type_wrapper<T> t_; \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700217 NDNBOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700218}; \
219template< typename T, typename fallback_ = ndnboost::mpl::bool_<default_> > \
220struct trait \
221{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700222 NDNBOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, ndnboost::is_class< T >::value >::value) ); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700223 typedef ndnboost::mpl::bool_< trait< T, fallback_ >::value > type; \
224};
225
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700226# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
227 NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \
228 , NDNBOOST_PP_CAT(trait,_tester) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700229 , name \
230 , default_ ) \
231/**/
232
233# else // other SFINAE-capable compilers
234
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700235# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700236template< typename T, typename fallback_ = ndnboost::mpl::bool_<default_> > \
237struct trait \
238{ \
239 struct gcc_3_2_wknd \
240 { \
241 template< typename U > \
242 static ndnboost::mpl::aux::yes_tag test( \
243 ndnboost::mpl::aux::type_wrapper<U> const volatile* \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700244 , ndnboost::mpl::aux::type_wrapper<NDNBOOST_MSVC_TYPENAME U::name>* = 0 \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700245 ); \
246 \
247 static ndnboost::mpl::aux::no_tag test(...); \
248 }; \
249 \
250 typedef ndnboost::mpl::aux::type_wrapper<T> t_; \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700251 NDNBOOST_STATIC_CONSTANT(bool, value = \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700252 sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
253 == sizeof(ndnboost::mpl::aux::yes_tag) \
254 ); \
255 typedef ndnboost::mpl::bool_<value> type; \
256}; \
257/**/
258
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700259# endif // NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700260
261
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700262#else // NDNBOOST_MPL_CFG_NO_HAS_XXX
Jeff Thompsona28eed82013-08-22 16:21:10 -0700263
264// placeholder implementation
265
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700266# define NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700267template< typename T, typename fallback_ = ndnboost::mpl::bool_<default_> > \
268struct trait \
269{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700270 NDNBOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700271 typedef fallback_ type; \
272}; \
273/**/
274
275#endif
276
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700277#define NDNBOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
278 NDNBOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(NDNBOOST_PP_CAT(has_,name), name, false) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700279/**/
280
281
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700282#if !defined(NDNBOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700283
284// Create a boolean Metafunction to detect a nested template
285// member. This implementation is based on a USENET newsgroup's
286// posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19),
287// Rani Sharoni's USENET posting cited above, the non-template has_xxx
288// implementations above, and discussion on the Boost mailing list.
289
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700290# if !defined(NDNBOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES)
291# if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1400)
292# define NDNBOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700293# endif
294# endif
295
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700296# if !defined(NDNBOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION)
297# if (defined(NDNBOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS))
298# define NDNBOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700299# endif
300# endif
301
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700302# if !defined(NDNBOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE)
303# if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1400)
304# define NDNBOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700305# endif
306# endif
307
308// NOTE: Many internal implementation macros take a Boost.Preprocessor
309// array argument called args which is of the following form.
310// ( 4, ( trait, name, max_arity, default_ ) )
311
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700312# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
313 NDNBOOST_PP_CAT(NDNBOOST_PP_ARRAY_ELEM(0, args) , _introspect) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700314 /**/
315
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700316# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
317 NDNBOOST_PP_CAT(NDNBOOST_PP_CAT(NDNBOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700318 /**/
319
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700320# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \
321 NDNBOOST_PP_CAT(NDNBOOST_PP_ARRAY_ELEM(0, args) , _test) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700322 /**/
323
324// Thanks to Guillaume Melquiond for pointing out the need for the
325// "substitute" template as an argument to the overloaded test
326// functions to get SFINAE to work for member templates with the
327// correct name but different number of arguments.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700328# define NDNBOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700329 template< \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700330 template< NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_PP_INC(n), typename V) > class V \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700331 > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700332 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700333 }; \
334 /**/
335
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700336# define NDNBOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
337 NDNBOOST_PP_REPEAT( \
338 NDNBOOST_PP_ARRAY_ELEM(2, args) \
339 , NDNBOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700340 , args \
341 ) \
342 /**/
343
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700344# if !NDNBOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
345# define NDNBOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700346 template< typename V > \
347 static ndnboost::mpl::aux::no_tag \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700348 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700349 /**/
350# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700351# define NDNBOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700352 static ndnboost::mpl::aux::no_tag \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700353 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700354 /**/
355# endif
356
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700357# if !NDNBOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
358# define NDNBOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700359 template< typename V > \
360 static ndnboost::mpl::aux::yes_tag \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700361 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700362 ndnboost::mpl::aux::type_wrapper< V > const volatile* \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700363 , NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \
364 V::template NDNBOOST_PP_ARRAY_ELEM(1, args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700365 >* = 0 \
366 ); \
367 /**/
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700368# define NDNBOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
369 NDNBOOST_PP_REPEAT( \
370 NDNBOOST_PP_ARRAY_ELEM(2, args) \
371 , NDNBOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700372 , args \
373 ) \
374 /**/
375# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700376# define NDNBOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700377 template< typename V > \
378 static ndnboost::mpl::aux::yes_tag \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700379 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700380 V const volatile* \
381 , member_macro(args, V, T)* = 0 \
382 ); \
383 /**/
384# endif
385
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700386# if !NDNBOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
387# define NDNBOOST_MPL_HAS_MEMBER_TEST(args) \
388 sizeof(NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700389 == sizeof(ndnboost::mpl::aux::yes_tag) \
390 /**/
391# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700392# if !NDNBOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
393# define NDNBOOST_MPL_HAS_MEMBER_TEST(args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700394 sizeof( \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700395 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700396 static_cast< ndnboost::mpl::aux::type_wrapper< U >* >(0) \
397 ) \
398 ) == sizeof(ndnboost::mpl::aux::yes_tag) \
399 /**/
400# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700401# define NDNBOOST_MPL_HAS_MEMBER_TEST(args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700402 sizeof( \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700403 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700404 static_cast< U* >(0) \
405 ) \
406 ) == sizeof(ndnboost::mpl::aux::yes_tag) \
407 /**/
408# endif
409# endif
410
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700411# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECT( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700412 args, substitute_macro, member_macro \
413 ) \
414 template< typename U > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700415 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \
416 NDNBOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
417 NDNBOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
418 NDNBOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
419 NDNBOOST_STATIC_CONSTANT( \
420 bool, value = NDNBOOST_MPL_HAS_MEMBER_TEST(args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700421 ); \
422 typedef ndnboost::mpl::bool_< value > type; \
423 }; \
424 /**/
425
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700426# define NDNBOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700427 args, introspect_macro, substitute_macro, member_macro \
428 ) \
429 template< \
430 typename T \
431 , typename fallback_ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700432 = ndnboost::mpl::bool_< NDNBOOST_PP_ARRAY_ELEM(3, args) > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700433 > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700434 class NDNBOOST_PP_ARRAY_ELEM(0, args) { \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700435 introspect_macro(args, substitute_macro, member_macro) \
436 public: \
437 static const bool value \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700438 = NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \
439 typedef typename NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700440 T \
441 >::type type; \
442 }; \
443 /**/
444
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700445// NDNBOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full
Jeff Thompsona28eed82013-08-22 16:21:10 -0700446// implementation of the function-based metafunction. Compile with -E
447// to see the preprocessor output for this macro.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700448# define NDNBOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700449 args, substitute_macro, member_macro \
450 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700451 NDNBOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700452 args \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700453 , NDNBOOST_MPL_HAS_MEMBER_INTROSPECT \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700454 , substitute_macro \
455 , member_macro \
456 ) \
457 /**/
458
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700459# if NDNBOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700460
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700461# if !defined(NDNBOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
462# if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1400)
463# define NDNBOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1
Jeff Thompsona28eed82013-08-22 16:21:10 -0700464# endif
465# endif
466
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700467# if !NDNBOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
468# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700469 args, n \
470 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700471 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700472 /**/
473# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700474# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700475 args, n \
476 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700477 NDNBOOST_PP_CAT( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700478 boost_mpl_has_xxx_ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700479 , NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700480 ) \
481 /**/
482# endif
483
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700484# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700485 args \
486 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700487 NDNBOOST_PP_CAT( \
488 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700489 args, 0 \
490 ) \
491 , _tag \
492 ) \
493 /**/
494
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700495# define NDNBOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700496 z, n, args \
497 ) \
498 template< \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700499 template< NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_PP_INC(n), typename U) > class U \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700500 > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700501 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700502 args, n \
503 ) { \
504 typedef \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700505 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700506 type; \
507 }; \
508 /**/
509
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700510# define NDNBOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700511 args, substitute_macro \
512 ) \
513 typedef void \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700514 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
515 NDNBOOST_PP_REPEAT( \
516 NDNBOOST_PP_ARRAY_ELEM(2, args) \
517 , NDNBOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700518 , args \
519 ) \
520 /**/
521
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700522# define NDNBOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700523 args, member_macro \
524 ) \
525 template< \
526 typename U \
527 , typename V \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700528 = NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700529 > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700530 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \
531 NDNBOOST_STATIC_CONSTANT(bool, value = false); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700532 typedef ndnboost::mpl::bool_< value > type; \
533 }; \
534 /**/
535
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700536# define NDNBOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700537 z, n, args \
538 ) \
539 template< typename U > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700540 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700541 U \
542 , typename \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700543 NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700544 args, n \
545 )< \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700546 NDNBOOST_MSVC_TYPENAME U::NDNBOOST_PP_ARRAY_ELEM(1, args)< > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700547 >::type \
548 > { \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700549 NDNBOOST_STATIC_CONSTANT(bool, value = true); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700550 typedef ndnboost::mpl::bool_< value > type; \
551 }; \
552 /**/
553
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700554# define NDNBOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700555 args, member_macro \
556 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700557 NDNBOOST_PP_REPEAT( \
558 NDNBOOST_PP_ARRAY_ELEM(2, args) \
559 , NDNBOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700560 , args \
561 ) \
562 /**/
563
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700564# define NDNBOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700565 args, substitute_macro, member_macro \
566 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700567 NDNBOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \
568 NDNBOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700569 template< typename U > \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700570 struct NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
571 : NDNBOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700572 }; \
573 /**/
574
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700575// NDNBOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full
Jeff Thompsona28eed82013-08-22 16:21:10 -0700576// implementation of the template-based metafunction. Compile with -E
577// to see the preprocessor output for this macro.
578//
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700579// Note that if NDNBOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is
580// defined NDNBOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs
Jeff Thompsona28eed82013-08-22 16:21:10 -0700581// to be expanded at namespace level before
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700582// NDNBOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used.
583# define NDNBOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700584 args, substitute_macro, member_macro \
585 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700586 NDNBOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700587 args, substitute_macro \
588 ) \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700589 NDNBOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700590 args \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700591 , NDNBOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700592 , substitute_macro \
593 , member_macro \
594 ) \
595 /**/
596
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700597# endif // NDNBOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700598
599// Note: In the current implementation the parameter and access macros
600// are no longer expanded.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700601# if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1400)
602# define NDNBOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
603 NDNBOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
604 ( 4, ( trait, name, NDNBOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
605 , NDNBOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
606 , NDNBOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700607 ) \
608 /**/
609# else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700610# define NDNBOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
611 NDNBOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
612 ( 4, ( trait, name, NDNBOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
613 , NDNBOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
614 , NDNBOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700615 ) \
616 /**/
617# endif
618
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700619#else // NDNBOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700620
621// placeholder implementation
622
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700623# define NDNBOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700624 template< typename T \
625 , typename fallback_ = ndnboost::mpl::bool_< default_ > > \
626 struct trait { \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700627 NDNBOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700628 typedef fallback_ type; \
629 }; \
630 /**/
631
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700632#endif // NDNBOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
Jeff Thompsona28eed82013-08-22 16:21:10 -0700633
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700634# define NDNBOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \
635 NDNBOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \
636 NDNBOOST_PP_CAT(has_, name), name, false \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700637 ) \
638 /**/
639
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700640#endif // NDNBOOST_MPL_HAS_XXX_HPP_INCLUDED