1// Brigand library
2//
3// Copyright (c) 2015 Edouard Alligand and Joel Falcou
4//
5// Boost Software License - Version 1.0 - August 17th, 2003
6//
7// Permission is hereby granted, free of charge, to any person or organization
8// obtaining a copy of the software and accompanying documentation covered by
9// this license (the "Software") to use, reproduce, display, distribute,
10// execute, and transmit the Software, and to prepare derivative works of the
11// Software, and to permit third-parties to whom the Software is furnished to
12// do so, all subject to the following:
13//
14// The copyright notices in the Software and this entire statement, including
15// the above license grant, this restriction and the following disclaimer,
16// must be included in all copies of the Software, in whole or in part, and
17// all derivative works of the Software, unless such copies or derivative
18// works are solely in the form of machine-executable object code generated by
19// a source language processor.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27// DEALINGS IN THE SOFTWARE.
28
29// This file contains a standalone version of Edouard Alligand and Joel Falcou's
30// Brigand library, which can be found at https://github.com/edouarda/brigand
31
32#pragma once
33
34#if defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__)
35#define BRIGAND_COMP_MSVC
36#if _MSC_VER == 1900
37#define BRIGAND_COMP_MSVC_2015
38#elif _MSC_VER == 1800
39#define BRIGAND_COMP_MSVC_2013
40#endif
41#elif __GNUC__
42#ifndef __clang__
43#define BRIGAND_COMP_GCC
44#else
45#define BRIGAND_COMP_CLANG
46#endif
47#endif
48
49#define BRIGAND_NO_BOOST_SUPPORT 1
50
51#include <cstddef>
52#include <cstdint>
53#include <cstring>
54#include <initializer_list>
55#include <tuple>
56#include <type_traits>
57#include <utility>
58
59#if !defined(BRIGAND_NO_BOOST_SUPPORT)
60#include <boost/fusion/container/vector/vector_fwd.hpp>
61#include <boost/fusion/container/deque/deque_fwd.hpp>
62#include <boost/fusion/container/list/list_fwd.hpp>
63#include <boost/fusion/container/set/set_fwd.hpp>
64#include <boost/variant.hpp>
65#endif
66
67namespace brigand
68{
69 template <class... T> struct list {};
70 template<typename T, T... Values>
71 using integral_list = brigand::list< std::integral_constant<T,Values>...>;
72 using empty_sequence = brigand::list<>;
73}
74namespace brigand
75{
76 namespace lazy
77 {
78 template <class A, template<class...> class B> struct wrap;
79 template<template<class...> class A, class... T, template<class...> class B>
80 struct wrap<A<T...>, B>
81 {
82 using type = B<T...>;
83 };
84 }
85 template<class A, template<class...> class B>
86 using wrap = typename lazy::wrap<A, B>::type;
87}
88namespace brigand
89{
90namespace detail
91{
92 template <typename... Ts>
93 struct append_impl
94 {
95 using type = brigand::empty_sequence;
96 };
97 template <typename T>
98 struct append_impl<T>
99 {
100 using type = T;
101 };
102 template <template <typename...> class L1, template <typename...> class L2, typename... T1s,
103 typename... T2s, typename... Ts>
104 struct append_impl<L1<T1s...>, L2<T2s...>, Ts...> : append_impl<L1<T1s..., T2s...>, Ts...>
105 {
106 };
107 template <template <typename...> class L, template <typename...> class L1,
108 template <typename...> class L2, template <typename...> class L3,
109 template <typename...> class L4, template <typename...> class L5,
110 template <typename...> class L6, template <typename...> class L7,
111 template <typename...> class L8, template <typename...> class L9,
112 template <typename...> class L10, template <typename...> class L11,
113 template <typename...> class L12, template <typename...> class L13,
114 template <typename...> class L14, template <typename...> class L15,
115 template <typename...> class L16, typename... Ts, typename... T1s, typename... T2s,
116 typename... T3s, typename... T4s, typename... T5s, typename... T6s, typename... T7s,
117 typename... T8s, typename... T9s, typename... T10s, typename... T11s,
118 typename... T12s, typename... T13s, typename... T14s, typename... T15s,
119 typename... T16s, typename... Us>
120 struct append_impl<L<Ts...>, L1<T1s...>, L2<T2s...>, L3<T3s...>, L4<T4s...>, L5<T5s...>,
121 L6<T6s...>, L7<T7s...>, L8<T8s...>, L9<T9s...>, L10<T10s...>, L11<T11s...>,
122 L12<T12s...>, L13<T13s...>, L14<T14s...>, L15<T15s...>, L16<T16s...>, Us...>
123 : append_impl<L<Ts..., T1s..., T2s..., T3s..., T4s..., T5s..., T6s..., T7s..., T8s...,
124 T9s..., T10s..., T11s..., T12s..., T13s..., T14s..., T15s..., T16s...>,
125 Us...>
126 {
127 };
128}
129namespace lazy
130{
131 template <typename... Ts>
132 using append = detail::append_impl<Ts...>;
133}
134template <typename... Ts>
135using append = typename detail::append_impl<Ts...>::type;
136namespace lazy
137{
138 template <typename T>
139 struct join;
140 template<template<typename...> class L, typename...Ts>
141 struct join<L<Ts...>> : ::brigand::detail::append_impl<L<>,Ts...>
142 {
143 };
144}
145template <typename T>
146using join = wrap<T,append>;
147}
148namespace brigand
149{
150 template <typename First, typename Second>
151 struct pair
152 {
153 using first_type = First;
154 using second_type = Second;
155 };
156}
157namespace brigand
158{
159 template<typename T> struct type_ { using type = T; };
160 template<typename T> using type_from = typename T::type;
161}
162namespace brigand
163{
164 struct no_such_type_ {};
165}
166namespace brigand
167{
168namespace lazy
169{
170 template <typename M, typename K>
171 struct lookup
172 : decltype(M::at(type_<K>{}))
173 {};
174}
175 template <typename M, typename K>
176 using lookup = typename lazy::lookup<M,K>::type;
177namespace detail
178{
179 template <class... T>
180 struct map_impl;
181 template <>
182 struct map_impl<>
183 {
184 template <typename U>
185 static type_<no_such_type_> at(U);
186 template <class K>
187 static std::false_type has_key(type_<K>);
188 template <class K>
189 static map_impl erase(type_<K>);
190 template <class P>
191 static map_impl<P> insert(type_<P>);
192 };
193 template <class... Ts>
194 struct map_impl
195 {
196 private:
197 struct Pack : pair<typename Ts::first_type, Ts>... {};
198 template<class K, class P>
199 static type_<typename P::second_type> at_impl(pair<K,P>*);
200 public:
201 template<class K>
202 static decltype(at_impl<K>(static_cast<Pack*>(nullptr))) at(type_<K>);
203 template<class K>
204 static type_<no_such_type_> at(K);
205 template <class K, class = decltype(at_impl<K>(static_cast<Pack*>(nullptr)))>
206 static std::true_type has_key(type_<K>);
207 template <class K>
208 static std::false_type has_key(K);
209 template <class K>
210 static append<map_impl<>, typename std::conditional<std::is_same<K, typename Ts::first_type>::value, list<>, list<Ts>>::type...> erase(type_<K>);
211 template <class P, class = decltype(static_cast<pair<typename P::first_type, P>*>(static_cast<Pack*>(nullptr)))>
212 static map_impl insert(type_<P>);
213 template <class P>
214 static map_impl<Ts..., typename P::type> insert(P);
215 };
216 template<class... Ts>
217 struct make_map : type_<typename Ts::first_type>... {
218 using type = map_impl<Ts...>;
219 };
220}
221 template<class... Ts>
222 using map = typename detail::make_map<Ts...>::type;
223}
224namespace brigand
225{
226namespace detail
227{
228 template<class, class>
229 struct dup_append_list;
230 template<template<class...> class List, class... Ts, class... Us>
231 struct dup_append_list<List<Ts...>, List<Us...>>
232 {
233 using type = List<Ts..., Ts..., Us...>;
234 };
235 template<class T, template<class...> class List, std::size_t N>
236 struct filled_list_impl
237 : dup_append_list<
238 typename filled_list_impl<T, List, N/2>::type,
239 typename filled_list_impl<T, List, N - N/2*2>::type
240 >
241 {};
242 template<class T, template<class...> class List>
243 struct filled_list_impl<T, List, 1>
244 {
245 using type = List<T>;
246 };
247 template<class T, template<class...> class List>
248 struct filled_list_impl<T, List, 0>
249 {
250 using type = List<>;
251 };
252}
253 template<class T, std::size_t N, template<class...> class List = list>
254 using filled_list = typename detail::filled_list_impl<T, List, N>::type;
255}
256namespace brigand
257{
258 namespace detail
259 {
260 template<class T> struct element_at;
261 template<class... Ts>
262 struct element_at<list<Ts...>>
263 {
264 template<class T> type_<T> static at(Ts..., type_<T>*, ...);
265 };
266 template<std::size_t N, typename Seq> struct at_impl;
267 template<std::size_t N, template<typename...> class L, class... Ts>
268 struct at_impl<N,L<Ts...>>
269 : decltype(element_at<brigand::filled_list<void const *, N>>::at(static_cast<type_<Ts>*>(nullptr)...))
270 {
271 };
272 }
273 template <class L, std::size_t Index>
274 using at_c = typename detail::at_impl<Index, L>::type;
275namespace detail
276{
277 template <typename T>
278 struct has_at_method
279 {
280 struct dummy {};
281 template <typename C, typename P>
282 static auto test(P * p) -> decltype(C::at(*p), std::true_type());
283 template <typename, typename>
284 static std::false_type test(...);
285 static const bool value = std::is_same<std::true_type, decltype(test<T, dummy>(nullptr))>::value;
286 };
287 template <class L, typename Index, bool>
288 struct at_dispatch
289 {
290 using type = at_c<L, Index::value>;
291 };
292 template <class L, typename Index>
293 struct at_dispatch<L, Index, true>
294 {
295 using type = lookup<L, Index>;
296 };
297}
298 template <class Seq, typename K>
299 using at = typename detail::at_dispatch<Seq, K, detail::has_at_method<Seq>::value>::type;
300}
301namespace brigand
302{
303 template <template <typename...> class, typename...>
304 struct bind
305 {
306 };
307}
308namespace brigand
309{
310 template<std::size_t Index> struct args
311 {
312 };
313 struct _1 {};
314 struct _2 {};
315 using _3 = args<2>;
316 using _4 = args<3>;
317 using _5 = args<4>;
318 using _6 = args<5>;
319 using _7 = args<6>;
320 using _8 = args<7>;
321 using _9 = args<8>;
322 using _state = _1;
323 using _element = _2;
324}
325namespace brigand
326{
327template <typename T>
328struct defer
329{
330};
331template <typename T>
332struct pin
333{
334};
335template <typename T>
336struct parent
337{
338};
339namespace detail
340{
341 template <typename T, typename... Ts>
342 struct packaged_lcall
343 {
344 };
345 template <typename T, typename... Ls>
346 struct apply {
347 using type = T;
348 };
349 template <template<typename...> class F, typename...Ts, typename... Args>
350 struct apply<bind<F,Ts...>, Args...>
351 {
352 using type = F<typename apply<Ts, Args...>::type...>;
353 };
354 template <template <typename...> class F, typename... Ts, typename L, typename... Ls>
355 struct apply<F<Ts...>, L, Ls...> : F<typename apply<Ts, L, Ls...>::type...>
356 {
357 };
358 template <typename T, typename... Args, typename...Ls>
359 struct apply<pin<T>, list<Args...>, Ls...>
360 {
361 using type = T;
362 };
363 template <std::size_t N, typename L, typename...Ls>
364 struct apply<args<N>, L, Ls...>
365 {
366 using type = at_c<L, N>;
367 };
368 template <typename T, typename...Ts, typename...Ls>
369 struct apply<_1, list<T, Ts...>, Ls...>
370 {
371 using type = T;
372 };
373 template <typename T, typename U, typename...Ts, typename...Ls>
374 struct apply<_2, list<T, U, Ts...>, Ls...>
375 {
376 using type = U;
377 };
378 template <typename T, typename L, typename...Ls>
379 struct apply<parent<T>, L, Ls...> : apply<T,Ls...>
380 {
381 };
382 template <typename Lambda, typename L, typename...Ls>
383 struct apply<defer<Lambda>, L, Ls...>
384 {
385 using type = packaged_lcall<Lambda, L, Ls...>;
386 };
387 template <template <typename...> class Lambda, typename... Ts, typename... PLs, typename L, typename...Ls>
388 struct apply<packaged_lcall<Lambda<Ts...>, PLs...>, L, Ls...> : Lambda<typename apply<Ts, L, Ls..., PLs...>::type...>
389 {
390 };
391 template <template <typename...> class Lambda, typename... Ts, typename... PLs, typename L, typename...Ls>
392 struct apply<packaged_lcall<bind<Lambda,Ts...>, PLs...>, L, Ls...>
393 {
394 using type = Lambda<typename apply<Ts, L, Ls..., PLs...>::type...>;
395 };
396 template<typename T, typename...Ts>
397 using bound_apply = typename apply<T, brigand::list<Ts...>>::type;
398}
399template <typename Lambda, typename... Args>
400using apply = typename detail::apply<Lambda, brigand::list<Args...>>::type;
401}
402namespace brigand
403{
404 template<std::size_t Index> struct args;
405 namespace detail
406 {
407 template<typename T, typename List>
408 struct substitute_impl
409 {
410 using type = T;
411 };
412 template<template<class...> class T, typename... Ts, typename List>
413 struct substitute_impl<T<Ts...>,List>
414 {
415 using type = T<typename substitute_impl<Ts,List>::type...>;
416 };
417 template<std::size_t Index, typename List>
418 struct substitute_impl<args<Index>,List>
419 {
420 using type = brigand::at_c<List,Index>;
421 };
422 }
423 template<typename T, typename List>
424 using substitute = typename detail::substitute_impl<T,List>::type;
425}
426
427namespace brigand
428{
429 template <std::int8_t V>
430 using int8_t = std::integral_constant<std::int8_t, V>;
431 template <std::uint8_t V>
432 using uint8_t = std::integral_constant<std::uint8_t, V>;
433 template <std::int16_t V>
434 using int16_t = std::integral_constant<std::int16_t, V>;
435 template <std::uint16_t V>
436 using uint16_t = std::integral_constant<std::uint16_t, V>;
437 template <std::int32_t V>
438 using int32_t = std::integral_constant<std::int32_t, V>;
439 template <std::uint32_t V>
440 using uint32_t = std::integral_constant<std::uint32_t, V>;
441 template <std::int64_t V>
442 using int64_t = std::integral_constant<std::int64_t, V>;
443 template <std::uint64_t V>
444 using uint64_t = std::integral_constant<std::uint64_t, V>;
445 template<std::size_t V>
446 using size_t = std::integral_constant<std::size_t, V>;
447 template<std::ptrdiff_t V>
448 using ptrdiff_t = std::integral_constant<std::ptrdiff_t, V>;
449}
450
451namespace brigand
452{
453namespace detail
454{
455 constexpr std::size_t count_bools(bool const * const begin, bool const * const end,
456 std::size_t n)
457 {
458 return begin == end ? n : detail::count_bools(begin + 1, end, n + *begin);
459 }
460 template <bool... Bs>
461 struct template_count_bools
462 {
463 using type = ::brigand::size_t<0>;
464 };
465 template <bool B, bool... Bs>
466 struct template_count_bools<B, Bs...>
467 {
468 using type = ::brigand::size_t<B + template_count_bools<Bs...>::type::value>;
469 };
470 template <bool B1, bool B2, bool B3, bool B4, bool B5, bool B6, bool B7, bool B8, bool B9,
471 bool B10, bool B11, bool B12, bool B13, bool B14, bool B15, bool B16, bool... Bs>
472 struct template_count_bools<B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15,
473 B16, Bs...>
474 {
475 using type =
476 ::brigand::size_t<B1 + B2 + B3 + B4 + B5 + B6 + B7 + B8 + B9 + B10 + B11 + B12 + B13 +
477 B14 + B15 + B16 + template_count_bools<Bs...>::type::value>;
478 };
479}
480namespace lazy
481{
482 template <typename List, typename Pred>
483 struct count_if
484 {
485 };
486 template <template <typename...> class S, typename Pred>
487 struct count_if<S<>, Pred>
488 {
489 using type = ::brigand::size_t<0>;
490 };
491#if defined(BRIGAND_COMP_GCC) || defined(BRIGAND_COMP_CLANG)
492 template <template <typename...> class S, template <typename...> class F>
493 struct count_if<S<>, bind<F, _1>>
494 {
495 using type = ::brigand::size_t<0>;
496 };
497 template <template <typename...> class S, template <typename...> class F>
498 struct count_if<S<>, F<_1>>
499 {
500 using type = ::brigand::size_t<0>;
501 };
502 template <template<typename...> class S, typename... Ts, typename Pred>
503 struct count_if<S<Ts...>, Pred>
504 {
505 static constexpr bool s_v[] = { ::brigand::apply<Pred, Ts>::type::value... };
506 using type = brigand::size_t<::brigand::detail::count_bools(s_v, s_v + sizeof...(Ts), 0u)>;
507 };
508 template <template <typename...> class S, typename... Ts, template <typename...> class F>
509 struct count_if<S<Ts...>, bind<F, _1>>
510 {
511 static constexpr bool s_v[] = { F<Ts>::value... };
512 using type = brigand::size_t<::brigand::detail::count_bools(s_v, s_v + sizeof...(Ts), 0u)>;
513 };
514 template <template <typename...> class S, typename... Ts, template <typename...> class F>
515 struct count_if<S<Ts...>, F<_1>>
516 {
517 static constexpr bool s_v[] = { F<Ts>::type::value... };
518 using type = brigand::size_t<::brigand::detail::count_bools(s_v, s_v + sizeof...(Ts), 0u)>;
519 };
520#else
521 template <template <typename...> class S, typename... Ts, typename Pred>
522 struct count_if<S<Ts...>, Pred> : ::brigand::detail::template_count_bools<::brigand::apply<Pred, Ts>::value...>
523 {
524 };
525#endif
526}
527template <typename List, typename Pred>
528using count_if = typename lazy::count_if<List, Pred>::type;
529template <class... T>
530using count = std::integral_constant<std::size_t, sizeof...(T)>;
531}
532namespace brigand
533{
534 template<class L> using size = wrap<L, count>;
535}
536namespace brigand
537{
538 namespace detail
539 {
540 template<class L, class... T> struct push_front_impl;
541 template<template<class...> class L, class... U, class... T>
542 struct push_front_impl<L<U...>, T...>
543 {
544 using type = L<T..., U...>;
545 };
546 }
547 namespace lazy {
548 template<class L, class... T>
549 struct push_front : detail::push_front_impl<L, T...>{};
550 }
551 template<class L, class... T>
552 using push_front = typename detail::push_front_impl<L, T...>::type;
553 namespace detail
554 {
555 template<class L> struct front_impl;
556 template<template<class...> class L, class T, class... U>
557 struct front_impl<L<T, U...>>
558 {
559 using type = T;
560 };
561 }
562 template <class L>
563 using front = typename detail::front_impl<L>::type;
564 namespace detail
565 {
566 template <class L, std::size_t N> struct pop_front_impl;
567 template<template<class...> class L, class T, class... U>
568 struct pop_front_impl<L<T, U...>, 1>
569 {
570 using type = L<U...>;
571 };
572 template<template<class...> class L, class> struct pop_front_element;
573 template<template<class...> class L, class... Ts>
574 struct pop_front_element<L, list<Ts...>>
575 {
576 template<class... Us>
577 static L<Us...> impl(Ts..., type_<Us>*...);
578 };
579 template<template<class...> class L, class... Ts, std::size_t N>
580 struct pop_front_impl<L<Ts...>, N>
581 {
582 using type = decltype(pop_front_element<L, filled_list<
583 void const *, N
584 >>::impl(static_cast<type_<Ts>*>(nullptr)...));
585 };
586 }
587 namespace lazy {
588 template <class L, class N = std::integral_constant<std::size_t, 1>>
589 struct pop_front : detail::pop_front_impl<L, N::value> {};
590 }
591 template <class L, class N = std::integral_constant<std::size_t, 1>>
592 using pop_front = typename detail::pop_front_impl<L, N::value>::type;
593}
594
595namespace brigand
596{
597namespace detail
598{
599 template<class L>
600 struct clear_impl;
601 template<template<class...> class L, class... Ts>
602 struct clear_impl<L<Ts...>>
603 {
604 using type = L<>;
605 };
606}
607 template<class L>
608 using clear = typename detail::clear_impl<L>::type;
609}
610namespace brigand
611{
612namespace detail
613{
614 template <bool b, typename O, typename L, std::size_t I>
615 struct split_at_impl;
616 template <template <typename...> class S, typename... Os, typename T, typename... Ts>
617 struct split_at_impl<false, S<Os...>, S<T, Ts...>, 0>
618 {
619 using type = S<S<Os...>, S<T, Ts...>>;
620 };
621 template <template <typename...> class S, typename... Os, typename... Ts>
622 struct split_at_impl<false, S<Os...>, S<Ts...>, 0>
623 {
624 using type = S<S<Os...>, S<Ts...>>;
625 };
626 template <template <typename...> class S, typename... Os, typename T, typename... Ts,
627 std::size_t I>
628 struct split_at_impl<false, S<Os...>, S<T, Ts...>, I>
629 : split_at_impl<false, S<Os..., T>, S<Ts...>, (I - 1)>
630 {
631 };
632 template <template <typename...> class S, typename... Os, typename T1, typename T2, typename T3,
633 typename T4, typename T5, typename T6, typename T7, typename T8, typename T9,
634 typename T10, typename T11, typename T12, typename T13, typename T14, typename T15,
635 typename T16, typename... Ts, std::size_t I>
636 struct split_at_impl<
637 true, S<Os...>,
638 S<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Ts...>, I>
639 : split_at_impl<((I - 16) > 16), S<Os..., T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
640 T13, T14, T15, T16>,
641 S<Ts...>, (I - 16)>
642 {
643 };
644 template <typename L, typename I>
645 struct call_split_at_impl : split_at_impl<(I::value > 16), brigand::clear<L>, L, I::value>
646 {
647 };
648}
649namespace lazy
650{
651 template <typename L, typename I>
652 using split_at = ::brigand::detail::call_split_at_impl<L, I>;
653}
654template <typename L, typename I>
655using split_at = typename ::brigand::lazy::split_at<L, I>::type;
656}
657namespace brigand
658{
659 namespace detail
660 {
661 template<class L, class... T> struct push_back_impl;
662 template<template<class...> class L, class... U, class... T>
663 struct push_back_impl<L<U...>, T...>
664 {
665 using type = L<U..., T...>;
666 };
667 }
668 template<class L, class... T>
669 using push_back = typename detail::push_back_impl<L, T...>::type;
670 template <class L>
671 using back = at_c<L, size<L>::value-1>;
672 template <class L, class N = std::integral_constant<std::size_t, 1>>
673 using pop_back = front<split_at<L, std::integral_constant<std::size_t, size<L>::value - N::value>>>;
674}
675namespace brigand
676{
677 namespace detail
678 {
679 template<class L1, class L2>
680 struct rot90;
681 template<
682 class... L1,
683 template<class...> class S1, class... T1,
684 template<class...> class S2, class... T2,
685 template<class...> class S3, class... T3,
686 template<class...> class S4, class... T4,
687 template<class...> class S5, class... T5,
688 template<class...> class S6, class... T6,
689 template<class...> class S7, class... T7,
690 template<class...> class S8, class... T8,
691 class... L2>
692 struct rot90<list<L1...>, list<
693 S1<T1...>, S2<T2...>, S3<T3...>, S4<T4...>,
694 S5<T5...>, S6<T6...>, S7<T7...>, S8<T8...>, L2...>>
695 : rot90<list<push_back<L1, T1, T2, T3, T4, T5, T6, T7, T8>...>, list<L2...>>
696 {};
697 template<class... L1, template<class...> class S, class... T, class... L2>
698 struct rot90<list<L1...>, list<S<T...>, L2...>>
699 : rot90<list<push_back<L1, T>...>, list<L2...>>
700 {};
701 template<class L1>
702 struct rot90<L1, list<>>
703 {
704 using type = L1;
705 };
706 template<class Func, class Seq1, class Seq2, class Seqs>
707 struct transform_impl;
708 template<class F, class T1, class T2, class Seq>
709 struct transform_apply;
710 template<class F, class T1, class T2, class... Ts>
711 struct transform_apply<F, T1, T2, list<Ts...>>
712 {
713 using type = brigand::apply<F, T1, T2, Ts...>;
714 };
715 template<
716 class Func,
717 template<class...> class Seq1, class... T1,
718 template<class...> class Seq2, class... T2,
719 class... Seqs>
720 struct transform_impl<Func, Seq1<T1...>, Seq2<T2...>, list<Seqs...>>
721 {
722 using type = Seq1<typename transform_apply<Func, T1, T2, Seqs>::type...>;
723 };
724 template<std::size_t N, class Seq1, class Seq2, class... FuncOrSeqs>
725 struct transform
726 : transform_impl<back<list<FuncOrSeqs...>>, Seq1, Seq2,
727 typename rot90<filled_list<list<>, size<Seq1>::value>, pop_back<list<FuncOrSeqs...>>>::type>
728 {};
729 template<template<class...> class Seq, class... T, class Func>
730 struct transform<0, Seq<T...>, Func>
731 {
732 using type = Seq<brigand::apply<Func, T>...>;
733 };
734 template<template<class...> class Seq, class... T, template<typename...> class Func>
735 struct transform<0, Seq<T...>, bind<Func, _1>>
736 {
737 using type = Seq<Func<T>...>;
738 };
739 template<template<class...> class Seq, class... T, template<typename...> class Func>
740 struct transform<0, Seq<T...>, Func<_1>>
741 {
742 using type = Seq<typename Func<T>::type...>;
743 };
744 template<template<class...> class Seq1, class... T1, template<class...> class Seq2, class... T2, class Func>
745 struct transform<1, Seq1<T1...>, Seq2<T2...>, Func>
746 {
747 using type = Seq1<brigand::apply<Func, T1, T2>...>;
748 };
749 }
750 namespace lazy
751 {
752 template<typename Sequence1, typename OpSeq1, typename... OpSeq2>
753 struct transform : detail::transform<sizeof...(OpSeq2), Sequence1, OpSeq1, OpSeq2...> {};
754 }
755 template<typename Sequence1, typename OpSeq1, typename... OpSeq2>
756 using transform = typename detail::transform<sizeof...(OpSeq2), Sequence1, OpSeq1, OpSeq2...>::type;
757}
758namespace brigand
759{
760 template <typename T>
761 struct make_integral : std::integral_constant <typename T::value_type, T::value> {};
762 template <typename L>
763 using as_integral_list = transform<L, make_integral<brigand::_1>>;
764}
765namespace brigand
766{
767namespace detail
768{
769 template <typename L, template <class...> class Sequence>
770 struct as_sequence_impl
771 {
772 using type = wrap<L, Sequence>;
773 };
774}
775template <typename L, template <class...> class Sequence>
776using as_sequence = typename detail::as_sequence_impl<L, Sequence>::type;
777template <typename L>
778using as_list = as_sequence<L, brigand::list>;
779}
780namespace brigand
781{
782 template <typename... T>
783 struct pair_wrapper_
784 {
785 static_assert (sizeof...(T) == 2
786 , "as_pair requires a type list of exactly two types"
787 );
788 using type = no_such_type_;
789 };
790 template <typename T, typename U>
791 struct pair_wrapper_<T,U>
792 {
793 using type = std::pair<T,U>;
794 };
795 template <typename... T>
796 using pair_wrapper = typename pair_wrapper_<T...>::type;
797 template <typename L>
798 using as_pair = wrap<L, pair_wrapper>;
799}
800namespace brigand
801{
802 template <typename... T>
803 using tuple_wrapper = typename std::tuple<T...>;
804 template <typename L>
805 using as_tuple = wrap<L, tuple_wrapper>;
806}
807#if !defined(BRIGAND_NO_BOOST_SUPPORT)
808namespace brigand
809{
810 template <typename... T>
811 using fusion_vector_wrapper = boost::fusion::vector<T...>;
812 template <typename... T>
813 using fusion_list_wrapper = boost::fusion::list<T...>;
814 template <typename... T>
815 using fusion_deque_wrapper = boost::fusion::deque<T...>;
816 template <typename... T>
817 using fusion_set_wrapper = boost::fusion::set<T...>;
818 template <typename L> using as_fusion_vector = wrap<L, fusion_vector_wrapper>;
819 template <typename L> using as_fusion_deque = wrap<L, fusion_deque_wrapper>;
820 template <typename L> using as_fusion_list = wrap<L, fusion_list_wrapper>;
821 template <typename L> using as_fusion_set = wrap<L, fusion_set_wrapper>;
822}
823namespace brigand
824{
825 template <typename... T>
826 using variant_wrapper = typename boost::variant<T...>;
827 template <typename L>
828 using as_variant = wrap<L, variant_wrapper>;
829}
830#endif
831
832namespace brigand
833{
834 template <bool B>
835 using bool_ = std::integral_constant<bool, B>;
836}
837namespace brigand
838{
839namespace detail
840{
841 template <typename Args>
842 struct non_null_impl : bool_<Args::value != 0>{};
843 using non_null = non_null_impl<_1>;
844}
845}
846
847namespace brigand
848{
849#ifdef BRIGAND_COMP_MSVC_2013
850 namespace detail
851 {
852 template <bool...> struct bools_ {};
853 template< typename Sequence, typename Predicate, typename... Ts> struct all_impl;
854 template< template<class...> class Sequence, typename Predicate, typename... Ts>
855 struct all_impl<Sequence<Ts...>, Predicate>
856 : std::is_same< bools_<true, ::brigand::apply<Predicate, Ts>::value...>
857 , bools_<::brigand::apply<Predicate, Ts>::value..., true>
858 >
859 {};
860 }
861#else
862 namespace detail
863 {
864 struct all_same
865 {
866 const bool value = false;
867 constexpr all_same(...) {}
868 template <typename T>
869 constexpr all_same(std::initializer_list<T *>) : value{ true }
870 {
871 }
872 };
873 template <typename Sequence, typename Predicate>
874 struct all_impl : bool_<true>{};
875 template <template <class...> class Sequence, typename Predicate, typename T, typename... Ts>
876 struct all_impl<Sequence<T,Ts...>, Predicate>
877 {
878 static constexpr all_same tester{ static_cast<::brigand::apply<Predicate, T> *>(nullptr),
879 static_cast<::brigand::apply<Predicate, Ts> *>(nullptr)... };
880 using type = bool_<(::brigand::apply<Predicate, T>::value != 0 && tester.value)>;
881 };
882 template <template <class...> class Sequence, template <typename...> class F, typename T,
883 typename... Ts>
884 struct all_impl<Sequence<T, Ts...>, bind<F, _1>>
885 {
886 static constexpr all_same tester{ static_cast<F<T> *>(nullptr),
887 static_cast<F<Ts> *>(nullptr)... };
888 using type = bool_<(F<T>::value != 0 && tester.value)>;
889 };
890 template <template <class...> class Sequence, template <typename...> class F, typename T,
891 typename... Ts>
892 struct all_impl<Sequence<T, Ts...>, F<_1>>
893 {
894 static constexpr all_same tester{ static_cast<typename F<T>::type *>(nullptr),
895 static_cast<typename F<Ts>::type *>(nullptr)... };
896 using type = bool_<(F<T>::type::value != 0 && tester.value)>;
897 };
898 }
899#endif
900 template <typename Sequence, typename Predicate = detail::non_null>
901 using all = typename detail::all_impl<Sequence, Predicate>::type;
902}
903namespace brigand
904{
905#ifdef BRIGAND_COMP_MSVC_2013
906 namespace detail
907 {
908 template<typename Sequence, typename Pred> struct none_impl
909 {
910 template<typename T>
911 struct nope
912 {
913 using that = brigand::apply<Pred, T>;
914 using type = bool_<!that::value>;
915 };
916 using type = all<Sequence, nope<_1>>;
917 };
918 }
919#else
920 namespace detail
921 {
922 template <typename Sequence, typename Predicate>
923 struct none_impl : bool_<true>{};
924 template <template <class...> class Sequence, typename Predicate, typename T, typename... Ts>
925 struct none_impl<Sequence<T,Ts...>, Predicate>
926 {
927 static constexpr all_same tester{ static_cast<::brigand::apply<Predicate, T> *>(nullptr),
928 static_cast<::brigand::apply<Predicate, Ts> *>(nullptr)... };
929 using type = bool_<(::brigand::apply<Predicate, T>::value == 0 && tester.value)>;
930 };
931 template <template <class...> class Sequence, template <typename...> class F, typename T,
932 typename... Ts>
933 struct none_impl<Sequence<T, Ts...>, bind<F, _1>>
934 {
935 static constexpr all_same tester{ static_cast<F<T> *>(nullptr),
936 static_cast<F<Ts> *>(nullptr)... };
937 using type = bool_<(F<T>::value == 0 && tester.value)>;
938 };
939 template <template <class...> class Sequence, template <typename...> class F, typename T,
940 typename... Ts>
941 struct none_impl<Sequence<T, Ts...>, F<_1>>
942 {
943 static constexpr all_same tester{ static_cast<typename F<T>::type *>(nullptr),
944 static_cast<typename F<Ts>::type *>(nullptr)... };
945 using type = bool_<(F<T>::type::value == 0 && tester.value)>;
946 };
947 }
948#endif
949 template< typename Sequence, typename Predicate = detail::non_null>
950 using none = typename detail::none_impl<Sequence,Predicate>::type;
951}
952namespace brigand
953{
954 namespace detail
955 {
956 template< typename Sequence, typename Predicate >
957 struct any_impl : bool_<!none<Sequence,Predicate>::value> {};
958 }
959 template<typename Sequence, typename Predicate = detail::non_null>
960 using any = typename detail::any_impl<Sequence,Predicate>::type;
961}
962namespace brigand
963{
964namespace detail
965{
966 template <template <typename...> class S, template <typename...> class F, typename... Ts>
967 struct finder
968 {
969 template <typename T>
970 using P = F<Ts..., T>;
971 template <bool InNext8, bool Match, typename... Ls>
972 struct find
973 {
974 using type = S<>;
975 };
976 template <typename L>
977 struct find<true, false, L>
978 {
979 using type = S<>;
980 };
981 template <typename L, typename... Ls>
982 struct find<true, true, L, Ls...>
983 {
984 using type = S<L, Ls...>;
985 };
986 template <typename L1, typename L2, typename... Ls>
987 struct find<true, false, L1, L2, Ls...> : find<true, F<Ts..., L2>::value, L2, Ls...>
988 {
989 };
990 template <typename L0, typename L1, typename L2, typename L3, typename L4, typename L5,
991 typename L6, typename L7, typename L8,
992 typename... Ls>
993 struct find<false, false, L0, L1, L2, L3, L4, L5, L6, L7, L8, Ls...>
994 : find<true, F<Ts..., L8>::value, L8, Ls...>
995 {
996 };
997 template <typename L1, typename L2, typename L3, typename L4, typename L5, typename L6,
998 typename L7, typename L8, typename L9, typename L10, typename L11, typename L12,
999 typename L13, typename L14, typename L15, typename L16,
1000 typename... Ls>
1001 struct find<false, false, L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15,
1002 L16, Ls...>
1003 : find<(P<L9>::value || P<L10>::value || P<L11>::value || P<L12>::value ||
1004 P<L13>::value || P<L14>::value || P<L15>::value || P<L16>::value),
1005 P<L9>::value, L9, L10, L11, L12, L13, L14, L15, L16, Ls...>
1006 {
1007 };
1008 };
1009}
1010}
1011namespace brigand
1012{
1013namespace detail
1014{
1015 template <template<class...> class L, class...>
1016 struct reverse_elements;
1017 template <template <class...> class L>
1018 struct reverse_elements<L>
1019 {
1020 using type = L<>;
1021 };
1022 template <template <class...> class L, class T0, class... Ts>
1023 struct reverse_elements<L, T0, Ts...>
1024 : append_impl<typename reverse_elements<L, Ts...>::type, L<T0>>
1025 {
1026 };
1027 template <template <class...> class L, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class... Ts>
1028 struct reverse_elements<L, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, Ts...>
1029 : append_impl<typename reverse_elements<L, Ts...>::type, L<T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0>>
1030 {
1031 };
1032 template<class L>
1033 struct reverse_impl;
1034 template<template<class...> class L, class... U>
1035 struct reverse_impl<L<U...>>
1036 : reverse_elements<L, U...>
1037 {
1038 };
1039}
1040namespace lazy
1041{
1042 template <typename L>
1043 using reverse = typename detail::reverse_impl<L>;
1044}
1045 template <typename L>
1046 using reverse = typename detail::reverse_impl<L>::type;
1047}
1048namespace brigand
1049{
1050namespace lazy
1051{
1052 template <typename Sequence, typename Predicate = ::brigand::detail::non_null>
1053 struct find;
1054 template <template <typename...> class Sequence, typename... Ls, typename Pred>
1055 struct find<Sequence<Ls...>, Pred>
1056 : detail::finder<Sequence, detail::bound_apply, Pred>::template find<
1057 false, false, void, void, void, void, void, void, void, void, Ls...>
1058 {
1059 };
1060 template <template <typename...> class Sequence, typename... Ls, template <typename...> class F>
1061 struct find<Sequence<Ls...>, bind<F, _1>>
1062 : detail::finder<Sequence, F>::template find<false, false, void, void, void, void, void,
1063 void, void, void, Ls...>
1064 {
1065 };
1066}
1067template <typename Sequence, typename Predicate = brigand::detail::non_null>
1068using find = typename lazy::find<Sequence, Predicate>::type;
1069namespace lazy
1070{
1071 template <typename Sequence, typename Predicate = detail::non_null>
1072 using reverse_find =
1073 ::brigand::lazy::reverse<::brigand::find<brigand::reverse<Sequence>, Predicate>>;
1074}
1075template <typename Sequence, typename Predicate = detail::non_null>
1076using reverse_find = typename ::brigand::lazy::reverse_find<Sequence, Predicate>::type;
1077namespace detail
1078{
1079 template <typename Sequence, typename Predicate>
1080 using find_size = size<brigand::find<Sequence, Predicate>>;
1081 template <typename Sequence, typename Predicate>
1082 using empty_find = bool_<find_size<Sequence, Predicate>::value == 0>;
1083 template <typename Sequence, typename Predicate>
1084 using non_empty_find = bool_<find_size<Sequence, Predicate>::value != 0>;
1085}
1086template <typename Sequence, typename Predicate = detail::non_null>
1087using not_found = typename detail::empty_find<Sequence, Predicate>;
1088template <typename Sequence, typename Predicate = detail::non_null>
1089using found = typename detail::non_empty_find<Sequence, Predicate>;
1090}
1091namespace brigand
1092{
1093namespace detail
1094{
1095 template <class L>
1096 struct flatten_impl
1097 {
1098 using type = L;
1099 };
1100 template <template<class...> class L, class T>
1101 struct flatten_element_impl
1102 {
1103 using type = L<T>;
1104 };
1105 template <template<class...> class L, class... Ts>
1106 struct flatten_element_impl<L, L<Ts...>>
1107 : append_impl<typename flatten_element_impl<L, Ts>::type...>
1108 {
1109 };
1110 template <template<class...> class L, class... Ts>
1111 struct flatten_impl<L<Ts...>>
1112 : flatten_element_impl<L, L<Ts...>>
1113 {
1114 };
1115}
1116namespace lazy
1117{
1118 template <typename Sequence>
1119 using flatten = typename detail::flatten_impl<Sequence>;
1120}
1121template <typename Sequence>
1122using flatten = typename lazy::flatten<Sequence>::type;
1123}
1124namespace brigand { namespace detail
1125{
1126 template<class Functor, class State, class Sequence>
1127 struct fold_impl
1128 {
1129 using type = State;
1130 };
1131 template<
1132 class Functor, class State, template <class...> class Sequence,
1133 class T0>
1134 struct fold_impl<Functor, State, Sequence<T0>>
1135 {
1136 using type = brigand::apply<Functor, State, T0>;
1137 };
1138 template<
1139 class Functor, class State, template <class...> class Sequence,
1140 class T0, class T1>
1141 struct fold_impl<Functor, State, Sequence<T0, T1>>
1142 {
1143 using type = brigand::apply<Functor,
1144 brigand::apply<Functor,State, T0>, T1
1145 >;
1146 };
1147 template<
1148 class Functor, class State, template <class...> class Sequence,
1149 class T0, class T1, class T2>
1150 struct fold_impl<Functor, State, Sequence<T0, T1, T2>>
1151 {
1152 using type = brigand::apply<Functor,
1153 brigand::apply<Functor,
1154 brigand::apply<Functor, State, T0>, T1
1155 >, T2
1156 >;
1157 };
1158 template<
1159 class Functor, class State, template <class...> class Sequence,
1160 class T0, class T1, class T2, class T3>
1161 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3>>
1162 {
1163 using type = brigand::apply<Functor,
1164 brigand::apply<Functor,
1165 brigand::apply<Functor,
1166 brigand::apply<Functor, State, T0>, T1
1167 >, T2
1168 >, T3
1169 >;
1170 };
1171 template<
1172 class Functor, class State, template <class...> class Sequence,
1173 class T0, class T1, class T2, class T3, class T4>
1174 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3, T4>>
1175 {
1176 using type = brigand::apply<Functor,
1177 brigand::apply<Functor,
1178 brigand::apply<Functor,
1179 brigand::apply<Functor,
1180 brigand::apply<Functor, State, T0>, T1
1181 >, T2
1182 >, T3
1183 >, T4
1184 >;
1185 };
1186 template<
1187 class Functor, class State, template <class...> class Sequence,
1188 class T0, class T1, class T2, class T3, class T4, class T5>
1189 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3, T4, T5>>
1190 {
1191 using type = brigand::apply<Functor,
1192 brigand::apply<Functor,
1193 brigand::apply<Functor,
1194 brigand::apply<Functor,
1195 brigand::apply<Functor,
1196 brigand::apply<Functor, State, T0>, T1
1197 >, T2
1198 >, T3
1199 >, T4
1200 >, T5
1201 >;
1202 };
1203 template<
1204 class Functor, class State, template <class...> class Sequence,
1205 class T0, class T1, class T2, class T3, class T4, class T5, class T6>
1206 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3, T4, T5, T6>>
1207 {
1208 using type = brigand::apply<Functor,
1209 brigand::apply<Functor,
1210 brigand::apply<Functor,
1211 brigand::apply<Functor,
1212 brigand::apply<Functor,
1213 brigand::apply<Functor,
1214 brigand::apply<Functor, State, T0>, T1
1215 >, T2
1216 >, T3
1217 >, T4
1218 >, T5
1219 >, T6
1220 >;
1221 };
1222 template<
1223 class Functor, class State, template <class...> class Sequence,
1224 class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1225 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3, T4, T5, T6, T7>>
1226 {
1227 using type = brigand::apply<Functor,
1228 brigand::apply<Functor,
1229 brigand::apply<Functor,
1230 brigand::apply<Functor,
1231 brigand::apply<Functor,
1232 brigand::apply<Functor,
1233 brigand::apply<Functor,
1234 brigand::apply<Functor, State, T0>, T1
1235 >, T2
1236 >, T3
1237 >, T4
1238 >, T5
1239 >, T6
1240 >, T7
1241 >;
1242 };
1243 template<
1244 class Functor, class State, template <class...> class Sequence,
1245 class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T>
1246 struct fold_impl<Functor, State, Sequence<T0, T1, T2, T3, T4, T5, T6, T7, T...>>
1247 : fold_impl<
1248 Functor,
1249 brigand::apply<Functor,
1250 brigand::apply<Functor,
1251 brigand::apply<Functor,
1252 brigand::apply<Functor,
1253 brigand::apply<Functor,
1254 brigand::apply<Functor,
1255 brigand::apply<Functor,
1256 brigand::apply<Functor,
1257 State, T0
1258 >, T1
1259 >, T2
1260 >, T3
1261 >, T4
1262 >, T5
1263 >, T6
1264 >, T7
1265 >,
1266 Sequence<T...>
1267 >
1268 {};
1269 template<typename Functor, typename State, typename Sequence>
1270 struct reverse_fold_impl
1271 {
1272 using type = State;
1273 };
1274 template <typename Functor, typename State, template <typename...> class L, typename T, typename... Ts>
1275 struct reverse_fold_impl<Functor, State, L<T, Ts...>>
1276 {
1277 using type =
1278 brigand::apply<Functor, typename reverse_fold_impl<Functor, State, L<Ts...>>::type, T>;
1279 };
1280 template<
1281 typename Functor, typename State, template <typename...> class L,
1282 typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename... Ts>
1283 struct reverse_fold_impl<Functor, State, L<T0, T1, T2, T3, T4, T5, T6, T7, Ts...>>{
1284 using type = brigand::apply<Functor,
1285 brigand::apply<Functor,
1286 brigand::apply<Functor,
1287 brigand::apply<Functor,
1288 brigand::apply<Functor,
1289 brigand::apply<Functor,
1290 brigand::apply<Functor,
1291 brigand::apply<Functor,
1292 typename reverse_fold_impl<Functor, State, L<Ts...>>::type, T7
1293 >, T6
1294 >, T5
1295 >, T4
1296 >, T3
1297 >, T2
1298 >, T1
1299 >, T0
1300 >;
1301 };
1302} }
1303namespace brigand
1304{
1305namespace lazy
1306{
1307 template <class Sequence, class State, class Functor>
1308 using fold = typename detail::fold_impl<Functor, State, Sequence>;
1309 template <class Sequence, class State, class Functor>
1310 using reverse_fold = typename detail::reverse_fold_impl<Functor, State, Sequence>;
1311}
1312template <class Sequence, class State, class Functor>
1313using fold = typename ::brigand::lazy::fold<Sequence, State, Functor>::type;
1314template <class Sequence, class State, class Functor>
1315using reverse_fold = typename ::brigand::lazy::reverse_fold<Sequence, State, Functor>::type;
1316}
1317namespace brigand
1318{
1319 template<class F, class...Ts> F for_each_args(F f, Ts&&...a)
1320 {
1321 return (void)std::initializer_list<int>{((void)std::ref(f)(static_cast<Ts&&>(a)),0)...}, f;
1322 }
1323}
1324namespace brigand
1325{
1326 namespace detail
1327 {
1328 template<template<class...> class List, typename... Elements, typename Functor>
1329 Functor for_each_impl( List<Elements...>&&, Functor f )
1330 {
1331 return for_each_args( f, type_<Elements>()... );
1332 }
1333 }
1334 template<typename List, typename Functor> Functor for_each( Functor f )
1335 {
1336 return detail::for_each_impl( List{}, f );
1337 }
1338}
1339namespace brigand
1340{
1341namespace detail
1342{
1343 template <bool Found, class Sequence, typename Predicate, typename NotFoundType>
1344 struct index_if_impl
1345 {
1346 using type = ::brigand::size_t<size<Sequence>::value -
1347 size<::brigand::find<Sequence, Predicate>>::value>;
1348 };
1349 template <class Sequence, typename Predicate, typename NotFoundType>
1350 struct index_if_impl<false, Sequence, Predicate, NotFoundType>
1351 {
1352 using type = NotFoundType;
1353 };
1354}
1355template <class Sequence, class Predicate, class NotFoundType = no_such_type_>
1356using index_if = typename detail::index_if_impl<::brigand::found<Sequence, Predicate>::value,
1357 Sequence, Predicate, NotFoundType>::type;
1358template <class Sequence, typename T>
1359using index_of = index_if<Sequence, std::is_same<T, ::brigand::_1>>;
1360}
1361
1362namespace brigand
1363{
1364 namespace detail
1365 {
1366 template<class T, class, class, T>
1367 struct range_cat;
1368#ifdef BRIGAND_COMP_MSVC
1369 template<class T, T Start, T Int>
1370 struct int_plus
1371 {
1372 using type = std::integral_constant<T, Start + Int>;
1373 };
1374#endif
1375 template<class T, class... Ts, T... Ints, T Start>
1376 struct range_cat<T, list<Ts...>, list<std::integral_constant<T, Ints>...>, Start>
1377 {
1378#ifdef BRIGAND_COMP_MSVC
1379 using type = list<Ts..., typename int_plus<T, Start, Ints>::type...>;
1380#else
1381 using type = list<Ts..., std::integral_constant<T, Start + Ints>...>;
1382#endif
1383 };
1384 template<class T, T Start, std::size_t N>
1385 struct range_impl
1386 : range_cat<
1387 T,
1388 typename range_impl<T, Start, N/2>::type,
1389 typename range_impl<T, Start, N - N/2>::type,
1390 N/2
1391 >
1392 {};
1393 template<class T, T Start>
1394 struct range_impl<T, Start, 1>
1395 {
1396 using type = list<std::integral_constant<T, Start>>;
1397 };
1398 template<class T, T Start>
1399 struct range_impl<T, Start, 0>
1400 {
1401 using type = list<>;
1402 };
1403 template<class T, class, class, T>
1404 struct reverse_range_cat;
1405#ifdef BRIGAND_COMP_MSVC
1406 template<class T, T Start, T Int>
1407 struct int_minus
1408 {
1409 using type = std::integral_constant<T, Int - Start>;
1410 };
1411#endif
1412 template<class T, class... Ts, T... Ints, T Start>
1413 struct reverse_range_cat<T, list<Ts...>, list<std::integral_constant<T, Ints>...>, Start>
1414 {
1415#ifdef BRIGAND_COMP_MSVC
1416 using type = list<Ts..., typename int_minus<T, Start, Ints>::type...>;
1417#else
1418 using type = list<Ts..., std::integral_constant<T, Ints - Start>...>;
1419#endif
1420 };
1421 template<class T, T Start, std::size_t N>
1422 struct reverse_range_impl
1423 : reverse_range_cat<
1424 T,
1425 typename reverse_range_impl<T, Start, N/2>::type,
1426 typename reverse_range_impl<T, Start, N - N/2>::type,
1427 N/2
1428 >
1429 {
1430 };
1431 template<class T, T Start>
1432 struct reverse_range_impl<T, Start, 1>
1433 {
1434 using type = list<std::integral_constant<T, Start>>;
1435 };
1436 template<class T, T Start>
1437 struct reverse_range_impl<T, Start, 0>
1438 {
1439 using type = list<>;
1440 };
1441 template <class T, T Start, T Stop>
1442 struct reverse_range_safe
1443 {
1444 static_assert(Start >= Stop, "Invalid parameters. reverse_range<> syntax is reverse_range<type, from, down_to>");
1445 using type = typename reverse_range_impl<T, Start, Start-Stop>::type;
1446 };
1447 }
1448 template<class T, T Start, T Stop>
1449 using range = typename detail::range_impl<T, Start, Stop-Start>::type;
1450 template<class T, T Start, T Stop>
1451 using reverse_range = typename detail::reverse_range_safe<T, Start, Stop>::type;
1452}
1453namespace brigand
1454{
1455namespace detail
1456{
1457 template<class, class T> struct unique_x_t
1458 { operator type_<T> (); };
1459 template<class Ints, class... Ts>
1460 struct is_set_impl;
1461 template<>
1462 struct is_set_impl<list<>>
1463 {
1464 using type = std::true_type;
1465 };
1466 inline std::true_type true_fn(...);
1467 template<class... Ints, class... Ts>
1468 struct is_set_impl<list<Ints...>, Ts...>
1469 {
1470 struct Pack : unique_x_t<Ints, Ts>... {};
1471 template<class... Us>
1472 static auto is_set(Us...) -> decltype(true_fn(static_cast<Us>(Pack())...));
1473 static std::false_type is_set(...);
1474 using type = decltype(is_set(type_<Ts>()...));
1475 };
1476}
1477 template<class... Ts>
1478 using is_set = typename detail::is_set_impl<range<int, 0, sizeof...(Ts)>, Ts...>::type;
1479}
1480
1481namespace brigand
1482{
1483#if defined(BRIGAND_COMP_GCC) || defined(BRIGAND_COMP_CLANG)
1484 namespace lazy
1485 {
1486 template <typename L, typename Pred>
1487 struct remove_if;
1488 template <template <class...> class L, typename... Ts, typename Pred>
1489 struct remove_if<L<Ts...>, Pred>
1490 : ::brigand::detail::append_impl<
1491 L<>, typename std::conditional<::brigand::apply<Pred, Ts>::value, list<>, list<Ts>>::type...>
1492 {
1493 };
1494 template <template <class...> class L, typename... Ts, template<typename...> class F>
1495 struct remove_if<L<Ts...>, bind<F,_1>>
1496 : ::brigand::detail::append_impl<
1497 L<>, typename std::conditional<F<Ts>::value, list<>, list<Ts>>::type...>
1498 {
1499 };
1500 template <template <class...> class L, typename... Ts, template<typename...> class F>
1501 struct remove_if<L<Ts...>, F<_1>>
1502 : ::brigand::detail::append_impl<
1503 L<>, typename std::conditional<F<Ts>::type::value, list<>, list<Ts>>::type...>
1504 {
1505 };
1506 }
1507 namespace lazy
1508 {
1509 template <typename L, typename T>
1510 struct remove;
1511 template <template <class...> class L, typename... Ts, typename T>
1512 struct remove<L<Ts...>, T>
1513 : ::brigand::detail::append_impl<
1514 L<>, typename std::conditional<std::is_same<Ts, T>::value, list<>, list<Ts>>::type...>
1515 {
1516 };
1517 }
1518 namespace lazy
1519 {
1520 template <typename L, typename Pred>
1521 struct filter;
1522 template <template <class...> class L, typename... Ts, typename Pred>
1523 struct filter<L<Ts...>, Pred>
1524 : ::brigand::detail::append_impl<
1525 L<>, typename std::conditional<::brigand::apply<Pred, Ts>::value, list<Ts>, list<>>::type...>
1526 {
1527 };
1528 template <template <class...> class L, typename... Ts, template<typename...> class F>
1529 struct filter<L<Ts...>, bind<F, _1>>
1530 : ::brigand::detail::append_impl<
1531 L<>, typename std::conditional<F<Ts>::value, list<Ts>, list<>>::type...>
1532 {
1533 };
1534 template <template <class...> class L, typename... Ts, template<typename...> class F>
1535 struct filter<L<Ts...>, F<_1>>
1536 : ::brigand::detail::append_impl<
1537 L<>, typename std::conditional<F<Ts>::type::value, list<Ts>, list<>>::type...>
1538 {
1539 };
1540 }
1541#else
1542namespace detail
1543{
1544 template <typename Pred, typename T, bool B>
1545 struct empty_if_true : std::conditional<::brigand::apply<Pred, T>::value == B, list<>, list<T>>
1546 {
1547 };
1548 template <template <typename...> class F, typename T, bool B>
1549 struct empty_if_true<bind<F, _1>, T, B> : std::conditional<F<T>::value == B, list<>, list<T>>
1550 {
1551 };
1552 template <template <typename...> class F, typename T, bool B>
1553 struct empty_if_true<F<_1>, T, B> : std::conditional<F<T>::type::value == B, list<>, list<T>>
1554 {
1555 };
1556}
1557namespace lazy
1558{
1559 template <typename L, typename Pred>
1560 struct remove_if;
1561 template <template <class...> class L, typename... Ts, typename Pred>
1562 struct remove_if<L<Ts...>, Pred>
1563 : ::brigand::detail::append_impl<
1564 L<>, typename ::brigand::detail::empty_if_true<Pred, Ts, true>::type...>
1565 {
1566 };
1567}
1568namespace lazy
1569{
1570 template <typename L, typename T>
1571 struct remove;
1572 template <template <class...> class L, typename... Ts, typename T>
1573 struct remove<L<Ts...>, T>
1574 : ::brigand::detail::append_impl<
1575 L<>, typename std::conditional<std::is_same<Ts, T>::value, list<>, list<Ts>>::type...>
1576 {
1577 };
1578}
1579namespace lazy
1580{
1581 template <typename L, typename Pred>
1582 struct filter;
1583 template <template <class...> class L, typename... Ts, typename Pred>
1584 struct filter<L<Ts...>, Pred>
1585 : ::brigand::detail::append_impl<
1586 L<>, typename ::brigand::detail::empty_if_true<Pred, Ts, false>::type...>
1587 {
1588 };
1589}
1590#endif
1591template <typename L, typename Pred>
1592using remove_if = typename lazy::remove_if<L, Pred>::type;
1593template <typename L, typename T>
1594using remove = typename lazy::remove<L, T>::type;
1595template <typename L, typename Pred>
1596using filter = typename lazy::filter<L, Pred>::type;
1597}
1598namespace brigand
1599{
1600template <class Seq, class Pred>
1601using partition = pair<filter<Seq, Pred>, remove_if<Seq, Pred>>;
1602}
1603
1604namespace brigand
1605{
1606 namespace detail
1607 {
1608 template <typename T, typename Pred, typename NewType>
1609 struct replacer : std::conditional<::brigand::apply<Pred, T>::value, NewType, T>
1610 {
1611 };
1612 template <typename T, template <typename...> class F, typename NewType>
1613 struct replacer<T, bind<F, _1>, NewType> : std::conditional<F<T>::value, NewType, T>
1614 {
1615 };
1616 template <typename T, template <typename...> class F, typename NewType>
1617 struct replacer<T, F<_1>, NewType> : std::conditional<F<T>::type::value, NewType, T>
1618 {
1619 };
1620 }
1621namespace lazy
1622{
1623 template <typename Sequence, typename Predicate, typename NewType>
1624 struct replace_if;
1625 template <template <typename...> class S, typename... Ts, typename Predicate, typename NewType>
1626 struct replace_if<S<Ts...>, Predicate, NewType>
1627 {
1628 using type = S<typename detail::replacer<Ts, Predicate, NewType>::type...>;
1629 };
1630 template <typename Sequence, typename OldType, typename NewType>
1631 using replace = replace_if<Sequence, std::is_same<_1, pin<OldType>>, NewType>;
1632}
1633template <typename Sequence, typename Predicate, typename NewType>
1634using replace_if = typename ::brigand::lazy::replace_if<Sequence, Predicate, NewType>::type;
1635template <typename Sequence, typename OldType, typename NewType>
1636using replace = typename ::brigand::lazy::replace<Sequence, OldType, NewType>::type;
1637}
1638
1639namespace brigand
1640{
1641 template<typename C, typename T, typename F>
1642 inline typename std::enable_if<C::value,T&&>::type select(T&& t, F&&)
1643 {
1644 return std::forward<T>(t);
1645 }
1646 template<typename C, typename T, typename F>
1647 inline typename std::enable_if<!C::value,F&&>::type select(T&&, F&& f)
1648 {
1649 return std::forward<F>(f);
1650 }
1651}
1652namespace brigand
1653{
1654namespace detail
1655{
1656 template<typename TOut, typename TCurrent, typename TDelim, typename... Ts>
1657 struct split_impl;
1658 template<template<typename...> class L, typename... Os, typename... Cs, typename TDelim, typename T, typename... Ts>
1659 struct split_impl<L<Os...>, L<Cs...>, TDelim, T, Ts...> :
1660 split_impl<L<Os...>, L<Cs..., T>, TDelim, Ts...> {};
1661 template<template<typename...> class L, typename... Os, typename... Cs, typename TDelim, typename T>
1662 struct split_impl<L<Os...>, L<Cs...>, TDelim, T> {
1663 using type = L<Os..., L<Cs..., T>>;
1664 };
1665 template<template<typename...> class L, typename... Os, typename... Cs, typename TDelim, typename... Ts>
1666 struct split_impl<L<Os...>, L<Cs...>, TDelim, TDelim, Ts...> :
1667 split_impl<L<Os..., L<Cs...>>, L<>, TDelim, Ts...> {};
1668 template<template<typename...> class L, typename... Os, typename... Cs, typename TDelim>
1669 struct split_impl<L<Os...>, L<Cs...>, TDelim, TDelim> {
1670 using type = L<Os..., L<Cs...>>;
1671 };
1672 template<template<typename...> class L, typename... Os, typename TDelim, typename... Ts>
1673 struct split_impl<L<Os...>, L<>, TDelim, TDelim, Ts...> :
1674 split_impl<L<Os...>, L<>, TDelim, Ts...> {};
1675 template<template<typename...> class L, typename... Os, typename TDelim>
1676 struct split_impl<L<Os...>, L<>, TDelim, TDelim> {
1677 using type = L<Os...>;
1678 };
1679 template<template<typename...> class L, typename... Os, typename TDelim>
1680 struct split_impl<L<Os...>, L<>, TDelim> {
1681 using type = L<Os...>;
1682 };
1683 template<typename TList, typename TDelim>
1684 struct split_helper;
1685 template<template<typename...> class L, typename T, typename... Ts, typename TDelim>
1686 struct split_helper<L<T,Ts...>, TDelim> : split_impl<L<>, L<>, TDelim, T, Ts...>{};
1687 template<template<typename...> class L, typename... T, typename TDelim>
1688 struct split_helper<L<T...>, TDelim> {
1689 using type = L<>;
1690 };
1691}
1692namespace lazy
1693{
1694 template<typename TList, typename TDelim>
1695 using split = detail::split_helper<TList, TDelim>;
1696}
1697template<typename TList, typename TDelim>
1698using split = typename lazy::split<TList, TDelim>::type;
1699}
1700namespace brigand
1701{
1702 template <typename A, typename B>
1703 struct less : bool_ < (A::value < B::value) > {};
1704}
1705
1706namespace brigand
1707{
1708 namespace detail
1709 {
1710 template<class L, class Seq1, class Seq2, class Comp>
1711 struct merge_impl;
1712 template<bool, class L, class Seq1, class Seq2, class Comp>
1713 struct merge_insert;
1714 template<class... R, class T0, class T1, class... Ts, class U, class... Us, class Comp>
1715 struct merge_insert<true, list<R...>, list<T0,T1,Ts...>, list<U,Us...>, Comp>
1716 : merge_insert<::brigand::apply<Comp,T1,U>::value, list<R...,T0>, list<T1,Ts...>, list<U,Us...>, Comp>
1717 {};
1718 template<class... R, class T, class U, class... Us, class Comp>
1719 struct merge_insert<true, list<R...>, list<T>, list<U,Us...>, Comp>
1720 {
1721 using list = ::brigand::list<R...,T>;
1722 using left = ::brigand::list<>;
1723 using right = ::brigand::list<U,Us...>;
1724 };
1725 template<class... R, class T, class... Ts, class U0, class U1, class... Us, class Comp>
1726 struct merge_insert<false, list<R...>, list<T,Ts...>, list<U0,U1,Us...>, Comp>
1727 : merge_insert<::brigand::apply<Comp,T,U1>::value, list<R...,U0>, list<T,Ts...>, list<U1,Us...>, Comp>
1728 {};
1729 template<class... R, class T, class... Ts, class U, class Comp>
1730 struct merge_insert<false, list<R...>, list<T,Ts...>, list<U>, Comp>
1731 {
1732 using list = ::brigand::list<R...,U>;
1733 using left = ::brigand::list<T,Ts...>;
1734 using right = ::brigand::list<>;
1735 };
1736 template<
1737 class... R,
1738 class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class... Ts,
1739 class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9, class... Us, class Comp>
1740 struct merge_impl<list<R...>, list<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,Ts...>, list<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9,Us...>, Comp>
1741 {
1742 using sub = merge_insert<::brigand::apply<Comp,T0,U0>::value, list<>, list<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>, list<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>, Comp>;
1743 using type = typename merge_impl<
1744 append<list<R...>, typename sub::list>,
1745 append<typename sub::left, list<Ts...>>,
1746 append<typename sub::right, list<Us...>>,
1747 Comp
1748 >::type;
1749 };
1750 template<class... R, class T, class... Ts, class U, class... Us, class Comp>
1751 struct merge_impl<list<R...>, list<T,Ts...>, list<U,Us...>, Comp>
1752 : std::conditional<
1753 ::brigand::apply<Comp,T,U>::value,
1754 merge_impl<list<R...,T>, list<Ts...>, list<U,Us...>, Comp>,
1755 merge_impl<list<R...,U>, list<T,Ts...>, list<Us...>, Comp>
1756 >::type
1757 {};
1758 template<class... R, class... Ts, class Comp>
1759 struct merge_impl<list<R...>, list<Ts...>, list<>, Comp>
1760 {
1761 using type = list<R..., Ts...>;
1762 };
1763 template<class... R, class... Us, class Comp>
1764 struct merge_impl<list<R...>, list<>, list<Us...>, Comp>
1765 {
1766 using type = list<R..., Us...>;
1767 };
1768 template<class... R, class Comp>
1769 struct merge_impl<list<R...>, list<>, list<>, Comp>
1770 {
1771 using type = list<R...>;
1772 };
1773 }
1774 template<class Seq1, class Seq2, class Comp = less<_1,_2>>
1775 using merge = append<clear<Seq1>, typename detail::merge_impl<list<>, wrap<Seq1, list>, wrap<Seq2, list>, Comp>::type>;
1776}
1777namespace brigand
1778{
1779namespace detail
1780{
1781 template <class Ls, class Seq, typename Comp>
1782 struct sort_impl;
1783 template<class L, class Comp>
1784 struct mini_sort;
1785 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... Ts, class Comp>
1786 struct mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, Ts...>, Comp>
1787 : merge_impl<
1788 list<>,
1789 typename mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7>, Comp>::type,
1790 typename mini_sort<list<T8, Ts...>, Comp>::type, Comp>
1791 {};
1792 template<class T0, class T1, class T2, class T3, class T4, class... Ts, class Comp>
1793 struct mini_sort<list<T0, T1, T2, T3, T4, Ts...>, Comp>
1794 : merge_impl<list<>, typename mini_sort<list<T0, T1, T2, T3>, Comp>::type, typename mini_sort<list<T4, Ts...>, Comp>::type, Comp>
1795 {};
1796 template<class T0, class T1, class T2, class T3, class Comp>
1797 struct mini_sort<list<T0, T1, T2, T3>, Comp>
1798 : merge_impl<list<>, typename mini_sort<list<T0, T1>, Comp>::type, typename mini_sort<list<T2, T3>, Comp>::type, Comp>
1799 {};
1800 template<class T0, class T1, class T2, class Comp>
1801 struct mini_sort<list<T0, T1, T2>, Comp>
1802 : merge_impl<list<>, typename mini_sort<list<T0, T1>, Comp>::type, list<T2>, Comp>
1803 {};
1804 template<class T0, class T1, class Comp>
1805 struct mini_sort<list<T0, T1>, Comp>
1806 {
1807 using type = typename std::conditional<::brigand::apply<Comp, T0, T1>::value, list<T0, T1>, list<T1, T0>>::type;
1808 };
1809 template<class T0, class Comp>
1810 struct mini_sort<list<T0>, Comp>
1811 {
1812 using type = list<T0>;
1813 };
1814 template <
1815 class T0, class T1, class T2, class T3, class T4, class T5, class T6,
1816 class T7, class T8, class T9, class T10, class T11, class T12, class T13,
1817 class T14, class T15, class T16, class T17, class... Ts, typename Comp>
1818 struct sort_impl<list<>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, Ts...>, Comp>
1819 : sort_impl<
1820 list<typename mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>, Comp>::type>,
1821 list<Ts...>, Comp>
1822 {};
1823 template <
1824 class L0,
1825 class T0, class T1, class T2, class T3, class T4, class T5, class T6,
1826 class T7, class T8, class T9, class T10, class T11, class T12, class T13,
1827 class T14, class T15, class T16, class T17, class... Ts, typename Comp>
1828 struct sort_impl<list<L0>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, Ts...>, Comp>
1829 : sort_impl<
1830 list<L0, typename mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>, Comp>::type>,
1831 list<Ts...>, Comp>
1832 {};
1833 template <
1834 class L0, class L1,
1835 class T0, class T1, class T2, class T3, class T4, class T5, class T6,
1836 class T7, class T8, class T9, class T10, class T11, class T12, class T13,
1837 class T14, class T15, class T16, class T17, class... Ts, typename Comp>
1838 struct sort_impl<list<L0,L1>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, Ts...>, Comp>
1839 : sort_impl<
1840 list<L0, L1, typename mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>, Comp>::type>,
1841 list<Ts...>, Comp>
1842 {};
1843 template <
1844 class L0, class L1, class L2,
1845 class T0, class T1, class T2, class T3, class T4, class T5, class T6,
1846 class T7, class T8, class T9, class T10, class T11, class T12, class T13,
1847 class T14, class T15, class T16, class T17, class... Ts, typename Comp>
1848 struct sort_impl<list<L0,L1,L2>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, Ts...>, Comp>
1849 : sort_impl<
1850 list<
1851 merge<L0, L1, Comp>,
1852 merge<
1853 typename mini_sort<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>, Comp>::type, L2, Comp>>,
1854 list<Ts...>, Comp>
1855 {};
1856 template <class T, class... Ts, typename Comp>
1857 struct sort_impl<list<>, list<T, Ts...>, Comp>
1858 {
1859 using type = typename mini_sort<list<T, Ts...>, Comp>::type;
1860 };
1861 template <class L, class T, class... Ts, typename Comp>
1862 struct sort_impl<list<L>, list<T, Ts...>, Comp>
1863 {
1864 using type = merge<typename mini_sort<list<T, Ts...>, Comp>::type, L, Comp>;
1865 };
1866 template <class L0, class L1, class T, class... Ts, typename Comp>
1867 struct sort_impl<list<L0, L1>, list<T, Ts...>, Comp>
1868 {
1869 using type = merge<L0, merge<typename mini_sort<list<T, Ts...>, Comp>::type, L1, Comp>, Comp>;
1870 };
1871 template <class L0, class L1, class L2, class T, class... Ts, typename Comp>
1872 struct sort_impl<list<L0, L1, L2>, list<T, Ts...>, Comp>
1873 {
1874 using type = merge<merge<L0, L1, Comp>, merge<typename mini_sort<list<T, Ts...>, Comp>::type, L2, Comp>, Comp>;
1875 };
1876 template <class L, typename Comp>
1877 struct sort_impl<list<L>, list<>, Comp>
1878 {
1879 using type = L;
1880 };
1881 template <class L0, class L1, typename Comp>
1882 struct sort_impl<list<L0, L1>, list<>, Comp>
1883 {
1884 using type = merge<L0,L1,Comp>;
1885 };
1886 template <class L0, class L1, class L2, typename Comp>
1887 struct sort_impl<list<L0,L1,L2>, list<>, Comp>
1888 {
1889 using type = merge<merge<L0,L1,Comp>,L2,Comp>;
1890 };
1891 template <typename Comp>
1892 struct sort_impl<list<>, list<>, Comp>
1893 {
1894 using type = list<>;
1895 };
1896 template <
1897 class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12,
1898 class T13, class T14, class T15, class T16, class T17, class T18, class T19, class T20, class T21, class T22, class T23, class T24,
1899 class T25, class T26, class T27, class T28, class T29, class T30, class T31, class T32, class T33, class T34, class T35, class T36,
1900 class T37, class T38, class T39, class T40, class T41, class T42, class T43, class T44, class T45, class T46, class T47, class T48,
1901 class T49, class T50, class T51, class T52, class T53, class T54, class T55, class T56, class T57, class T58, class T59, class T60,
1902 class T61, class T62, class T63, class T64, class T65, class T66, class T67, class T68, class T69, class T70, class T71, class T72,
1903 class T73, class T74, class T75, class T76, class T77, class T78, class T79, class T80, class T81, class T82, class T83, class T84,
1904 class T85, class T86, class T87, class T88, class T89, class T90, class T91, class T92, class T93, class T94, class T95, class T96,
1905 class T97, class T98, class T99, class T100, class T101, class T102, class T103, class T104, class T105, class T106, class T107,
1906 class T108, class T109, class T110, class T111, class T112, class T113, class T114, class T115, class T116, class T117, class T118,
1907 class T119, class T120, class T121, class T122, class T123, class T124, class T125, class T126, class T127, class T128, class T129,
1908 class T130, class T131, class T132, class T133, class T134, class T135, class T136, class T137, class T138, class T139, class T140,
1909 class T141, class T142, class T143, class T144, class T145, class T146, class T147, class T148, class T149, class T150, class T151,
1910 class T152, class T153, class T154, class T155, class T156, class T157, class T158, class T159, class T160, class T161, class T162,
1911 class T163, class T164, class T165, class T166, class T167, class T168, class T169, class T170, class T171, class T172, class T173,
1912 class T174, class T175, class T176, class T177, class T178, class T179, class T180, class T181, class T182, class T183, class T184,
1913 class T185, class T186, class T187, class T188, class T189, class T190, class T191, class T192, class T193, class T194, class T195,
1914 class T196, class T197, class T198, class T199, class T200, class T201, class T202, class T203, class T204, class T205, class T206,
1915 class T207, class T208, class T209, class T210, class T211, class T212, class T213, class T214, class T215, class T216, class T217,
1916 class T218, class T219, class T220, class T221, class T222, class T223, class T224, class T225, class T226, class T227, class T228,
1917 class T229, class T230, class T231, class T232, class T233, class T234, class T235, class T236, class T237, class T238, class T239,
1918 class T240, class T241, class T242, class T243, class T244, class T245, class T246, class T247, class T248, class T249, class T250,
1919 class T251, class T252, class T253, class T254, class T255, typename... Ts, typename Comp>
1920 struct sort_impl<list<>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21,
1921 T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, T46, T47,
1922 T48, T49, T50, T51, T52, T53, T54, T55, T56, T57, T58, T59, T60, T61, T62, T63, T64, T65, T66, T67, T68, T69, T70, T71, T72, T73,
1923 T74, T75, T76, T77, T78, T79, T80, T81, T82, T83, T84, T85, T86, T87, T88, T89, T90, T91, T92, T93, T94, T95, T96, T97, T98, T99,
1924 T100, T101, T102, T103, T104, T105, T106, T107, T108, T109, T110, T111, T112, T113, T114, T115, T116, T117, T118, T119, T120, T121,
1925 T122, T123, T124, T125, T126, T127, T128, T129, T130, T131, T132, T133, T134, T135, T136, T137, T138, T139, T140, T141, T142, T143,
1926 T144, T145, T146, T147, T148, T149, T150, T151, T152, T153, T154, T155, T156, T157, T158, T159, T160, T161, T162, T163, T164, T165,
1927 T166, T167, T168, T169, T170, T171, T172, T173, T174, T175, T176, T177, T178, T179, T180, T181, T182, T183, T184, T185, T186, T187,
1928 T188, T189, T190, T191, T192, T193, T194, T195, T196, T197, T198, T199, T200, T201, T202, T203, T204, T205, T206, T207, T208, T209,
1929 T210, T211, T212, T213, T214, T215, T216, T217, T218, T219, T220, T221, T222, T223, T224, T225, T226, T227, T228, T229, T230, T231,
1930 T232, T233, T234, T235, T236, T237, T238, T239, T240, T241, T242, T243, T244, T245, T246, T247, T248, T249, T250, T251, T252, T253,
1931 T254, T255, Ts...>, Comp>
1932 {
1933 using type = merge<
1934 typename sort_impl<list<>, list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
1935 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
1936 T46, T47, T48, T49, T50, T51, T52, T53, T54, T55, T56, T57, T58, T59, T60, T61, T62, T63, T64, T65, T66, T67, T68, T69, T70,
1937 T71, T72, T73, T74, T75, T76, T77, T78, T79, T80, T81, T82, T83, T84, T85, T86, T87, T88, T89, T90, T91, T92, T93, T94, T95,
1938 T96, T97, T98, T99, T100, T101, T102, T103, T104, T105, T106, T107, T108, T109, T110, T111, T112, T113, T114, T115, T116,
1939 T117, T118, T119, T120, T121, T122, T123, T124, T125, T126, T127, T128, T129, T130, T131, T132, T133, T134, T135, T136, T137,
1940 T138, T139, T140, T141, T142, T143, T144, T145, T146, T147, T148, T149, T150, T151, T152, T153, T154, T155, T156, T157, T158,
1941 T159, T160, T161, T162, T163, T164, T165, T166, T167, T168, T169, T170, T171, T172, T173, T174, T175, T176, T177, T178, T179,
1942 T180, T181, T182, T183, T184, T185, T186, T187, T188, T189, T190, T191, T192, T193, T194, T195, T196, T197, T198, T199, T200,
1943 T201, T202, T203, T204, T205, T206, T207, T208, T209, T210, T211, T212, T213, T214, T215, T216, T217, T218, T219, T220, T221,
1944 T222, T223, T224, T225, T226, T227, T228, T229, T230, T231, T232, T233, T234, T235, T236, T237, T238, T239, T240, T241, T242,
1945 T243, T244, T245, T246, T247, T248, T249, T250, T251, T252, T253, T254>, Comp>::type,
1946 typename sort_impl<list<>, list<T255, Ts...>, Comp>::type, Comp
1947 >;
1948 };
1949}
1950template <class Seq, class Comp = less<_1,_2>>
1951using sort = append<clear<Seq>, typename detail::sort_impl<list<>, wrap<Seq, list>, Comp>::type>;
1952}
1953
1954namespace brigand
1955{
1956 template <typename A>
1957 struct complement : std::integral_constant< typename A::value_type
1958 , typename A::value_type(~A::value)
1959 > {};
1960}
1961
1962namespace brigand
1963{
1964 template <typename A, typename B>
1965 struct divides : std::integral_constant < typename A::value_type, A::value / B::value > {};
1966}
1967namespace brigand
1968{
1969 template<class T>
1970 struct identity
1971 {
1972 using type = T;
1973 };
1974}
1975
1976namespace brigand
1977{
1978 template <typename A, typename B>
1979 struct max : std::integral_constant < typename A::value_type
1980 , (A::value < B::value) ? B::value : A::value
1981 >
1982 {};
1983}
1984
1985namespace brigand
1986{
1987 template <typename A, typename B>
1988 struct min : std::integral_constant < typename A::value_type
1989 , (A::value < B::value) ? A::value : B::value
1990 >
1991 {};
1992}
1993
1994namespace brigand
1995{
1996 template <typename A, typename B>
1997 struct minus : std::integral_constant < typename A::value_type, A::value - B::value > {};
1998}
1999
2000namespace brigand
2001{
2002 template <typename A, typename B>
2003 struct modulo : std::integral_constant < typename A::value_type, A::value % B::value > {};
2004}
2005
2006namespace brigand
2007{
2008 template <typename A>
2009 struct negate : std::integral_constant < typename A::value_type, -A::value > {};
2010}
2011
2012namespace brigand
2013{
2014 template <typename A>
2015 struct next : std::integral_constant < typename A::value_type, A::value + 1 > {};
2016}
2017
2018namespace brigand
2019{
2020 template <typename A, typename B>
2021 struct plus : std::integral_constant < typename A::value_type, A::value + B::value > {};
2022}
2023
2024namespace brigand
2025{
2026 template <typename A>
2027 struct prev : std::integral_constant < typename A::value_type, A::value - 1 > {};
2028}
2029
2030namespace brigand
2031{
2032 template <typename A, typename B>
2033 struct times : std::integral_constant < typename A::value_type, A::value * B::value > {};
2034}
2035
2036namespace brigand
2037{
2038 template <typename A, typename B>
2039 struct bitand_ : std::integral_constant<typename A::value_type, A::value & B::value> {};
2040}
2041
2042namespace brigand
2043{
2044 template <typename A, typename B>
2045 struct bitor_ : std::integral_constant<typename A::value_type, A::value | B::value> {};
2046}
2047
2048namespace brigand
2049{
2050 template <typename A, typename B>
2051 struct bitxor_ : std::integral_constant<typename A::value_type, A::value ^ B::value> {};
2052}
2053
2054namespace brigand
2055{
2056 template <typename A, typename B>
2057 struct shift_left : std::integral_constant<typename A::value_type, (A::value << B::value)> {};
2058}
2059
2060namespace brigand
2061{
2062 template <typename A, typename B>
2063 struct shift_right : std::integral_constant<typename A::value_type, (A::value >> B::value)> {};
2064}
2065namespace brigand
2066{
2067 template <typename A, typename B>
2068 struct equal_to : bool_ < (A::value == B::value) > {};
2069}
2070namespace brigand
2071{
2072 template <typename A, typename B>
2073 struct greater : bool_<(A::value > B::value) > {};
2074}
2075namespace brigand
2076{
2077 template <typename A, typename B>
2078 struct greater_equal : bool_ < (A::value >= B::value) > {};
2079}
2080namespace brigand
2081{
2082 template <typename A, typename B>
2083 struct less_equal : bool_ < (A::value <= B::value) > {};
2084}
2085namespace brigand
2086{
2087 template <typename A, typename B>
2088 struct not_equal_to : bool_ < (A::value != B::value) > {};
2089}
2090
2091namespace brigand
2092{
2093 template <typename Condition, typename A, typename B>
2094 struct eval_if
2095 {
2096 using type = typename std::conditional<Condition::value, A, B>::type::type;
2097 };
2098 template <bool Condition, typename A, typename B>
2099 struct eval_if_c
2100 {
2101 using type = typename std::conditional<Condition, A, B>::type::type;
2102 };
2103}
2104
2105namespace brigand
2106{
2107 template <typename Condition, typename A, typename B>
2108 struct if_ : std::conditional<Condition::value, A, B> {};
2109 template <bool Condition, typename A, typename B>
2110 struct if_c : std::conditional<Condition, A, B> {};
2111}
2112
2113namespace brigand
2114{
2115 template <typename A, typename B>
2116 struct and_ : std::integral_constant <typename A::value_type, A::value && B::value > {};
2117}
2118
2119namespace brigand
2120{
2121 template <typename T>
2122 struct not_ : std::integral_constant<typename T::value_type, !T::value> {};
2123}
2124
2125namespace brigand
2126{
2127 template <typename A, typename B>
2128 struct or_ : std::integral_constant < typename A::value_type, A::value || B::value > {};
2129}
2130
2131namespace brigand
2132{
2133 template <typename A, typename B>
2134 struct xor_ : std::integral_constant<typename A::value_type, A::value != B::value> {};
2135}
2136namespace brigand
2137{
2138 template<class T>
2139 struct always
2140 {
2141 using type = T;
2142 };
2143}
2144namespace brigand
2145{
2146namespace detail
2147{
2148 template<template<class> class F, unsigned N, class T>
2149 struct repeat_impl
2150 : repeat_impl<F, N-7, F<F<F<F<F<F<F<T>>>>>>>>
2151 {};
2152 template<template<class> class F, class T>
2153 struct repeat_impl<F, 7, T>
2154 {
2155 using type = F<F<F<F<F<F<F<T>>>>>>>;
2156 };
2157 template<template<class> class F, class T>
2158 struct repeat_impl<F, 6, T>
2159 {
2160 using type = F<F<F<F<F<F<T>>>>>>;
2161 };
2162 template<template<class> class F, class T>
2163 struct repeat_impl<F, 5, T>
2164 {
2165 using type = F<F<F<F<F<T>>>>>;
2166 };
2167 template<template<class> class F, class T>
2168 struct repeat_impl<F, 4, T>
2169 {
2170 using type = F<F<F<F<T>>>>;
2171 };
2172 template<template<class> class F, class T>
2173 struct repeat_impl<F, 3, T>
2174 {
2175 using type = F<F<F<T>>>;
2176 };
2177 template<template<class> class F, class T>
2178 struct repeat_impl<F, 2, T>
2179 {
2180 using type = F<F<T>>;
2181 };
2182 template<template<class> class F, class T>
2183 struct repeat_impl<F, 1, T>
2184 {
2185 using type = F<T>;
2186 };
2187 template<template<class> class F, class T>
2188 struct repeat_impl<F, 0, T>
2189 {
2190 using type = T;
2191 };
2192}
2193namespace lazy
2194{
2195 template<template<class> class F, class N, class T>
2196 using repeat = typename detail::repeat_impl<F, N::value, T>;
2197}
2198 template<template<class> class F, class N, class T>
2199 using repeat = typename ::brigand::lazy::repeat<F, N, T>::type;
2200}
2201
2202namespace brigand
2203{
2204 template<typename T>
2205 struct sizeof_ : std::integral_constant <std::size_t, sizeof(T)> {};
2206}
2207namespace brigand
2208{
2209namespace detail
2210{
2211 template<class C, class K>
2212 struct has_key_impl
2213 {
2214 using type = decltype(C::has_key(type_<K>{}));
2215 };
2216}
2217 template<class L, class K>
2218 using has_key = typename detail::has_key_impl<L, K>::type;
2219}
2220namespace brigand
2221{
2222namespace detail
2223{
2224 template<class Start, unsigned N, class Next, class... E>
2225 struct mksq8
2226 : mksq8<brigand::apply<Next, Start>, N-1, Next, E..., Start>
2227 {};
2228 template<class Start, class Next, class... E>
2229 struct mksq8<Start, 0, Next, E...>
2230 {
2231 using type = list<E...>;
2232 };
2233 template<class Start, class Next, class... E>
2234 struct mksq8<Start, 1, Next, E...>
2235 {
2236 using type = list<E..., Start>;
2237 };
2238 template<class Start, class Next>
2239 struct mksq8<Start, 8, Next>
2240 {
2241 using t1 = brigand::apply<Next, Start>;
2242 using t2 = brigand::apply<Next, t1>;
2243 using t3 = brigand::apply<Next, t2>;
2244 using t4 = brigand::apply<Next, t3>;
2245 using t5 = brigand::apply<Next, t4>;
2246 using t6 = brigand::apply<Next, t5>;
2247 using t7 = brigand::apply<Next, t6>;
2248 using type = list<Start, t1, t2, t3, t4, t5, t6, t7>;
2249 };
2250 template<template<class...> class List, class Start, unsigned N, class Next, bool, class... L>
2251 struct make_sequence_impl
2252 : make_sequence_impl<
2253 List,
2254 brigand::apply<Next, typename mksq8<Start, 8, Next>::t7>,
2255 N-8,
2256 Next,
2257 (N-8<=8),
2258 L...,
2259 typename mksq8<Start, 8, Next>::type
2260 >
2261 {};
2262 template<template<class...> class List, class Start, unsigned N, class Next, class... L>
2263 struct make_sequence_impl<List, Start, N, Next, true, L...>
2264 {
2265 using type = append<List<>, L..., typename mksq8<Start, N, Next>::type>;
2266 };
2267}
2268 template<class Start, unsigned N, class Next = next<_1>, template<class...> class List = list>
2269 using make_sequence = typename detail::make_sequence_impl<List, Start, N, Next, (N<=8)>::type;
2270}
2271
2272namespace brigand
2273{
2274 template<class L, std::size_t Index>
2275 using erase_c = append<
2276 front<split_at<L, size_t<Index>>>,
2277 pop_front<back<split_at<L, size_t<Index>>>>
2278 >;
2279namespace detail
2280{
2281 template <typename T>
2282 struct has_erase_method
2283 {
2284 struct dummy {};
2285 template <typename C, typename P>
2286 static auto test(P * p) -> decltype(C::erase(type_<P>{}), std::true_type());
2287 template <typename, typename>
2288 static std::false_type test(...);
2289 static const bool value = std::is_same<std::true_type, decltype(test<T, dummy>(nullptr))>::value;
2290 };
2291 template<class L, class I, bool>
2292 struct erase_dispatch
2293 {
2294 using type = erase_c<L, I::value>;
2295 };
2296 template<class C, class K>
2297 struct erase_dispatch<C, K, true>
2298 {
2299 using type = decltype(C::erase(type_<K>{}));
2300 };
2301}
2302 template<class L, class K>
2303 using erase = typename detail::erase_dispatch<L, K, detail::has_erase_method<L>::value>::type;
2304}
2305namespace brigand
2306{
2307namespace detail
2308{
2309 template <class C, class T>
2310 struct insert_impl
2311 {
2312 using type = decltype(C::insert(type_<T>{}));
2313 };
2314}
2315 template<class L, class T>
2316 using insert = typename detail::insert_impl<L, T>::type;
2317}
2318namespace brigand
2319{
2320namespace detail
2321{
2322 template <class L, class K>
2323 struct contains_impl
2324 {
2325 using type = decltype(L::contains(type_<K>{}));
2326 };
2327}
2328 template <class L, class K>
2329 using contains = typename detail::contains_impl<L, K>::type;
2330}
2331namespace brigand
2332{
2333namespace detail
2334{
2335 template<class... Ts>
2336 struct make_set;
2337 template<class U, class K>
2338 struct set_erase_pred_impl
2339 {
2340 using type = list<U>;
2341 };
2342 template<class K>
2343 struct set_erase_pred_impl<K,K>
2344 {
2345 using type = list<>;
2346 };
2347 template <class... T>
2348 struct set_impl
2349 {
2350 template <typename K, typename = decltype(static_cast<type_<K>*>(static_cast<make_set<T...>*>(nullptr)))>
2351 static std::true_type contains(type_<K>);
2352 template <typename K>
2353 static std::false_type contains(K);
2354 template <typename K, typename = decltype(static_cast<type_<K>*>(static_cast<make_set<T...>*>(nullptr)))>
2355 static std::true_type has_key(type_<K>);
2356 template <typename K>
2357 static std::false_type has_key(K);
2358 template <class K>
2359 static append<set_impl<>, typename set_erase_pred_impl<T, K>::type...> erase(type_<K>);
2360 template<class K, class = decltype(static_cast<type_<K>*>(static_cast<make_set<T...>*>(nullptr)))>
2361 static set_impl insert(type_<K>);
2362 template<class K>
2363 static set_impl<T..., typename K::type> insert(K);
2364 };
2365 template<class... Ts>
2366 struct make_set : type_<Ts>...
2367 {
2368 using type = set_impl<Ts...>;
2369 };
2370}
2371 template<class... Ts>
2372 using set = typename detail::make_set<Ts...>::type;
2373}
2374namespace brigand
2375{
2376namespace detail
2377{
2378 template <typename Pair>
2379 struct get_second {
2380 using type = typename Pair::second_type;
2381 };
2382}
2383template <typename Map, template <class...> class Sequence = brigand::list>
2384using values_as_sequence = transform<as_sequence<Map, Sequence>, detail::get_second<_1>>;
2385}
2386namespace brigand
2387{
2388namespace detail
2389{
2390 template <typename Pair>
2391 struct get_first {
2392 using type = typename Pair::first_type;
2393 };
2394}
2395template <typename Map, template <class...> class Sequence = brigand::set>
2396using keys_as_sequence = transform<as_sequence<Map, Sequence>, detail::get_first<_1>>;
2397}
2398namespace brigand
2399{
2400 struct empty_base {};
2401}
2402namespace brigand
2403{
2404 template<typename T, typename R = void > struct has_type
2405 {
2406 using type = R;
2407 };
2408}
2409namespace brigand
2410{
2411 template<typename... Ts> struct inherit;
2412 template<typename T> struct inherit<T>
2413 {
2414 struct type : public T {};
2415 };
2416 template<> struct inherit<>
2417 {
2418 using type = empty_base;
2419 };
2420 template<> struct inherit<empty_base>
2421 {
2422 using type = empty_base;
2423 };
2424 template<typename T1, typename T2> struct inherit<T1,T2>
2425 {
2426 struct type : public T1, T2 {};
2427 };
2428 template<typename T1> struct inherit<T1,empty_base>
2429 {
2430 using type = T1;
2431 };
2432 template<typename T2> struct inherit<empty_base,T2>
2433 {
2434 using type = T2;
2435 };
2436 template<> struct inherit<empty_base,empty_base>
2437 {
2438 using type = empty_base;
2439 };
2440 template<typename T1, typename T2, typename T3, typename... Ts>
2441 struct inherit<T1, T2, T3, Ts...>
2442 : inherit<T1, typename inherit<T2,typename inherit<T3, Ts...>::type>::type>
2443 {};
2444}
2445namespace brigand
2446{
2447 namespace lazy
2448 {
2449 template< typename Types
2450 , typename Node
2451 , typename Root = brigand::empty_base
2452 >
2453 struct inherit_linearly;
2454 template< typename Types
2455 , template<typename...> class Node, typename...Ts
2456 , typename Root
2457 >
2458 struct inherit_linearly<Types,Node<Ts...>,Root>
2459 {
2460 using type = brigand::fold<Types,Root,bind<Node,Ts...>>;
2461 };
2462 }
2463 template< typename Types
2464 , typename Node
2465 , typename Root = brigand::empty_base
2466 >
2467 using inherit_linearly = typename lazy::inherit_linearly<Types,Node,Root>::type;
2468}
2469
2470namespace brigand
2471{
2472 template<typename RealType, typename Type, Type Value>
2473 struct real_ : std::integral_constant<Type,Value>
2474 {
2475 using value_type = RealType;
2476 using parent = std::integral_constant<Type,Value>;
2477 inline operator value_type() const
2478 {
2479 value_type that;
2480 std::memcpy(&that, &parent::value, sizeof(value_type));
2481 return that;
2482 }
2483 };
2484 template<std::uint32_t Value>
2485 struct single_ : real_<float, std::uint32_t, Value> {};
2486 template<std::uint64_t Value>
2487 struct double_ : real_<double, std::uint64_t,Value> {};
2488}
2489