1
0
forked from boostorg/mp11
Files
boost_mp11/include/boost/mp11_single.hpp
2017-06-08 19:22:53 +03:00

2749 lines
82 KiB
C++

#ifndef BOOST_MP11_HPP_INCLUDED
#define BOOST_MP11_HPP_INCLUDED
// Copyright 2015 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
#ifndef BOOST_MP11_LIST_HPP_INCLUDED
#define BOOST_MP11_LIST_HPP_INCLUDED
// Copyright 2015-2017 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
#ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
#define BOOST_MP11_INTEGRAL_HPP_INCLUDED
// Copyright 2015 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 <type_traits>
#include <cstddef>
namespace boost
{
namespace mp11
{
// mp_bool
template<bool B> using mp_bool = std::integral_constant<bool, B>;
using mp_true = mp_bool<true>;
using mp_false = mp_bool<false>;
// mp_to_bool
template<class T> using mp_to_bool = mp_bool<static_cast<bool>( T::value )>;
// mp_not<T>
template<class T> using mp_not = mp_bool< !T::value >;
// mp_int
template<int I> using mp_int = std::integral_constant<int, I>;
// mp_size_t
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
#ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
// Copyright 2015, 2016 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
namespace boost
{
namespace mp11
{
// mp_list<T...>
template<class... T> struct mp_list
{
};
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
// Copyright 2015-2017 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
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
#define BOOST_MP11_UTILITY_HPP_INCLUDED
// Copyright 2015, 2017 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/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost
{
namespace mp11
{
// mp_identity
template<class T> struct mp_identity
{
using type = T;
};
// mp_identity_t
template<class T> using mp_identity_t = T;
// mp_inherit
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
// 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;
// mp_defer
namespace detail
{
template<template<class...> class F, class... T> struct mp_defer_impl
{
using type = F<T...>;
};
struct mp_no_type
{
};
} // namespace detail
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>;
// mp_eval_if, mp_eval_if_c
namespace detail
{
template<bool C, class T, template<class...> class F, class... U> struct mp_eval_if_c_impl;
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<true, T, F, U...>
{
using type = T;
};
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<false, T, F, U...>: mp_defer<F, U...>
{
};
} // namespace detail
template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl<C, T, F, U...>::type;
template<class C, class T, template<class...> class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, F, U...>::type;
template<class C, class T, class Q, class... U> using mp_eval_if_q = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, Q::template fn, U...>::type;
// mp_quote
template<template<class...> class F> struct mp_quote
{
// the indirection through mp_defer works around the language inability
// to expand T... into a fixed parameter list of an alias template
template<class... T> using fn = typename mp_defer<F, T...>::type;
};
// mp_invoke
#if BOOST_WORKAROUND( BOOST_MSVC, < 1900 )
namespace detail
{
template<class Q, class... T> struct mp_invoke_impl: mp_defer<Q::template fn, T...> {};
} // namespace detail
template<class Q, class... T> using mp_invoke = typename detail::mp_invoke_impl<Q, T...>::type;
#elif BOOST_WORKAROUND( BOOST_GCC, < 50000 )
template<class Q, class... T> using mp_invoke = typename mp_defer<Q::template fn, T...>::type;
#else
template<class Q, class... T> using mp_invoke = typename Q::template fn<T...>;
#endif
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost
{
namespace mp11
{
// mp_append<L...>
namespace detail
{
template<class... L> struct mp_append_impl;
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<> struct mp_append_impl<>
{
using type = mp_list<>;
};
template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
{
using type = L<T...>;
};
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, Lr...>
{
using type = typename mp_append_impl<L1<T1..., T2...>, Lr...>::type;
};
#else
template<class L1 = mp_list<>, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl;
template<
template<class...> class L1, class... T1,
template<class...> class L2, class... T2,
template<class...> class L3, class... T3,
template<class...> class L4, class... T4,
template<class...> class L5, class... T5,
template<class...> class L6, class... T6,
template<class...> class L7, class... T7,
template<class...> class L8, class... T8,
template<class...> class L9, class... T9,
template<class...> class L10, class... T10,
template<class...> class L11, class... T11>
struct append_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
{
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
};
template<
class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>,
class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>,
class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>,
class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>,
class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>,
class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>,
class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>,
class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>,
class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>,
class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>,
class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<>
> struct append_111_impl
{
using type = typename append_11_impl<
typename append_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
typename append_11_impl<mp_list<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
typename append_11_impl<mp_list<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
typename append_11_impl<mp_list<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
typename append_11_impl<mp_list<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
typename append_11_impl<mp_list<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
typename append_11_impl<mp_list<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
typename append_11_impl<mp_list<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
typename append_11_impl<mp_list<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
typename append_11_impl<mp_list<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
typename append_11_impl<mp_list<>, 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_inf_impl
{
using prefix = typename append_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 mp_append_impl<prefix, Lr...>::type;
};
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...>
{
};
#endif
} // namespace detail
template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost
{
namespace mp11
{
// mp_size<L>
namespace detail
{
template<class L> struct mp_size_impl;
template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
{
using type = mp_size_t<sizeof...(T)>;
};
} // namespace detail
template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
// mp_empty<L>
template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
// mp_front<L>
namespace detail
{
template<class L> struct mp_front_impl;
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;
// mp_pop_front<L>
namespace detail
{
template<class L> struct mp_pop_front_impl;
template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
{
using type = L<T...>;
};
} // namespace detail
template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
// mp_first<L>
template<class L> using mp_first = mp_front<L>;
// mp_rest<L>
template<class L> using mp_rest = mp_pop_front<L>;
// mp_second<L>
namespace detail
{
template<class L> struct mp_second_impl;
template<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
{
using type = T2;
};
} // namespace detail
template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
// mp_third<L>
namespace detail
{
template<class L> struct mp_third_impl;
template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
{
using type = T3;
};
} // namespace detail
template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
// mp_push_front<L, T...>
namespace detail
{
template<class L, class... T> struct mp_push_front_impl;
template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
{
using type = L<T..., U...>;
};
} // namespace detail
template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
// mp_push_back<L, T...>
namespace detail
{
template<class L, class... T> struct mp_push_back_impl;
template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
{
using type = L<U..., T...>;
};
} // namespace detail
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
// mp_rename<L, B>
namespace detail
{
template<class A, template<class...> class B> struct mp_rename_impl;
template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
{
using type = B<T...>;
};
} // namespace detail
template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, 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;
// mp_replace_front<L, T>
namespace detail
{
template<class L, class T> struct mp_replace_front_impl;
template<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
{
using type = L<T, U...>;
};
} // namespace detail
template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
// mp_replace_first<L, T>
template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
// mp_replace_second<L, T>
namespace detail
{
template<class L, class T> struct mp_replace_second_impl;
template<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
{
using type = L<U1, T, U...>;
};
} // namespace detail
template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
// mp_replace_third<L, T>
namespace detail
{
template<class L, class T> struct mp_replace_third_impl;
template<template<class...> class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl<L<U1, U2, U3, U...>, T>
{
using type = L<U1, U2, T, U...>;
};
} // namespace detail
template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
#ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED
#define BOOST_MP11_ALGORITHM_HPP_INCLUDED
// Copyright 2015-2017 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
#ifndef BOOST_MP11_SET_HPP_INCLUDED
#define BOOST_MP11_SET_HPP_INCLUDED
// Copyright 2015 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 <type_traits>
namespace boost
{
namespace mp11
{
// mp_set_contains<S, V>
namespace detail
{
template<class S, class V> struct mp_set_contains_impl;
template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
{
using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...>>>;
};
} // namespace detail
template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
// mp_set_push_back<S, T...>
namespace detail
{
template<class S, class... T> struct mp_set_push_back_impl;
template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
{
using type = L<U...>;
};
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
{
using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
using type = typename mp_set_push_back_impl<S, T...>::type;
};
} // namespace detail
template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
// mp_set_push_front<S, T...>
namespace detail
{
template<class S, class... T> struct mp_set_push_front_impl;
template<template<class...> class L, class... U> struct mp_set_push_front_impl<L<U...>>
{
using type = L<U...>;
};
template<template<class...> class L, class... U, class T1> struct mp_set_push_front_impl<L<U...>, T1>
{
using type = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<T1, U...>>;
};
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_front_impl<L<U...>, T1, T...>
{
using S = typename mp_set_push_front_impl<L<U...>, T...>::type;
using type = typename mp_set_push_front_impl<S, T1>::type;
};
} // namespace detail
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
#define BOOST_MP11_FUNCTION_HPP_INCLUDED
// Copyright 2015-2017 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
#ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
// Copyright 2015, 2016 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
#ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
// Copyright 2015 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
#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
// Copyright 2016 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/config.hpp>
#include <boost/detail/workaround.hpp>
#if defined( BOOST_NO_CXX11_CONSTEXPR )
# define BOOST_MP11_NO_CONSTEXPR
#elif defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
# define BOOST_MP11_NO_CONSTEXPR
#endif
#if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
#elif defined(BOOST_CLANG) && defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
# endif
#endif
#if defined(__has_builtin)
# if __has_builtin(__type_pack_element)
# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT
# endif
#endif
#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
#include <boost/detail/workaround.hpp>
#include <type_traits>
namespace boost
{
namespace mp11
{
// mp_plus
namespace detail
{
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
template<class... T> struct mp_plus_impl
{
static const auto _v = (T::value + ... + 0);
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
};
#else
template<class... T> struct mp_plus_impl;
template<> struct mp_plus_impl<>
{
using type = std::integral_constant<int, 0>;
};
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
template<class T1, class... T> struct mp_plus_impl<T1, T...>
{
static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
};
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
{
static const
decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
_v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
};
#else
template<class T1, class... T> struct mp_plus_impl<T1, T...>
{
static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
};
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
{
static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
};
#endif
#endif
} // namespace detail
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
#include <boost/config.hpp>
namespace boost
{
namespace mp11
{
// mp_count<L, V>
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 )
constexpr std::size_t cx_plus()
{
return 0;
}
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
{
return 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...);
}
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...)>;
};
#else
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
{
using type = mp_size_t<mp_plus<std::is_same<T, V>...>::value>;
};
#endif
} // namespace detail
template<class L, class V> using mp_count = typename detail::mp_count_impl<L, V>::type;
// mp_count_if<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_count_if_impl;
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
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)>;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
{
using type = mp_size_t<cx_plus(mp_to_bool<P<T>>::value...)>;
};
#else
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class T> struct _f { using type = mp_to_bool<P<T>>; };
using type = mp_size_t<mp_plus<typename _f<T>::type...>::value>;
#else
using type = mp_size_t<mp_plus<mp_to_bool<P<T>>...>::value>;
#endif
};
#endif
} // namespace detail
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
#include <type_traits>
namespace boost
{
namespace mp11
{
// mp_void<T...>
namespace detail
{
template<class... T> struct mp_void_impl
{
using type = void;
};
} // namespace detail
template<class... T> using mp_void = typename detail::mp_void_impl<T...>::type;
// mp_and<T...>
#if BOOST_WORKAROUND( BOOST_MSVC, < 1910 )
namespace detail
{
template<class... T> struct mp_and_impl;
} // namespace detail
template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
namespace detail
{
template<> struct mp_and_impl<>
{
using type = mp_true;
};
template<class T> struct mp_and_impl<T>
{
using type = T;
};
template<class T1, class... T> struct mp_and_impl<T1, T...>
{
using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
};
} // namespace detail
#else
namespace detail
{
template<class L, class E = void> struct mp_and_impl
{
using type = mp_false;
};
template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
{
using type = mp_true;
};
} // namespace detail
template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
#endif
// mp_all<T...>
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) || BOOST_WORKAROUND( BOOST_GCC, < 70200 )
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>...>;
#endif
// mp_or<T...>
namespace detail
{
template<class... T> struct mp_or_impl;
} // namespace detail
template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
namespace detail
{
template<> struct mp_or_impl<>
{
using type = mp_false;
};
template<class T> struct mp_or_impl<T>
{
using type = T;
};
template<class T1, class... T> struct mp_or_impl<T1, T...>
{
using type = mp_eval_if< T1, T1, mp_or, T... >;
};
} // namespace detail
// mp_any<T...>
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_WORKAROUND( BOOST_GCC, < 70200 )
template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
#else
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
#endif
// mp_same<T...>
namespace detail
{
template<class... T> struct mp_same_impl;
template<> struct mp_same_impl<>
{
using type = mp_true;
};
template<class T1, class... T> struct mp_same_impl<T1, T...>
{
using type = mp_all<std::is_same<T1, T>...>;
};
} // namespace detail
template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
// Copyright 2015 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
namespace boost
{
namespace mp11
{
// mp_map_find
namespace detail
{
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>...>;
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;
};
} // namespace detail
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
#define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
// Copyright 2017 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/config.hpp>
#include <type_traits>
#include <utility>
#include <cassert>
#if !defined( BOOST_NO_CXX14_CONSTEXPR )
# define BOOST_MP11_CONSTEXPR14 constexpr
#else
# define BOOST_MP11_CONSTEXPR14
#endif
namespace boost
{
namespace mp11
{
namespace detail
{
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 )
{
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-16>::template call<K+16>( i-16, std::forward<F>(f) );
}
};
template<> struct mp_with_index_impl_<0>
{
};
template<> struct mp_with_index_impl_<1>
{
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 )
{
return std::forward<F>(f)( mp_size_t<K+0>() );
}
};
template<> struct mp_with_index_impl_<2>
{
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 )
{
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
default: return std::forward<F>(f)( mp_size_t<K+1>() );
}
}
};
template<> struct mp_with_index_impl_<3>
{
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 )
{
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
default: return std::forward<F>(f)( mp_size_t<K+2>() );
}
}
};
template<> struct mp_with_index_impl_<4>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+3>() );
}
}
};
template<> struct mp_with_index_impl_<5>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+4>() );
}
}
};
template<> struct mp_with_index_impl_<6>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+5>() );
}
}
};
template<> struct mp_with_index_impl_<7>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+6>() );
}
}
};
template<> struct mp_with_index_impl_<8>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+7>() );
}
}
};
template<> struct mp_with_index_impl_<9>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+8>() );
}
}
};
template<> struct mp_with_index_impl_<10>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+9>() );
}
}
};
template<> struct mp_with_index_impl_<11>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+10>() );
}
}
};
template<> struct mp_with_index_impl_<12>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+11>() );
}
}
};
template<> struct mp_with_index_impl_<13>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+12>() );
}
}
};
template<> struct mp_with_index_impl_<14>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+13>() );
}
}
};
template<> struct mp_with_index_impl_<15>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+14>() );
}
}
};
template<> struct mp_with_index_impl_<16>
{
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 )
{
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>() );
default: return std::forward<F>(f)( mp_size_t<K+15>() );
}
}
};
} // namespace detail
template<std::size_t N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
{
assert( i < N );
return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
}
template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
{
return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
}
#undef BOOST_MP11_CONSTEXPR14
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
// Copyright 2015, 2017 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 <cstddef>
namespace boost
{
namespace mp11
{
// integer_sequence
template<class T, T... I> struct integer_sequence
{
};
// detail::make_integer_sequence_impl
namespace detail
{
// iseq_if_c
template<bool C, class T, class E> struct iseq_if_c_impl;
template<class T, class E> struct iseq_if_c_impl<true, T, E>
{
using type = T;
};
template<class T, class E> struct iseq_if_c_impl<false, T, E>
{
using type = E;
};
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
// iseq_identity
template<class T> struct iseq_identity
{
using type = T;
};
template<class S1, class S2> struct append_integer_sequence;
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
{
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
};
template<class T, T N> struct make_integer_sequence_impl;
template<class T, T N> struct make_integer_sequence_impl_
{
private:
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
static T const M = N / 2;
static T const R = N % 2;
using S1 = typename make_integer_sequence_impl<T, M>::type;
using S2 = typename append_integer_sequence<S1, S1>::type;
using S3 = typename make_integer_sequence_impl<T, R>::type;
using S4 = typename append_integer_sequence<S2, S3>::type;
public:
using type = S4;
};
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N>>>
{
};
} // namespace detail
// make_integer_sequence
template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
// index_sequence
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
// make_index_sequence
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
// index_sequence_for
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <type_traits>
#include <utility>
namespace boost
{
namespace mp11
{
// mp_assign<L1, L2>
namespace detail
{
template<class L1, class L2> struct mp_assign_impl;
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...>;
};
} // namespace detail
template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
// mp_clear<L>
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
// mp_fold<L, V, F> forward declaration
namespace detail
{
template<class L, class V, template<class...> class F> struct mp_fold_impl;
} // namespace detail
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
// mp_transform<F, L...>
namespace detail
{
template<template<class...> class F, class... L> struct mp_transform_impl
{
};
template<template<class...> class F, template<class...> class L, class... T> struct mp_transform_impl<F, L<T...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L<typename f<T>::type...>;
#else
using type = L<F<T>...>;
#endif
};
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...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L1<typename f<T1, T2>::type...>;
#else
using type = L1<F<T1,T2>...>;
#endif
};
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...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L1<typename f<T1, T2, T3>::type...>;
#else
using type = L1<F<T1,T2,T3>...>;
#endif
};
#if BOOST_WORKAROUND( BOOST_MSVC, == 1900 ) || BOOST_WORKAROUND( BOOST_GCC, < 40800 )
template<class... L> using mp_same_size_1 = mp_same<mp_size<L>...>;
template<class... L> struct mp_same_size_2: mp_defer<mp_same_size_1, L...> {};
#endif
} // namespace detail
#if BOOST_WORKAROUND( BOOST_MSVC, == 1900 ) || BOOST_WORKAROUND( BOOST_GCC, < 40800 )
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...>>::type;
#else
template<template<class...> class F, class... L> using mp_transform = typename mp_if<mp_same<mp_size<L>...>, detail::mp_transform_impl<F, L...>>::type;
#endif
template<class Q, class... L> using mp_transform_q = mp_transform<Q::template fn, L...>;
namespace detail
{
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...>
{
using A1 = L1<mp_list<T1, T2, T3, T4>...>;
template<class V, class T> using _f = mp_transform<mp_push_back, V, T>;
using A2 = mp_fold<mp_list<L...>, A1, _f>;
template<class T> using _g = mp_apply<F, T>;
using type = mp_transform<_g, A2>;
};
} // namespace detail
// mp_transform_if<P, F, L...>
namespace detail
{
template<template<class...> class P, template<class...> class F, class... L> struct mp_transform_if_impl
{
// the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"
using Qp = mp_quote<P>;
using Qf = mp_quote<F>;
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct _f_ { using type = mp_eval_if_q<mp_not<mp_invoke<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>; };
template<class... U> using _f = typename _f_<U...>::type;
#else
template<class... U> using _f = mp_eval_if_q<mp_not<mp_invoke<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>;
#endif
using type = mp_transform<_f, L...>;
};
} // namespace detail
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;
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;
// mp_fill<L, V>
namespace detail
{
template<class L, class V> struct mp_fill_impl;
template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<T...>, V>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1900 )
template<class...> struct _f { using type = V; };
using type = L<typename _f<T>::type...>;
#else
template<class...> using _f = V;
using type = L<_f<T>...>;
#endif
};
} // namespace detail
template<class L, class V> using mp_fill = typename detail::mp_fill_impl<L, V>::type;
// mp_contains<L, V>
template<class L, class V> using mp_contains = mp_to_bool<mp_count<L, V>>;
// mp_repeat(_c)<L, N>
namespace detail
{
template<class L, std::size_t N> struct mp_repeat_c_impl
{
using _l1 = typename mp_repeat_c_impl<L, N/2>::type;
using _l2 = typename mp_repeat_c_impl<L, N%2>::type;
using type = mp_append<_l1, _l1, _l2>;
};
template<class L> struct mp_repeat_c_impl<L, 0>
{
using type = mp_clear<L>;
};
template<class L> struct mp_repeat_c_impl<L, 1>
{
using type = L;
};
} // namespace detail
template<class L, std::size_t N> using mp_repeat_c = typename detail::mp_repeat_c_impl<L, N>::type;
template<class L, class N> using mp_repeat = typename detail::mp_repeat_c_impl<L, std::size_t{ N::value }>::type;
// mp_product<F, L...>
namespace detail
{
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>
{
using type = mp_list<mp_rename<P, F>>;
};
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...>
{
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 L1, class... L> struct mp_product_impl<F, L1, L...>
{
using type = mp_assign<L1, typename mp_product_impl_2<F, mp_list<>, L1, L...>::type>;
};
} // namespace detail
template<template<class...> class F, class... L> using mp_product = typename detail::mp_product_impl<F, L...>::type;
template<class Q, class... L> using mp_product_q = typename detail::mp_product_impl<Q::template fn, L...>::type;
// mp_drop(_c)<L, N>
namespace detail
{
template<class L, class L2> 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<class... W> static mp_identity<L<W...>> f( U*..., mp_identity<W>*... );
using R = decltype( f( (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, class N> using mp_drop = typename detail::mp_drop_impl<L, mp_repeat<mp_list<void>, N>>::type;
// mp_iota(_c)<N>
namespace detail
{
template<class S> 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...>>
{
using type = mp_list<std::integral_constant<U, J>...>;
};
template<class S> using mp_from_sequence = typename mp_from_sequence_impl<S>::type;
} // namespace detail
template<std::size_t N> using mp_iota_c = detail::mp_from_sequence<make_index_sequence<N>>;
template<class N> using mp_iota = detail::mp_from_sequence<make_integer_sequence<typename std::remove_const<decltype(N::value)>::type, N::value>>;
// mp_at(_c)<L, I>
namespace detail
{
template<class L, std::size_t I> struct mp_at_c_impl;
#if defined(BOOST_MP11_HAS_TYPE_PACK_ELEMENT)
template<template<class...> class L, class... T, std::size_t I> struct mp_at_c_impl<L<T...>, I>
{
using type = __type_pack_element<I, T...>;
};
#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 type = mp_second<mp_map_find<_map, mp_size_t<I>>>;
};
#endif
} // namespace detail
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;
template<class L, class I> using mp_at = mp_at_c<L, std::size_t{ I::value }>;
// mp_take(_c)<L, N>
namespace detail
{
template<class L, std::size_t N, class E = void> struct mp_take_c_impl;
template<template<class...> class L, class... T> struct mp_take_c_impl<L<T...>, 0>
{
using type = L<>;
};
template<template<class...> class L, class T1, class... T> struct mp_take_c_impl<L<T1, T...>, 1>
{
using type = L<T1>;
};
template<template<class...> class L, class T1, class T2, class... T> struct mp_take_c_impl<L<T1, T2, T...>, 2>
{
using type = L<T1, T2>;
};
template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_take_c_impl<L<T1, T2, T3, T...>, 3>
{
using type = L<T1, T2, T3>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class... T> struct mp_take_c_impl<L<T1, T2, T3, T4, T...>, 4>
{
using type = L<T1, T2, T3, T4>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class... T, std::size_t N> struct mp_take_c_impl<L<T1, T2, T3, T4, T5, T...>, N, typename std::enable_if<N >= 5>::type>
{
using type = mp_append<L<T1, T2, T3, T4, T5>, typename mp_take_c_impl<L<T...>, N-5>::type>;
};
} // namespace detail
template<class L, std::size_t N> using mp_take_c = typename detail::mp_take_c_impl<L, N>::type;
template<class L, class N> using mp_take = typename detail::mp_take_c_impl<L, std::size_t{ N::value }>::type;
// mp_replace<L, V, W>
namespace detail
{
template<class L, class V, class W> struct mp_replace_impl;
template<template<class...> class L, class... T, class V, class W> struct mp_replace_impl<L<T...>, V, W>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<class A> struct _f { using type = mp_if<std::is_same<A, V>, W, A>; };
using type = L<typename _f<T>::type...>;
#else
template<class A> using _f = mp_if<std::is_same<A, V>, W, A>;
using type = L<_f<T>...>;
#endif
};
} // namespace detail
template<class L, class V, class W> using mp_replace = typename detail::mp_replace_impl<L, V, W>::type;
// mp_replace_if<L, P, W>
namespace detail
{
template<class L, template<class...> class P, class W> struct mp_replace_if_impl;
template<template<class...> class L, class... T, template<class...> class P, class W> struct mp_replace_if_impl<L<T...>, P, W>
{
template<class U> using _f = mp_if<P<U>, W, U>;
using type = L<_f<T>...>;
};
} // namespace detail
template<class L, template<class...> class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl<L, P, W>::type;
// mp_copy_if<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_copy_if_impl;
template<template<class...> class L, class... T, template<class...> class P> struct mp_copy_if_impl<L<T...>, P>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class U> struct _f { using type = mp_if<P<U>, mp_list<U>, mp_list<>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<P<U>, mp_list<U>, mp_list<>>;
using type = mp_append<L<>, _f<T>...>;
#endif
};
} // namespace detail
template<class L, template<class...> class P> using mp_copy_if = typename detail::mp_copy_if_impl<L, P>::type;
// mp_remove<L, V>
namespace detail
{
template<class L, class V> struct mp_remove_impl;
template<template<class...> class L, class... T, class V> struct mp_remove_impl<L<T...>, V>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class U> struct _f { using type = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>;
using type = mp_append<L<>, _f<T>...>;
#endif
};
} // namespace detail
template<class L, class V> using mp_remove = typename detail::mp_remove_impl<L, V>::type;
// mp_remove_if<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_remove_if_impl;
template<template<class...> class L, class... T, template<class...> class P> struct mp_remove_if_impl<L<T...>, P>
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class U> struct _f { using type = mp_if<P<U>, mp_list<>, mp_list<U>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
using type = mp_append<L<>, _f<T>...>;
#endif
};
} // namespace detail
template<class L, template<class...> class P> using mp_remove_if = typename detail::mp_remove_if_impl<L, P>::type;
// mp_partition<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_partition_impl;
template<template<class...> class L, class... T, template<class...> class P> struct mp_partition_impl<L<T...>, P>
{
using type = L<mp_copy_if<L<T...>, P>, mp_remove_if<L<T...>, P>>;
};
} // namespace detail
template<class L, template<class...> class P> using mp_partition = typename detail::mp_partition_impl<L, P>::type;
// mp_sort<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_sort_impl;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, template<class...> class P> struct mp_sort_impl<L<T...>, P>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = L<>;
};
#else
template<template<class...> class L, template<class...> class P> struct mp_sort_impl<L<>, P>
{
using type = L<>;
};
#endif
template<template<class...> class L, class T1, template<class...> class P> struct mp_sort_impl<L<T1>, P>
{
using type = L<T1>;
};
template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_sort_impl<L<T1, T...>, P>
{
template<class U> using F = P<U, T1>;
using part = mp_partition<L<T...>, F>;
using S1 = typename mp_sort_impl<mp_first<part>, P>::type;
using S2 = typename mp_sort_impl<mp_second<part>, P>::type;
using type = mp_append<mp_push_back<S1, T1>, S2>;
};
} // namespace detail
template<class L, template<class...> class P> using mp_sort = typename detail::mp_sort_impl<L, P>::type;
// mp_find<L, V>
namespace detail
{
template<class L, class V> struct mp_find_impl;
#if defined( BOOST_CLANG ) && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
struct mp_index_holder
{
std::size_t i_;
bool f_;
};
constexpr inline mp_index_holder operator+( mp_index_holder const & v, bool f )
{
if( v.f_ )
{
return v;
}
else if( f )
{
return { v.i_, true };
}
else
{
return { v.i_ + 1, false };
}
}
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
{
static constexpr mp_index_holder _v{ 0, false };
using type = mp_size_t< (_v + ... + std::is_same<T, V>::value).i_ >;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
{
using type = mp_size_t<0>;
};
constexpr std::size_t cx_find_index( bool const * first, bool const * last )
{
return first == last || *first? 0: 1 + cx_find_index( first + 1, last );
}
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
{
static constexpr bool _v[] = { std::is_same<T, V>::value... };
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
};
#else
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = mp_size_t<0>;
};
#else
template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
{
using type = mp_size_t<0>;
};
#endif
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<V, T...>, V>
{
using type = mp_size_t<0>;
};
template<template<class...> class L, class T1, class... T, class V> struct mp_find_impl<L<T1, T...>, V>
{
using _r = typename mp_find_impl<mp_list<T...>, V>::type;
using type = mp_size_t<1 + _r::value>;
};
#endif
} // namespace detail
template<class L, class V> using mp_find = typename detail::mp_find_impl<L, V>::type;
// mp_find_if<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_find_if_impl;
#if defined( BOOST_CLANG ) && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{
static constexpr mp_index_holder _v{ 0, false };
using type = mp_size_t< (_v + ... + P<T>::value).i_ >;
};
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
{
using type = mp_size_t<0>;
};
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{
static constexpr bool _v[] = { P<T>::value... };
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
};
#else
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = mp_size_t<0>;
};
#else
template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
{
using type = mp_size_t<0>;
};
#endif
template<class L, template<class...> class P> struct mp_find_if_impl_2
{
using _r = typename mp_find_if_impl<L, P>::type;
using type = mp_size_t<1 + _r::value>;
};
template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_find_if_impl<L<T1, T...>, P>
{
using type = typename mp_if<P<T1>, mp_identity<mp_size_t<0>>, mp_find_if_impl_2<mp_list<T...>, P>>::type;
};
#endif
} // namespace detail
template<class L, template<class...> class P> using mp_find_if = typename detail::mp_find_if_impl<L, P>::type;
// mp_reverse<L>
namespace detail
{
template<class L> struct mp_reverse_impl;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T> struct mp_reverse_impl<L<T...>>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = L<>;
};
#else
template<template<class...> class L> struct mp_reverse_impl<L<>>
{
using type = L<>;
};
#endif
template<template<class...> class L, class T1> struct mp_reverse_impl<L<T1>>
{
using type = L<T1>;
};
template<template<class...> class L, class T1, class T2> struct mp_reverse_impl<L<T1, T2>>
{
using type = L<T2, T1>;
};
template<template<class...> class L, class T1, class T2, class T3> struct mp_reverse_impl<L<T1, T2, T3>>
{
using type = L<T3, T2, T1>;
};
template<template<class...> class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl<L<T1, T2, T3, T4>>
{
using type = L<T4, T3, T2, T1>;
};
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>>
{
using type = L<T5, T4, T3, T2, T1>;
};
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>>
{
using type = L<T6, T5, T4, T3, T2, T1>;
};
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>>
{
using type = L<T7, T6, T5, T4, T3, T2, T1>;
};
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>>
{
using type = L<T8, T7, T6, T5, T4, T3, T2, T1>;
};
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>>
{
using type = L<T9, T8, T7, T6, T5, T4, T3, T2, 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> struct mp_reverse_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>>
{
using type = mp_push_back<typename mp_reverse_impl<L<T...>>::type, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1>;
};
} // namespace detail
template<class L> using mp_reverse = typename detail::mp_reverse_impl<L>::type;
// mp_fold<L, V, F>
namespace detail
{
template<class L, class V, template<class...> class F> struct mp_fold_impl;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T...>, V, F>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = V;
};
#else
template<template<class...> class L, class V, template<class...> class F> struct mp_fold_impl<L<>, V, F>
{
using type = V;
};
#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>
{
using type = typename mp_fold_impl<L<T...>, F<V, T1>, F>::type;
};
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;
};
} // namespace detail
// mp_reverse_fold<L, V, F>
namespace detail
{
template<class L, class V, template<class...> class F> struct mp_reverse_fold_impl;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, class V, template<class...> class F> struct mp_reverse_fold_impl<L<T...>, V, F>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = V;
};
#else
template<template<class...> class L, class V, template<class...> class F> struct mp_reverse_fold_impl<L<>, V, F>
{
using type = V;
};
#endif
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>
{
using rest = typename mp_reverse_fold_impl<L<T...>, V, F>::type;
using type = F<T1, rest>;
};
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>
{
using rest = typename mp_reverse_fold_impl<L<T...>, V, F>::type;
using type = F<T1, F<T2, F<T3, F<T4, F<T5, F<T6, F<T7, F<T8, F<T9, F<T10, rest>>>>>>>>>>;
};
} // namespace detail
template<class L, class V, template<class...> class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl<L, V, F>::type;
// mp_unique<L>
namespace detail
{
template<class L> struct mp_unique_impl;
template<template<class...> class L, class... T> struct mp_unique_impl<L<T...>>
{
using type = mp_set_push_back<L<>, T...>;
};
} // namespace detail
template<class L> using mp_unique = typename detail::mp_unique_impl<L>::type;
// 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 >;
// mp_none_of<L, P>
template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_count_if<L, P>::value == 0 >;
// mp_any_of<L, P>
template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;
// mp_replace_at_c<L, I, W>
namespace detail
{
template<class L, class I, class W> struct mp_replace_at_impl
{
static_assert( I::value >= 0, "mp_replace_at<L, I, W>: I must not be negative" );
template<class T1, class T2> using _p = std::is_same<T2, mp_size_t<I::value>>;
template<class T1, class T2> using _f = W;
using type = mp_transform_if<_p, _f, L, mp_iota<mp_size<L>>>;
};
} // namespace detail
template<class L, class I, class W> using mp_replace_at = typename detail::mp_replace_at_impl<L, I, W>::type;
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;
//mp_for_each<L>(f)
namespace detail
{
template<class... T, class F> BOOST_CONSTEXPR F mp_for_each_impl( mp_list<T...>, F && f )
{
using A = int[sizeof...(T)];
return (void)A{ ((void)f(T()), 0)... }, std::forward<F>(f);
}
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<class F> BOOST_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f )
{
return std::forward<F>(f);
}
#endif
} // namespace detail
template<class L, class F> BOOST_CONSTEXPR F mp_for_each( F && f )
{
return detail::mp_for_each_impl( mp_rename<L, mp_list>(), std::forward<F>(f) );
}
// mp_insert<L, I, T...>
template<class L, class I, class... T> using mp_insert = mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;
// mp_insert_c<L, I, T...>
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...>>;
// mp_erase<L, I, J>
template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>;
// mp_erase_c<L, I, J>
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>>;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED
#ifndef BOOST_MP11_MAP_HPP_INCLUDED
#define BOOST_MP11_MAP_HPP_INCLUDED
// Copyright 2015-2017 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 <type_traits>
namespace boost
{
namespace mp11
{
// mp_map_contains<M, K>
template<class M, class K> using mp_map_contains = mp_not<std::is_same<mp_map_find<M, K>, void>>;
// mp_map_insert<M, T>
template<class M, class T> using mp_map_insert = mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;
// mp_map_replace<M, T>
namespace detail
{
template<class M, class T> struct mp_map_replace_impl;
template<template<class...> class M, class... U, class T> struct mp_map_replace_impl<M<U...>, T>
{
using K = mp_first<T>;
// mp_replace_if is inlined here using a struct _f because of msvc-14.0
template<class V> struct _f { using type = mp_if< std::is_same<mp_first<V>, K>, T, V >; };
using type = mp_if< mp_map_contains<M<U...>, K>, M<typename _f<U>::type...>, M<U..., T> >;
};
} // namespace detail
template<class M, class T> using mp_map_replace = typename detail::mp_map_replace_impl<M, T>::type;
// mp_map_update<M, T, F>
namespace detail
{
template<class M, class T, template<class...> class F> struct mp_map_update_impl
{
template<class U> using _f = std::is_same<mp_first<T>, mp_first<U>>;
// _f3<L<X, Y...>> -> L<X, F<X, Y...>>
template<class L> using _f3 = mp_assign<L, mp_list<mp_first<L>, mp_rename<L, F>>>;
using type = mp_if< mp_map_contains<M, mp_first<T>>, mp_transform_if<_f, _f3, M>, mp_push_back<M, T> >;
};
} // namespace detail
template<class M, class T, template<class...> class F> using mp_map_update = typename detail::mp_map_update_impl<M, T, F>::type;
// mp_map_erase<M, K>
namespace detail
{
template<class M, class K> struct mp_map_erase_impl
{
template<class T> using _f = std::is_same<mp_first<T>, K>;
using type = mp_remove_if<M, _f>;
};
} // namespace detail
template<class M, class K> using mp_map_erase = typename detail::mp_map_erase_impl<M, K>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED
#ifndef BOOST_MP11_BIND_HPP_INCLUDED
#define BOOST_MP11_BIND_HPP_INCLUDED
// Copyright 2017 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 <cstddef>
namespace boost
{
namespace mp11
{
// mp_arg
template<std::size_t I> struct mp_arg
{
template<class... T> using fn = mp_at_c<mp_list<T...>, I>;
};
using _1 = mp_arg<0>;
using _2 = mp_arg<1>;
using _3 = mp_arg<2>;
using _4 = mp_arg<3>;
using _5 = mp_arg<4>;
using _6 = mp_arg<5>;
using _7 = mp_arg<6>;
using _8 = mp_arg<7>;
using _9 = mp_arg<8>;
// mp_bind
template<template<class...> class F, class... T> struct mp_bind;
namespace detail
{
template<class V, class... T> struct eval_bound_arg
{
using type = V;
};
template<std::size_t I, class... T> struct eval_bound_arg<mp_arg<I>, T...>
{
using type = typename mp_arg<I>::template fn<T...>;
};
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind<F, U...>, T...>
{
using type = typename mp_bind<F, U...>::template fn<T...>;
};
} // namespace detail
template<template<class...> class F, class... T> struct mp_bind
{
template<class... U> using fn = F<typename detail::eval_bound_arg<T, U...>::type...>;
};
template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;
// mp_bind_front
template<template<class...> class F, class... T> struct mp_bind_front
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 )
#else
private:
#endif
template<class... U> struct _fn { using type = F<T..., U...>; };
public:
// the indirection through _fn works around the language inability
// to expand U... into a fixed parameter list of an alias template
template<class... U> using fn = typename _fn<U...>::type;
};
template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>;
// mp_bind_back
template<template<class...> class F, class... T> struct mp_bind_back
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 )
#else
private:
#endif
template<class... U> struct _fn { using type = F<U..., T...>; };
public:
template<class... U> using fn = typename _fn<U...>::type;
};
template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED
#ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
#define BOOST_MP11_TUPLE_HPP_INCLUDED
// Copyright 2015, 2017 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/config.hpp>
#include <boost/detail/workaround.hpp>
#include <tuple>
#include <utility>
#include <type_traits>
#include <cstddef>
namespace boost
{
namespace mp11
{
// tuple_apply
namespace detail
{
template<class F, class Tp, std::size_t... J> BOOST_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))... ) )
{
return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
}
} // namespace detail
template<class F, class Tp,
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
BOOST_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
-> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
{
return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
}
// construct_from_tuple
namespace detail
{
template<class T, class Tp, std::size_t... J> BOOST_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
{
return T( std::get<J>(std::forward<Tp>(tp))... );
}
} // namespace detail
template<class T, class Tp,
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
BOOST_CONSTEXPR T construct_from_tuple( Tp && tp )
{
return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
}
// tuple_for_each
namespace detail
{
template<class Tp, std::size_t... J, class F> BOOST_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);
}
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t>, F && f )
{
return std::forward<F>(f);
}
#endif
} // namespace detail
template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
{
using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
}
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_TUPLE_HPP_INCLUDED
#endif // #ifndef BOOST_MP11_HPP_INCLUDED