1 // Copyright Cromwell D. Enage 2018. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP 7 #define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP 8 9 #include <boost/parameter/aux_/preprocessor/impl/function_name.hpp> 10 11 // Defines the no-spec implementation function header. 12 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(name, is_const) \ 13 template <typename ResultType, typename Args> \ 14 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) ResultType \ 15 BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ 16 name, is_const \ 17 )(ResultType(*)(), Args const& args) 18 /**/ 19 20 #include <boost/parameter/config.hpp> 21 22 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 23 24 #include <boost/parameter/aux_/preprocessor/impl/parenthesized_return_type.hpp> 25 26 // Expands to the result metafunction for the specified no-spec function. 27 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 28 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \ 29 template <typename TaggedArg0, typename ...TaggedArgs> \ 30 using BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \ 31 = typename BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result); 32 /**/ 33 #else 34 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \ 35 template <typename TaggedArg0, typename ...TaggedArgs> \ 36 struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \ 37 : BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result) \ 38 { \ 39 }; 40 /**/ 41 #endif // BOOST_PARAMETER_CAN_USE_MP11 42 43 #include <boost/parameter/compose.hpp> 44 #include <boost/parameter/are_tagged_arguments.hpp> 45 #include <boost/parameter/aux_/preprocessor/impl/parenthesized_type.hpp> 46 #include <boost/core/enable_if.hpp> 47 48 // Exapnds to a variadic constructor that is enabled if and only if all its 49 // arguments are tagged arguments. The enclosing class must inherit from the 50 // specified base class, which in turn must implement a constructor that takes 51 // in the argument pack that this one passes on. 52 #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \ 53 template < \ 54 typename TaggedArg0 \ 55 , typename ...TaggedArgs \ 56 , typename = typename ::boost::enable_if< \ 57 ::boost::parameter \ 58 ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \ 59 >::type \ 60 > inline explicit \ 61 class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \ 62 : BOOST_PARAMETER_PARENTHESIZED_TYPE(base)( \ 63 ::boost::parameter::compose(arg0, args...) \ 64 ) \ 65 { \ 66 } 67 /**/ 68 69 // Exapnds to a variadic constructor that is enabled if and only if all its 70 // arguments are tagged arguments. The specified function must be able to 71 // take in the argument pack that this constructor passes on. 72 #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \ 73 template < \ 74 typename TaggedArg0 \ 75 , typename ...TaggedArgs \ 76 , typename = typename ::boost::enable_if< \ 77 ::boost::parameter \ 78 ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \ 79 >::type \ 80 > inline explicit \ 81 class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \ 82 { \ 83 func(::boost::parameter::compose(arg0, args...)); \ 84 } 85 /**/ 86 87 #include <boost/parameter/aux_/preprocessor/nullptr.hpp> 88 #include <boost/preprocessor/control/expr_if.hpp> 89 90 // Exapnds to a variadic function that is enabled if and only if 91 // all its arguments are tagged arguments. 92 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \ 93 template <typename TaggedArg0, typename ...TaggedArgs> \ 94 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(impl) \ 95 inline typename ::boost::lazy_enable_if< \ 96 ::boost::parameter \ 97 ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \ 98 , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 99 impl, c \ 100 )<TaggedArg0,TaggedArgs...> \ 101 >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \ 102 (TaggedArg0 const& arg0, TaggedArgs const&... args) \ 103 BOOST_PP_EXPR_IF(c, const) \ 104 { \ 105 return BOOST_PP_EXPR_IF(is_m, this->) \ 106 BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME(impl, c)( \ 107 static_cast< \ 108 typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 109 impl, c \ 110 )<TaggedArg0,TaggedArgs...>::type(*)() \ 111 >(BOOST_PARAMETER_AUX_PP_NULLPTR) \ 112 , ::boost::parameter::compose(arg0, args...) \ 113 ); \ 114 } 115 /**/ 116 117 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 118 119 #include <boost/parameter/aux_/void.hpp> 120 #include <boost/parameter/aux_/preprocessor/impl/parenthesized_return_type.hpp> 121 #include <boost/preprocessor/facilities/intercept.hpp> 122 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 123 124 // Expands to the result metafunction for the specified no-spec function. 125 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \ 126 template < \ 127 BOOST_PP_ENUM_BINARY_PARAMS( \ 128 BOOST_PARAMETER_COMPOSE_MAX_ARITY \ 129 , typename TaggedArg \ 130 , = ::boost::parameter::void_ BOOST_PP_INTERCEPT \ 131 ) \ 132 > \ 133 struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \ 134 : BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result) \ 135 { \ 136 }; 137 /**/ 138 139 #include <boost/parameter/compose.hpp> 140 #include <boost/parameter/aux_/preprocessor/impl/parenthesized_type.hpp> 141 #include <boost/preprocessor/comparison/equal.hpp> 142 #include <boost/preprocessor/control/expr_if.hpp> 143 #include <boost/preprocessor/repetition/enum_params.hpp> 144 #include <boost/preprocessor/tuple/elem.hpp> 145 146 #if defined(BOOST_NO_SFINAE) 147 148 // Exapnds to a tagged-argument constructor overload that passes the argument 149 // pack to the base class delegate constructor. 150 #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ 151 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 152 BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ 153 BOOST_PP_TUPLE_ELEM(2, 0, data)( \ 154 BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \ 155 ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \ 156 ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ 157 ) \ 158 { \ 159 } 160 /**/ 161 162 // Exapnds to a tagged-argument constructor overload that passes the argument 163 // pack to the delegate function. 164 #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ 165 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 166 BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ 167 BOOST_PP_TUPLE_ELEM(2, 0, data)( \ 168 BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \ 169 ) \ 170 { \ 171 BOOST_PP_TUPLE_ELEM(2, 1, data)( \ 172 ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \ 173 ); \ 174 } 175 /**/ 176 177 #include <boost/parameter/aux_/preprocessor/nullptr.hpp> 178 179 // Exapnds to a tagged-argument function overload. 180 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \ 181 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 182 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ 183 inline typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 184 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 185 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 186 )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type \ 187 BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ 188 BOOST_PP_TUPLE_ELEM(4, 0, data) \ 189 )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \ 190 BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ 191 { \ 192 return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ 193 BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ 194 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 195 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 196 )( \ 197 static_cast< \ 198 typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 199 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 200 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 201 )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type(*)() \ 202 >(BOOST_PARAMETER_AUX_PP_NULLPTR) \ 203 , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ 204 ); \ 205 } 206 /**/ 207 208 #else // !defined(BOOST_NO_SFINAE) 209 210 #include <boost/parameter/are_tagged_arguments.hpp> 211 #include <boost/parameter/aux_/preprocessor/nullptr.hpp> 212 #include <boost/core/enable_if.hpp> 213 214 // Exapnds to a tagged-argument constructor overload that passes the argument 215 // pack to the base class delegate constructor. This constructor is enabled 216 // if and only if all its arguments are tagged arguments. 217 #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ 218 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 219 BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ 220 BOOST_PP_TUPLE_ELEM(2, 0, data)( \ 221 BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \ 222 , typename ::boost::enable_if< \ 223 ::boost::parameter::are_tagged_arguments< \ 224 BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \ 225 > \ 226 >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR \ 227 ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \ 228 ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ 229 ) \ 230 { \ 231 } 232 /**/ 233 234 // Exapnds to a tagged-argument constructor overload that passes the argument 235 // pack to the delegate function. This constructor is enabled if and only if 236 // all its arguments are tagged arguments. 237 #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ 238 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 239 BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ 240 BOOST_PP_TUPLE_ELEM(2, 0, data)( \ 241 BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \ 242 , typename ::boost::enable_if< \ 243 ::boost::parameter::are_tagged_arguments< \ 244 BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \ 245 > \ 246 >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR \ 247 ) \ 248 { \ 249 BOOST_PP_TUPLE_ELEM(2, 1, data)( \ 250 ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \ 251 ); \ 252 } 253 /**/ 254 255 // Exapnds to a function overload that is enabled if and only if 256 // all its arguments are tagged arguments. 257 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \ 258 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \ 259 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ 260 inline typename ::boost::lazy_enable_if< \ 261 ::boost::parameter \ 262 ::are_tagged_arguments<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)> \ 263 , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 264 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 265 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 266 )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)> \ 267 >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ 268 BOOST_PP_TUPLE_ELEM(4, 0, data) \ 269 )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \ 270 BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ 271 { \ 272 return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ 273 BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ 274 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 275 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 276 )( \ 277 static_cast< \ 278 typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ 279 BOOST_PP_TUPLE_ELEM(4, 1, data) \ 280 , BOOST_PP_TUPLE_ELEM(4, 3, data) \ 281 )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type(*)() \ 282 >(BOOST_PARAMETER_AUX_PP_NULLPTR) \ 283 , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ 284 ); \ 285 } 286 /**/ 287 288 #endif // BOOST_NO_SFINAE 289 290 #include <boost/preprocessor/arithmetic/inc.hpp> 291 #include <boost/preprocessor/repetition/repeat_from_to.hpp> 292 293 // Emulates a variadic constructor that is enabled if and only if all its 294 // arguments are tagged arguments. The enclosing class must inherit from the 295 // specified base class, which in turn must implement a constructor that takes 296 // in the argument pack that this one passes on. 297 #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \ 298 BOOST_PP_REPEAT_FROM_TO( \ 299 1 \ 300 , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \ 301 , BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z \ 302 , (class_, base) \ 303 ) 304 /**/ 305 306 // Emulates a variadic constructor that is enabled if and only if all its 307 // arguments are tagged arguments. The specified function must be able to 308 // take in the argument pack that this constructor passes on. 309 #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \ 310 BOOST_PP_REPEAT_FROM_TO( \ 311 1 \ 312 , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \ 313 , BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z \ 314 , (class_, func) \ 315 ) 316 /**/ 317 318 // Emulates a variadic function that is enabled if and only if 319 // all its arguments are tagged arguments. 320 #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \ 321 BOOST_PP_REPEAT_FROM_TO( \ 322 1 \ 323 , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \ 324 , BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z \ 325 , (name, impl, is_m, c) \ 326 ) 327 /**/ 328 329 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING 330 #endif // include guard 331 332