• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 //  (C) Copyright Edward Diener 2011,2012,2013
3 //  Use, modification and distribution are subject to the Boost Software License,
4 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt).
6 
7 #if !defined(BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP)
8 #define BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP
9 
10 #include <boost/config.hpp>
11 #include <boost/mpl/bool.hpp>
12 #include <boost/mpl/eval_if.hpp>
13 #include <boost/mpl/has_xxx.hpp>
14 #include <boost/preprocessor/arithmetic/add.hpp>
15 #include <boost/preprocessor/arithmetic/sub.hpp>
16 #include <boost/preprocessor/array/elem.hpp>
17 #include <boost/preprocessor/cat.hpp>
18 #include <boost/preprocessor/punctuation/comma_if.hpp>
19 #include <boost/preprocessor/repetition/repeat.hpp>
20 #include <boost/preprocessor/repetition/enum.hpp>
21 #include <boost/preprocessor/array/enum.hpp>
22 #include <boost/preprocessor/array/size.hpp>
23 #include <boost/tti/detail/denclosing_type.hpp>
24 #include <boost/tti/gen/namespace_gen.hpp>
25 
26 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
27 
28 #define BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS(z,n,args) \
29 BOOST_PP_ARRAY_ELEM(BOOST_PP_ADD(4,n),args) \
30 /**/
31 
32 #define BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION(args,introspect_macro) \
33    template \
34      < \
35      typename BOOST_TTI_DETAIL_TP_T, \
36      typename BOOST_TTI_DETAIL_TP_FALLBACK_ \
37        = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \
38      > \
39    struct BOOST_PP_ARRAY_ELEM(0, args) \
40      { \
41      private: \
42      introspect_macro(args) \
43      public: \
44        static const bool value \
45          = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< BOOST_TTI_DETAIL_TP_T >::value; \
46        typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
47          < \
48          BOOST_TTI_DETAIL_TP_T \
49          >::type type; \
50      }; \
51 /**/
52 
53 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
54 
55 #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE(z,n,args) \
56   template \
57     < \
58     template \
59       < \
60       BOOST_PP_ENUM_ ## z \
61         ( \
62         BOOST_PP_SUB \
63           ( \
64           BOOST_PP_ARRAY_SIZE(args), \
65           4 \
66           ), \
67         BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \
68         args \
69         ) \
70       > \
71     class BOOST_TTI_DETAIL_TM_V \
72     > \
73   struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
74     { \
75     }; \
76 /**/
77 
78 #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \
79   BOOST_PP_REPEAT \
80     ( \
81     BOOST_PP_ARRAY_ELEM(2, args), \
82     BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE, \
83     args \
84     ) \
85 /**/
86 
87 #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT(args) \
88   template< typename U > \
89   struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
90     { \
91     BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \
92     BOOST_MPL_HAS_MEMBER_REJECT(args, BOOST_PP_NIL) \
93     BOOST_MPL_HAS_MEMBER_ACCEPT(args, BOOST_PP_NIL) \
94     BOOST_STATIC_CONSTANT \
95       ( \
96       bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
97       ); \
98     typedef boost::mpl::bool_< value > type; \
99     }; \
100 /**/
101 
102 #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE(args) \
103   BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \
104     ( \
105     args, \
106     BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT \
107     ) \
108 /**/
109 
110 #else // !!BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
111 
112 #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE(z,n,args) \
113   template \
114     < \
115     template \
116       < \
117       BOOST_PP_ENUM_ ## z \
118         ( \
119         BOOST_PP_SUB \
120           ( \
121           BOOST_PP_ARRAY_SIZE(args), \
122           4 \
123           ), \
124         BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \
125         args \
126         ) \
127       > \
128     class BOOST_TTI_DETAIL_TM_U \
129     > \
130   struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE \
131     ( \
132     args, \
133     n \
134     ) \
135     { \
136     typedef \
137       BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
138       type; \
139     }; \
140 /**/
141 
142 #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE(args) \
143   typedef void \
144       BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
145   BOOST_PP_REPEAT \
146     ( \
147     BOOST_PP_ARRAY_ELEM(2, args), \
148     BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE, \
149     args \
150     ) \
151 /**/
152 
153 #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE(args) \
154   BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \
155   BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \
156   template< typename BOOST_TTI_DETAIL_TP_U > \
157   struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
158       : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< BOOST_TTI_DETAIL_TP_U > { \
159   }; \
160 /**/
161 
162 #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE(args) \
163   BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE \
164     ( \
165     args \
166     ) \
167   BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \
168     ( \
169     args, \
170     BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
171     ) \
172 /**/
173 
174 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
175 
176 #else // defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
177 
178 #define BOOST_TTI_DETAIL_SAME(trait,name) \
179   BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF \
180     ( \
181     trait, \
182     name, \
183     false \
184     ) \
185 /**/
186 
187 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tp) \
188   BOOST_TTI_DETAIL_SAME(trait,name) \
189 /**/
190 
191 #endif // !BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
192 
193 #define BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS_OP(trait,name,tpArray) \
194   BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(BOOST_PP_CAT(trait,_detail),name,tpArray) \
195   template<class BOOST_TTI_DETAIL_TP_T> \
196   struct BOOST_PP_CAT(trait,_detail_cp_op) : \
197     BOOST_PP_CAT(trait,_detail)<BOOST_TTI_DETAIL_TP_T> \
198     { \
199     }; \
200 /**/
201 
202 #define BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
203   BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS_OP(trait,name,tpArray) \
204   template<class BOOST_TTI_DETAIL_TP_T> \
205   struct trait \
206     { \
207     typedef typename \
208       boost::mpl::eval_if \
209         < \
210         BOOST_TTI_NAMESPACE::detail::enclosing_type<BOOST_TTI_DETAIL_TP_T>, \
211         BOOST_PP_CAT(trait,_detail_cp_op)<BOOST_TTI_DETAIL_TP_T>, \
212         boost::mpl::false_ \
213         >::type type; \
214     BOOST_STATIC_CONSTANT(bool,value=type::value); \
215     }; \
216 /**/
217 
218 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
219 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
220 
221 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
222   BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE \
223     (  \
224       ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) )  \
225     )  \
226 /**/
227 
228 #else // BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
229 
230 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
231   BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \
232     ( \
233       ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) )  \
234     ) \
235 /**/
236 
237 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
238 #endif // !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
239 
240 #endif // BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP
241