update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -199,7 +199,10 @@ template<class Q, class... L> using mp_filter_q = typename detail::mp_filter_imp
namespace detail
{
template<class L, class V> struct mp_fill_impl;
template<class L, class V> struct mp_fill_impl
{
// An error "no type named 'type'" here means that the L argument of mp_fill is not a list
};
template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<T...>, V>
{
@@ -216,6 +219,15 @@ template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<
#endif
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A, class V> struct mp_fill_impl<L<A...>, V>
{
using type = L<((void)A, V::value)...>;
};
#endif
} // namespace detail
template<class L, class V> using mp_fill = typename detail::mp_fill_impl<L, V>::type;
@@ -254,7 +266,9 @@ template<class L, class N> using mp_repeat = typename detail::mp_repeat_c_impl<L
namespace detail
{
template<template<class...> class F, class P, class... L> struct mp_product_impl_2;
template<template<class...> class F, class P, class... L> struct mp_product_impl_2
{
};
template<template<class...> class F, class P> struct mp_product_impl_2<F, P>
{
@@ -266,7 +280,14 @@ template<template<class...> class F, class P, template<class...> class L1, class
using type = mp_append<typename mp_product_impl_2<F, mp_push_back<P, T1>, L...>::type...>;
};
template<template<class...> class F, class... L> struct mp_product_impl;
template<template<class...> class F, class... L> struct mp_product_impl
{
};
template<template<class...> class F> struct mp_product_impl<F>
{
using type = mp_list< F<> >;
};
template<template<class...> class F, class L1, class... L> struct mp_product_impl<F, L1, L...>
{
@@ -282,41 +303,41 @@ template<class Q, class... L> using mp_product_q = typename detail::mp_product_i
namespace detail
{
template<class L, class L2> struct mp_drop_impl;
template<class L, class L2, class En> struct mp_drop_impl;
template<template<class...> class L, class... T, template<class...> class L2, class... U> struct mp_drop_impl<L<T...>, L2<U...>>
template<template<class...> class L, class... T, template<class...> class L2, class... U> struct mp_drop_impl<L<T...>, L2<U...>, mp_true>
{
template<class... W> static mp_identity<L<W...>> f( U*..., mp_identity<W>*... );
using R = decltype( f( (mp_identity<T>*)0 ... ) );
using R = decltype( f( static_cast<mp_identity<T>*>(0) ... ) );
using type = typename R::type;
};
} // namespace detail
template<class L, std::size_t N> using mp_drop_c = typename detail::mp_drop_impl<L, mp_repeat_c<mp_list<void>, N>>::type;
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>;
template<class L, class N> using mp_drop = typename detail::mp_drop_impl<L, mp_repeat<mp_list<void>, N>>::type;
template<class L, class N> using mp_drop = mp_drop_c<L, std::size_t{ N::value }>;
// mp_from_sequence<S>
// mp_from_sequence<S, F>
namespace detail
{
template<class S> struct mp_from_sequence_impl;
template<class S, class F> struct mp_from_sequence_impl;
template<template<class T, T... I> class S, class U, U... J> struct mp_from_sequence_impl<S<U, J...>>
template<template<class T, T... I> class S, class U, U... J, class F> struct mp_from_sequence_impl<S<U, J...>, F>
{
using type = mp_list<std::integral_constant<U, J>...>;
using type = mp_list_c<U, (F::value + J)...>;
};
} // namespace detail
template<class S> using mp_from_sequence = typename detail::mp_from_sequence_impl<S>::type;
template<class S, class F = mp_int<0>> using mp_from_sequence = typename detail::mp_from_sequence_impl<S, F>::type;
// mp_iota(_c)<N>
template<std::size_t N> using mp_iota_c = mp_from_sequence<make_index_sequence<N>>;
template<class N> using mp_iota = mp_from_sequence<make_integer_sequence<typename std::remove_const<decltype(N::value)>::type, N::value>>;
// mp_iota(_c)<N, F>
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>>;
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>;
// mp_at(_c)<L, I>
namespace detail
@@ -331,11 +352,20 @@ template<template<class...> class L, class... T, std::size_t I> struct mp_at_c_i
using type = __type_pack_element<I, T...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A, std::size_t I> struct mp_at_c_impl<L<A...>, I>
{
using type = __type_pack_element<I, mp_value<A>...>;
};
#endif
#else
template<class L, std::size_t I> struct mp_at_c_impl
{
using _map = mp_transform<mp_list, mp_iota<mp_size<L> >, L>;
using _map = mp_transform<mp_list, mp_iota<mp_size<L> >, mp_rename<L, mp_list>>;
using type = mp_second<mp_map_find<_map, mp_size_t<I> > >;
};
@@ -405,31 +435,31 @@ struct mp_take_c_impl<4, L<T1, T2, T3, T4, T...>>
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class... T>
struct mp_take_c_impl<5, L<T1, T2, T3, T4, T5, T...>>
{
using type = L<T1, T2, T3, T4, T5>;
using type = L<T1, T2, T3, T4, T5>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T>
struct mp_take_c_impl<6, L<T1, T2, T3, T4, T5, T6, T...>>
{
using type = L<T1, T2, T3, T4, T5, T6>;
using type = L<T1, T2, T3, T4, T5, T6>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T>
struct mp_take_c_impl<7, L<T1, T2, T3, T4, T5, T6, T7, T...>>
{
using type = L<T1, T2, T3, T4, T5, T6, T7>;
using type = L<T1, T2, T3, T4, T5, T6, T7>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... T>
struct mp_take_c_impl<8, L<T1, T2, T3, T4, T5, T6, T7, T8, T...>>
{
using type = L<T1, T2, T3, T4, T5, T6, T7, T8>;
using type = L<T1, T2, T3, T4, T5, T6, T7, T8>;
};
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>
struct mp_take_c_impl<9, L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T...>>
{
using type = L<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
using type = L<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
};
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>
@@ -440,8 +470,8 @@ struct mp_take_c_impl<N, L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, typen
} // namespace detail
template<class L, std::size_t N> using mp_take_c = typename detail::mp_take_c_impl<N, L>::type;
template<class L, class N> using mp_take = typename detail::mp_take_c_impl<std::size_t{ N::value }, L>::type;
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>;
template<class L, class N> using mp_take = mp_take_c<L, std::size_t{ N::value }>;
// mp_back<L>
template<class L> using mp_back = mp_at_c<L, mp_size<L>::value - 1>;
@@ -519,6 +549,19 @@ template<class L, class V> using mp_remove = typename detail::mp_remove_impl<L,
// mp_remove_if<L, P>
// in detail/mp_remove_if.hpp
// mp_flatten<L, L2 = mp_clear<L>>
namespace detail
{
template<class L2> struct mp_flatten_impl
{
template<class T> using fn = mp_if<mp_similar<L2, T>, T, mp_list<T>>;
};
} // namespace detail
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>>>;
// mp_partition<L, P>
namespace detail
{
@@ -950,6 +993,32 @@ template<template<class...> class L, class... T> struct mp_unique_impl<L<T...>>
template<class L> using mp_unique = typename detail::mp_unique_impl<L>::type;
// mp_unique_if<L, P>
namespace detail
{
template<template<class...> class P> struct mp_unique_if_push_back
{
template<class...> struct impl
{
};
template<template<class...> class L, class... Ts, class T>
struct impl<L<Ts...>, T>
{
using type = mp_if<mp_any<P<Ts, T>...>, L<Ts...>, L<Ts..., T>>;
};
template<class... T> using fn = typename impl<T...>::type;
};
} // namespace detail
template<class L, template<class...> class P>
using mp_unique_if = mp_fold_q<L, mp_clear<L>, detail::mp_unique_if_push_back<P>>;
template<class L, class Q> using mp_unique_if_q = mp_unique_if<L, Q::template fn>;
// mp_all_of<L, P>
template<class L, template<class...> class P> using mp_all_of = mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;
template<class L, class Q> using mp_all_of_q = mp_all_of<L, Q::template fn>;
@@ -1062,10 +1131,196 @@ struct mp_starts_with_impl<L1<T1...>, L2<T2...> > {
template<class L1, class L2>
using mp_starts_with = typename detail::mp_starts_with_impl<L1, L2>::type;
// mp_rotate_left(_c)<L, N>
namespace detail
{
// limit divisor to 1 to avoid division by 0 and give a rotation of 0 for lists containing 0 or 1 elements
template<std::size_t Ln, std::size_t N> using canonical_left_rotation = mp_size_t<N % (Ln == 0? 1: Ln)>;
// perform right rotation as a left rotation by inverting the number of elements to rotate
template<std::size_t Ln, std::size_t N> using canonical_right_rotation = mp_size_t<Ln - N % (Ln == 0? 1: Ln)>;
// avoid errors when rotating fixed-sized lists by using mp_list for the transformation
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> >>;
} // namespace detail
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>>;
template<class L, class N> using mp_rotate_left = mp_rotate_left_c<L, std::size_t{ N::value }>;
// mp_rotate_right(_c)<L, N>
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>>;
template<class L, class N> using mp_rotate_right = mp_rotate_right_c<L, std::size_t{ N::value }>;
// mp_min_element<L, P>
// mp_max_element<L, P>
// in detail/mp_min_element.hpp
// mp_power_set<L>
namespace detail
{
template<class L> struct mp_power_set_impl;
} // namespace detail
template<class L> using mp_power_set = typename detail::mp_power_set_impl<L>::type;
namespace detail
{
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
template<template<class...> class L, class... T> struct mp_power_set_impl< L<T...> >
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = L< L<> >;
};
#else
template<template<class...> class L> struct mp_power_set_impl< L<> >
{
using type = L< L<> >;
};
#endif
template<template<class...> class L, class T1, class... T> struct mp_power_set_impl< L<T1, T...> >
{
using S1 = mp_power_set< L<T...> >;
template<class L2> using _f = mp_push_front<L2, T1>;
using S2 = mp_transform<_f, S1>;
using type = mp_append< S1, S2 >;
};
} // namespace detail
// mp_partial_sum<L, V, F>
namespace detail
{
template<template<class...> class F> struct mp_partial_sum_impl_f
{
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 )
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>> >;
#else
template<class V, class T, class N = F<mp_first<V>, T>> using fn = mp_list<N, mp_push_back<mp_second<V>, N>>;
#endif
};
} // namespace detail
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>> >;
template<class L, class V, class Q> using mp_partial_sum_q = mp_partial_sum<L, V, Q::template fn>;
// mp_iterate<V, F, R>
namespace detail
{
template<class V, template<class...> class F, template<class...> class R, class N> struct mp_iterate_impl;
} // namespace detail
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;
namespace detail
{
template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_false>
{
template<class X> using _f = mp_list<F<X>>;
using type = mp_eval_or<mp_list<>, _f, V>;
};
template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_true>
{
using type = mp_push_front<mp_iterate<R<V>, F, R>, F<V>>;
};
} // namespace detail
template<class V, class Qf, class Qr> using mp_iterate_q = mp_iterate<V, Qf::template fn, Qr::template fn>;
// mp_pairwise_fold<L, F>
namespace detail
{
template<class L, class Q> using mp_pairwise_fold_impl = mp_transform_q<Q, mp_pop_back<L>, mp_pop_front<L>>;
} // namespace detail
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>;
template<class L, template<class...> class F> using mp_pairwise_fold = mp_pairwise_fold_q<L, mp_quote<F>>;
// mp_intersperse<L, S>
namespace detail
{
template<class L, class S> struct mp_intersperse_impl
{
};
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
template<template<class...> class L, class... T, class S> struct mp_intersperse_impl<L<T...>, S>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = L<>;
};
#else
template<template<class...> class L, class S> struct mp_intersperse_impl<L<>, S>
{
using type = L<>;
};
#endif
template<template<class...> class L, class T1, class... T, class S> struct mp_intersperse_impl<L<T1, T...>, S>
{
using type = mp_append<L<T1>, L<S, T>...>;
};
} // namespace detail
template<class L, class S> using mp_intersperse = typename detail::mp_intersperse_impl<L, S>::type;
// mp_split<L, S>
namespace detail
{
template<class L, class S, class J> struct mp_split_impl;
} // namespace detail
template<class L, class S> using mp_split = typename detail::mp_split_impl<L, S, mp_find<L, S>>::type;
namespace detail
{
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>>;
template<class L, class S, class J> struct mp_split_impl
{
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>;
};
} // namespace detail
// mp_join<L, S>
template<class L, class S> using mp_join = mp_apply<mp_append, mp_intersperse<L, mp_list<S>>>;
} // namespace mp11
} // namespace boost

View File

@@ -47,7 +47,9 @@
# endif
#elif defined(__clang__)
#endif
#if defined(__clang__)
// Clang
@@ -121,27 +123,27 @@
# endif
#endif
// BOOST_MP11_HAS_TEMPLATE_AUTO
#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L
# define BOOST_MP11_HAS_TEMPLATE_AUTO
#endif
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
// mp_value<0> is bool, mp_value<-1L> is int, etc
# undef BOOST_MP11_HAS_TEMPLATE_AUTO
#endif
// BOOST_MP11_DEPRECATED(msg)
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 )
# define BOOST_MP11_DEPRECATED(msg)
#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 )
#elif defined(__GNUC__) || defined(__clang__)
# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif BOOST_MP11_CLANG
# if defined(__has_cpp_attribute)
// 3.8 warns about [[deprecated]] when in C++11 mode
// so we only use it on 3.9 and above, detected via [[fallthrough]]
// can't version check because Apple
# if __has_cpp_attribute(deprecated) && __has_cpp_attribute(fallthrough)
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
# else
# define BOOST_MP11_DEPRECATED(msg)
# endif
# else // defined(__has_cpp_attribute)
# define BOOST_MP11_DEPRECATED(msg)
# endif
#else
#elif defined(_MSC_VER) && _MSC_VER >= 1900
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
#else
# define BOOST_MP11_DEPRECATED(msg)
#endif
#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED

View File

@@ -8,7 +8,10 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/mp_count.hpp>
#include <boost/mp11/detail/mp_is_value_list.hpp>
#include <boost/mp11/detail/mp_list.hpp>
#include <boost/mp11/detail/mp_list_v.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/mp11/detail/config.hpp>
@@ -22,6 +25,8 @@ namespace mp11
namespace detail
{
// append_type_lists
template<class... L> struct mp_append_impl;
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
@@ -167,17 +172,148 @@ template<class... L> struct mp_append_impl: mp_append_impl_cuda_workaround<L...>
#else
template<class... L> struct mp_append_impl: mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >::template fn<L...>
template<class... L> struct mp_append_impl:
mp_cond<
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_inf_impl>,
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_111_impl>,
mp_true, mp_quote<append_11_impl>
>::template fn<L...>
{
};
#endif
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
#endif
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
struct append_type_lists
{
template<class... L> using fn = typename mp_append_impl<L...>::type;
};
// append_value_lists
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<class... L> struct append_value_impl;
template<class L1 = mp_list_v<>, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl
{
};
template<
template<auto...> class L1, auto... T1,
template<auto...> class L2, auto... T2,
template<auto...> class L3, auto... T3,
template<auto...> class L4, auto... T4,
template<auto...> class L5, auto... T5,
template<auto...> class L6, auto... T6,
template<auto...> class L7, auto... T7,
template<auto...> class L8, auto... T8,
template<auto...> class L9, auto... T9,
template<auto...> class L10, auto... T10,
template<auto...> class L11, auto... T11>
struct append_value_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
{
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
};
template<
class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>,
class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>,
class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>,
class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>,
class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>,
class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>,
class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>,
class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>,
class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>,
class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>,
class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<>
> struct append_value_111_impl
{
using type = typename append_value_11_impl<
typename append_value_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
typename append_value_11_impl<mp_list_v<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
typename append_value_11_impl<mp_list_v<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
typename append_value_11_impl<mp_list_v<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
typename append_value_11_impl<mp_list_v<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
typename append_value_11_impl<mp_list_v<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
typename append_value_11_impl<mp_list_v<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
typename append_value_11_impl<mp_list_v<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
typename append_value_11_impl<mp_list_v<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
typename append_value_11_impl<mp_list_v<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
typename append_value_11_impl<mp_list_v<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
>::type;
};
template<
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
class... Lr
> struct append_value_inf_impl
{
using prefix = typename append_value_111_impl<
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
>::type;
using type = typename append_value_impl<prefix, Lr...>::type;
};
template<class... L> struct append_value_impl:
mp_cond<
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_value_inf_impl>,
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_value_111_impl>,
mp_true, mp_quote<append_value_11_impl>
>::template fn<L...>
{
};
struct append_value_lists
{
template<class... L> using fn = typename append_value_impl<L...>::type;
};
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
} // namespace detail
template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<class... L> using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if<mp_list<L...>, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn<L...>;
#else
template<class... L> using mp_append = detail::append_type_lists::fn<L...>;
#endif
} // namespace mp11
} // namespace boost

View File

@@ -21,16 +21,7 @@ namespace mp11
namespace detail
{
template<class L, class V> struct mp_count_impl;
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
{
using type = mp_size_t<(std::is_same<T, V>::value + ... + 0)>;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
#if !defined( BOOST_MP11_NO_CONSTEXPR )
constexpr std::size_t cx_plus()
{
@@ -39,15 +30,42 @@ constexpr std::size_t cx_plus()
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
{
return t1 + cx_plus(t...);
return static_cast<std::size_t>(t1) + cx_plus(t...);
}
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
{
return t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10 + cx_plus(t...);
return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
}
#endif
template<class L, class V> struct mp_count_impl;
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
template<class V, class... T> constexpr std::size_t cx_count()
{
constexpr bool a[] = { false, std::is_same<T, V>::value... };
std::size_t r = 0;
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
{
r += a[ i ];
}
return r;
}
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
{
using type = mp_size_t<cx_count<V, T...>()>;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
{
using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
@@ -72,11 +90,25 @@ namespace detail
template<class L, template<class...> class P> struct mp_count_if_impl;
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
template<template<class...> class P, class... T> constexpr std::size_t cx_count_if()
{
constexpr bool a[] = { false, static_cast<bool>( P<T>::value )... };
std::size_t r = 0;
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
{
r += a[ i ];
}
return r;
}
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
{
using type = mp_size_t<(mp_to_bool<P<T>>::value + ... + 0)>;
using type = mp_size_t<cx_count_if<P, T...>()>;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )

View File

@@ -0,0 +1,119 @@
#ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
// Copyright 2015-2020, 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/integral.hpp>
#include <boost/mp11/detail/config.hpp>
namespace boost
{
namespace mp11
{
// mp_if, mp_if_c
namespace detail
{
template<bool C, class T, class... E> struct mp_if_c_impl
{
};
template<class T, class... E> struct mp_if_c_impl<true, T, E...>
{
using type = T;
};
template<class T, class E> struct mp_if_c_impl<false, T, E>
{
using type = E;
};
} // namespace detail
template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
// mp_valid
#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800
// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17
namespace detail
{
template<class...> using void_t = void;
template<class, template<class...> class F, class... T>
struct mp_valid_impl: mp_false {};
template<template<class...> class F, class... T>
struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
} // namespace detail
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
#else
// implementation by Bruno Dutra (by the name is_evaluable)
namespace detail
{
template<template<class...> class F, class... T> struct mp_valid_impl
{
template<template<class...> class G, class = G<T...>> static mp_true check(int);
template<template<class...> class> static mp_false check(...);
using type = decltype(check<F>(0));
};
} // namespace detail
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
#endif
template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
// mp_defer
namespace detail
{
template<template<class...> class F, class... T> struct mp_defer_impl
{
using type = F<T...>;
};
struct mp_no_type
{
};
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
{
using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
};
#endif
} // namespace detail
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
#else
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
#endif
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED

View File

@@ -9,6 +9,7 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/config.hpp>
#include <boost/mp11/detail/mp_defer.hpp>
namespace boost
{
@@ -41,12 +42,113 @@ template<template<class...> class L, class V, template<class...> class F> struct
#endif
template<template<class...> class L, class T1, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T1, T...>, V, F>
//
template<class V, template<class...> class F> struct mp_fold_Q1
{
using type = typename mp_fold_impl<L<T...>, F<V, T1>, F>::type;
template<class T1>
using fn = F<V, T1>;
};
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_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
template<class V, template<class...> class F> struct mp_fold_Q2
{
template<class T1, class T2>
using fn = F<F<V, T1>, T2>;
};
template<class V, template<class...> class F> struct mp_fold_Q3
{
template<class T1, class T2, class T3>
using fn = F<F<F<V, T1>, T2>, T3>;
};
template<class V, template<class...> class F> struct mp_fold_Q4
{
template<class T1, class T2, class T3, class T4>
using fn = F<F<F<F<V, T1>, T2>, T3>, T4>;
};
template<class V, template<class...> class F> struct mp_fold_Q5
{
template<class T1, class T2, class T3, class T4, class T5>
using fn = F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>;
};
template<class V, template<class...> class F> struct mp_fold_Q6
{
template<class T1, class T2, class T3, class T4, class T5, class T6>
using fn = F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>;
};
template<class V, template<class...> class F> struct mp_fold_Q7
{
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
using fn = F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>;
};
template<class V, template<class...> class F> struct mp_fold_Q8
{
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
using fn = F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>;
};
template<class V, template<class...> class F> struct mp_fold_Q9
{
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
using fn = F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
};
//
template<template<class...> class L, class T1, class V, template<class...> class F>
struct mp_fold_impl<L<T1>, V, F>: mp_defer<mp_fold_Q1<V, F>::template fn, T1>
{
};
template<template<class...> class L, class T1, class T2, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2>, V, F>: mp_defer<mp_fold_Q2<V, F>::template fn, T1, T2>
{
};
template<template<class...> class L, class T1, class T2, class T3, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3>, V, F>: mp_defer<mp_fold_Q3<V, F>::template fn, T1, T2, T3>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4>, V, F>: mp_defer<mp_fold_Q4<V, F>::template fn, T1, T2, T3, T4>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4, T5>, V, F>: mp_defer<mp_fold_Q5<V, F>::template fn, T1, T2, T3, T4, T5>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6>, V, F>: mp_defer<mp_fold_Q6<V, F>::template fn, T1, T2, T3, T4, T5, T6>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7>, V, F>: mp_defer<mp_fold_Q7<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8>, V, F>: mp_defer<mp_fold_Q8<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8>
{
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class V, template<class...> class F>
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9>, V, F>: mp_defer<mp_fold_Q9<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8, T9>
{
};
//
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_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
{
using type = typename mp_fold_impl<L<T...>, F<F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type;
};

View File

@@ -0,0 +1,50 @@
#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
// Copyright 2015-2023 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/mp_value.hpp>
#include <boost/mp11/detail/config.hpp>
namespace boost
{
namespace mp11
{
// mp_front<L>
namespace detail
{
template<class L> struct mp_front_impl
{
// An error "no type named 'type'" here means that the argument to mp_front
// is either not a list, or is an empty list
};
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
{
using type = T1;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto... A> struct mp_front_impl<L<A1, A...>>
{
using type = mp_value<A1>;
};
#endif
} // namespace detail
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED

View File

@@ -0,0 +1,41 @@
#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/integral.hpp>
#include <boost/mp11/detail/config.hpp>
namespace boost
{
namespace mp11
{
// mp_is_value_list<L>
namespace detail
{
template<class L> struct mp_is_value_list_impl
{
using type = mp_false;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A> struct mp_is_value_list_impl<L<A...>>
{
using type = mp_true;
};
#endif
} // namespace detail
template<class L> using mp_is_value_list = typename detail::mp_is_value_list_impl<L>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED

View File

@@ -0,0 +1,27 @@
#ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/config.hpp>
namespace boost
{
namespace mp11
{
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
// mp_list_v<A...>
template<auto... A> struct mp_list_v
{
};
#endif
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED

View File

@@ -9,6 +9,17 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/utility.hpp>
#include <boost/mp11/detail/config.hpp>
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
// not exactly good practice, but...
namespace std
{
template<class... _Types> class tuple;
}
#endif
namespace boost
{
@@ -19,18 +30,51 @@ namespace mp11
namespace detail
{
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
template<class T> using mpmf_wrap = mp_identity<T>;
template<class T> using mpmf_unwrap = typename T::type;
#else
template<class... T> struct mpmf_tuple {};
template<class T> struct mpmf_wrap_impl
{
using type = mp_identity<T>;
};
template<class... T> struct mpmf_wrap_impl< std::tuple<T...> >
{
using type = mp_identity< mpmf_tuple<T...> >;
};
template<class T> using mpmf_wrap = typename mpmf_wrap_impl<T>::type;
template<class T> struct mpmf_unwrap_impl
{
using type = typename T::type;
};
template<class... T> struct mpmf_unwrap_impl< mp_identity< mpmf_tuple<T...> > >
{
using type = std::tuple<T...>;
};
template<class T> using mpmf_unwrap = typename mpmf_unwrap_impl<T>::type;
#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
template<class M, class K> struct mp_map_find_impl;
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
{
using U = mp_inherit<mp_identity<T>...>;
using U = mp_inherit<mpmf_wrap<T>...>;
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
static mp_identity<void> f( ... );
using V = decltype( f((U*)0) );
using type = typename V::type;
using type = mpmf_unwrap< decltype( f( static_cast<U*>(0) ) ) >;
};
} // namespace detail

View File

@@ -20,7 +20,10 @@ namespace mp11
namespace detail
{
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 )
// msvc fails with parser stack overflow for large sizeof...(T)
// clang exceeds -fbracket-depth, which defaults to 256
template<class... T> struct mp_plus_impl
{

View File

@@ -0,0 +1,54 @@
#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
// Copyright 2015-2023 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/mp_defer.hpp>
#include <boost/mp11/detail/mp_value.hpp>
#include <boost/mp11/detail/config.hpp>
namespace boost
{
namespace mp11
{
// mp_rename<L, B>
namespace detail
{
template<class L, template<class...> class B> struct mp_rename_impl
{
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
};
template<template<class...> class L, class... T, template<class...> class B> struct mp_rename_impl<L<T...>, B>: mp_defer<B, T...>
{
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A, template<class...> class B> struct mp_rename_impl<L<A...>, B>: mp_defer<B, mp_value<A>...>
{
};
#endif
} // namespace detail
template<class L, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<L, B>::type;
// mp_apply<F, L>
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
// mp_apply_q<Q, L>
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED

View File

@@ -0,0 +1,25 @@
#ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/config.hpp>
#include <type_traits>
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
namespace boost
{
namespace mp11
{
template<auto A> using mp_value = std::integral_constant<decltype(A), A>;
} // namespace mp11
} // namespace boost
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
#endif // #ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED

View File

@@ -20,10 +20,12 @@
# define BOOST_MP11_CONSTEXPR14
#endif
#if defined( _MSC_VER ) && !defined( __clang__ )
# define BOOST_MP11_UNREACHABLE() __assume(false)
#if defined( __GNUC__ ) || defined( __clang__ )
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable();
#elif defined( _MSC_VER )
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false);
#else
# define BOOST_MP11_UNREACHABLE() __builtin_unreachable()
# define BOOST_MP11_UNREACHABLE_DEFAULT
#endif
namespace boost
@@ -38,27 +40,14 @@ template<std::size_t N> struct mp_with_index_impl_
{
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
{
switch( i )
if( i < N / 2 )
{
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
return mp_with_index_impl_<N/2>::template call<K>( i, std::forward<F>(f) );
}
else
{
return mp_with_index_impl_<N-N/2>::template call<K+N/2>( i - N/2, std::forward<F>(f) );
}
return mp_with_index_impl_<N-16>::template call<K+16>( i-16, std::forward<F>(f) );
}
};
@@ -80,7 +69,7 @@ template<> struct mp_with_index_impl_<2>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
}
@@ -93,7 +82,7 @@ template<> struct mp_with_index_impl_<3>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -107,7 +96,7 @@ template<> struct mp_with_index_impl_<4>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -122,7 +111,7 @@ template<> struct mp_with_index_impl_<5>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -138,7 +127,7 @@ template<> struct mp_with_index_impl_<6>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -155,7 +144,7 @@ template<> struct mp_with_index_impl_<7>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -173,7 +162,7 @@ template<> struct mp_with_index_impl_<8>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -192,7 +181,7 @@ template<> struct mp_with_index_impl_<9>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -212,7 +201,7 @@ template<> struct mp_with_index_impl_<10>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -233,7 +222,7 @@ template<> struct mp_with_index_impl_<11>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -255,7 +244,7 @@ template<> struct mp_with_index_impl_<12>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -278,7 +267,7 @@ template<> struct mp_with_index_impl_<13>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -302,7 +291,7 @@ template<> struct mp_with_index_impl_<14>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -327,7 +316,7 @@ template<> struct mp_with_index_impl_<15>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -353,7 +342,7 @@ template<> struct mp_with_index_impl_<16>
{
switch( i )
{
default: BOOST_MP11_UNREACHABLE();
BOOST_MP11_UNREACHABLE_DEFAULT
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
@@ -388,7 +377,7 @@ template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F
}
#undef BOOST_MP11_CONSTEXPR14
#undef BOOST_MP11_UNREACHABLE
#undef BOOST_MP11_UNREACHABLE_DEFAULT
} // namespace mp11
} // namespace boost

View File

@@ -0,0 +1,160 @@
#ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
// Copyright 2017, 2019 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/list.hpp>
#include <boost/mp11/algorithm.hpp>
namespace boost
{
namespace mpl
{
struct forward_iterator_tag;
namespace aux
{
struct mp11_tag {};
template<class L> struct mp11_iterator
{
using category = forward_iterator_tag;
using type = mp11::mp_first<L>;
using next = mp11_iterator<mp11::mp_rest<L>>;
};
} // namespace aux
// at
template< typename Tag > struct at_impl;
template<> struct at_impl<aux::mp11_tag>
{
template<class L, class I> struct apply
{
using type = mp11::mp_at<L, I>;
};
};
// back
template< typename Tag > struct back_impl;
template<> struct back_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using N = mp11::mp_size<L>;
using type = mp11::mp_at_c<L, N::value - 1>;
};
};
// begin
template< typename Tag > struct begin_impl;
template<> struct begin_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = aux::mp11_iterator<L>;
};
};
// clear
template< typename Tag > struct clear_impl;
template<> struct clear_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_clear<L>;
};
};
// end
template< typename Tag > struct end_impl;
template<> struct end_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
};
};
// front
template< typename Tag > struct front_impl;
template<> struct front_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_front<L>;
};
};
// pop_front
template< typename Tag > struct pop_front_impl;
template<> struct pop_front_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_pop_front<L>;
};
};
// push_back
template< typename Tag > struct push_back_impl;
template<> struct push_back_impl<aux::mp11_tag>
{
template<class L, class T> struct apply
{
using type = mp11::mp_push_back<L, T>;
};
};
// push_front
template< typename Tag > struct push_front_impl;
template<> struct push_front_impl<aux::mp11_tag>
{
template<class L, class T> struct apply
{
using type = mp11::mp_push_front<L, T>;
};
};
// size
template< typename Tag > struct size_impl;
template<> struct size_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_size<L>;
};
};
} // namespace mpl
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED

View File

@@ -80,17 +80,14 @@ template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>:
#endif
// mp_all<T...>
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 100000 )
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
#elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>;
#else
template<class... T> using mp_all = mp_and<mp_to_bool<T>...>;
template<class... T> using mp_all = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_false >::value == 0 >;
#endif
@@ -125,13 +122,14 @@ template<class T1, class... T> struct mp_or_impl<T1, T...>
} // namespace detail
// mp_any<T...>
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 100000 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
#else
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
template<class... T> using mp_any = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_true >::value != 0 >;
#endif
@@ -148,7 +146,7 @@ template<> struct mp_same_impl<>
template<class T1, class... T> struct mp_same_impl<T1, T...>
{
using type = mp_all<std::is_same<T1, T>...>;
using type = mp_bool< mp_count<mp_list<T...>, T1>::value == sizeof...(T) >;
};
} // namespace detail
@@ -186,6 +184,11 @@ template<template<class...> class L, class... T1, class... T2> struct mp_similar
using type = mp_true;
};
template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>>
{
using type = mp_true;
};
template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...>
{
using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >;

View File

@@ -9,6 +9,7 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/version.hpp>
#include <boost/mp11/detail/mp_value.hpp>
#include <type_traits>
#include <cstddef>

View File

@@ -1,7 +1,7 @@
#ifndef BOOST_MP11_LIST_HPP_INCLUDED
#define BOOST_MP11_LIST_HPP_INCLUDED
// Copyright 2015-2017 Peter Dimov.
// Copyright 2015-2023 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -10,7 +10,11 @@
#include <boost/mp11/integral.hpp>
#include <boost/mp11/detail/mp_list.hpp>
#include <boost/mp11/detail/mp_list_v.hpp>
#include <boost/mp11/detail/mp_is_list.hpp>
#include <boost/mp11/detail/mp_is_value_list.hpp>
#include <boost/mp11/detail/mp_front.hpp>
#include <boost/mp11/detail/mp_rename.hpp>
#include <boost/mp11/detail/mp_append.hpp>
#include <boost/mp11/detail/config.hpp>
#include <type_traits>
@@ -20,12 +24,21 @@ namespace boost
namespace mp11
{
// mp_list<T...>
// in detail/mp_list.hpp
// mp_list_c<T, I...>
template<class T, T... I> using mp_list_c = mp_list<std::integral_constant<T, I>...>;
// mp_list_v<A...>
// in detail/mp_list_v.hpp
// mp_is_list<L>
// in detail/mp_is_list.hpp
// mp_is_value_list<L>
// in detail/mp_is_value_list.hpp
// mp_size<L>
namespace detail
{
@@ -40,6 +53,15 @@ template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
using type = mp_size_t<sizeof...(T)>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A> struct mp_size_impl<L<A...>>
{
using type = mp_size_t<sizeof...(A)>;
};
#endif
} // namespace detail
template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
@@ -51,13 +73,35 @@ template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
namespace detail
{
template<class L1, class L2> struct mp_assign_impl;
template<class L1, class L2> struct mp_assign_impl
{
// An error "no type named 'type'" here means that the arguments to mp_assign aren't lists
};
template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
{
using type = L1<U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L1, auto... A, template<class...> class L2, class... U> struct mp_assign_impl<L1<A...>, L2<U...>>
{
using type = L1<U::value...>;
};
template<template<class...> class L1, class... T, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<T...>, L2<B...>>
{
using type = L1<mp_value<B>...>;
};
template<template<auto...> class L1, auto... A, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<A...>, L2<B...>>
{
using type = L1<B...>;
};
#endif
} // namespace detail
template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
@@ -66,23 +110,7 @@ template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
// mp_front<L>
namespace detail
{
template<class L> struct mp_front_impl
{
// An error "no type named 'type'" here means that the argument to mp_front
// is either not a list, or is an empty list
};
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
{
using type = T1;
};
} // namespace detail
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
// in detail/mp_front.hpp
// mp_pop_front<L>
namespace detail
@@ -99,6 +127,15 @@ template<template<class...> class L, class T1, class... T> struct mp_pop_front_i
using type = L<T...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto... A> struct mp_pop_front_impl<L<A1, A...>>
{
using type = L<A...>;
};
#endif
} // namespace detail
template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
@@ -124,6 +161,15 @@ template<template<class...> class L, class T1, class T2, class... T> struct mp_s
using type = T2;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto... A> struct mp_second_impl<L<A1, A2, A...>>
{
using type = mp_value<A2>;
};
#endif
} // namespace detail
template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
@@ -143,6 +189,15 @@ template<template<class...> class L, class T1, class T2, class T3, class... T> s
using type = T3;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A> struct mp_third_impl<L<A1, A2, A3, A...>>
{
using type = mp_value<A3>;
};
#endif
} // namespace detail
template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
@@ -161,6 +216,15 @@ template<template<class...> class L, class... U, class... T> struct mp_push_fron
using type = L<T..., U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A, class... T> struct mp_push_front_impl<L<A...>, T...>
{
using type = L<T::value..., A...>;
};
#endif
} // namespace detail
template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
@@ -179,31 +243,50 @@ template<template<class...> class L, class... U, class... T> struct mp_push_back
using type = L<U..., T...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto... A, class... T> struct mp_push_back_impl<L<A...>, T...>
{
using type = L<A..., T::value...>;
};
#endif
} // namespace detail
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
// mp_rename<L, B>
// mp_apply<F, L>
// mp_apply_q<Q, L>
// in detail/mp_rename.hpp
// mp_rename_v<L, B>
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
namespace detail
{
template<class A, template<class...> class B> struct mp_rename_impl
template<class L, template<auto...> class B> struct mp_rename_v_impl
{
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
// An error "no type named 'type'" here means that the first argument to mp_rename_v is not a list
};
template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
template<template<class...> class L, class... T, template<auto...> class B> struct mp_rename_v_impl<L<T...>, B>
{
using type = B<T...>;
using type = B<T::value...>;
};
template<template<auto...> class L, auto... A, template<auto...> class B> struct mp_rename_v_impl<L<A...>, B>
{
using type = B<A...>;
};
} // namespace detail
template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
template<class L, template<auto...> class B> using mp_rename_v = typename detail::mp_rename_v_impl<L, B>::type;
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
#endif
// mp_replace_front<L, T>
namespace detail
@@ -220,6 +303,15 @@ template<template<class...> class L, class U1, class... U, class T> struct mp_re
using type = L<T, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto... A, class T> struct mp_replace_front_impl<L<A1, A...>, T>
{
using type = L<T::value, A...>;
};
#endif
} // namespace detail
template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
@@ -242,6 +334,15 @@ template<template<class...> class L, class U1, class U2, class... U, class T> st
using type = L<U1, T, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto... A, class T> struct mp_replace_second_impl<L<A1, A2, A...>, T>
{
using type = L<A1, T::value, A...>;
};
#endif
} // namespace detail
template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
@@ -261,6 +362,15 @@ template<template<class...> class L, class U1, class U2, class U3, class... U, c
using type = L<U1, U2, T, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, class T> struct mp_replace_third_impl<L<A1, A2, A3, A...>, T>
{
using type = L<A1, A2, T::value, A...>;
};
#endif
} // namespace detail
template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
@@ -280,6 +390,15 @@ template<template<class...> class L, class U1, class... U, template<class...> cl
using type = L<F<U1>, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto... A, template<class...> class F> struct mp_transform_front_impl<L<A1, A...>, F>
{
using type = L<F<mp_value<A1>>::value, A...>;
};
#endif
} // namespace detail
template<class L, template<class...> class F> using mp_transform_front = typename detail::mp_transform_front_impl<L, F>::type;
@@ -304,6 +423,15 @@ template<template<class...> class L, class U1, class U2, class... U, template<cl
using type = L<U1, F<U2>, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto... A, template<class...> class F> struct mp_transform_second_impl<L<A1, A2, A...>, F>
{
using type = L<A1, F<mp_value<A2>>::value, A...>;
};
#endif
} // namespace detail
template<class L, template<class...> class F> using mp_transform_second = typename detail::mp_transform_second_impl<L, F>::type;
@@ -324,6 +452,15 @@ template<template<class...> class L, class U1, class U2, class U3, class... U, t
using type = L<U1, U2, F<U3>, U...>;
};
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, template<class...> class F> struct mp_transform_third_impl<L<A1, A2, A3, A...>, F>
{
using type = L<A1, A2, F<mp_value<A3>>::value, A...>;
};
#endif
} // namespace detail
template<class L, template<class...> class F> using mp_transform_third = typename detail::mp_transform_third_impl<L, F>::type;

View File

@@ -1,175 +1,14 @@
#ifndef BOOST_MP11_MPL_HPP_INCLUDED
#define BOOST_MP11_MPL_HPP_INCLUDED
// Copyright 2017 Peter Dimov.
// Copyright 2017, 2019 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/list.hpp>
#include <boost/mp11/algorithm.hpp>
#include <tuple>
namespace boost
{
namespace mpl
{
struct forward_iterator_tag;
namespace aux
{
struct mp11_tag {};
template<class L> struct mp11_iterator
{
using category = forward_iterator_tag;
using type = mp11::mp_first<L>;
using next = mp11_iterator<mp11::mp_rest<L>>;
};
} // namespace aux
// at
template< typename Tag > struct at_impl;
template<> struct at_impl<aux::mp11_tag>
{
template<class L, class I> struct apply
{
using type = mp11::mp_at<L, I>;
};
};
// back
template< typename Tag > struct back_impl;
template<> struct back_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using N = mp11::mp_size<L>;
using type = mp11::mp_at_c<L, N::value - 1>;
};
};
// begin
template< typename Tag > struct begin_impl;
template<> struct begin_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = aux::mp11_iterator<L>;
};
};
// clear
template< typename Tag > struct clear_impl;
template<> struct clear_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_clear<L>;
};
};
// end
template< typename Tag > struct end_impl;
template<> struct end_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
};
};
// front
template< typename Tag > struct front_impl;
template<> struct front_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_front<L>;
};
};
// pop_front
template< typename Tag > struct pop_front_impl;
template<> struct pop_front_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_pop_front<L>;
};
};
// push_back
template< typename Tag > struct push_back_impl;
template<> struct push_back_impl<aux::mp11_tag>
{
template<class L, class T> struct apply
{
using type = mp11::mp_push_back<L, T>;
};
};
// push_front
template< typename Tag > struct push_front_impl;
template<> struct push_front_impl<aux::mp11_tag>
{
template<class L, class T> struct apply
{
using type = mp11::mp_push_front<L, T>;
};
};
// sequence_tag
template< typename Sequence > struct sequence_tag;
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
{
using type = aux::mp11_tag;
};
template<class... T> struct sequence_tag<std::tuple<T...>>
{
using type = aux::mp11_tag;
};
// size
template< typename Tag > struct size_impl;
template<> struct size_impl<aux::mp11_tag>
{
template<class L> struct apply
{
using type = mp11::mp_size<L>;
};
};
} // namespace mpl
} // namespace boost
#include <boost/mp11/mpl_list.hpp>
#include <boost/mp11/mpl_tuple.hpp>
#endif // #ifndef BOOST_MP11_MPL_HPP_INCLUDED

View File

@@ -0,0 +1,28 @@
#ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
#define BOOST_MP11_MPL_LIST_HPP_INCLUDED
// Copyright 2017, 2019 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/mpl_common.hpp>
namespace boost
{
namespace mpl
{
template< typename Sequence > struct sequence_tag;
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
{
using type = aux::mp11_tag;
};
} // namespace mpl
} // namespace boost
#endif // #ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED

View File

@@ -0,0 +1,29 @@
#ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
#define BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
// Copyright 2017, 2019 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/detail/mpl_common.hpp>
#include <tuple>
namespace boost
{
namespace mpl
{
template< typename Sequence > struct sequence_tag;
template<class... T> struct sequence_tag<std::tuple<T...>>
{
using type = aux::mp11_tag;
};
} // namespace mpl
} // namespace boost
#endif // #ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED

View File

@@ -1,7 +1,7 @@
#ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
#define BOOST_MP11_TUPLE_HPP_INCLUDED
// Copyright 2015, 2017 Peter Dimov.
// Copyright 2015-2020 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -9,6 +9,8 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/integer_sequence.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/function.hpp>
#include <boost/mp11/detail/config.hpp>
#include <tuple>
#include <utility>
@@ -29,10 +31,12 @@ namespace mp11
namespace detail
{
using std::get;
template<class F, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
-> decltype( std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... ) )
-> decltype( std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... ) )
{
return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
return std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... );
}
} // namespace detail
@@ -51,7 +55,7 @@ namespace detail
template<class T, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
{
return T( std::get<J>(std::forward<Tp>(tp))... );
return T( get<J>(std::forward<Tp>(tp))... );
}
} // namespace detail
@@ -70,7 +74,7 @@ namespace detail
template<class Tp, std::size_t... J, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
{
using A = int[sizeof...(J)];
return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
return (void)A{ ((void)f(get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
}
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
@@ -86,6 +90,89 @@ template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F &
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
}
// tuple_transform
namespace detail
{
// std::forward_as_tuple is not constexpr in C++11 or libstdc++ 5.x
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_r( T&&... t ) -> std::tuple<T&&...>
{
return std::tuple<T&&...>( std::forward<T>( t )... );
}
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_v( T&&... t ) -> std::tuple<T...>
{
return std::tuple<T...>( std::forward<T>( t )... );
}
template<std::size_t J, class... Tp>
BOOST_MP11_CONSTEXPR auto tp_extract( Tp&&... tp )
-> decltype( tp_forward_r( get<J>( std::forward<Tp>( tp ) )... ) )
{
return tp_forward_r( get<J>( std::forward<Tp>( tp ) )... );
}
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
template<class F, class... Tp, std::size_t... J>
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp&&... tp )
-> decltype( tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... ) )
{
return tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... );
}
#else
template<class F, class Tp1, std::size_t... J>
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1 )
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... ) )
{
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... );
}
template<class F, class Tp1, class Tp2, std::size_t... J>
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2 )
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... ) )
{
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... );
}
template<class F, class Tp1, class Tp2, class Tp3, std::size_t... J>
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2, Tp3&& tp3 )
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... ) )
{
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... );
}
#endif // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
} // namespace detail
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
template<class F, class Tp1, class... Tp,
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp1>::type>::value>>
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp1&& tp1, Tp&&... tp )
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... ) )
{
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... );
}
#else
template<class F, class... Tp,
class Z = mp_list<mp_size_t<std::tuple_size<typename std::remove_reference<Tp>::type>::value>...>,
class E = mp_if<mp_apply<mp_same, Z>, mp_front<Z>>,
class Seq = make_index_sequence<E::value>>
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp&&... tp )
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... ) )
{
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... );
}
#endif // BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
} // namespace mp11
} // namespace boost

View File

@@ -1,7 +1,7 @@
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
#define BOOST_MP11_UTILITY_HPP_INCLUDED
// Copyright 2015, 2017, 2019 Peter Dimov.
// Copyright 2015-2020 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -9,6 +9,11 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/integral.hpp>
#include <boost/mp11/detail/mp_list.hpp>
#include <boost/mp11/detail/mp_fold.hpp>
#include <boost/mp11/detail/mp_front.hpp>
#include <boost/mp11/detail/mp_rename.hpp>
#include <boost/mp11/detail/mp_defer.hpp>
#include <boost/mp11/detail/config.hpp>
namespace boost
@@ -29,104 +34,9 @@ template<class T> using mp_identity_t = typename mp_identity<T>::type;
template<class... T> struct mp_inherit: T... {};
// mp_if, mp_if_c
namespace detail
{
template<bool C, class T, class... E> struct mp_if_c_impl
{
};
template<class T, class... E> struct mp_if_c_impl<true, T, E...>
{
using type = T;
};
template<class T, class E> struct mp_if_c_impl<false, T, E>
{
using type = E;
};
} // namespace detail
template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
// mp_valid
#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800
// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17
namespace detail
{
template<class...> using void_t = void;
template<class, template<class...> class F, class... T>
struct mp_valid_impl: mp_false {};
template<template<class...> class F, class... T>
struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
} // namespace detail
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
#else
// implementation by Bruno Dutra (by the name is_evaluable)
namespace detail
{
template<template<class...> class F, class... T> struct mp_valid_impl
{
template<template<class...> class G, class = G<T...>> static mp_true check(int);
template<template<class...> class> static mp_false check(...);
using type = decltype(check<F>(0));
};
} // namespace detail
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
#endif
template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
// mp_defer
namespace detail
{
template<template<class...> class F, class... T> struct mp_defer_impl
{
using type = F<T...>;
};
struct mp_no_type
{
};
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
{
using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
};
#endif
} // namespace detail
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
#else
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
#endif
// moved to detail/mp_defer.hpp
// mp_eval_if, mp_eval_if_c
namespace detail
@@ -157,6 +67,10 @@ template<class C, class T, class Q, class... U> using mp_eval_if_not_q = mp_eval
template<class T, template<class...> class F, class... U> using mp_eval_or = mp_eval_if_not<mp_valid<F, U...>, T, F, U...>;
template<class T, class Q, class... U> using mp_eval_or_q = mp_eval_or<T, Q::template fn, U...>;
// mp_valid_and_true
template<template<class...> class F, class... T> using mp_valid_and_true = mp_eval_or<mp_false, F, T...>;
template<class Q, class... T> using mp_valid_and_true_q = mp_valid_and_true<Q::template fn, T...>;
// mp_cond
// so elegant; so doesn't work
@@ -219,9 +133,6 @@ template<class Q, class... T> using mp_invoke_q = typename Q::template fn<T...>;
#endif
// old name for mp_invoke_q retained for compatibility, but deprecated
template<class Q, class... T> using mp_invoke BOOST_MP11_DEPRECATED("please use mp_invoke_q") = mp_invoke_q<Q, T...>;
// mp_not_fn<P>
template<template<class...> class P> struct mp_not_fn
{
@@ -230,6 +141,28 @@ template<template<class...> class P> struct mp_not_fn
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
// mp_compose
namespace detail
{
template<class L, class Q> using mp_compose_helper = mp_list< mp_apply_q<Q, L> >;
} // namespace detail
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
template<template<class...> class... F> struct mp_compose
{
template<class... T> using fn = mp_front< mp_fold<mp_list<mp_quote<F>...>, mp_list<T...>, detail::mp_compose_helper> >;
};
#endif
template<class... Q> struct mp_compose_q
{
template<class... T> using fn = mp_front< mp_fold<mp_list<Q...>, mp_list<T...>, detail::mp_compose_helper> >;
};
} // namespace mp11
} // namespace boost

View File

@@ -11,6 +11,6 @@
// Same format as BOOST_VERSION:
// major * 100000 + minor * 100 + patch
#define BOOST_MP11_VERSION 107000
#define BOOST_MP11_VERSION 108300
#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED