diff --git a/boost/logic/tribool.hpp b/boost/logic/tribool.hpp new file mode 100644 index 0000000..041c59c --- /dev/null +++ b/boost/logic/tribool.hpp @@ -0,0 +1,469 @@ +// Three-state boolean logic library + +// Copyright Douglas Gregor 2002-2004. Use, modification and +// distribution is subject to 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) + + +// For more information, see http://www.boost.org +#ifndef BOOST_LOGIC_TRIBOOL_HPP +#define BOOST_LOGIC_TRIBOOL_HPP + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +namespace boost { namespace logic { + +/// INTERNAL ONLY +namespace detail { +/** + * INTERNAL ONLY + * + * \brief A type used only to uniquely identify the 'indeterminate' + * function/keyword. + */ +struct indeterminate_t +{ +#if BOOST_WORKAROUND(__BORLANDC__, < 0x0600) + char dummy_; // BCB would use 8 bytes by default +#endif +}; + +} // end namespace detail + +/** + * INTERNAL ONLY + * The type of the 'indeterminate' keyword. This has the same type as the + * function 'indeterminate' so that we can recognize when the keyword is + * used. + */ +typedef bool (*indeterminate_keyword_t)(tribool, detail::indeterminate_t); + +/** + * \brief Keyword and test function for the indeterminate tribool value + * + * The \c indeterminate function has a dual role. It's first role is + * as a unary function that tells whether the tribool value is in the + * "indeterminate" state. It's second role is as a keyword + * representing the indeterminate (just like "true" and "false" + * represent the true and false states). If you do not like the name + * "indeterminate", and would prefer to use a different name, see the + * macro \c BOOST_TRIBOOL_THIRD_STATE. + * + * \returns x.value == tribool::indeterminate_value + * \throws nothrow + */ +BOOST_CONSTEXPR inline bool +indeterminate(tribool x, + detail::indeterminate_t dummy = detail::indeterminate_t()) BOOST_NOEXCEPT; + +/** + * \brief A 3-state boolean type. + * + * 3-state boolean values are either true, false, or + * indeterminate. + */ +class tribool +{ +#if defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) +private: + /// INTERNAL ONLY + struct dummy { + void nonnull() {}; + }; + + typedef void (dummy::*safe_bool)(); +#endif + +public: + /** + * Construct a new 3-state boolean value with the value 'false'. + * + * \throws nothrow + */ + BOOST_CONSTEXPR tribool() BOOST_NOEXCEPT : value(false_value) {} + + /** + * Construct a new 3-state boolean value with the given boolean + * value, which may be \c true or \c false. + * + * \throws nothrow + */ + BOOST_CONSTEXPR tribool(bool initial_value) BOOST_NOEXCEPT : value(initial_value? true_value : false_value) {} + + /** + * Construct a new 3-state boolean value with an indeterminate value. + * + * \throws nothrow + */ + BOOST_CONSTEXPR tribool(indeterminate_keyword_t) BOOST_NOEXCEPT : value(indeterminate_value) {} + + /** + * Use a 3-state boolean in a boolean context. Will evaluate true in a + * boolean context only when the 3-state boolean is definitely true. + * + * \returns true if the 3-state boolean is true, false otherwise + * \throws nothrow + */ +#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) + + BOOST_CONSTEXPR explicit operator bool () const BOOST_NOEXCEPT + { + return value == true_value; + } + +#else + + BOOST_CONSTEXPR operator safe_bool() const BOOST_NOEXCEPT + { + return value == true_value? &dummy::nonnull : 0; + } + +#endif + + /** + * The actual stored value in this 3-state boolean, which may be false, true, + * or indeterminate. + */ + enum value_t { false_value, true_value, indeterminate_value } value; +}; + +// Check if the given tribool has an indeterminate value. Also doubles as a +// keyword for the 'indeterminate' value +BOOST_CONSTEXPR inline bool indeterminate(tribool x, detail::indeterminate_t) BOOST_NOEXCEPT +{ + return x.value == tribool::indeterminate_value; +} + +/** @defgroup logical Logical operations + */ +//@{ +/** + * \brief Computes the logical negation of a tribool + * + * \returns the logical negation of the tribool, according to the + * table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
!
+ *
false
true
true
false
indeterminate
indeterminate
+ * \throws nothrow + */ +BOOST_CONSTEXPR inline tribool operator!(tribool x) BOOST_NOEXCEPT +{ + return x.value == tribool::false_value? tribool(true) + :x.value == tribool::true_value? tribool(false) + :tribool(indeterminate); +} + +/** + * \brief Computes the logical conjunction of two tribools + * + * \returns the result of logically ANDing the two tribool values, + * according to the following table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
&&
false
true
indeterminate
false
false
false
false
true
false
true
indeterminate
indeterminate
false
indeterminate
indeterminate
+ * \throws nothrow + */ +BOOST_CONSTEXPR inline tribool operator&&(tribool x, tribool y) BOOST_NOEXCEPT +{ + return (static_cast(!x) || static_cast(!y)) + ? tribool(false) + : ((static_cast(x) && static_cast(y)) ? tribool(true) : indeterminate) + ; +} + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator&&(tribool x, bool y) BOOST_NOEXCEPT +{ return y? x : tribool(false); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator&&(bool x, tribool y) BOOST_NOEXCEPT +{ return x? y : tribool(false); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator&&(indeterminate_keyword_t, tribool x) BOOST_NOEXCEPT +{ return !x? tribool(false) : tribool(indeterminate); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator&&(tribool x, indeterminate_keyword_t) BOOST_NOEXCEPT +{ return !x? tribool(false) : tribool(indeterminate); } + +/** + * \brief Computes the logical disjunction of two tribools + * + * \returns the result of logically ORing the two tribool values, + * according to the following table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
||
false
true
indeterminate
false
false
true
indeterminate
true
true
true
true
indeterminate
indeterminate
true
indeterminate
+ * \throws nothrow + */ +BOOST_CONSTEXPR inline tribool operator||(tribool x, tribool y) BOOST_NOEXCEPT +{ + return (static_cast(!x) && static_cast(!y)) + ? tribool(false) + : ((static_cast(x) || static_cast(y)) ? tribool(true) : tribool(indeterminate)) + ; +} + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator||(tribool x, bool y) BOOST_NOEXCEPT +{ return y? tribool(true) : x; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator||(bool x, tribool y) BOOST_NOEXCEPT +{ return x? tribool(true) : y; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator||(indeterminate_keyword_t, tribool x) BOOST_NOEXCEPT +{ return x? tribool(true) : tribool(indeterminate); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator||(tribool x, indeterminate_keyword_t) BOOST_NOEXCEPT +{ return x? tribool(true) : tribool(indeterminate); } +//@} + +/** + * \brief Compare tribools for equality + * + * \returns the result of comparing two tribool values, according to + * the following table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
==
false
true
indeterminate
false
true
false
indeterminate
true
false
true
indeterminate
indeterminate
indeterminate
indeterminate
indeterminate
+ * \throws nothrow + */ +BOOST_CONSTEXPR inline tribool operator==(tribool x, tribool y) BOOST_NOEXCEPT +{ + return (indeterminate(x) || indeterminate(y)) + ? indeterminate + : ((x && y) || (!x && !y)) + ; +} + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator==(tribool x, bool y) BOOST_NOEXCEPT { return x == tribool(y); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator==(bool x, tribool y) BOOST_NOEXCEPT { return tribool(x) == y; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator==(indeterminate_keyword_t, tribool x) BOOST_NOEXCEPT +{ return tribool(indeterminate) == x; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator==(tribool x, indeterminate_keyword_t) BOOST_NOEXCEPT +{ return tribool(indeterminate) == x; } + +/** + * \brief Compare tribools for inequality + * + * \returns the result of comparing two tribool values for inequality, + * according to the following table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
!=
false
true
indeterminate
false
false
true
indeterminate
true
true
false
indeterminate
indeterminate
indeterminate
indeterminate
indeterminate
+ * \throws nothrow + */ +BOOST_CONSTEXPR inline tribool operator!=(tribool x, tribool y) BOOST_NOEXCEPT +{ + return (indeterminate(x) || indeterminate(y)) + ? indeterminate + : !((x && y) || (!x && !y)) + ; +} + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator!=(tribool x, bool y) BOOST_NOEXCEPT { return x != tribool(y); } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator!=(bool x, tribool y) BOOST_NOEXCEPT { return tribool(x) != y; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator!=(indeterminate_keyword_t, tribool x) BOOST_NOEXCEPT +{ return tribool(indeterminate) != x; } + +/** + * \overload + */ +BOOST_CONSTEXPR inline tribool operator!=(tribool x, indeterminate_keyword_t) BOOST_NOEXCEPT +{ return x != tribool(indeterminate); } + +} } // end namespace boost::logic + +// Pull tribool and indeterminate into namespace "boost" +namespace boost { + using logic::tribool; + using logic::indeterminate; +} + +/** + * \brief Declare a new name for the third state of a tribool + * + * Use this macro to declare a new name for the third state of a + * tribool. This state can have any number of new names (in addition + * to \c indeterminate), all of which will be equivalent. The new name will be + * placed in the namespace in which the macro is expanded. + * + * Example: + * BOOST_TRIBOOL_THIRD_STATE(true_or_false) + * + * tribool x(true_or_false); + * // potentially set x + * if (true_or_false(x)) { + * // don't know what x is + * } + */ +#define BOOST_TRIBOOL_THIRD_STATE(Name) \ +inline bool \ +Name(boost::logic::tribool x, \ + boost::logic::detail::indeterminate_t = \ + boost::logic::detail::indeterminate_t()) \ +{ return x.value == boost::logic::tribool::indeterminate_value; } + +#endif // BOOST_LOGIC_TRIBOOL_HPP + diff --git a/boost/logic/tribool_fwd.hpp b/boost/logic/tribool_fwd.hpp new file mode 100644 index 0000000..2cdd91b --- /dev/null +++ b/boost/logic/tribool_fwd.hpp @@ -0,0 +1,15 @@ +// Three-state boolean logic library + +// Copyright Douglas Gregor 2002-2004. Use, modification and +// distribution is subject to 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) + + +// For more information, see http://www.boost.org +#ifndef BOOST_LOGIC_TRIBOOL_FWD_HPP +#define BOOST_LOGIC_TRIBOOL_FWD_HPP + +namespace boost { namespace logic { class tribool; } } + +#endif // BOOST_LOGIC_TRIBOOL_FWD_HPP diff --git a/boost/logic/tribool_io.hpp b/boost/logic/tribool_io.hpp new file mode 100644 index 0000000..2696dca --- /dev/null +++ b/boost/logic/tribool_io.hpp @@ -0,0 +1,343 @@ +// Three-state boolean logic library + +// Copyright Douglas Gregor 2002-2004. Use, modification and +// distribution is subject to 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_LOGIC_TRIBOOL_IO_HPP +#define BOOST_LOGIC_TRIBOOL_IO_HPP + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma once +#endif + +#ifndef BOOST_NO_STD_LOCALE +# include +#endif + +#include +#include + +namespace boost { namespace logic { + +#ifdef BOOST_NO_STD_LOCALE + +/** + * \brief Returns a string containing the default name for the \c + * false value of a tribool with the given character type T. + * + * This function only exists when the C++ standard library + * implementation does not support locales. + */ +template std::basic_string default_false_name(); + +/** + * \brief Returns the character string "false". + * + * This function only exists when the C++ standard library + * implementation does not support locales. + */ +template<> +inline std::basic_string default_false_name() +{ return "false"; } + +# if !defined(BOOST_NO_CWCHAR) +/** + * \brief Returns the wide character string L"false". + * + * This function only exists when the C++ standard library + * implementation does not support locales. + */ +template<> +inline std::basic_string default_false_name() +{ return L"false"; } +# endif + +/** + * \brief Returns a string containing the default name for the \c true + * value of a tribool with the given character type T. + * + * This function only exists when the C++ standard library + * implementation does not support locales. + */ +template std::basic_string default_true_name(); + +/** + * \brief Returns the character string "true". + * + * This function only exists when the C++ standard library + * implementation does not support locales. + */ +template<> +inline std::basic_string default_true_name() +{ return "true"; } + +# if !defined(BOOST_NO_CWCHAR) +/** + * \brief Returns the wide character string L"true". + * + * This function only exists * when the C++ standard library + * implementation does not support * locales. + */ +template<> +inline std::basic_string default_true_name() +{ return L"true"; } +# endif +#endif + +/** + * \brief Returns a string containing the default name for the indeterminate + * value of a tribool with the given character type T. + * + * This routine is used by the input and output streaming operators + * for tribool when there is no locale support or the stream's locale + * does not contain the indeterminate_name facet. + */ +template std::basic_string get_default_indeterminate_name(); + +/// Returns the character string "indeterminate". +template<> +inline std::basic_string get_default_indeterminate_name() +{ return "indeterminate"; } + +#if !defined(BOOST_NO_CWCHAR) +/// Returns the wide character string L"indeterminate". +template<> +inline std::basic_string get_default_indeterminate_name() +{ return L"indeterminate"; } +#endif + +// http://www.cantrip.org/locale.html + +#ifndef BOOST_NO_STD_LOCALE +/** + * \brief A locale facet specifying the name of the indeterminate + * value of a tribool. + * + * The facet is used to perform I/O on tribool values when \c + * std::boolalpha has been specified. This class template is only + * available if the C++ standard library implementation supports + * locales. + */ +template +class indeterminate_name : public std::locale::facet, private boost::noncopyable +{ +public: + typedef CharT char_type; + typedef std::basic_string string_type; + + /// Construct the facet with the default name + indeterminate_name() : name_(get_default_indeterminate_name()) {} + + /// Construct the facet with the given name for the indeterminate value + explicit indeterminate_name(const string_type& initial_name) + : name_(initial_name) {} + + /// Returns the name for the indeterminate value + string_type name() const { return name_; } + + /// Uniquily identifies this facet with the locale. + static std::locale::id id; + +private: + string_type name_; +}; + +template std::locale::id indeterminate_name::id; +#endif + +/** + * \brief Writes the value of a tribool to a stream. + * + * When the value of @p x is either \c true or \c false, this routine + * is semantically equivalent to: + * \code out << static_cast(x); \endcode + * + * When @p x has an indeterminate value, it outputs either the integer + * value 2 (if (out.flags() & std::ios_base::boolalpha) == 0) + * or the name of the indeterminate value. The name of the + * indeterminate value comes from the indeterminate_name facet (if it + * is defined in the output stream's locale), or from the + * get_default_indeterminate_name function (if it is not defined in the + * locale or if the C++ standard library implementation does not + * support locales). + * + * \returns @p out + */ +template +inline std::basic_ostream& +operator<<(std::basic_ostream& out, tribool x) +{ + if (!indeterminate(x)) { + out << static_cast(x); + } else { + typename std::basic_ostream::sentry cerberus(out); + if (cerberus) { + if (out.flags() & std::ios_base::boolalpha) { +#ifndef BOOST_NO_STD_LOCALE + if (BOOST_HAS_FACET(indeterminate_name, out.getloc())) { + const indeterminate_name& facet = + BOOST_USE_FACET(indeterminate_name, out.getloc()); + out << facet.name(); + } else { + out << get_default_indeterminate_name(); + } +#else + out << get_default_indeterminate_name(); +#endif + } + else + out << 2; + } + } + return out; +} + +/** + * \brief Writes the indeterminate tribool value to a stream. + * + * This routine outputs either the integer + * value 2 (if (out.flags() & std::ios_base::boolalpha) == 0) + * or the name of the indeterminate value. The name of the + * indeterminate value comes from the indeterminate_name facet (if it + * is defined in the output stream's locale), or from the + * get_default_indeterminate_name function (if it is not defined in the + * locale or if the C++ standard library implementation does not + * support locales). + * + * \returns @p out + */ +template +inline std::basic_ostream& +operator<<(std::basic_ostream& out, + bool (*)(tribool, detail::indeterminate_t)) +{ return out << tribool(indeterminate); } + +/** + * \brief Reads a tribool value from a stream. + * + * When (out.flags() & std::ios_base::boolalpha) == 0, this + * function reads a \c long value from the input stream @p in and + * converts that value to a tribool. If that value is 0, @p x becomes + * \c false; if it is 1, @p x becomes \c true; if it is 2, @p becomes + * \c indetermine; otherwise, the operation fails (and the fail bit is + * set on the input stream @p in). + * + * When (out.flags() & std::ios_base::boolalpha) != 0, this + * function first determines the names of the false, true, and + * indeterminate values. The false and true names are extracted from + * the \c std::numpunct facet of the input stream's locale (if the C++ + * standard library implementation supports locales), or from the \c + * default_false_name and \c default_true_name functions (if there is + * no locale support). The indeterminate name is extracted from the + * appropriate \c indeterminate_name facet (if it is available in the + * input stream's locale), or from the \c get_default_indeterminate_name + * function (if the C++ standard library implementation does not + * support locales, or the \c indeterminate_name facet is not + * specified for this locale object). The input is then matched to + * each of these names, and the tribool @p x is assigned the value + * corresponding to the longest name that matched. If no name is + * matched or all names are empty, the operation fails (and the fail + * bit is set on the input stream @p in). + * + * \returns @p in + */ +template +inline std::basic_istream& +operator>>(std::basic_istream& in, tribool& x) +{ + if (in.flags() & std::ios_base::boolalpha) { + typename std::basic_istream::sentry cerberus(in); + if (cerberus) { + typedef std::basic_string string_type; + +#ifndef BOOST_NO_STD_LOCALE + const std::numpunct& numpunct_facet = + BOOST_USE_FACET(std::numpunct, in.getloc()); + + string_type falsename = numpunct_facet.falsename(); + string_type truename = numpunct_facet.truename(); + + string_type othername; + if (BOOST_HAS_FACET(indeterminate_name, in.getloc())) { + othername = + BOOST_USE_FACET(indeterminate_name, in.getloc()).name(); + } else { + othername = get_default_indeterminate_name(); + } +#else + string_type falsename = default_false_name(); + string_type truename = default_true_name(); + string_type othername = get_default_indeterminate_name(); +#endif + + typename string_type::size_type pos = 0; + bool falsename_ok = true, truename_ok = true, othername_ok = true; + + // Modeled after the code from Library DR 17 + while ((falsename_ok && pos < falsename.size()) + || (truename_ok && pos < truename.size()) + || (othername_ok && pos < othername.size())) { + typename Traits::int_type c = in.get(); + if (c == Traits::eof()) + return in; + + bool matched = false; + if (falsename_ok && pos < falsename.size()) { + if (Traits::eq(Traits::to_char_type(c), falsename[pos])) + matched = true; + else + falsename_ok = false; + } + + if (truename_ok && pos < truename.size()) { + if (Traits::eq(Traits::to_char_type(c), truename[pos])) + matched = true; + else + truename_ok = false; + } + + if (othername_ok && pos < othername.size()) { + if (Traits::eq(Traits::to_char_type(c), othername[pos])) + matched = true; + else + othername_ok = false; + } + + if (matched) { ++pos; } + if (pos > falsename.size()) falsename_ok = false; + if (pos > truename.size()) truename_ok = false; + if (pos > othername.size()) othername_ok = false; + } + + if (pos == 0) + in.setstate(std::ios_base::failbit); + else { + if (falsename_ok) x = false; + else if (truename_ok) x = true; + else if (othername_ok) x = indeterminate; + else in.setstate(std::ios_base::failbit); + } + } + } else { + long value; + if (in >> value) { + switch (value) { + case 0: x = false; break; + case 1: x = true; break; + case 2: x = indeterminate; break; + default: in.setstate(std::ios_base::failbit); break; + } + } + } + + return in; +} + +} } // end namespace boost::logic + +#endif // BOOST_LOGIC_TRIBOOL_IO_HPP diff --git a/boost/mp11.hpp b/boost/mp11.hpp new file mode 100644 index 0000000..5e45939 --- /dev/null +++ b/boost/mp11.hpp @@ -0,0 +1,22 @@ +#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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef BOOST_MP11_HPP_INCLUDED diff --git a/boost/mp11/algorithm.hpp b/boost/mp11/algorithm.hpp new file mode 100644 index 0000000..6ffc572 --- /dev/null +++ b/boost/mp11/algorithm.hpp @@ -0,0 +1,1111 @@ +#ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED +#define BOOST_MP11_ALGORITHM_HPP_INCLUDED + +// Copyright 2015-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_transform +namespace detail +{ + +template class F, class... L> struct mp_transform_impl +{ +}; + +template class F, template class L, class... T> struct mp_transform_impl> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L::type...>; + +#else + + using type = L...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_impl, L2, L3> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template using mp_same_size_1 = mp_same...>; +template struct mp_same_size_2: mp_defer {}; + +#endif + +struct list_size_mismatch +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> struct mp_transform_cuda_workaround +{ + using type = mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template class F, class... L> using mp_transform = typename mp_if::type, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> using mp_transform = typename detail::mp_transform_cuda_workaround< F, L...>::type::type; + +#else + +template class F, class... L> using mp_transform = typename mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#endif + +#endif + +template using mp_transform_q = mp_transform; + +namespace detail +{ + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, class... L> struct mp_transform_impl, L2, L3, L4, L...> +{ + using A1 = L1...>; + + template using _f = mp_transform; + + using A2 = mp_fold, A1, _f>; + + template using _g = mp_apply; + + using type = mp_transform<_g, A2>; +}; + +} // namespace detail + +// mp_transform_if +namespace detail +{ + +template class P, template 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

; + using Qf = mp_quote; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f_ { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; + template using _f = typename _f_::type; + +#else + + template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; + +#endif + + using type = mp_transform<_f, L...>; +}; + +} // namespace detail + +template class P, template class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl::type; +template using mp_transform_if_q = typename detail::mp_transform_if_impl::type; + +// mp_filter +namespace detail +{ + +template class P, class L1, class... L> struct mp_filter_impl +{ + using Qp = mp_quote

; + + template using _f = mp_if< mp_invoke_q, mp_list, mp_list<> >; + + using _t1 = mp_transform<_f, L1, L...>; + using _t2 = mp_apply; + + using type = mp_assign; +}; + +} // namespace detail + +template class P, class... L> using mp_filter = typename detail::mp_filter_impl::type; +template using mp_filter_q = typename detail::mp_filter_impl::type; + +// mp_fill +namespace detail +{ + +template struct mp_fill_impl; + +template class L, class... T, class V> struct mp_fill_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) + + template struct _f { using type = V; }; + using type = L::type...>; + +#else + + template using _f = V; + using type = L<_f...>; + +#endif +}; + +} // namespace detail + +template using mp_fill = typename detail::mp_fill_impl::type; + +// mp_contains +template using mp_contains = mp_to_bool>; + +// mp_repeat(_c) +namespace detail +{ + +template struct mp_repeat_c_impl +{ + using _l1 = typename mp_repeat_c_impl::type; + using _l2 = typename mp_repeat_c_impl::type; + + using type = mp_append<_l1, _l1, _l2>; +}; + +template struct mp_repeat_c_impl +{ + using type = mp_clear; +}; + +template struct mp_repeat_c_impl +{ + using type = L; +}; + +} // namespace detail + +template using mp_repeat_c = typename detail::mp_repeat_c_impl::type; +template using mp_repeat = typename detail::mp_repeat_c_impl::type; + +// mp_product +namespace detail +{ + +template class F, class P, class... L> struct mp_product_impl_2; + +template class F, class P> struct mp_product_impl_2 +{ + using type = mp_list>; +}; + +template class F, class P, template class L1, class... T1, class... L> struct mp_product_impl_2, L...> +{ + using type = mp_append, L...>::type...>; +}; + +template class F, class... L> struct mp_product_impl; + +template class F, class L1, class... L> struct mp_product_impl +{ + using type = mp_assign, L1, L...>::type>; +}; + +} // namespace detail + +template class F, class... L> using mp_product = typename detail::mp_product_impl::type; +template using mp_product_q = typename detail::mp_product_impl::type; + +// mp_drop(_c) +namespace detail +{ + +template struct mp_drop_impl; + +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2> +{ + template static mp_identity> f( U*..., mp_identity*... ); + + using R = decltype( f( (mp_identity*)0 ... ) ); + + using type = typename R::type; +}; + +} // namespace detail + +template using mp_drop_c = typename detail::mp_drop_impl, N>>::type; + +template using mp_drop = typename detail::mp_drop_impl, N>>::type; + +// mp_from_sequence +namespace detail +{ + +template struct mp_from_sequence_impl; + +template class S, class U, U... J> struct mp_from_sequence_impl> +{ + using type = mp_list...>; +}; + +} // namespace detail + +template using mp_from_sequence = typename detail::mp_from_sequence_impl::type; + +// mp_iota(_c) +template using mp_iota_c = mp_from_sequence>; +template using mp_iota = mp_from_sequence::type, N::value>>; + +// mp_at(_c) +namespace detail +{ + +template struct mp_at_c_impl; + +#if defined(BOOST_MP11_HAS_TYPE_PACK_ELEMENT) + +template class L, class... T, std::size_t I> struct mp_at_c_impl, I> +{ + using type = __type_pack_element; +}; + +#else + +template struct mp_at_c_impl +{ + using _map = mp_transform >, L>; + using type = mp_second > >; +}; + +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template struct mp_at_c_cuda_workaround +{ + using type = mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template using mp_at_c = typename detail::mp_at_c_cuda_workaround< L, I >::type::type; + +#else + +template using mp_at_c = typename mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>::type; + +#endif + +template using mp_at = mp_at_c; + +// mp_take(_c) +namespace detail +{ + +template struct mp_take_c_impl +{ +}; + +template class L, class... T> +struct mp_take_c_impl<0, L> +{ + using type = L<>; +}; + +template class L, class T1, class... T> +struct mp_take_c_impl<1, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class... T> +struct mp_take_c_impl<2, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class... T> +struct mp_take_c_impl<3, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class... T> +struct mp_take_c_impl<4, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class... T> +struct mp_take_c_impl<5, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T> +struct mp_take_c_impl<6, L> +{ + using type = L; +}; + +template 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> +{ + using type = L; +}; + +template 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> +{ + using type = L; +}; + +template 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> +{ + using type = L; +}; + +template 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> +struct mp_take_c_impl, typename std::enable_if= 10>::type> +{ + using type = mp_append, typename mp_take_c_impl>::type>; +}; + +} // namespace detail + +template using mp_take_c = typename detail::mp_take_c_impl::type; +template using mp_take = typename detail::mp_take_c_impl::type; + +// mp_back +template using mp_back = mp_at_c::value - 1>; + +// mp_pop_back +template using mp_pop_back = mp_take_c::value - 1>; + +// mp_replace +namespace detail +{ + +template struct mp_replace_impl; + +template class L, class... T, class V, class W> struct mp_replace_impl, V, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + template struct _f { using type = mp_if, W, A>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, A>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template using mp_replace = typename detail::mp_replace_impl::type; + +// mp_replace_if +namespace detail +{ + +template class P, class W> struct mp_replace_if_impl; + +template class L, class... T, template class P, class W> struct mp_replace_if_impl, P, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, W, U>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, U>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl::type; +template using mp_replace_if_q = mp_replace_if; + +// mp_copy_if +// in detail/mp_copy_if.hpp + +// mp_remove +namespace detail +{ + +template struct mp_remove_impl; + +template class L, class... T, class V> struct mp_remove_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template using mp_remove = typename detail::mp_remove_impl::type; + +// mp_remove_if +// in detail/mp_remove_if.hpp + +// mp_flatten> +namespace detail +{ + +template struct mp_flatten_impl +{ + template using fn = mp_if, T, mp_list>; +}; + +} // namespace detail + +template> using mp_flatten = mp_apply, L>, mp_clear>>; + +// mp_partition +namespace detail +{ + +template class P> struct mp_partition_impl; + +template class L, class... T, template class P> struct mp_partition_impl, P> +{ + using type = L, P>, mp_remove_if, P>>; +}; + +} // namespace detail + +template class P> using mp_partition = typename detail::mp_partition_impl::type; +template using mp_partition_q = mp_partition; + +// mp_sort +namespace detail +{ + +template class P> struct mp_sort_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_sort_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_sort_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, template class P> struct mp_sort_impl, P> +{ + using type = L; +}; + +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + template using F = P; + + using part = mp_partition, F>; + + using S1 = typename mp_sort_impl, P>::type; + using S2 = typename mp_sort_impl, P>::type; + + using type = mp_append, S2>; +}; + +} // namespace detail + +template class P> using mp_sort = typename detail::mp_sort_impl::type; +template using mp_sort_q = mp_sort; + +// mp_nth_element(_c) +namespace detail +{ + +template class P> struct mp_nth_element_impl; + +template class L, class T1, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I == 0, "mp_nth_element index out of range" ); + using type = T1; +}; + +template class L, class T1, class... T, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" ); + + template using F = P; + + using part = mp_partition, F>; + + using L1 = mp_first; + static std::size_t const N1 = mp_size::value; + + using L2 = mp_second; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + + struct detail + { + struct mp_nth_element_impl_cuda_workaround + { + using type = mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >; + }; + }; + + using type = typename detail::mp_nth_element_impl_cuda_workaround::type::type; + +#else + + using type = typename mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >::type; + +#endif +}; + +} // namespace detail + +template class P> using mp_nth_element_c = typename detail::mp_nth_element_impl::type; +template class P> using mp_nth_element = typename detail::mp_nth_element_impl::type; +template using mp_nth_element_q = mp_nth_element; + +// mp_find +namespace detail +{ + +template struct mp_find_impl; + +#if BOOST_MP11_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 class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + std::is_same::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + std::size_t m = 0; + + while( first != last && !*first ) + { + ++m; + ++first; + } + + return m; +} + +#else + +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 ); +} + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr bool _v[] = { std::is_same::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +template class L, class T1, class... T, class V> struct mp_find_impl, V> +{ + using _r = typename mp_find_impl, V>::type; + using type = mp_size_t<1 + _r::value>; +}; + +#endif + +} // namespace detail + +template using mp_find = typename detail::mp_find_impl::type; + +// mp_find_if +namespace detail +{ + +template class P> struct mp_find_if_impl; + +#if BOOST_MP11_CLANG && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + P::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr bool _v[] = { P::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class P> struct mp_find_if_impl_2 +{ + using _r = typename mp_find_if_impl::type; + using type = mp_size_t<1 + _r::value>; +}; + +template class L, class T1, class... T, template class P> struct mp_find_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_if_impl_2, P>>::type; +}; + +#endif + +} // namespace detail + +template class P> using mp_find_if = typename detail::mp_find_if_impl::type; +template using mp_find_if_q = mp_find_if; + +// mp_reverse +namespace detail +{ + +template struct mp_reverse_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T> struct mp_reverse_impl> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L> struct mp_reverse_impl> +{ + using type = L<>; +}; + +#endif + +template class L, class T1> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> struct mp_reverse_impl> +{ + using type = L; +}; + +template 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> +{ + using type = mp_push_back>::type, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1>; +}; + +} // namespace detail + +template using mp_reverse = typename detail::mp_reverse_impl::type; + +// mp_fold +// in detail/mp_fold.hpp + +// mp_reverse_fold +namespace detail +{ + +template class F> struct mp_reverse_fold_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F; +}; + +template 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 F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F > > > > > > > > >; +}; + +} // namespace detail + +template class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl::type; +template using mp_reverse_fold_q = mp_reverse_fold; + +// mp_unique +namespace detail +{ + +template struct mp_unique_impl; + +template class L, class... T> struct mp_unique_impl> +{ + using type = mp_set_push_back, T...>; +}; + +} // namespace detail + +template using mp_unique = typename detail::mp_unique_impl::type; + +// mp_unique_if +namespace detail +{ + +template class P> struct mp_unique_if_push_back +{ + template struct impl + { + }; + + template class L, class... Ts, class T> + struct impl, T> + { + using type = mp_if...>, L, L>; + }; + + template using fn = typename impl::type; +}; + +} // namespace detail + +template class P> +using mp_unique_if = mp_fold_q, detail::mp_unique_if_push_back

>; + +template using mp_unique_if_q = mp_unique_if; + +// mp_all_of +template class P> using mp_all_of = mp_bool< mp_count_if::value == mp_size::value >; +template using mp_all_of_q = mp_all_of; + +// mp_none_of +template class P> using mp_none_of = mp_bool< mp_count_if::value == 0 >; +template using mp_none_of_q = mp_none_of; + +// mp_any_of +template class P> using mp_any_of = mp_bool< mp_count_if::value != 0 >; +template using mp_any_of_q = mp_any_of; + +// mp_replace_at_c +namespace detail +{ + +template struct mp_replace_at_impl +{ + static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); + + template using _p = std::is_same>; + template using _f = W; + + using type = mp_transform_if<_p, _f, L, mp_iota > >; +}; + +} // namespace detail + +template using mp_replace_at = typename detail::mp_replace_at_impl::type; +template using mp_replace_at_c = typename detail::mp_replace_at_impl, W>::type; + +//mp_for_each(f) +namespace detail +{ + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list, F && f ) +{ + using A = int[sizeof...(T)]; + return (void)A{ ((void)f(T()), 0)... }, std::forward(f); +} + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f ) +{ + return std::forward(f); +} + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, >= 1900 ) + +// msvc has a limit of 1024 + +template BOOST_MP11_CONSTEXPR mp_if_c::value <= 1024, F> mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +template BOOST_MP11_CONSTEXPR mp_if_c::value >= 1025, F> mp_for_each( F && f ) +{ + using L2 = mp_rename; + + using L3 = mp_take_c; + using L4 = mp_drop_c; + + return mp_for_each( mp_for_each( std::forward(f) ) ); +} + +#else + +template BOOST_MP11_CONSTEXPR F mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +#endif + +// mp_insert +template using mp_insert = mp_append, mp_push_front, T...>>; + +// mp_insert_c +template using mp_insert_c = mp_append, mp_push_front, T...>>; + +// mp_erase +template using mp_erase = mp_append, mp_drop>; + +// mp_erase_c +template using mp_erase_c = mp_append, mp_drop_c>; + +// mp_starts_with +// contributed by Glen Joseph Fernandes (glenjofe@gmail.com) +namespace detail { + +template +struct mp_starts_with_impl { }; + +template class L1, class... T1, template class L2, + class... T2> +struct mp_starts_with_impl, L2 > { + template + static mp_false check(L); + + template + static mp_true check(mp_list); + + using type = decltype(check(mp_list())); +}; + +} // namespace detail + +template +using mp_starts_with = typename detail::mp_starts_with_impl::type; + +// mp_min_element +// mp_max_element +// in detail/mp_min_element.hpp + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED diff --git a/boost/mp11/bind.hpp b/boost/mp11/bind.hpp new file mode 100644 index 0000000..bbdecd2 --- /dev/null +++ b/boost/mp11/bind.hpp @@ -0,0 +1,111 @@ +#ifndef BOOST_MP11_BIND_HPP_INCLUDED +#define BOOST_MP11_BIND_HPP_INCLUDED + +// Copyright 2017, 2018 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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_bind_front +template class F, class... T> struct mp_bind_front +{ + // the indirection through mp_defer works around the language inability + // to expand U... into a fixed parameter list of an alias template + + template using fn = typename mp_defer::type; +}; + +template using mp_bind_front_q = mp_bind_front; + +// mp_bind_back +template class F, class... T> struct mp_bind_back +{ + template using fn = typename mp_defer::type; +}; + +template using mp_bind_back_q = mp_bind_back; + +// mp_arg +template struct mp_arg +{ + template using fn = mp_at_c, 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 class F, class... T> struct mp_bind; + +namespace detail +{ + +template struct eval_bound_arg +{ + using type = V; +}; + +template struct eval_bound_arg, T...> +{ + using type = typename mp_arg::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_front::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_back::template fn; +}; + +} // namespace detail + +template class F, class... T> struct mp_bind +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 ) +private: + + template struct _f { using type = F::type...>; }; + +public: + + template using fn = typename _f::type; + +#else + + template using fn = F::type...>; + +#endif +}; + +template using mp_bind_q = mp_bind; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED diff --git a/boost/mp11/detail/config.hpp b/boost/mp11/detail/config.hpp new file mode 100644 index 0000000..248dce0 --- /dev/null +++ b/boost/mp11/detail/config.hpp @@ -0,0 +1,139 @@ +#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2016, 2018, 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 + +// BOOST_MP11_WORKAROUND + +#if defined( BOOST_STRICT_CONFIG ) || defined( BOOST_MP11_NO_WORKAROUNDS ) + +# define BOOST_MP11_WORKAROUND( symbol, test ) 0 + +#else + +# define BOOST_MP11_WORKAROUND( symbol, test ) ((symbol) != 0 && ((symbol) test)) + +#endif + +// + +#define BOOST_MP11_CUDA 0 +#define BOOST_MP11_CLANG 0 +#define BOOST_MP11_INTEL 0 +#define BOOST_MP11_GCC 0 +#define BOOST_MP11_MSVC 0 + +#define BOOST_MP11_CONSTEXPR constexpr + +#if defined( __CUDACC__ ) + +// nvcc + +# undef BOOST_MP11_CUDA +# define BOOST_MP11_CUDA (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__) + +// CUDA (8.0) has no constexpr support in msvc mode: +# if defined(_MSC_VER) && (BOOST_MP11_CUDA < 9000000) + +# define BOOST_MP11_NO_CONSTEXPR + +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR + +# endif + +#elif defined(__clang__) + +// Clang + +# undef BOOST_MP11_CLANG +# define BOOST_MP11_CLANG (__clang_major__ * 100 + __clang_minor__) + +# if 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 BOOST_MP11_CLANG < 400 && __cplusplus >= 201402L \ + && defined( __GLIBCXX__ ) && !__has_include() + +// Clang pre-4 in C++14 mode, libstdc++ pre-4.9, ::gets is not defined, +// but Clang tries to import it into std + + extern "C" char *gets (char *__s); +#endif + +#elif defined(__INTEL_COMPILER) + +// Intel C++ + +# undef BOOST_MP11_INTEL +# define BOOST_MP11_INTEL __INTEL_COMPILER + +#elif defined(__GNUC__) + +// g++ + +# undef BOOST_MP11_GCC +# define BOOST_MP11_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + +#elif defined(_MSC_VER) + +// MS Visual C++ + +# undef BOOST_MP11_MSVC +# define BOOST_MP11_MSVC _MSC_VER + +# if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) +# define BOOST_MP11_NO_CONSTEXPR +# endif + +#if _MSC_FULL_VER < 190024210 // 2015u3 +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR +#endif + +#endif + +// BOOST_MP11_HAS_CXX14_CONSTEXPR + +#if !defined(BOOST_MP11_NO_CONSTEXPR) && defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +# define BOOST_MP11_HAS_CXX14_CONSTEXPR +#endif + +// BOOST_MP11_HAS_FOLD_EXPRESSIONS + +#if !defined(BOOST_MP11_HAS_FOLD_EXPRESSIONS) && defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603 +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS +#endif + +// BOOST_MP11_HAS_TYPE_PACK_ELEMENT + +#if defined(__has_builtin) +# if __has_builtin(__type_pack_element) +# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT +# endif +#endif + +// BOOST_MP11_DEPRECATED(msg) + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) +# define BOOST_MP11_DEPRECATED(msg) +#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 ) +# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg))) +#elif BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 ) +# define BOOST_MP11_DEPRECATED(msg) +#elif BOOST_MP11_CLANG +// -pedantic warns about [[deprecated]] when in C++11 mode +# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg))) +#else +# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]] +#endif + +#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_append.hpp b/boost/mp11/detail/mp_append.hpp new file mode 100644 index 0000000..937d15e --- /dev/null +++ b/boost/mp11/detail/mp_append.hpp @@ -0,0 +1,185 @@ +#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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_append + +namespace detail +{ + +template struct mp_append_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template struct mp_append_impl +{ +}; + +template<> struct mp_append_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_append_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_append_impl, L2> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_append_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4> struct mp_append_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, template class L5, class... T5, class... Lr> struct mp_append_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename mp_append_impl, Lr...>::type; +}; + +#else + +template, 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 L1, class... T1, + template class L2, class... T2, + template class L3, class... T3, + template class L4, class... T4, + template class L5, class... T5, + template class L6, class... T6, + template class L7, class... T7, + template class L8, class... T8, + template class L9, class... T9, + template class L10, class... T10, + template class L11, class... T11> + +struct append_11_impl, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11> +{ + using type = L1; +}; + +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::type, + typename append_11_impl, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type, + typename append_11_impl, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type, + typename append_11_impl, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type, + typename append_11_impl, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type, + typename append_11_impl, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type, + typename append_11_impl, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type, + typename append_11_impl, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type, + typename append_11_impl, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type, + typename append_11_impl, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type, + typename append_11_impl, 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::type; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template +struct mp_append_impl_cuda_workaround +{ + using type = mp_if_c<(sizeof...(L) > 111), mp_quote, mp_if_c<(sizeof...(L) > 11), mp_quote, mp_quote > >; +}; + +template struct mp_append_impl: mp_append_impl_cuda_workaround::type::template fn +{ +}; + +#else + +template struct mp_append_impl: mp_if_c<(sizeof...(L) > 111), mp_quote, mp_if_c<(sizeof...(L) > 11), mp_quote, mp_quote > >::template fn +{ +}; + +#endif + +#endif + +} // namespace detail + +template using mp_append = typename detail::mp_append_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_copy_if.hpp b/boost/mp11/detail/mp_copy_if.hpp new file mode 100644 index 0000000..4edcde0 --- /dev/null +++ b/boost/mp11/detail/mp_copy_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED + +// Copyright 2015-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 +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_copy_if +namespace detail +{ + +template class P> struct mp_copy_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_copy_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list, mp_list<>>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list, mp_list<>>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_copy_if = typename detail::mp_copy_if_impl::type; +template using mp_copy_if_q = mp_copy_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_count.hpp b/boost/mp11/detail/mp_count.hpp new file mode 100644 index 0000000..1e221ca --- /dev/null +++ b/boost/mp11/detail/mp_count.hpp @@ -0,0 +1,115 @@ +#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 + +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_count +namespace detail +{ + +template struct mp_count_impl; + +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t<(std::is_same::value + ... + 0)>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +constexpr std::size_t cx_plus() +{ + return 0; +} + +template constexpr std::size_t cx_plus(T1 t1, T... t) +{ + return static_cast(t1) + cx_plus(t...); +} + +template +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 static_cast(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...); +} + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t::value...)>; +}; + +#else + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t...>::value>; +}; + +#endif + +} // namespace detail + +template using mp_count = typename detail::mp_count_impl::type; + +// mp_count_if +namespace detail +{ + +template class P> struct mp_count_if_impl; + +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t<(mp_to_bool>::value + ... + 0)>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t>::value...)>; +}; + +#else + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f { using type = mp_to_bool>; }; + using type = mp_size_t::type...>::value>; + +#else + + using type = mp_size_t>...>::value>; + +#endif +}; + +#endif + +} // namespace detail + +template class P> using mp_count_if = typename detail::mp_count_if_impl::type; +template using mp_count_if_q = mp_count_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_fold.hpp b/boost/mp11/detail/mp_fold.hpp new file mode 100644 index 0000000..0745e87 --- /dev/null +++ b/boost/mp11/detail/mp_fold.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FOLD_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 + +namespace boost +{ +namespace mp11 +{ + +// mp_fold +namespace detail +{ + +template class F> struct mp_fold_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_fold is not a list +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = typename mp_fold_impl, F, F>::type; +}; + +template 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 F> struct mp_fold_impl, V, F> +{ + using type = typename mp_fold_impl, F, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type; +}; + +} // namespace detail + +template class F> using mp_fold = typename detail::mp_fold_impl::type; +template using mp_fold_q = mp_fold; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_is_list.hpp b/boost/mp11/detail/mp_is_list.hpp new file mode 100644 index 0000000..25b378b --- /dev/null +++ b/boost/mp11/detail/mp_is_list.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED + +// Copyright 2015-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 + +namespace boost +{ +namespace mp11 +{ + +// mp_is_list +namespace detail +{ + +template struct mp_is_list_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_list_impl> +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_is_list = typename detail::mp_is_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_list.hpp b/boost/mp11/detail/mp_list.hpp new file mode 100644 index 0000000..8e8d3e5 --- /dev/null +++ b/boost/mp11/detail/mp_list.hpp @@ -0,0 +1,24 @@ +#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 +template struct mp_list +{ +}; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_map_find.hpp b/boost/mp11/detail/mp_map_find.hpp new file mode 100644 index 0000000..ec0fabd --- /dev/null +++ b/boost/mp11/detail/mp_map_find.hpp @@ -0,0 +1,43 @@ +#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 + +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_map_find +namespace detail +{ + +template struct mp_map_find_impl; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; + + template class L, class... U> static mp_identity> f( mp_identity>* ); + static mp_identity f( ... ); + + using V = decltype( f((U*)0) ); + + using type = typename V::type; +}; + +} // namespace detail + +template using mp_map_find = typename detail::mp_map_find_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_min_element.hpp b/boost/mp11/detail/mp_min_element.hpp new file mode 100644 index 0000000..55c21ac --- /dev/null +++ b/boost/mp11/detail/mp_min_element.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MIN_ELEMENT_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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_min_element +namespace detail +{ + +template class P> struct select_min +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_min_element = mp_fold_q, mp_first, detail::select_min

>; +template using mp_min_element_q = mp_min_element; + +// mp_max_element +namespace detail +{ + +template class P> struct select_max +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_max_element = mp_fold_q, mp_first, detail::select_max

>; +template using mp_max_element_q = mp_max_element; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_plus.hpp b/boost/mp11/detail/mp_plus.hpp new file mode 100644 index 0000000..90ed4c9 --- /dev/null +++ b/boost/mp11/detail/mp_plus.hpp @@ -0,0 +1,81 @@ +#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 + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_plus +namespace detail +{ + +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + +template struct mp_plus_impl +{ + static const auto _v = (T::value + ... + 0); + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl; + +template<> struct mp_plus_impl<> +{ + using type = std::integral_constant; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template struct mp_plus_impl +{ + static const decltype(T1::value + mp_plus_impl::type::value) _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + 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::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::type::value; + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl +{ + static const auto _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + 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::type::value; + using type = std::integral_constant::type, _v>; +}; + +#endif + +#endif + +} // namespace detail + +template using mp_plus = typename detail::mp_plus_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_remove_if.hpp b/boost/mp11/detail/mp_remove_if.hpp new file mode 100644 index 0000000..9687b4a --- /dev/null +++ b/boost/mp11/detail/mp_remove_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED + +// Copyright 2015-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 +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_remove_if +namespace detail +{ + +template class P> struct mp_remove_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_remove_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_remove_if = typename detail::mp_remove_if_impl::type; +template using mp_remove_if_q = mp_remove_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_void.hpp b/boost/mp11/detail/mp_void.hpp new file mode 100644 index 0000000..a7ac7b7 --- /dev/null +++ b/boost/mp11/detail/mp_void.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_VOID_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 + +namespace boost +{ +namespace mp11 +{ + +// mp_void +namespace detail +{ + +template struct mp_void_impl +{ + using type = void; +}; + +} // namespace detail + +template using mp_void = typename detail::mp_void_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED diff --git a/boost/mp11/detail/mp_with_index.hpp b/boost/mp11/detail/mp_with_index.hpp new file mode 100644 index 0000000..1062877 --- /dev/null +++ b/boost/mp11/detail/mp_with_index.hpp @@ -0,0 +1,396 @@ +#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 +#include +#include +#include +#include + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) +# define BOOST_MP11_CONSTEXPR14 constexpr +#else +# define BOOST_MP11_CONSTEXPR14 +#endif + +#if defined( _MSC_VER ) && !defined( __clang__ ) +# define BOOST_MP11_UNREACHABLE() __assume(false) +#else +# define BOOST_MP11_UNREACHABLE() __builtin_unreachable() +#endif + +namespace boost +{ +namespace mp11 +{ + +namespace detail +{ + +template struct mp_with_index_impl_ +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + + return mp_with_index_impl_::template call( i-16, std::forward(f) ); + } +}; + +template<> struct mp_with_index_impl_<0> +{ +}; + +template<> struct mp_with_index_impl_<1> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t /*i*/, F && f ) + { + return std::forward(f)( mp_size_t() ); + } +}; + +template<> struct mp_with_index_impl_<2> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<3> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<4> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<5> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<6> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<7> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<8> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<9> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<10> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<11> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<12> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<13> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<14> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<15> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<16> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + default: BOOST_MP11_UNREACHABLE(); + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + } +}; + +} // namespace detail + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + assert( i < N ); + return detail::mp_with_index_impl_::template call<0>( i, std::forward(f) ); +} + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + return mp_with_index( i, std::forward(f) ); +} + +#undef BOOST_MP11_CONSTEXPR14 +#undef BOOST_MP11_UNREACHABLE + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED diff --git a/boost/mp11/detail/mpl_common.hpp b/boost/mp11/detail/mpl_common.hpp new file mode 100644 index 0000000..208885c --- /dev/null +++ b/boost/mp11/detail/mpl_common.hpp @@ -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 +#include + +namespace boost +{ +namespace mpl +{ + +struct forward_iterator_tag; + +namespace aux +{ + +struct mp11_tag {}; + +template struct mp11_iterator +{ + using category = forward_iterator_tag; + + using type = mp11::mp_first; + using next = mp11_iterator>; +}; + +} // namespace aux + +// at + +template< typename Tag > struct at_impl; + +template<> struct at_impl +{ + template struct apply + { + using type = mp11::mp_at; + }; +}; + +// back + +template< typename Tag > struct back_impl; + +template<> struct back_impl +{ + template struct apply + { + using N = mp11::mp_size; + using type = mp11::mp_at_c; + }; +}; + +// begin + +template< typename Tag > struct begin_impl; + +template<> struct begin_impl +{ + template struct apply + { + using type = aux::mp11_iterator; + }; +}; + +// clear + +template< typename Tag > struct clear_impl; + +template<> struct clear_impl +{ + template struct apply + { + using type = mp11::mp_clear; + }; +}; + +// end + +template< typename Tag > struct end_impl; + +template<> struct end_impl +{ + template struct apply + { + using type = aux::mp11_iterator>; + }; +}; + +// front + +template< typename Tag > struct front_impl; + +template<> struct front_impl +{ + template struct apply + { + using type = mp11::mp_front; + }; +}; + +// pop_front + +template< typename Tag > struct pop_front_impl; + +template<> struct pop_front_impl +{ + template struct apply + { + using type = mp11::mp_pop_front; + }; +}; + +// push_back + +template< typename Tag > struct push_back_impl; + +template<> struct push_back_impl +{ + template struct apply + { + using type = mp11::mp_push_back; + }; +}; + +// push_front + +template< typename Tag > struct push_front_impl; + +template<> struct push_front_impl +{ + template struct apply + { + using type = mp11::mp_push_front; + }; +}; + +// size + +template< typename Tag > struct size_impl; + +template<> struct size_impl +{ + template struct apply + { + using type = mp11::mp_size; + }; +}; + +} // namespace mpl +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED diff --git a/boost/mp11/function.hpp b/boost/mp11/function.hpp new file mode 100644 index 0000000..1aeccac --- /dev/null +++ b/boost/mp11/function.hpp @@ -0,0 +1,226 @@ +#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED +#define BOOST_MP11_FUNCTION_HPP_INCLUDED + +// Copyright 2015-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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_void +// in detail/mp_void.hpp + +// mp_and +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) + +namespace detail +{ + +template struct mp_and_impl; + +} // namespace detail + +template using mp_and = mp_to_bool< typename detail::mp_and_impl::type >; + +namespace detail +{ + +template<> struct mp_and_impl<> +{ + using type = mp_true; +}; + +template struct mp_and_impl +{ + using type = T; +}; + +template struct mp_and_impl +{ + using type = mp_eval_if< mp_not, T1, mp_and, T... >; +}; + +} // namespace detail + +#else + +namespace detail +{ + +template struct mp_and_impl +{ + using type = mp_false; +}; + +template struct mp_and_impl< mp_list, mp_void...> > +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_and = typename detail::mp_and_impl>::type; + +#endif + +// mp_all +// 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 using mp_all = mp_bool< mp_count_if< mp_list, mp_not >::value == 0 >; + +#elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +template using mp_all = mp_bool<(static_cast(T::value) && ...)>; + +#else + +template using mp_all = mp_and...>; + +#endif + +// mp_or +namespace detail +{ + +template struct mp_or_impl; + +} // namespace detail + +template using mp_or = mp_to_bool< typename detail::mp_or_impl::type >; + +namespace detail +{ + +template<> struct mp_or_impl<> +{ + using type = mp_false; +}; + +template struct mp_or_impl +{ + using type = T; +}; + +template struct mp_or_impl +{ + using type = mp_eval_if< T1, T1, mp_or, T... >; +}; + +} // namespace detail + +// mp_any +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356 +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + +template using mp_any = mp_bool<(static_cast(T::value) || ...)>; + +#else + +template using mp_any = mp_bool< mp_count_if< mp_list, mp_to_bool >::value != 0 >; + +#endif + +// mp_same +namespace detail +{ + +template struct mp_same_impl; + +template<> struct mp_same_impl<> +{ + using type = mp_true; +}; + +template struct mp_same_impl +{ + using type = mp_all...>; +}; + +} // namespace detail + +template using mp_same = typename detail::mp_same_impl::type; + +// mp_similar +namespace detail +{ + +template struct mp_similar_impl; + +template<> struct mp_similar_impl<> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_false; +}; + +template class L, class... T1, class... T2> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template class L, class... T> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_all< typename mp_similar_impl::type, typename mp_similar_impl::type, typename mp_similar_impl::type... >; +}; + +} // namespace detail + +template using mp_similar = typename detail::mp_similar_impl::type; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-compare" +#endif + +// mp_less +template using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic pop +#endif + +// mp_min +template using mp_min = mp_min_element, mp_less>; + +// mp_max +template using mp_max = mp_max_element, mp_less>; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED diff --git a/boost/mp11/integer_sequence.hpp b/boost/mp11/integer_sequence.hpp new file mode 100644 index 0000000..83e2450 --- /dev/null +++ b/boost/mp11/integer_sequence.hpp @@ -0,0 +1,112 @@ +#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED +#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED + +// Copyright 2015, 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 +#include + +#if defined(__has_builtin) +# if __has_builtin(__make_integer_seq) +# define BOOST_MP11_HAS_MAKE_INTEGER_SEQ +# endif +#endif + +namespace boost +{ +namespace mp11 +{ + +// integer_sequence +template struct integer_sequence +{ +}; + +#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +template using make_integer_sequence = __make_integer_seq; + +#else + +// detail::make_integer_sequence_impl +namespace detail +{ + +// iseq_if_c +template struct iseq_if_c_impl; + +template struct iseq_if_c_impl +{ + using type = T; +}; + +template struct iseq_if_c_impl +{ + using type = E; +}; + +template using iseq_if_c = typename iseq_if_c_impl::type; + +// iseq_identity +template struct iseq_identity +{ + using type = T; +}; + +template struct append_integer_sequence; + +template struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; +}; + +template struct make_integer_sequence_impl; + +template struct make_integer_sequence_impl_ +{ +private: + + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); + + static T const M = N / 2; + static T const R = N % 2; + + using S1 = typename make_integer_sequence_impl::type; + using S2 = typename append_integer_sequence::type; + using S3 = typename make_integer_sequence_impl::type; + using S4 = typename append_integer_sequence::type; + +public: + + using type = S4; +}; + +template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > +{ +}; + +} // namespace detail + +// make_integer_sequence +template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +// index_sequence +template using index_sequence = integer_sequence; + +// make_index_sequence +template using make_index_sequence = make_integer_sequence; + +// index_sequence_for +template using index_sequence_for = make_integer_sequence; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED diff --git a/boost/mp11/integral.hpp b/boost/mp11/integral.hpp new file mode 100644 index 0000000..0671673 --- /dev/null +++ b/boost/mp11/integral.hpp @@ -0,0 +1,41 @@ +#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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_bool +template using mp_bool = std::integral_constant; + +using mp_true = mp_bool; +using mp_false = mp_bool; + +// mp_to_bool +template using mp_to_bool = mp_bool( T::value )>; + +// mp_not +template using mp_not = mp_bool< !T::value >; + +// mp_int +template using mp_int = std::integral_constant; + +// mp_size_t +template using mp_size_t = std::integral_constant; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED diff --git a/boost/mp11/list.hpp b/boost/mp11/list.hpp new file mode 100644 index 0000000..e0d3e29 --- /dev/null +++ b/boost/mp11/list.hpp @@ -0,0 +1,335 @@ +#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 + +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_list_c +template using mp_list_c = mp_list...>; + +// mp_is_list +// in detail/mp_is_list.hpp + +// mp_size +namespace detail +{ + +template struct mp_size_impl +{ +// An error "no type named 'type'" here means that the argument to mp_size is not a list +}; + +template class L, class... T> struct mp_size_impl> +{ + using type = mp_size_t; +}; + +} // namespace detail + +template using mp_size = typename detail::mp_size_impl::type; + +// mp_empty +template using mp_empty = mp_bool< mp_size::value == 0 >; + +// mp_assign +namespace detail +{ + +template struct mp_assign_impl; + +template class L1, class... T, template class L2, class... U> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +} // namespace detail + +template using mp_assign = typename detail::mp_assign_impl::type; + +// mp_clear +template using mp_clear = mp_assign>; + +// mp_front +namespace detail +{ + +template 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 class L, class T1, class... T> struct mp_front_impl> +{ + using type = T1; +}; + +} // namespace detail + +template using mp_front = typename detail::mp_front_impl::type; + +// mp_pop_front +namespace detail +{ + +template struct mp_pop_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_pop_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_pop_front_impl> +{ + using type = L; +}; + +} // namespace detail + +template using mp_pop_front = typename detail::mp_pop_front_impl::type; + +// mp_first +template using mp_first = mp_front; + +// mp_rest +template using mp_rest = mp_pop_front; + +// mp_second +namespace detail +{ + +template struct mp_second_impl +{ +// An error "no type named 'type'" here means that the argument to mp_second +// is either not a list, or has fewer than two elements +}; + +template class L, class T1, class T2, class... T> struct mp_second_impl> +{ + using type = T2; +}; + +} // namespace detail + +template using mp_second = typename detail::mp_second_impl::type; + +// mp_third +namespace detail +{ + +template struct mp_third_impl +{ +// An error "no type named 'type'" here means that the argument to mp_third +// is either not a list, or has fewer than three elements +}; + +template class L, class T1, class T2, class T3, class... T> struct mp_third_impl> +{ + using type = T3; +}; + +} // namespace detail + +template using mp_third = typename detail::mp_third_impl::type; + +// mp_push_front +namespace detail +{ + +template struct mp_push_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list +}; + +template class L, class... U, class... T> struct mp_push_front_impl, T...> +{ + using type = L; +}; + +} // namespace detail + +template using mp_push_front = typename detail::mp_push_front_impl::type; + +// mp_push_back +namespace detail +{ + +template struct mp_push_back_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list +}; + +template class L, class... U, class... T> struct mp_push_back_impl, T...> +{ + using type = L; +}; + +} // namespace detail + +template using mp_push_back = typename detail::mp_push_back_impl::type; + +// mp_rename +namespace detail +{ + +template 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 class A, class... T, template class B> struct mp_rename_impl, B> +{ + using type = B; +}; + +} // namespace detail + +template class B> using mp_rename = typename detail::mp_rename_impl::type; + +template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; + +template using mp_apply_q = typename detail::mp_rename_impl::type; + +// mp_replace_front +namespace detail +{ + +template struct mp_replace_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, class T> struct mp_replace_front_impl, T> +{ + using type = L; +}; + +} // namespace detail + +template using mp_replace_front = typename detail::mp_replace_front_impl::type; + +// mp_replace_first +template using mp_replace_first = typename detail::mp_replace_front_impl::type; + +// mp_replace_second +namespace detail +{ + +template struct mp_replace_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl, T> +{ + using type = L; +}; + +} // namespace detail + +template using mp_replace_second = typename detail::mp_replace_second_impl::type; + +// mp_replace_third +namespace detail +{ + +template struct mp_replace_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl, T> +{ + using type = L; +}; + +} // namespace detail + +template using mp_replace_third = typename detail::mp_replace_third_impl::type; + +// mp_transform_front +namespace detail +{ + +template class F> struct mp_transform_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, template class F> struct mp_transform_front_impl, F> +{ + using type = L, U...>; +}; + +} // namespace detail + +template class F> using mp_transform_front = typename detail::mp_transform_front_impl::type; +template using mp_transform_front_q = mp_transform_front; + +// mp_transform_first +template class F> using mp_transform_first = typename detail::mp_transform_front_impl::type; +template using mp_transform_first_q = mp_transform_first; + +// mp_transform_second +namespace detail +{ + +template class F> struct mp_transform_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, template class F> struct mp_transform_second_impl, F> +{ + using type = L, U...>; +}; + +} // namespace detail + +template class F> using mp_transform_second = typename detail::mp_transform_second_impl::type; +template using mp_transform_second_q = mp_transform_second; + +// mp_transform_third +namespace detail +{ + +template class F> struct mp_transform_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, template class F> struct mp_transform_third_impl, F> +{ + using type = L, U...>; +}; + +} // namespace detail + +template class F> using mp_transform_third = typename detail::mp_transform_third_impl::type; +template using mp_transform_third_q = mp_transform_third; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED diff --git a/boost/mp11/map.hpp b/boost/mp11/map.hpp new file mode 100644 index 0000000..b9581ac --- /dev/null +++ b/boost/mp11/map.hpp @@ -0,0 +1,119 @@ +#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 +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_map_contains +template using mp_map_contains = mp_not, void>>; + +// mp_map_insert +template using mp_map_insert = mp_if< mp_map_contains>, M, mp_push_back >; + +// mp_map_replace +namespace detail +{ + +template struct mp_map_replace_impl; + +template class M, class... U, class T> struct mp_map_replace_impl, T> +{ + using K = mp_first; + + // mp_replace_if is inlined here using a struct _f because of msvc-14.0 + + template struct _f { using type = mp_if< std::is_same, K>, T, V >; }; + + using type = mp_if< mp_map_contains, K>, M::type...>, M >; +}; + +} // namespace detail + +template using mp_map_replace = typename detail::mp_map_replace_impl::type; + +// mp_map_update +namespace detail +{ + +template class F> struct mp_map_update_impl +{ + template using _f = std::is_same, mp_first>; + + // _f3> -> L> + template using _f3 = mp_assign, mp_rename > >; + + using type = mp_if< mp_map_contains>, mp_transform_if<_f, _f3, M>, mp_push_back >; +}; + +} // namespace detail + +template class F> using mp_map_update = typename detail::mp_map_update_impl::type; +template using mp_map_update_q = mp_map_update; + +// mp_map_erase +namespace detail +{ + +template struct mp_map_erase_impl +{ + template using _f = std::is_same, K>; + using type = mp_remove_if; +}; + +} // namespace detail + +template using mp_map_erase = typename detail::mp_map_erase_impl::type; + +// mp_map_keys +template using mp_map_keys = mp_transform; + +// mp_is_map +namespace detail +{ + +template struct mp_is_map_element: mp_false +{ +}; + +template class L, class T1, class... T> struct mp_is_map_element>: mp_true +{ +}; + +template using mp_keys_are_set = mp_is_set>; + +template struct mp_is_map_impl +{ + using type = mp_false; +}; + +template class M, class... T> struct mp_is_map_impl> +{ + using type = mp_eval_if...>>, mp_false, mp_keys_are_set, M>; +}; + +} // namespace detail + +template using mp_is_map = typename detail::mp_is_map_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED diff --git a/boost/mp11/mpl.hpp b/boost/mp11/mpl.hpp new file mode 100644 index 0000000..994705f --- /dev/null +++ b/boost/mp11/mpl.hpp @@ -0,0 +1,14 @@ +#ifndef BOOST_MP11_MPL_HPP_INCLUDED +#define BOOST_MP11_MPL_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 +#include + +#endif // #ifndef BOOST_MP11_MPL_HPP_INCLUDED diff --git a/boost/mp11/mpl_list.hpp b/boost/mp11/mpl_list.hpp new file mode 100644 index 0000000..643da43 --- /dev/null +++ b/boost/mp11/mpl_list.hpp @@ -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 + +namespace boost +{ +namespace mpl +{ + +template< typename Sequence > struct sequence_tag; + +template struct sequence_tag> +{ + using type = aux::mp11_tag; +}; + +} // namespace mpl +} // namespace boost + +#endif // #ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED diff --git a/boost/mp11/mpl_tuple.hpp b/boost/mp11/mpl_tuple.hpp new file mode 100644 index 0000000..b6900b1 --- /dev/null +++ b/boost/mp11/mpl_tuple.hpp @@ -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 +#include + +namespace boost +{ +namespace mpl +{ + +template< typename Sequence > struct sequence_tag; + +template struct sequence_tag> +{ + using type = aux::mp11_tag; +}; + +} // namespace mpl +} // namespace boost + +#endif // #ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED diff --git a/boost/mp11/set.hpp b/boost/mp11/set.hpp new file mode 100644 index 0000000..808636b --- /dev/null +++ b/boost/mp11/set.hpp @@ -0,0 +1,188 @@ +#ifndef BOOST_MP11_SET_HPP_INCLUDED +#define BOOST_MP11_SET_HPP_INCLUDED + +// Copyright 2015, 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 +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_set_contains +namespace detail +{ + +template struct mp_set_contains_impl +{ +}; + +template class L, class... T, class V> struct mp_set_contains_impl, V> +{ + using type = mp_to_bool, mp_inherit...> > >; +}; + +} // namespace detail + +template using mp_set_contains = typename detail::mp_set_contains_impl::type; + +// mp_set_push_back +namespace detail +{ + +template struct mp_set_push_back_impl +{ +}; + +template class L, class... U> struct mp_set_push_back_impl> +{ + using type = L; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_back_impl, T1, T...> +{ + using S = mp_if, T1>, L, L>; + using type = typename mp_set_push_back_impl::type; +}; + +} // namespace detail + +template using mp_set_push_back = typename detail::mp_set_push_back_impl::type; + +// mp_set_push_front +namespace detail +{ + +template struct mp_set_push_front_impl +{ +}; + +template class L, class... U> struct mp_set_push_front_impl> +{ + using type = L; +}; + +template class L, class... U, class T1> struct mp_set_push_front_impl, T1> +{ + using type = mp_if, T1>, L, L>; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_front_impl, T1, T...> +{ + using S = typename mp_set_push_front_impl, T...>::type; + using type = typename mp_set_push_front_impl::type; +}; + +} // namespace detail + +template using mp_set_push_front = typename detail::mp_set_push_front_impl::type; + +// mp_is_set +namespace detail +{ + +template struct mp_is_set_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_set_impl> +{ + using type = mp_to_bool, mp_set_push_back, T...> > >; +}; + +} // namespace detail + +template using mp_is_set = typename detail::mp_is_set_impl::type; + +// mp_set_union +namespace detail +{ + +template struct mp_set_union_impl +{ +}; + +template<> struct mp_set_union_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_set_union_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_set_union_impl, L2> +{ + using type = mp_set_push_back, T2...>; +}; + +template using mp_set_union_ = typename mp_set_union_impl, L...>>::type; + +template struct mp_set_union_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_union = typename detail::mp_set_union_impl::type; + +// mp_set_intersection +namespace detail +{ + +template struct in_all_sets +{ + template using fn = mp_all< mp_set_contains... >; +}; + +template using mp_set_intersection_ = mp_if< mp_all...>, mp_copy_if_q> >; + +template struct mp_set_intersection_impl +{ +}; + +template<> struct mp_set_intersection_impl<> +{ + using type = mp_list<>; +}; + +template struct mp_set_intersection_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_intersection = typename detail::mp_set_intersection_impl::type; + +// mp_set_difference +namespace detail +{ + +template struct in_any_set +{ + template using fn = mp_any< mp_set_contains... >; +}; + +} // namespace detail + +template using mp_set_difference = mp_if< mp_all...>, mp_remove_if_q> >; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED diff --git a/boost/mp11/tuple.hpp b/boost/mp11/tuple.hpp new file mode 100644 index 0000000..c65be1b --- /dev/null +++ b/boost/mp11/tuple.hpp @@ -0,0 +1,96 @@ +#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 +#include +#include +#include +#include +#include + +#if BOOST_MP11_MSVC +# pragma warning( push ) +# pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp' +#endif + +namespace boost +{ +namespace mp11 +{ + +// tuple_apply +namespace detail +{ + +template BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence ) + -> decltype( std::forward(f)( std::get(std::forward(tp))... ) ) +{ + return std::forward(f)( std::get(std::forward(tp))... ); +} + +} // namespace detail + +template::type>::value>> +BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp ) + -> decltype( detail::tuple_apply_impl( std::forward(f), std::forward(tp), Seq() ) ) +{ + return detail::tuple_apply_impl( std::forward(f), std::forward(tp), Seq() ); +} + +// construct_from_tuple +namespace detail +{ + +template BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence ) +{ + return T( std::get(std::forward(tp))... ); +} + +} // namespace detail + +template::type>::value>> +BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp ) +{ + return detail::construct_from_tuple_impl( std::forward(tp), Seq() ); +} + +// tuple_for_each +namespace detail +{ + +template BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence, F && f ) +{ + using A = int[sizeof...(J)]; + return (void)A{ ((void)f(std::get(std::forward(tp))), 0)... }, std::forward(f); +} + +template BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence, F && f ) +{ + return std::forward(f); +} + +} // namespace detail + +template BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f ) +{ + using seq = make_index_sequence::type>::value>; + return detail::tuple_for_each_impl( std::forward(tp), seq(), std::forward(f) ); +} + +} // namespace mp11 +} // namespace boost + +#if BOOST_MP11_MSVC +# pragma warning( pop ) +#endif + +#endif // #ifndef BOOST_TUPLE_HPP_INCLUDED diff --git a/boost/mp11/utility.hpp b/boost/mp11/utility.hpp new file mode 100644 index 0000000..38989f4 --- /dev/null +++ b/boost/mp11/utility.hpp @@ -0,0 +1,236 @@ +#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED +#define BOOST_MP11_UTILITY_HPP_INCLUDED + +// Copyright 2015, 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 +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_identity +template struct mp_identity +{ + using type = T; +}; + +// mp_identity_t +template using mp_identity_t = typename mp_identity::type; + +// mp_inherit +template struct mp_inherit: T... {}; + +// mp_if, mp_if_c +namespace detail +{ + +template struct mp_if_c_impl +{ +}; + +template struct mp_if_c_impl +{ + using type = T; +}; + +template struct mp_if_c_impl +{ + using type = E; +}; + +} // namespace detail + +template using mp_if_c = typename detail::mp_if_c_impl::type; +template using mp_if = typename detail::mp_if_c_impl(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 using void_t = void; + +template class F, class... T> +struct mp_valid_impl: mp_false {}; + +template class F, class... T> +struct mp_valid_impl>, F, T...>: mp_true {}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl; + +#else + +// implementation by Bruno Dutra (by the name is_evaluable) +namespace detail +{ + +template class F, class... T> struct mp_valid_impl +{ + template class G, class = G> static mp_true check(int); + template class> static mp_false check(...); + + using type = decltype(check(0)); +}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; + +#endif + +template using mp_valid_q = mp_valid; + +// mp_defer +namespace detail +{ + +template class F, class... T> struct mp_defer_impl +{ + using type = F; +}; + +struct mp_no_type +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> struct mp_defer_cuda_workaround +{ + using type = mp_if, detail::mp_defer_impl, detail::mp_no_type>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type; + +#else + +template class F, class... T> using mp_defer = mp_if, detail::mp_defer_impl, detail::mp_no_type>; + +#endif + +// mp_eval_if, mp_eval_if_c +namespace detail +{ + +template class F, class... U> struct mp_eval_if_c_impl; + +template class F, class... U> struct mp_eval_if_c_impl +{ + using type = T; +}; + +template class F, class... U> struct mp_eval_if_c_impl: mp_defer +{ +}; + +} // namespace detail + +template class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl::type; +template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; +template using mp_eval_if_q = typename detail::mp_eval_if_c_impl(C::value), T, Q::template fn, U...>::type; + +// mp_eval_if_not +template class F, class... U> using mp_eval_if_not = mp_eval_if, T, F, U...>; +template using mp_eval_if_not_q = mp_eval_if, T, Q::template fn, U...>; + +// mp_eval_or +template class F, class... U> using mp_eval_or = mp_eval_if_not, T, F, U...>; +template using mp_eval_or_q = mp_eval_or; + +// mp_cond + +// so elegant; so doesn't work +// template using mp_cond = mp_eval_if; + +namespace detail +{ + +template struct mp_cond_impl; + +} // namespace detail + +template using mp_cond = typename detail::mp_cond_impl::type; + +namespace detail +{ + +template using mp_cond_ = mp_eval_if; + +template struct mp_cond_impl: mp_defer +{ +}; + +} // namespace detail + +// mp_quote +template 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 using fn = typename mp_defer::type; +}; + +// mp_quote_trait +template class F> struct mp_quote_trait +{ + template using fn = typename F::type; +}; + +// mp_invoke_q +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +namespace detail +{ + +template struct mp_invoke_q_impl: mp_defer {}; + +} // namespace detail + +template using mp_invoke_q = typename detail::mp_invoke_q_impl::type; + +#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 ) + +template using mp_invoke_q = typename mp_defer::type; + +#else + +template using mp_invoke_q = typename Q::template fn; + +#endif + +// old name for mp_invoke_q retained for compatibility, but deprecated +template using mp_invoke BOOST_MP11_DEPRECATED("please use mp_invoke_q") = mp_invoke_q; + +// mp_not_fn

+template class P> struct mp_not_fn +{ + template using fn = mp_not< mp_invoke_q, T...> >; +}; + +template using mp_not_fn_q = mp_not_fn; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED diff --git a/boost/mp11/version.hpp b/boost/mp11/version.hpp new file mode 100644 index 0000000..3eba110 --- /dev/null +++ b/boost/mp11/version.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_MP11_VERSION_HPP_INCLUDED +#define BOOST_MP11_VERSION_HPP_INCLUDED + +// Copyright 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 + +// Same format as BOOST_VERSION: +// major * 100000 + minor * 100 + patch + +#define BOOST_MP11_VERSION 107300 + +#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED