1#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
2#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
3
4// Copyright 2015-2017 Peter Dimov.
5//
6// Distributed under the Boost Software License, Version 1.0.
7//
8// See accompanying file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt
10
11#include <boost/mp11/detail/mp_count.hpp>
12#include <boost/mp11/detail/mp_is_value_list.hpp>
13#include <boost/mp11/detail/mp_list.hpp>
14#include <boost/mp11/detail/mp_list_v.hpp>
15#include <boost/mp11/utility.hpp>
16#include <boost/mp11/detail/config.hpp>
17
18namespace boost
19{
20namespace mp11
21{
22
23// mp_append<L...>
24
25namespace detail
26{
27
28// append_type_lists
29
30template<class... L> struct mp_append_impl;
31
32#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
33
34template<class... L> struct mp_append_impl
35{
36};
37
38template<> struct mp_append_impl<>
39{
40 using type = mp_list<>;
41};
42
43template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
44{
45 using type = L<T...>;
46};
47
48template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_append_impl<L1<T1...>, L2<T2...>>
49{
50 using type = L1<T1..., T2...>;
51};
52
53template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>>
54{
55 using type = L1<T1..., T2..., T3...>;
56};
57
58template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>>
59{
60 using type = L1<T1..., T2..., T3..., T4...>;
61};
62
63template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, template<class...> class L5, class... T5, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, Lr...>
64{
65 using type = typename mp_append_impl<L1<T1..., T2..., T3..., T4..., T5...>, Lr...>::type;
66};
67
68#else
69
70template<class L1 = mp_list<>, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl
71{
72};
73
74template<
75 template<class...> class L1, class... T1,
76 template<class...> class L2, class... T2,
77 template<class...> class L3, class... T3,
78 template<class...> class L4, class... T4,
79 template<class...> class L5, class... T5,
80 template<class...> class L6, class... T6,
81 template<class...> class L7, class... T7,
82 template<class...> class L8, class... T8,
83 template<class...> class L9, class... T9,
84 template<class...> class L10, class... T10,
85 template<class...> class L11, class... T11>
86
87struct append_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
88{
89 using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
90};
91
92template<
93
94 class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>,
95 class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>,
96 class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>,
97 class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>,
98 class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>,
99 class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>,
100 class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>,
101 class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>,
102 class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>,
103 class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>,
104 class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<>
105
106> struct append_111_impl
107{
108 using type = typename append_11_impl<
109
110 typename append_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
111 typename append_11_impl<mp_list<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
112 typename append_11_impl<mp_list<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
113 typename append_11_impl<mp_list<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
114 typename append_11_impl<mp_list<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
115 typename append_11_impl<mp_list<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
116 typename append_11_impl<mp_list<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
117 typename append_11_impl<mp_list<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
118 typename append_11_impl<mp_list<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
119 typename append_11_impl<mp_list<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
120 typename append_11_impl<mp_list<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
121
122 >::type;
123};
124
125template<
126
127 class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
128 class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
129 class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
130 class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
131 class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
132 class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
133 class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
134 class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
135 class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
136 class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
137 class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
138 class... Lr
139
140> struct append_inf_impl
141{
142 using prefix = typename append_111_impl<
143
144 L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
145 L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
146 L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
147 L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
148 L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
149 L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
150 L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
151 L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
152 L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
153 L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
154 LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
155
156 >::type;
157
158 using type = typename mp_append_impl<prefix, Lr...>::type;
159};
160
161#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
162
163template<class... L>
164struct mp_append_impl_cuda_workaround
165{
166 using type = mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >;
167};
168
169template<class... L> struct mp_append_impl: mp_append_impl_cuda_workaround<L...>::type::template fn<L...>
170{
171};
172
173#else
174
175template<class... L> struct mp_append_impl:
176 mp_cond<
177 mp_bool<(sizeof...(L) > 111)>, mp_quote<append_inf_impl>,
178 mp_bool<(sizeof...(L) > 11)>, mp_quote<append_111_impl>,
179 mp_true, mp_quote<append_11_impl>
180 >::template fn<L...>
181{
182};
183
184#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
185
186#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
187
188struct append_type_lists
189{
190 template<class... L> using fn = typename mp_append_impl<L...>::type;
191};
192
193// append_value_lists
194
195#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
196
197template<class... L> struct append_value_impl;
198
199template<class L1 = mp_list_v<>, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl
200{
201};
202
203template<
204 template<auto...> class L1, auto... T1,
205 template<auto...> class L2, auto... T2,
206 template<auto...> class L3, auto... T3,
207 template<auto...> class L4, auto... T4,
208 template<auto...> class L5, auto... T5,
209 template<auto...> class L6, auto... T6,
210 template<auto...> class L7, auto... T7,
211 template<auto...> class L8, auto... T8,
212 template<auto...> class L9, auto... T9,
213 template<auto...> class L10, auto... T10,
214 template<auto...> class L11, auto... T11>
215
216struct append_value_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
217{
218 using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
219};
220
221template<
222
223 class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>,
224 class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>,
225 class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>,
226 class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>,
227 class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>,
228 class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>,
229 class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>,
230 class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>,
231 class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>,
232 class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>,
233 class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<>
234
235> struct append_value_111_impl
236{
237 using type = typename append_value_11_impl<
238
239 typename append_value_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
240 typename append_value_11_impl<mp_list_v<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
241 typename append_value_11_impl<mp_list_v<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
242 typename append_value_11_impl<mp_list_v<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
243 typename append_value_11_impl<mp_list_v<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
244 typename append_value_11_impl<mp_list_v<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
245 typename append_value_11_impl<mp_list_v<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
246 typename append_value_11_impl<mp_list_v<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
247 typename append_value_11_impl<mp_list_v<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
248 typename append_value_11_impl<mp_list_v<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
249 typename append_value_11_impl<mp_list_v<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
250
251 >::type;
252};
253
254template<
255
256 class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
257 class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
258 class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
259 class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
260 class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
261 class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
262 class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
263 class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
264 class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
265 class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
266 class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
267 class... Lr
268
269> struct append_value_inf_impl
270{
271 using prefix = typename append_value_111_impl<
272
273 L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
274 L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
275 L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
276 L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
277 L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
278 L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
279 L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
280 L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
281 L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
282 L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
283 LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
284
285 >::type;
286
287 using type = typename append_value_impl<prefix, Lr...>::type;
288};
289
290template<class... L> struct append_value_impl:
291 mp_cond<
292 mp_bool<(sizeof...(L) > 111)>, mp_quote<append_value_inf_impl>,
293 mp_bool<(sizeof...(L) > 11)>, mp_quote<append_value_111_impl>,
294 mp_true, mp_quote<append_value_11_impl>
295 >::template fn<L...>
296{
297};
298
299struct append_value_lists
300{
301 template<class... L> using fn = typename append_value_impl<L...>::type;
302};
303
304#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
305
306} // namespace detail
307
308#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
309
310template<class... L> using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if<mp_list<L...>, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn<L...>;
311
312#else
313
314template<class... L> using mp_append = detail::append_type_lists::fn<L...>;
315
316#endif
317
318} // namespace mp11
319} // namespace boost
320
321#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
322