1 // Copyright Cromwell D. Enage 2019. 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_COMPOSE_HPP 7 #define BOOST_PARAMETER_COMPOSE_HPP 8 9 #include <boost/parameter/aux_/arg_list.hpp> 10 11 namespace boost { namespace parameter { 12 compose()13 inline BOOST_CONSTEXPR ::boost::parameter::aux::empty_arg_list compose() 14 { 15 return ::boost::parameter::aux::empty_arg_list(); 16 } 17 }} // namespace boost::parameter 18 19 #include <boost/parameter/config.hpp> 20 21 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 22 23 namespace boost { namespace parameter { namespace aux { 24 25 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 26 template <typename ...TaggedArgs> 27 struct compose_arg_list 28 { 29 using type = ::boost::parameter::aux::flat_like_arg_list< 30 ::boost::parameter::aux::flat_like_arg_tuple< 31 typename TaggedArgs::base_type::key_type 32 , typename TaggedArgs::base_type 33 >... 34 >; 35 }; 36 #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) 37 template <typename TaggedArg0, typename ...TaggedArgs> 38 struct compose_arg_list; 39 40 template <typename TaggedArg0> 41 struct compose_arg_list<TaggedArg0> 42 { 43 typedef ::boost::parameter::aux::arg_list<TaggedArg0> type; 44 }; 45 46 template <typename TaggedArg0, typename ...TaggedArgs> 47 struct compose_arg_list 48 { 49 typedef ::boost::parameter::aux::arg_list< 50 TaggedArg0 51 , typename ::boost::parameter::aux 52 ::compose_arg_list<TaggedArgs...>::type 53 > type; 54 }; 55 #endif // BOOST_PARAMETER_CAN_USE_MP11 56 }}} // namespace boost::parameter::aux 57 58 #include <boost/parameter/are_tagged_arguments.hpp> 59 #include <boost/core/enable_if.hpp> 60 61 namespace boost { namespace parameter { namespace result_of { 62 63 template <typename ...TaggedArgs> 64 struct compose 65 : ::boost::lazy_enable_if< 66 ::boost::parameter::are_tagged_arguments<TaggedArgs...> 67 , ::boost::parameter::aux::compose_arg_list<TaggedArgs...> 68 > 69 { 70 }; 71 72 template <> 73 struct compose<> 74 { 75 typedef ::boost::parameter::aux::empty_arg_list type; 76 }; 77 }}} // namespace boost::parameter::result_of 78 79 namespace boost { namespace parameter { 80 81 template <typename TaggedArg0, typename ...TaggedArgs> 82 inline BOOST_CONSTEXPR typename ::boost::parameter::result_of 83 ::compose<TaggedArg0,TaggedArgs...>::type compose(TaggedArg0 const & arg0,TaggedArgs const &...args)84 compose(TaggedArg0 const& arg0, TaggedArgs const&... args) 85 { 86 return typename ::boost::parameter::aux 87 ::compose_arg_list<TaggedArg0,TaggedArgs...>::type( 88 ::boost::parameter::aux::value_type_is_not_void() 89 , arg0 90 , args... 91 ); 92 } 93 }} // namespace boost::parameter 94 95 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) 96 97 #define BOOST_PARAMETER_compose_arg_list_type_suffix(z, n, suffix) suffix 98 99 #include <boost/preprocessor/cat.hpp> 100 101 #define BOOST_PARAMETER_compose_arg_list_type_prefix(z, n, prefix) \ 102 ::boost::parameter::aux::arg_list<BOOST_PP_CAT(prefix, n) 103 /**/ 104 105 #include <boost/preprocessor/facilities/intercept.hpp> 106 #include <boost/preprocessor/repetition/enum.hpp> 107 #include <boost/preprocessor/repetition/repeat.hpp> 108 109 #define BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ 110 BOOST_PP_CAT(BOOST_PP_ENUM_, z)( \ 111 n, BOOST_PARAMETER_compose_arg_list_type_prefix, prefix \ 112 ) BOOST_PP_CAT(BOOST_PP_REPEAT_, z)( \ 113 n, BOOST_PARAMETER_compose_arg_list_type_suffix, > \ 114 ) 115 /**/ 116 117 #include <boost/parameter/aux_/void.hpp> 118 #include <boost/preprocessor/arithmetic/inc.hpp> 119 #include <boost/preprocessor/arithmetic/sub.hpp> 120 #include <boost/preprocessor/repetition/enum_params.hpp> 121 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 122 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 123 124 #if defined(BOOST_NO_SFINAE) 125 #define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \ 126 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \ 127 inline BOOST_CONSTEXPR \ 128 BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ 129 compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \ 130 { \ 131 return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \ 132 BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ 133 BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ 134 z \ 135 , BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, n) \ 136 , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \ 137 ) \ 138 ); \ 139 } 140 /**/ 141 #else // !defined(BOOST_NO_SFINAE) 142 #include <boost/parameter/are_tagged_arguments.hpp> 143 #include <boost/core/enable_if.hpp> 144 145 namespace boost { namespace parameter { namespace result_of { 146 147 template < 148 BOOST_PP_ENUM_BINARY_PARAMS( 149 BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) 150 , typename TaggedArg 151 , = void BOOST_PP_INTERCEPT 152 ) 153 > 154 struct compose; 155 156 template <> 157 struct compose<> 158 { 159 typedef ::boost::parameter::aux::empty_arg_list type; 160 }; 161 }}} // namespace boost::parameter::result_of 162 163 #define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \ 164 namespace boost { namespace parameter { namespace result_of { \ 165 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \ 166 struct compose<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)> \ 167 : ::boost::enable_if< \ 168 ::boost::parameter \ 169 ::are_tagged_arguments<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)> \ 170 , BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ 171 > \ 172 { \ 173 }; \ 174 }}} \ 175 namespace boost { namespace parameter { \ 176 template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \ 177 inline BOOST_CONSTEXPR typename ::boost::parameter::result_of \ 178 ::compose<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)>::type \ 179 compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \ 180 { \ 181 return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \ 182 BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ 183 BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ 184 z \ 185 , BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, n) \ 186 , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \ 187 ) \ 188 ); \ 189 } \ 190 }} 191 /**/ 192 #endif // BOOST_NO_SFINAE 193 194 #include <boost/preprocessor/repetition/repeat_from_to.hpp> 195 196 BOOST_PP_REPEAT_FROM_TO( 197 1 198 , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) 199 , BOOST_PARAMETER_compose_arg_list_function_overload 200 , TaggedArg 201 ) 202 203 #undef BOOST_PARAMETER_compose_arg_list_function_overload 204 #undef BOOST_PARAMETER_compose_arg_list_type 205 #undef BOOST_PARAMETER_compose_arg_list_type_prefix 206 #undef BOOST_PARAMETER_compose_arg_list_type_suffix 207 208 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING 209 #endif // include guard 210 211