| 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 | |