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