Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:52

0001 #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED
0002 #define BOOST_MP11_ALGORITHM_HPP_INCLUDED
0003 
0004 //  Copyright 2015-2019 Peter Dimov
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0.
0007 //
0008 //  See accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt
0010 
0011 #include <boost/mp11/list.hpp>
0012 #include <boost/mp11/set.hpp>
0013 #include <boost/mp11/integral.hpp>
0014 #include <boost/mp11/utility.hpp>
0015 #include <boost/mp11/function.hpp>
0016 #include <boost/mp11/detail/mp_count.hpp>
0017 #include <boost/mp11/detail/mp_plus.hpp>
0018 #include <boost/mp11/detail/mp_map_find.hpp>
0019 #include <boost/mp11/detail/mp_with_index.hpp>
0020 #include <boost/mp11/detail/mp_fold.hpp>
0021 #include <boost/mp11/detail/mp_min_element.hpp>
0022 #include <boost/mp11/detail/mp_copy_if.hpp>
0023 #include <boost/mp11/detail/mp_remove_if.hpp>
0024 #include <boost/mp11/detail/config.hpp>
0025 #include <boost/mp11/integer_sequence.hpp>
0026 #include <type_traits>
0027 #include <utility>
0028 
0029 namespace boost
0030 {
0031 namespace mp11
0032 {
0033 
0034 // mp_transform<F, L...>
0035 namespace detail
0036 {
0037 
0038 template<template<class...> class F, class... L> struct mp_transform_impl
0039 {
0040 };
0041 
0042 template<template<class...> class F, template<class...> class L, class... T> struct mp_transform_impl<F, L<T...>>
0043 {
0044 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0045 
0046     template<class... U> struct f { using type = F<U...>; };
0047 
0048     using type = L<typename f<T>::type...>;
0049 
0050 #else
0051 
0052     using type = L<F<T>...>;
0053 
0054 #endif
0055 };
0056 
0057 template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_transform_impl<F, L1<T1...>, L2<T2...>>
0058 {
0059 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0060 
0061     template<class... U> struct f { using type = F<U...>; };
0062 
0063     using type = L1<typename f<T1, T2>::type...>;
0064 
0065 #else
0066 
0067     using type = L1<F<T1,T2>...>;
0068 
0069 #endif
0070 };
0071 
0072 template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_transform_impl<F, L1<T1...>, L2<T2...>, L3<T3...>>
0073 {
0074 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0075 
0076     template<class... U> struct f { using type = F<U...>; };
0077 
0078     using type = L1<typename f<T1, T2, T3>::type...>;
0079 
0080 #else
0081 
0082     using type = L1<F<T1,T2,T3>...>;
0083 
0084 #endif
0085 };
0086 
0087 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
0088 
0089 template<class... L> using mp_same_size_1 = mp_same<mp_size<L>...>;
0090 template<class... L> struct mp_same_size_2: mp_defer<mp_same_size_1, L...> {};
0091 
0092 #endif
0093 
0094 struct list_size_mismatch
0095 {
0096 };
0097 
0098 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0099 
0100 template<template<class...> class F, class... L> struct mp_transform_cuda_workaround
0101 {
0102     using type = mp_if<mp_same<mp_size<L>...>, detail::mp_transform_impl<F, L...>, detail::list_size_mismatch>;
0103 };
0104 
0105 #endif
0106 
0107 } // namespace detail
0108 
0109 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
0110 
0111 template<template<class...> class F, class... L> using mp_transform = typename mp_if<typename detail::mp_same_size_2<L...>::type, detail::mp_transform_impl<F, L...>, detail::list_size_mismatch>::type;
0112 
0113 #else
0114 
0115 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0116 
0117 template<template<class...> class F, class... L> using mp_transform = typename detail::mp_transform_cuda_workaround< F, L...>::type::type;
0118 
0119 #else
0120 
0121 template<template<class...> class F, class... L> using mp_transform = typename mp_if<mp_same<mp_size<L>...>, detail::mp_transform_impl<F, L...>, detail::list_size_mismatch>::type;
0122 
0123 #endif
0124 
0125 #endif
0126 
0127 template<class Q, class... L> using mp_transform_q = mp_transform<Q::template fn, L...>;
0128 
0129 namespace detail
0130 {
0131 
0132 template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, class... L> struct mp_transform_impl<F, L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L...>
0133 {
0134     using A1 = L1<mp_list<T1, T2, T3, T4>...>;
0135 
0136     template<class V, class T> using _f = mp_transform<mp_push_back, V, T>;
0137 
0138     using A2 = mp_fold<mp_list<L...>, A1, _f>;
0139 
0140     template<class T> using _g = mp_apply<F, T>;
0141 
0142     using type = mp_transform<_g, A2>;
0143 };
0144 
0145 } // namespace detail
0146 
0147 // mp_transform_if<P, F, L...>
0148 namespace detail
0149 {
0150 
0151 template<template<class...> class P, template<class...> class F, class... L> struct mp_transform_if_impl
0152 {
0153     // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"
0154 
0155     using Qp = mp_quote<P>;
0156     using Qf = mp_quote<F>;
0157 
0158 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0159 
0160     template<class... U> struct _f_ { using type = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>; };
0161     template<class... U> using _f = typename _f_<U...>::type;
0162 
0163 #else
0164 
0165     template<class... U> using _f = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>;
0166 
0167 #endif
0168 
0169     using type = mp_transform<_f, L...>;
0170 };
0171 
0172 } // namespace detail
0173 
0174 template<template<class...> class P, template<class...> class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl<P, F, L...>::type;
0175 template<class Qp, class Qf, class... L> using mp_transform_if_q = typename detail::mp_transform_if_impl<Qp::template fn, Qf::template fn, L...>::type;
0176 
0177 // mp_filter<P, L...>
0178 namespace detail
0179 {
0180 
0181 template<template<class...> class P, class L1, class... L> struct mp_filter_impl
0182 {
0183     using Qp = mp_quote<P>;
0184 
0185     template<class T1, class... T> using _f = mp_if< mp_invoke_q<Qp, T1, T...>, mp_list<T1>, mp_list<> >;
0186 
0187     using _t1 = mp_transform<_f, L1, L...>;
0188     using _t2 = mp_apply<mp_append, _t1>;
0189 
0190     using type = mp_assign<L1, _t2>;
0191 };
0192 
0193 } // namespace detail
0194 
0195 template<template<class...> class P, class... L> using mp_filter = typename detail::mp_filter_impl<P, L...>::type;
0196 template<class Q, class... L> using mp_filter_q = typename detail::mp_filter_impl<Q::template fn, L...>::type;
0197 
0198 // mp_fill<L, V>
0199 namespace detail
0200 {
0201 
0202 template<class L, class V> struct mp_fill_impl
0203 {
0204 // An error "no type named 'type'" here means that the L argument of mp_fill is not a list
0205 };
0206 
0207 template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<T...>, V>
0208 {
0209 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 )
0210 
0211     template<class...> struct _f { using type = V; };
0212     using type = L<typename _f<T>::type...>;
0213 
0214 #else
0215 
0216     template<class...> using _f = V;
0217     using type = L<_f<T>...>;
0218 
0219 #endif
0220 };
0221 
0222 #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
0223 
0224 template<template<auto...> class L, auto... A, class V> struct mp_fill_impl<L<A...>, V>
0225 {
0226     using type = L<((void)A, V::value)...>;
0227 };
0228 
0229 #endif
0230 
0231 } // namespace detail
0232 
0233 template<class L, class V> using mp_fill = typename detail::mp_fill_impl<L, V>::type;
0234 
0235 // mp_contains<L, V>
0236 template<class L, class V> using mp_contains = mp_to_bool<mp_count<L, V>>;
0237 
0238 // mp_repeat(_c)<L, N>
0239 namespace detail
0240 {
0241 
0242 template<class L, std::size_t N> struct mp_repeat_c_impl
0243 {
0244     using _l1 = typename mp_repeat_c_impl<L, N/2>::type;
0245     using _l2 = typename mp_repeat_c_impl<L, N%2>::type;
0246 
0247     using type = mp_append<_l1, _l1, _l2>;
0248 };
0249 
0250 template<class L> struct mp_repeat_c_impl<L, 0>
0251 {
0252     using type = mp_clear<L>;
0253 };
0254 
0255 template<class L> struct mp_repeat_c_impl<L, 1>
0256 {
0257     using type = L;
0258 };
0259 
0260 } // namespace detail
0261 
0262 template<class L, std::size_t N> using mp_repeat_c = typename detail::mp_repeat_c_impl<L, N>::type;
0263 template<class L, class N> using mp_repeat = typename detail::mp_repeat_c_impl<L, std::size_t{ N::value }>::type;
0264 
0265 // mp_product<F, L...>
0266 namespace detail
0267 {
0268 
0269 template<template<class...> class F, class P, class... L> struct mp_product_impl_2
0270 {
0271 };
0272 
0273 template<template<class...> class F, class P> struct mp_product_impl_2<F, P>
0274 {
0275     using type = mp_list<mp_rename<P, F>>;
0276 };
0277 
0278 template<template<class...> class F, class P, template<class...> class L1, class... T1, class... L> struct mp_product_impl_2<F, P, L1<T1...>, L...>
0279 {
0280     using type = mp_append<typename mp_product_impl_2<F, mp_push_back<P, T1>, L...>::type...>;
0281 };
0282 
0283 template<template<class...> class F, class... L> struct mp_product_impl
0284 {
0285 };
0286 
0287 template<template<class...> class F> struct mp_product_impl<F>
0288 {
0289     using type = mp_list< F<> >;
0290 };
0291 
0292 template<template<class...> class F, class L1, class... L> struct mp_product_impl<F, L1, L...>
0293 {
0294     using type = mp_assign<L1, typename mp_product_impl_2<F, mp_list<>, L1, L...>::type>;
0295 };
0296 
0297 } // namespace detail
0298 
0299 template<template<class...> class F, class... L> using mp_product = typename detail::mp_product_impl<F, L...>::type;
0300 template<class Q, class... L> using mp_product_q = typename detail::mp_product_impl<Q::template fn, L...>::type;
0301 
0302 // mp_drop(_c)<L, N>
0303 namespace detail
0304 {
0305 
0306 template<class L, class L2, class En> struct mp_drop_impl;
0307 
0308 template<template<class...> class L, class... T, template<class...> class L2, class... U> struct mp_drop_impl<L<T...>, L2<U...>, mp_true>
0309 {
0310     template<class... W> static mp_identity<L<W...>> f( U*..., mp_identity<W>*... );
0311 
0312     using R = decltype( f( static_cast<mp_identity<T>*>(0) ... ) );
0313 
0314     using type = typename R::type;
0315 };
0316 
0317 } // namespace detail
0318 
0319 template<class L, std::size_t N> using mp_drop_c = mp_assign<L, typename detail::mp_drop_impl<mp_rename<L, mp_list>, mp_repeat_c<mp_list<void>, N>, mp_bool<N <= mp_size<L>::value>>::type>;
0320 
0321 template<class L, class N> using mp_drop = mp_drop_c<L, std::size_t{ N::value }>;
0322 
0323 // mp_from_sequence<S, F>
0324 namespace detail
0325 {
0326 
0327 template<class S, class F> struct mp_from_sequence_impl;
0328 
0329 template<template<class T, T... I> class S, class U, U... J, class F> struct mp_from_sequence_impl<S<U, J...>, F>
0330 {
0331     using type = mp_list_c<U, (F::value + J)...>;
0332 };
0333 
0334 } // namespace detail
0335 
0336 template<class S, class F = mp_int<0>> using mp_from_sequence = typename detail::mp_from_sequence_impl<S, F>::type;
0337 
0338 // mp_iota(_c)<N, F>
0339 template<std::size_t N, std::size_t F = 0> using mp_iota_c = mp_from_sequence<make_index_sequence<N>, mp_size_t<F>>;
0340 template<class N, class F = mp_int<0>> using mp_iota = mp_from_sequence<make_integer_sequence<typename std::remove_const<decltype(N::value)>::type, N::value>, F>;
0341 
0342 // mp_at(_c)<L, I>
0343 namespace detail
0344 {
0345 
0346 template<class L, std::size_t I> struct mp_at_c_impl;
0347 
0348 #if defined(BOOST_MP11_HAS_TYPE_PACK_ELEMENT)
0349 
0350 template<template<class...> class L, class... T, std::size_t I> struct mp_at_c_impl<L<T...>, I>
0351 {
0352     using type = __type_pack_element<I, T...>;
0353 };
0354 
0355 #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
0356 
0357 template<template<auto...> class L, auto... A, std::size_t I> struct mp_at_c_impl<L<A...>, I>
0358 {
0359     using type = __type_pack_element<I, mp_value<A>...>;
0360 };
0361 
0362 #endif
0363 
0364 #else
0365 
0366 template<class L, std::size_t I> struct mp_at_c_impl
0367 {
0368     using _map = mp_transform<mp_list, mp_iota<mp_size<L> >, mp_rename<L, mp_list>>;
0369     using type = mp_second<mp_map_find<_map, mp_size_t<I> > >;
0370 };
0371 
0372 #endif
0373 
0374 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0375 
0376 template<class L, std::size_t I> struct mp_at_c_cuda_workaround
0377 {
0378     using type = mp_if_c<(I < mp_size<L>::value), detail::mp_at_c_impl<L, I>, void>;
0379 };
0380 
0381 #endif
0382 
0383 } // namespace detail
0384 
0385 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0386 
0387 template<class L, std::size_t I> using mp_at_c = typename detail::mp_at_c_cuda_workaround< L, I >::type::type;
0388 
0389 #else
0390 
0391 template<class L, std::size_t I> using mp_at_c = typename mp_if_c<(I < mp_size<L>::value), detail::mp_at_c_impl<L, I>, void>::type;
0392 
0393 #endif
0394 
0395 template<class L, class I> using mp_at = mp_at_c<L, std::size_t{ I::value }>;
0396 
0397 // mp_take(_c)<L, N>
0398 namespace detail
0399 {
0400 
0401 template<std::size_t N, class L, class E = void> struct mp_take_c_impl
0402 {
0403 };
0404 
0405 template<template<class...> class L, class... T>
0406 struct mp_take_c_impl<0, L<T...>>
0407 {
0408     using type = L<>;
0409 };
0410 
0411 template<template<class...> class L, class T1, class... T>
0412 struct mp_take_c_impl<1, L<T1, T...>>
0413 {
0414     using type = L<T1>;
0415 };
0416 
0417 template<template<class...> class L, class T1, class T2, class... T>
0418 struct mp_take_c_impl<2, L<T1, T2, T...>>
0419 {
0420     using type = L<T1, T2>;
0421 };
0422 
0423 template<template<class...> class L, class T1, class T2, class T3, class... T>
0424 struct mp_take_c_impl<3, L<T1, T2, T3, T...>>
0425 {
0426     using type = L<T1, T2, T3>;
0427 };
0428 
0429 template<template<class...> class L, class T1, class T2, class T3, class T4, class... T>
0430 struct mp_take_c_impl<4, L<T1, T2, T3, T4, T...>>
0431 {
0432     using type = L<T1, T2, T3, T4>;
0433 };
0434 
0435 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class... T>
0436 struct mp_take_c_impl<5, L<T1, T2, T3, T4, T5, T...>>
0437 {
0438     using type = L<T1, T2, T3, T4, T5>;
0439 };
0440 
0441 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T>
0442 struct mp_take_c_impl<6, L<T1, T2, T3, T4, T5, T6, T...>>
0443 {
0444     using type = L<T1, T2, T3, T4, T5, T6>;
0445 };
0446 
0447 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T>
0448 struct mp_take_c_impl<7, L<T1, T2, T3, T4, T5, T6, T7, T...>>
0449 {
0450     using type = L<T1, T2, T3, T4, T5, T6, T7>;
0451 };
0452 
0453 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... T>
0454 struct mp_take_c_impl<8, L<T1, T2, T3, T4, T5, T6, T7, T8, T...>>
0455 {
0456     using type = L<T1, T2, T3, T4, T5, T6, T7, T8>;
0457 };
0458 
0459 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class... T>
0460 struct mp_take_c_impl<9, L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T...>>
0461 {
0462     using type = L<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
0463 };
0464 
0465 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, std::size_t N>
0466 struct mp_take_c_impl<N, L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, typename std::enable_if<N >= 10>::type>
0467 {
0468     using type = mp_append<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, typename mp_take_c_impl<N-10, L<T...>>::type>;
0469 };
0470 
0471 } // namespace detail
0472 
0473 template<class L, std::size_t N> using mp_take_c = mp_assign<L, typename detail::mp_take_c_impl<N, mp_rename<L, mp_list>>::type>;
0474 template<class L, class N> using mp_take = mp_take_c<L, std::size_t{ N::value }>;
0475 
0476 // mp_back<L>
0477 template<class L> using mp_back = mp_at_c<L, mp_size<L>::value - 1>;
0478 
0479 // mp_pop_back<L>
0480 template<class L> using mp_pop_back = mp_take_c<L, mp_size<L>::value - 1>;
0481 
0482 // mp_replace<L, V, W>
0483 namespace detail
0484 {
0485 
0486 template<class L, class V, class W> struct mp_replace_impl;
0487 
0488 template<template<class...> class L, class... T, class V, class W> struct mp_replace_impl<L<T...>, V, W>
0489 {
0490 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0491     template<class A> struct _f { using type = mp_if<std::is_same<A, V>, W, A>; };
0492     using type = L<typename _f<T>::type...>;
0493 #else
0494     template<class A> using _f = mp_if<std::is_same<A, V>, W, A>;
0495     using type = L<_f<T>...>;
0496 #endif
0497 };
0498 
0499 } // namespace detail
0500 
0501 template<class L, class V, class W> using mp_replace = typename detail::mp_replace_impl<L, V, W>::type;
0502 
0503 // mp_replace_if<L, P, W>
0504 namespace detail
0505 {
0506 
0507 template<class L, template<class...> class P, class W> struct mp_replace_if_impl;
0508 
0509 template<template<class...> class L, class... T, template<class...> class P, class W> struct mp_replace_if_impl<L<T...>, P, W>
0510 {
0511 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0512     template<class U> struct _f { using type = mp_if<P<U>, W, U>; };
0513     using type = L<typename _f<T>::type...>;
0514 #else
0515     template<class U> using _f = mp_if<P<U>, W, U>;
0516     using type = L<_f<T>...>;
0517 #endif
0518 };
0519 
0520 } // namespace detail
0521 
0522 template<class L, template<class...> class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl<L, P, W>::type;
0523 template<class L, class Q, class W> using mp_replace_if_q = mp_replace_if<L, Q::template fn, W>;
0524 
0525 // mp_copy_if<L, P>
0526 //   in detail/mp_copy_if.hpp
0527 
0528 // mp_remove<L, V>
0529 namespace detail
0530 {
0531 
0532 template<class L, class V> struct mp_remove_impl;
0533 
0534 template<template<class...> class L, class... T, class V> struct mp_remove_impl<L<T...>, V>
0535 {
0536 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0537     template<class U> struct _f { using type = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>; };
0538     using type = mp_append<L<>, typename _f<T>::type...>;
0539 #else
0540     template<class U> using _f = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>;
0541     using type = mp_append<L<>, _f<T>...>;
0542 #endif
0543 };
0544 
0545 } // namespace detail
0546 
0547 template<class L, class V> using mp_remove = typename detail::mp_remove_impl<L, V>::type;
0548 
0549 // mp_remove_if<L, P>
0550 //   in detail/mp_remove_if.hpp
0551 
0552 // mp_flatten<L, L2 = mp_clear<L>>
0553 namespace detail
0554 {
0555 
0556 template<class L2> struct mp_flatten_impl
0557 {
0558     template<class T> using fn = mp_if<mp_similar<L2, T>, T, mp_list<T>>;
0559 };
0560 
0561 } // namespace detail
0562 
0563 template<class L, class L2 = mp_clear<L>> using mp_flatten = mp_apply<mp_append, mp_push_front<mp_transform_q<detail::mp_flatten_impl<L2>, L>, mp_clear<L>>>;
0564 
0565 // mp_partition<L, P>
0566 namespace detail
0567 {
0568 
0569 template<class L, template<class...> class P> struct mp_partition_impl;
0570 
0571 template<template<class...> class L, class... T, template<class...> class P> struct mp_partition_impl<L<T...>, P>
0572 {
0573     using type = L<mp_copy_if<L<T...>, P>, mp_remove_if<L<T...>, P>>;
0574 };
0575 
0576 } // namespace detail
0577 
0578 template<class L, template<class...> class P> using mp_partition = typename detail::mp_partition_impl<L, P>::type;
0579 template<class L, class Q> using mp_partition_q = mp_partition<L, Q::template fn>;
0580 
0581 // mp_sort<L, P>
0582 namespace detail
0583 {
0584 
0585 template<class L, template<class...> class P> struct mp_sort_impl;
0586 
0587 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0588 
0589 template<template<class...> class L, class... T, template<class...> class P> struct mp_sort_impl<L<T...>, P>
0590 {
0591     static_assert( sizeof...(T) == 0, "T... must be empty" );
0592     using type = L<>;
0593 };
0594 
0595 #else
0596 
0597 template<template<class...> class L, template<class...> class P> struct mp_sort_impl<L<>, P>
0598 {
0599     using type = L<>;
0600 };
0601 
0602 #endif
0603 
0604 template<template<class...> class L, class T1, template<class...> class P> struct mp_sort_impl<L<T1>, P>
0605 {
0606     using type = L<T1>;
0607 };
0608 
0609 template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_sort_impl<L<T1, T...>, P>
0610 {
0611     template<class U> using F = P<U, T1>;
0612 
0613     using part = mp_partition<L<T...>, F>;
0614 
0615     using S1 = typename mp_sort_impl<mp_first<part>, P>::type;
0616     using S2 = typename mp_sort_impl<mp_second<part>, P>::type;
0617 
0618     using type = mp_append<mp_push_back<S1, T1>, S2>;
0619 };
0620 
0621 } // namespace detail
0622 
0623 template<class L, template<class...> class P> using mp_sort = typename detail::mp_sort_impl<L, P>::type;
0624 template<class L, class Q> using mp_sort_q = mp_sort<L, Q::template fn>;
0625 
0626 // mp_nth_element(_c)<L, I, P>
0627 namespace detail
0628 {
0629 
0630 template<class L, std::size_t I, template<class...> class P> struct mp_nth_element_impl;
0631 
0632 template<template<class...> class L, class T1, std::size_t I, template<class...> class P> struct mp_nth_element_impl<L<T1>, I, P>
0633 {
0634     static_assert( I == 0, "mp_nth_element index out of range" );
0635     using type = T1;
0636 };
0637 
0638 template<template<class...> class L, class T1, class... T, std::size_t I, template<class...> class P> struct mp_nth_element_impl<L<T1, T...>, I, P>
0639 {
0640     static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" );
0641 
0642     template<class U> using F = P<U, T1>;
0643 
0644     using part = mp_partition<L<T...>, F>;
0645 
0646     using L1 = mp_first<part>;
0647     static std::size_t const N1 = mp_size<L1>::value;
0648 
0649     using L2 = mp_second<part>;
0650 
0651 #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
0652 
0653     struct detail
0654     {
0655         struct mp_nth_element_impl_cuda_workaround
0656         {
0657             using type = mp_cond<
0658 
0659                 mp_bool<(I < N1)>, mp_nth_element_impl<L1, I, P>,
0660                 mp_bool<(I == N1)>, mp_identity<T1>,
0661                 mp_true, mp_nth_element_impl<L2, I - N1 - 1, P>
0662 
0663             >;
0664         };
0665     };
0666 
0667     using type = typename detail::mp_nth_element_impl_cuda_workaround::type::type;
0668 
0669 #else
0670 
0671     using type = typename mp_cond<
0672 
0673         mp_bool<(I < N1)>, mp_nth_element_impl<L1, I, P>,
0674         mp_bool<(I == N1)>, mp_identity<T1>,
0675         mp_true, mp_nth_element_impl<L2, I - N1 - 1, P>
0676 
0677     >::type;
0678 
0679 #endif
0680 };
0681 
0682 } // namespace detail
0683 
0684 template<class L, std::size_t I, template<class...> class P> using mp_nth_element_c = typename detail::mp_nth_element_impl<L, I, P>::type;
0685 template<class L, class I, template<class...> class P> using mp_nth_element = typename detail::mp_nth_element_impl<L, std::size_t{ I::value }, P>::type;
0686 template<class L, class I, class Q> using mp_nth_element_q = mp_nth_element<L, I, Q::template fn>;
0687 
0688 // mp_find<L, V>
0689 namespace detail
0690 {
0691 
0692 template<class L, class V> struct mp_find_impl;
0693 
0694 #if BOOST_MP11_CLANG && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
0695 
0696 struct mp_index_holder
0697 {
0698     std::size_t i_;
0699     bool f_;
0700 };
0701 
0702 constexpr inline mp_index_holder operator+( mp_index_holder const & v, bool f )
0703 {
0704     if( v.f_ )
0705     {
0706         return v;
0707     }
0708     else if( f )
0709     {
0710         return { v.i_, true };
0711     }
0712     else
0713     {
0714         return { v.i_ + 1, false };
0715     }
0716 }
0717 
0718 template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
0719 {
0720     static constexpr mp_index_holder _v{ 0, false };
0721     using type = mp_size_t< (_v + ... + std::is_same<T, V>::value).i_ >;
0722 };
0723 
0724 #elif !defined( BOOST_MP11_NO_CONSTEXPR )
0725 
0726 template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
0727 {
0728     using type = mp_size_t<0>;
0729 };
0730 
0731 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
0732 
0733 constexpr std::size_t cx_find_index( bool const * first, bool const * last )
0734 {
0735     std::size_t m = 0;
0736 
0737     while( first != last && !*first )
0738     {
0739         ++m;
0740         ++first;
0741     }
0742 
0743     return m;
0744 }
0745 
0746 #else
0747 
0748 constexpr std::size_t cx_find_index( bool const * first, bool const * last )
0749 {
0750     return first == last || *first? 0: 1 + cx_find_index( first + 1, last );
0751 }
0752 
0753 #endif
0754 
0755 template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
0756 {
0757     static constexpr bool _v[] = { std::is_same<T, V>::value... };
0758     using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
0759 };
0760 
0761 #else
0762 
0763 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0764 
0765 template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
0766 {
0767     static_assert( sizeof...(T) == 0, "T... must be empty" );
0768     using type = mp_size_t<0>;
0769 };
0770 
0771 #else
0772 
0773 template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
0774 {
0775     using type = mp_size_t<0>;
0776 };
0777 
0778 #endif
0779 
0780 template<template<class...> class L, class... T, class V> struct mp_find_impl<L<V, T...>, V>
0781 {
0782     using type = mp_size_t<0>;
0783 };
0784 
0785 template<template<class...> class L, class T1, class... T, class V> struct mp_find_impl<L<T1, T...>, V>
0786 {
0787     using _r = typename mp_find_impl<mp_list<T...>, V>::type;
0788     using type = mp_size_t<1 + _r::value>;
0789 };
0790 
0791 #endif
0792 
0793 } // namespace detail
0794 
0795 template<class L, class V> using mp_find = typename detail::mp_find_impl<L, V>::type;
0796 
0797 // mp_find_if<L, P>
0798 namespace detail
0799 {
0800 
0801 template<class L, template<class...> class P> struct mp_find_if_impl;
0802 
0803 #if BOOST_MP11_CLANG && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
0804 
0805 template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
0806 {
0807     static constexpr mp_index_holder _v{ 0, false };
0808     using type = mp_size_t< (_v + ... + P<T>::value).i_ >;
0809 };
0810 
0811 #elif !defined( BOOST_MP11_NO_CONSTEXPR )
0812 
0813 template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
0814 {
0815     using type = mp_size_t<0>;
0816 };
0817 
0818 template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
0819 {
0820     static constexpr bool _v[] = { P<T>::value... };
0821     using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
0822 };
0823 
0824 #else
0825 
0826 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0827 
0828 template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
0829 {
0830     static_assert( sizeof...(T) == 0, "T... must be empty" );
0831     using type = mp_size_t<0>;
0832 };
0833 
0834 #else
0835 
0836 template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
0837 {
0838     using type = mp_size_t<0>;
0839 };
0840 
0841 #endif
0842 
0843 template<class L, template<class...> class P> struct mp_find_if_impl_2
0844 {
0845     using _r = typename mp_find_if_impl<L, P>::type;
0846     using type = mp_size_t<1 + _r::value>;
0847 };
0848 
0849 template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_find_if_impl<L<T1, T...>, P>
0850 {
0851     using type = typename mp_if<P<T1>, mp_identity<mp_size_t<0>>, mp_find_if_impl_2<mp_list<T...>, P>>::type;
0852 };
0853 
0854 #endif
0855 
0856 } // namespace detail
0857 
0858 template<class L, template<class...> class P> using mp_find_if = typename detail::mp_find_if_impl<L, P>::type;
0859 template<class L, class Q> using mp_find_if_q = mp_find_if<L, Q::template fn>;
0860 
0861 // mp_reverse<L>
0862 namespace detail
0863 {
0864 
0865 template<class L> struct mp_reverse_impl;
0866 
0867 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0868 
0869 template<template<class...> class L, class... T> struct mp_reverse_impl<L<T...>>
0870 {
0871     static_assert( sizeof...(T) == 0, "T... must be empty" );
0872     using type = L<>;
0873 };
0874 
0875 #else
0876 
0877 template<template<class...> class L> struct mp_reverse_impl<L<>>
0878 {
0879     using type = L<>;
0880 };
0881 
0882 #endif
0883 
0884 template<template<class...> class L, class T1> struct mp_reverse_impl<L<T1>>
0885 {
0886     using type = L<T1>;
0887 };
0888 
0889 template<template<class...> class L, class T1, class T2> struct mp_reverse_impl<L<T1, T2>>
0890 {
0891     using type = L<T2, T1>;
0892 };
0893 
0894 template<template<class...> class L, class T1, class T2, class T3> struct mp_reverse_impl<L<T1, T2, T3>>
0895 {
0896     using type = L<T3, T2, T1>;
0897 };
0898 
0899 template<template<class...> class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl<L<T1, T2, T3, T4>>
0900 {
0901     using type = L<T4, T3, T2, T1>;
0902 };
0903 
0904 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5> struct mp_reverse_impl<L<T1, T2, T3, T4, T5>>
0905 {
0906     using type = L<T5, T4, T3, T2, T1>;
0907 };
0908 
0909 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6>>
0910 {
0911     using type = L<T6, T5, T4, T3, T2, T1>;
0912 };
0913 
0914 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6, T7>>
0915 {
0916     using type = L<T7, T6, T5, T4, T3, T2, T1>;
0917 };
0918 
0919 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6, T7, T8>>
0920 {
0921     using type = L<T8, T7, T6, T5, T4, T3, T2, T1>;
0922 };
0923 
0924 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9>>
0925 {
0926     using type = L<T9, T8, T7, T6, T5, T4, T3, T2, T1>;
0927 };
0928 
0929 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>>
0930 {
0931     using type = mp_push_back<typename mp_reverse_impl<L<T...>>::type, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1>;
0932 };
0933 
0934 } // namespace detail
0935 
0936 template<class L> using mp_reverse = typename detail::mp_reverse_impl<L>::type;
0937 
0938 // mp_fold<L, V, F>
0939 //   in detail/mp_fold.hpp
0940 
0941 // mp_reverse_fold<L, V, F>
0942 namespace detail
0943 {
0944 
0945 template<class L, class V, template<class...> class F> struct mp_reverse_fold_impl;
0946 
0947 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
0948 
0949 template<template<class...> class L, class... T, class V, template<class...> class F> struct mp_reverse_fold_impl<L<T...>, V, F>
0950 {
0951     static_assert( sizeof...(T) == 0, "T... must be empty" );
0952     using type = V;
0953 };
0954 
0955 #else
0956 
0957 template<template<class...> class L, class V, template<class...> class F> struct mp_reverse_fold_impl<L<>, V, F>
0958 {
0959     using type = V;
0960 };
0961 
0962 #endif
0963 
0964 template<template<class...> class L, class T1, class... T, class V, template<class...> class F> struct mp_reverse_fold_impl<L<T1, T...>, V, F>
0965 {
0966     using rest = typename mp_reverse_fold_impl<L<T...>, V, F>::type;
0967     using type = F<T1, rest>;
0968 };
0969 
0970 template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template<class...> class F> struct mp_reverse_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
0971 {
0972     using rest = typename mp_reverse_fold_impl<L<T...>, V, F>::type;
0973     using type = F<T1, F<T2, F<T3, F<T4, F<T5, F<T6, F<T7, F<T8, F<T9, F<T10, rest> > > > > > > > > >;
0974 };
0975 
0976 } // namespace detail
0977 
0978 template<class L, class V, template<class...> class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl<L, V, F>::type;
0979 template<class L, class V, class Q> using mp_reverse_fold_q = mp_reverse_fold<L, V, Q::template fn>;
0980 
0981 // mp_unique<L>
0982 namespace detail
0983 {
0984 
0985 template<class L> struct mp_unique_impl;
0986 
0987 template<template<class...> class L, class... T> struct mp_unique_impl<L<T...>>
0988 {
0989     using type = mp_set_push_back<L<>, T...>;
0990 };
0991 
0992 } // namespace detail
0993 
0994 template<class L> using mp_unique = typename detail::mp_unique_impl<L>::type;
0995 
0996 // mp_unique_if<L, P>
0997 namespace detail
0998 {
0999 
1000 template<template<class...> class P> struct mp_unique_if_push_back
1001 {
1002     template<class...> struct impl
1003     {
1004     };
1005 
1006     template<template<class...> class L, class... Ts, class T>
1007     struct impl<L<Ts...>, T>
1008     {
1009         using type = mp_if<mp_any<P<Ts, T>...>, L<Ts...>, L<Ts..., T>>;
1010     };
1011 
1012     template<class... T> using fn = typename impl<T...>::type;
1013 };
1014 
1015 } // namespace detail
1016 
1017 template<class L, template<class...> class P>
1018 using mp_unique_if = mp_fold_q<L, mp_clear<L>, detail::mp_unique_if_push_back<P>>;
1019 
1020 template<class L, class Q> using mp_unique_if_q = mp_unique_if<L, Q::template fn>;
1021 
1022 // mp_all_of<L, P>
1023 template<class L, template<class...> class P> using mp_all_of = mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;
1024 template<class L, class Q> using mp_all_of_q = mp_all_of<L, Q::template fn>;
1025 
1026 // mp_none_of<L, P>
1027 template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_count_if<L, P>::value == 0 >;
1028 template<class L, class Q> using mp_none_of_q = mp_none_of<L, Q::template fn>;
1029 
1030 // mp_any_of<L, P>
1031 template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;
1032 template<class L, class Q> using mp_any_of_q = mp_any_of<L, Q::template fn>;
1033 
1034 // mp_replace_at_c<L, I, W>
1035 namespace detail
1036 {
1037 
1038 template<class L, class I, class W> struct mp_replace_at_impl
1039 {
1040     static_assert( I::value >= 0, "mp_replace_at<L, I, W>: I must not be negative" );
1041 
1042     template<class T1, class T2> using _p = std::is_same<T2, mp_size_t<I::value>>;
1043     template<class T1, class T2> using _f = W;
1044 
1045     using type = mp_transform_if<_p, _f, L, mp_iota<mp_size<L> > >;
1046 };
1047 
1048 } // namespace detail
1049 
1050 template<class L, class I, class W> using mp_replace_at = typename detail::mp_replace_at_impl<L, I, W>::type;
1051 template<class L, std::size_t I, class W> using mp_replace_at_c = typename detail::mp_replace_at_impl<L, mp_size_t<I>, W>::type;
1052 
1053 //mp_for_each<L>(f)
1054 namespace detail
1055 {
1056 
1057 template<class... T, class F> BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list<T...>, F && f )
1058 {
1059     using A = int[sizeof...(T)];
1060     return (void)A{ ((void)f(T()), 0)... }, std::forward<F>(f);
1061 }
1062 
1063 template<class F> BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f )
1064 {
1065     return std::forward<F>(f);
1066 }
1067 
1068 } // namespace detail
1069 
1070 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, >= 1900 )
1071 
1072 // msvc has a limit of 1024
1073 
1074 template<class L, class F> BOOST_MP11_CONSTEXPR mp_if_c<mp_size<L>::value <= 1024, F> mp_for_each( F && f )
1075 {
1076     return detail::mp_for_each_impl( mp_rename<L, mp_list>(), std::forward<F>(f) );
1077 }
1078 
1079 template<class L, class F> BOOST_MP11_CONSTEXPR mp_if_c<mp_size<L>::value >= 1025, F> mp_for_each( F && f )
1080 {
1081     using L2 = mp_rename<L, mp_list>;
1082 
1083     using L3 = mp_take_c<L2, 1024>;
1084     using L4 = mp_drop_c<L2, 1024>;
1085 
1086     return mp_for_each<L4>( mp_for_each<L3>( std::forward<F>(f) ) );
1087 }
1088 
1089 #else
1090 
1091 template<class L, class F> BOOST_MP11_CONSTEXPR F mp_for_each( F && f )
1092 {
1093     return detail::mp_for_each_impl( mp_rename<L, mp_list>(), std::forward<F>(f) );
1094 }
1095 
1096 #endif
1097 
1098 // mp_insert<L, I, T...>
1099 template<class L, class I, class... T> using mp_insert = mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;
1100 
1101 // mp_insert_c<L, I, T...>
1102 template<class L, std::size_t I, class... T> using mp_insert_c = mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>;
1103 
1104 // mp_erase<L, I, J>
1105 template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>;
1106 
1107 // mp_erase_c<L, I, J>
1108 template<class L, std::size_t I, std::size_t J> using mp_erase_c = mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>;
1109 
1110 // mp_starts_with<L1, L2>
1111 // contributed by Glen Joseph Fernandes (glenjofe@gmail.com)
1112 namespace detail {
1113 
1114 template<class L1, class L2>
1115 struct mp_starts_with_impl { };
1116 
1117 template<template<class...> class L1, class... T1, template<class...> class L2,
1118     class... T2>
1119 struct mp_starts_with_impl<L1<T1...>, L2<T2...> > {
1120     template<class L>
1121     static mp_false check(L);
1122 
1123     template<class... T>
1124     static mp_true check(mp_list<T2..., T...>);
1125 
1126     using type = decltype(check(mp_list<T1...>()));
1127 };
1128 
1129 } // namespace detail
1130 
1131 template<class L1, class L2>
1132 using mp_starts_with = typename detail::mp_starts_with_impl<L1, L2>::type;
1133 
1134 // mp_rotate_left(_c)<L, N>
1135 namespace detail
1136 {
1137 
1138 // limit divisor to 1 to avoid division by 0 and give a rotation of 0 for lists containing 0 or 1 elements
1139 template<std::size_t Ln, std::size_t N> using canonical_left_rotation = mp_size_t<N % (Ln == 0? 1: Ln)>;
1140 
1141 // perform right rotation as a left rotation by inverting the number of elements to rotate
1142 template<std::size_t Ln, std::size_t N> using canonical_right_rotation = mp_size_t<Ln - N % (Ln == 0? 1: Ln)>;
1143 
1144 // avoid errors when rotating fixed-sized lists by using mp_list for the transformation
1145 template<class L, class N, class L2 = mp_rename<L, mp_list>> using mp_rotate_impl = mp_assign<L, mp_append< mp_drop<L2, N>, mp_take<L2, N> >>;
1146 
1147 } // namespace detail
1148 
1149 template<class L, std::size_t N> using mp_rotate_left_c = detail::mp_rotate_impl<L, detail::canonical_left_rotation<mp_size<L>::value, N>>;
1150 template<class L, class N> using mp_rotate_left = mp_rotate_left_c<L, std::size_t{ N::value }>;
1151 
1152 // mp_rotate_right(_c)<L, N>
1153 template<class L, std::size_t N> using mp_rotate_right_c = mp_rotate_left<L, detail::canonical_right_rotation<mp_size<L>::value, N>>;
1154 template<class L, class N> using mp_rotate_right = mp_rotate_right_c<L, std::size_t{ N::value }>;
1155 
1156 // mp_min_element<L, P>
1157 // mp_max_element<L, P>
1158 //   in detail/mp_min_element.hpp
1159 
1160 // mp_power_set<L>
1161 namespace detail
1162 {
1163 
1164 template<class L> struct mp_power_set_impl;
1165 
1166 } // namespace detail
1167 
1168 template<class L> using mp_power_set = typename detail::mp_power_set_impl<L>::type;
1169 
1170 namespace detail
1171 {
1172 
1173 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
1174 
1175 template<template<class...> class L, class... T> struct mp_power_set_impl< L<T...> >
1176 {
1177     static_assert( sizeof...(T) == 0, "T... must be empty" );
1178     using type = L< L<> >;
1179 };
1180 
1181 #else
1182 
1183 template<template<class...> class L> struct mp_power_set_impl< L<> >
1184 {
1185     using type = L< L<> >;
1186 };
1187 
1188 #endif
1189 
1190 template<template<class...> class L, class T1, class... T> struct mp_power_set_impl< L<T1, T...> >
1191 {
1192     using S1 = mp_power_set< L<T...> >;
1193 
1194     template<class L2> using _f = mp_push_front<L2, T1>;
1195 
1196     using S2 = mp_transform<_f, S1>;
1197 
1198     using type = mp_append< S1, S2 >;
1199 };
1200 
1201 } // namespace detail
1202 
1203 // mp_partial_sum<L, V, F>
1204 namespace detail
1205 {
1206 
1207 template<template<class...> class F> struct mp_partial_sum_impl_f
1208 {
1209 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 )
1210 
1211     template<class V, class T> using fn = mp_list<F<mp_first<V>, T>, mp_push_back<mp_second<V>, F<mp_first<V>, T>> >;
1212 
1213 #else
1214 
1215     template<class V, class T, class N = F<mp_first<V>, T>> using fn = mp_list<N, mp_push_back<mp_second<V>, N>>;
1216 
1217 #endif
1218 };
1219 
1220 } // namespace detail
1221 
1222 template<class L, class V, template<class...> class F> using mp_partial_sum = mp_second<mp_fold_q<L, mp_list<V, mp_clear<L>>, detail::mp_partial_sum_impl_f<F>> >;
1223 template<class L, class V, class Q> using mp_partial_sum_q = mp_partial_sum<L, V, Q::template fn>;
1224 
1225 // mp_iterate<V, F, R>
1226 namespace detail
1227 {
1228 
1229 template<class V, template<class...> class F, template<class...> class R, class N> struct mp_iterate_impl;
1230 
1231 } // namespace detail
1232 
1233 template<class V, template<class...> class F, template<class...> class R> using mp_iterate = typename detail::mp_iterate_impl<V, F, R, mp_valid<R, V>>::type;
1234 
1235 namespace detail
1236 {
1237 
1238 template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_false>
1239 {
1240     template<class X> using _f = mp_list<F<X>>;
1241     using type = mp_eval_or<mp_list<>, _f, V>;
1242 };
1243 
1244 template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_true>
1245 {
1246     using type = mp_push_front<mp_iterate<R<V>, F, R>, F<V>>;
1247 };
1248 
1249 } // namespace detail
1250 
1251 template<class V, class Qf, class Qr> using mp_iterate_q = mp_iterate<V, Qf::template fn, Qr::template fn>;
1252 
1253 // mp_pairwise_fold<L, F>
1254 namespace detail
1255 {
1256 
1257 template<class L, class Q> using mp_pairwise_fold_impl = mp_transform_q<Q, mp_pop_back<L>, mp_pop_front<L>>;
1258 
1259 } // namespace detail
1260 
1261 template<class L, class Q> using mp_pairwise_fold_q = mp_eval_if<mp_empty<L>, mp_clear<L>, detail::mp_pairwise_fold_impl, L, Q>;
1262 template<class L, template<class...> class F> using mp_pairwise_fold = mp_pairwise_fold_q<L, mp_quote<F>>;
1263 
1264 // mp_intersperse<L, S>
1265 namespace detail
1266 {
1267 
1268 template<class L, class S> struct mp_intersperse_impl
1269 {
1270 };
1271 
1272 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
1273 
1274 template<template<class...> class L, class... T, class S> struct mp_intersperse_impl<L<T...>, S>
1275 {
1276     static_assert( sizeof...(T) == 0, "T... must be empty" );
1277     using type = L<>;
1278 };
1279 
1280 #else
1281 
1282 template<template<class...> class L, class S> struct mp_intersperse_impl<L<>, S>
1283 {
1284     using type = L<>;
1285 };
1286 
1287 #endif
1288 
1289 template<template<class...> class L, class T1, class... T, class S> struct mp_intersperse_impl<L<T1, T...>, S>
1290 {
1291     using type = mp_append<L<T1>, L<S, T>...>;
1292 };
1293 
1294 } // namespace detail
1295 
1296 template<class L, class S> using mp_intersperse = typename detail::mp_intersperse_impl<L, S>::type;
1297 
1298 // mp_split<L, S>
1299 namespace detail
1300 {
1301 
1302 template<class L, class S, class J> struct mp_split_impl;
1303 
1304 } // namespace detail
1305 
1306 template<class L, class S> using mp_split = typename detail::mp_split_impl<L, S, mp_find<L, S>>::type;
1307 
1308 namespace detail
1309 {
1310 
1311 template<class L, class S, class J> using mp_split_impl_ = mp_push_front<mp_split<mp_drop_c<L, J::value + 1>, S>, mp_take<L, J>>;
1312 
1313 template<class L, class S, class J> struct mp_split_impl
1314 {
1315     using type = mp_eval_if_c<mp_size<L>::value == J::value, mp_push_back<mp_clear<L>, L>, mp_split_impl_, L, S, J>;
1316 };
1317 
1318 } // namespace detail
1319 
1320 // mp_join<L, S>
1321 
1322 template<class L, class S> using mp_join = mp_apply<mp_append, mp_intersperse<L, mp_list<S>>>;
1323 
1324 } // namespace mp11
1325 } // namespace boost
1326 
1327 #endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED