• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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