1 
2 //  (C) Copyright Edward Diener 2019
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_FUNCTION_TEMPLATE_HPP)
8 #define BOOST_TTI_FUNCTION_TEMPLATE_HPP
9 
10 #include <boost/config.hpp>
11 #include <boost/function_types/property_tags.hpp>
12 #include <boost/mpl/vector.hpp>
13 #include <boost/preprocessor/cat.hpp>
14 #include <boost/tti/gen/namespace_gen.hpp>
15 #include <boost/tti/gen/has_function_template_gen.hpp>
16 #include <boost/tti/detail/dfunction_template.hpp>
17 
18 #if BOOST_PP_VARIADICS
19 
20 #include <boost/tti/detail/dmacro_fun_template.hpp>
21 
22 /*
23 
24   The succeeding comments in this file are in doxygen format.
25 
26 */
27 
28 /** \file
29 */
30 
31 /// A macro which expands to a metafunction which tests whether an inner member function template or static member function template with a particular name exists.
32 /**
33 
34     BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE is a macro which expands to a metafunction.
35     The metafunction tests whether an inner member function template or static member function template with a particular name exists.
36     The macro takes the form of BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(trait,name,...) where
37 
38     trait = the name of the metafunction <br/>
39     name  = inner member function template or static member function template name <br/>
40     ...   = variadic parameters.
41 
42     The variadic parameter(s) are either:
43 
44     A sequence of valid instantiations for the static member function template parameters
45     ie. 'int,long,double' etc.
46 
47     or
48 
49     A single variadic parameter which is a Boost PP array whose elements are
50     a sequence of valid instantiations for the static member function template parameters
51     ie. '(3,(int,long,double))' etc. This form is allowed in order to be compatible
52     with using the non-variadic form of this macro.
53 
54     BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE generates a metafunction called "trait" where 'trait' is the first macro parameter.
55 
56   @code
57 
58             template<class BOOST_TTI_TP_T,class BOOST_TTI_R,class BOOST_TTI_FS,class BOOST_TTI_TAG>
59             struct trait
60               {
61               static const value = unspecified;
62               typedef mpl::bool_<true-or-false> type;
63               };
64 
65             The metafunction types and return:
66 
67               BOOST_TTI_TP_T   = the enclosing type in which to look for our 'name'.
68                                  The enclosing type can be a class, struct, or union.
69 
70               BOOST_TTI_TP_R   = the return type of the function template
71                                  in a single instantiation of the function template
72 
73               BOOST_TTI_TP_FS  = (optional) the parameters of the function template as a boost::mpl forward sequence
74                                  if the function template parameters are not empty. These parameters are a single
75                                  instantiation of the function template.
76 
77               BOOST_TTI_TP_TAG = (optional) a boost::function_types tag to apply to the function template
78                                  if a tag is needed.
79 
80               returns = 'value' is true if the 'name' exists,
81                         with the appropriate member function template or static member function template type,
82                         otherwise 'value' is false.
83 
84   @endcode
85 
86 */
87 #define BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(trait,name,...) \
88   BOOST_TTI_DETAIL_TRAIT_HAS_FUNCTION_TEMPLATE \
89     ( \
90     trait, \
91     name, \
92     BOOST_TTI_DETAIL_FUN_TEMPLATE_VARIADIC_TO_ARRAY(__VA_ARGS__) \
93     ) \
94   template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_R,class BOOST_TTI_TP_FS = boost::mpl::vector<>,class BOOST_TTI_TP_TAG = boost::function_types::null_tag> \
95   struct trait \
96     { \
97     typedef typename \
98     BOOST_PP_CAT(trait,_detail_hft)<BOOST_TTI_TP_T,BOOST_TTI_TP_R,BOOST_TTI_TP_FS,BOOST_TTI_TP_TAG>::type type; \
99     BOOST_STATIC_CONSTANT(bool,value=type::value); \
100     }; \
101 /**/
102 
103 
104 /// A macro which expands to a metafunction which tests whether an inner member function template or static member function template with a particular name exists.
105 /**
106 
107     BOOST_TTI__HAS_FUNCTION_TEMPLATE is a macro which expands to a metafunction.
108     The metafunction tests whether an inner member function template or static member function template with a particular name exists.
109     The macro takes the form of BOOST_TTI_HAS_FUNCTION_TEMPLATE(name,...) where
110 
111     name  = inner member function template or static member function template name <br/>
112     ...   = variadic parameters.
113 
114     The variadic parameter(s) are either:
115 
116     A sequence of valid instantiations for the static member function template parameters
117     ie. 'int,long,double' etc.
118 
119     or
120 
121     A single variadic parameter which is a Boost PP array whose elements are
122     a sequence of valid instantiations for the static member function template parameters
123     ie. '(3,(int,long,double))' etc. This form is allowed in order to be compatible
124     with using the non-variadic form of this macro.
125 
126     BOOST_TTI_HAS_FUNCTION_TEMPLATE generates a metafunction called "has_function_template_'name'" where 'name' is the first macro parameter.
127 
128   @code
129 
130             template<class BOOST_TTI_TP_T,class BOOST_TTI_R,class BOOST_TTI_FS,class BOOST_TTI_TAG>
131             struct has_function_template_'name'
132               {
133               static const value = unspecified;
134               typedef mpl::bool_<true-or-false> type;
135               };
136 
137             The metafunction types and return:
138 
139               BOOST_TTI_TP_T   = the enclosing type in which to look for our 'name'.
140                                  The enclosing type can be a class, struct, or union.
141 
142               BOOST_TTI_TP_R   = the return type of the function template
143                                  in a single instantiation of the function template
144 
145               BOOST_TTI_TP_FS  = (optional) the parameters of the function template as a boost::mpl forward sequence
146                                  if the function template parameters are not empty. These parameters are a single
147                                  instantiation of the function template.
148 
149               BOOST_TTI_TP_TAG = (optional) a boost::function_types tag to apply to the function template
150                                  if a tag is needed.
151 
152               returns = 'value' is true if the 'name' exists,
153                         with the appropriate member function template or static member function template type,
154                         otherwise 'value' is false.
155 
156   @endcode
157 
158 */
159 #define BOOST_TTI_HAS_FUNCTION_TEMPLATE(name,...) \
160   BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE \
161   ( \
162   BOOST_TTI_HAS_FUNCTION_TEMPLATE_GEN(name), \
163   name, \
164   __VA_ARGS__ \
165   ) \
166 /**/
167 
168 #else // !BOOST_PP_VARIADICS
169 
170 /*
171 
172   The succeeding comments in this file are in doxygen format.
173 
174 */
175 
176 /** \file
177 */
178 
179 /// A macro which expands to a metafunction which tests whether an inner member function template or static member function template with a particular name exists.
180 /**
181 
182     BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE is a macro which expands to a metafunction.
183     The metafunction tests whether an inner member function template or static member function template with a particular name exists.
184     The macro takes the form of BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(trait,name,pparray) where
185 
186     trait   = the name of the metafunction <br/>
187     name    = inner member function template or static member function template name <br/>
188     pparray = a Boost PP array whose elements are a sequence of valid instantiations for
189               the static member function template parameters ie. '(3,(int,long,double))' etc.
190 
191     BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE generates a metafunction called "trait" where 'trait' is the first macro parameter.
192 
193   @code
194 
195             template<class BOOST_TTI_TP_T,class BOOST_TTI_R,class BOOST_TTI_FS,class BOOST_TTI_TAG>
196             struct trait
197               {
198               static const value = unspecified;
199               typedef mpl::bool_<true-or-false> type;
200               };
201 
202             The metafunction types and return:
203 
204               BOOST_TTI_TP_T   = the enclosing type in which to look for our 'name'.
205                                  The enclosing type can be a class, struct, or union.
206 
207               BOOST_TTI_TP_R   = the return type of the function template
208                                  in a single instantiation of the function template
209 
210               BOOST_TTI_TP_FS  = (optional) the parameters of the function template as a boost::mpl forward sequence
211                                  if the function template parameters are not empty. These parameters are a single
212                                  instantiation of the function template.
213 
214               BOOST_TTI_TP_TAG = (optional) a boost::function_types tag to apply to the function template
215                                  if a tag is needed.
216 
217               returns = 'value' is true if the 'name' exists,
218                         with the appropriate member function template or static member function template type,
219                         otherwise 'value' is false.
220 
221   @endcode
222 
223 */
224 #define BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(trait,name,pparray) \
225   BOOST_TTI_DETAIL_TRAIT_HAS_FUNCTION_TEMPLATE(trait,name,pparray) \
226   template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_R,class BOOST_TTI_TP_FS = boost::mpl::vector<>,class BOOST_TTI_TP_TAG = boost::function_types::null_tag> \
227   struct trait \
228     { \
229     typedef typename \
230     BOOST_PP_CAT(trait,_detail_hft)<BOOST_TTI_TP_T,BOOST_TTI_TP_R,BOOST_TTI_TP_FS,BOOST_TTI_TP_TAG>::type type; \
231     BOOST_STATIC_CONSTANT(bool,value=type::value); \
232     }; \
233 /**/
234 
235 /// A macro which expands to a metafunction which tests whether an inner member function template or static member function template with a particular name exists.
236 /**
237 
238     BOOST_TTI_HAS_FUNCTION_TEMPLATE is a macro which expands to a metafunction.
239     The metafunction tests whether an inner member function template or static member function template with a particular name exists.
240     The macro takes the form of BOOST_TTI_HAS_FUNCTION_TEMPLATE(name,pparray) where
241 
242     name    = inner member function template or static member function template name <br/>
243     pparray = a Boost PP array whose elements are a sequence of valid instantiations for
244               the static member function template parameters ie. '(3,(int,long,double))' etc.
245 
246     BOOST_TTI_HAS_FUNCTION_TEMPLATE generates a metafunction called "has_function_template_'name'" where 'name' is the first macro parameter.
247 
248   @code
249 
250             template<class BOOST_TTI_TP_T,class BOOST_TTI_R,class BOOST_TTI_FS,class BOOST_TTI_TAG>
251             struct has_function_template_'name'
252               {
253               static const value = unspecified;
254               typedef mpl::bool_<true-or-false> type;
255               };
256 
257             The metafunction types and return:
258 
259               BOOST_TTI_TP_T   = the enclosing type in which to look for our 'name'.
260                                  The enclosing type can be a class, struct, or union.
261 
262               BOOST_TTI_TP_R   = the return type of the function template
263                                  in a single instantiation of the function template
264 
265               BOOST_TTI_TP_FS  = (optional) the parameters of the function template as a boost::mpl forward sequence
266                                  if the function template parameters are not empty. These parameters are a single
267                                  instantiation of the function template.
268 
269               BOOST_TTI_TP_TAG = (optional) a boost::function_types tag to apply to the function template
270                                  if a tag is needed.
271 
272               returns = 'value' is true if the 'name' exists,
273                         with the appropriate member function template or static member function template type,
274                         otherwise 'value' is false.
275 
276   @endcode
277 
278 */
279 #define BOOST_TTI_HAS_FUNCTION_TEMPLATE(name,pparray) \
280   BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE \
281   ( \
282   BOOST_TTI_HAS_FUNCTION_TEMPLATE_GEN(name), \
283   name, \
284   pparray \
285   ) \
286 /**/
287 
288 #endif // BOOST_PP_VARIADICS
289 
290 #endif // BOOST_TTI_FUNCTION_TEMPLATE_HPP
291