mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-22 23:45:39 +00:00
externals: Update boost-ext to include logic and mp11.
- Needed for safe_numerics.
This commit is contained in:
parent
caf8e19fb1
commit
5e8300b76a
469
boost/logic/tribool.hpp
Normal file
469
boost/logic/tribool.hpp
Normal file
|
@ -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 <boost/logic/tribool_fwd.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#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 <tt>x.value == tribool::indeterminate_value</tt>
|
||||||
|
* \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:
|
||||||
|
* <table border=1>
|
||||||
|
* <tr>
|
||||||
|
* <th><center><code>!</code></center></th>
|
||||||
|
* <th/>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* \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:
|
||||||
|
* <table border=1>
|
||||||
|
* <tr>
|
||||||
|
* <th><center><code>&&</code></center></th>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* \throws nothrow
|
||||||
|
*/
|
||||||
|
BOOST_CONSTEXPR inline tribool operator&&(tribool x, tribool y) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return (static_cast<bool>(!x) || static_cast<bool>(!y))
|
||||||
|
? tribool(false)
|
||||||
|
: ((static_cast<bool>(x) && static_cast<bool>(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:
|
||||||
|
* <table border=1>
|
||||||
|
* <tr>
|
||||||
|
* <th><center><code>||</code></center></th>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* \throws nothrow
|
||||||
|
*/
|
||||||
|
BOOST_CONSTEXPR inline tribool operator||(tribool x, tribool y) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return (static_cast<bool>(!x) && static_cast<bool>(!y))
|
||||||
|
? tribool(false)
|
||||||
|
: ((static_cast<bool>(x) || static_cast<bool>(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:
|
||||||
|
* <table border=1>
|
||||||
|
* <tr>
|
||||||
|
* <th><center><code>==</code></center></th>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* \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:
|
||||||
|
* <table border=1>
|
||||||
|
* <tr>
|
||||||
|
* <th><center><code>!=</code></center></th>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>false</center></th>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>true</center></th>
|
||||||
|
* <td><center>true</center></td>
|
||||||
|
* <td><center>false</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <th><center>indeterminate</center></th>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* <td><center>indeterminate</center></td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* \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
|
||||||
|
|
15
boost/logic/tribool_fwd.hpp
Normal file
15
boost/logic/tribool_fwd.hpp
Normal file
|
@ -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
|
343
boost/logic/tribool_io.hpp
Normal file
343
boost/logic/tribool_io.hpp
Normal file
|
@ -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 <boost/logic/tribool.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_LOCALE
|
||||||
|
# include <locale>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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<typename T> std::basic_string<T> 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<char> default_false_name<char>()
|
||||||
|
{ 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<wchar_t> default_false_name<wchar_t>()
|
||||||
|
{ 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<typename T> std::basic_string<T> 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<char> default_true_name<char>()
|
||||||
|
{ 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<wchar_t> default_true_name<wchar_t>()
|
||||||
|
{ 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<typename T> std::basic_string<T> get_default_indeterminate_name();
|
||||||
|
|
||||||
|
/// Returns the character string "indeterminate".
|
||||||
|
template<>
|
||||||
|
inline std::basic_string<char> get_default_indeterminate_name<char>()
|
||||||
|
{ return "indeterminate"; }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CWCHAR)
|
||||||
|
/// Returns the wide character string L"indeterminate".
|
||||||
|
template<>
|
||||||
|
inline std::basic_string<wchar_t> get_default_indeterminate_name<wchar_t>()
|
||||||
|
{ 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<typename CharT>
|
||||||
|
class indeterminate_name : public std::locale::facet, private boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_string<CharT> string_type;
|
||||||
|
|
||||||
|
/// Construct the facet with the default name
|
||||||
|
indeterminate_name() : name_(get_default_indeterminate_name<CharT>()) {}
|
||||||
|
|
||||||
|
/// 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<typename CharT> std::locale::id indeterminate_name<CharT>::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<bool>(x); \endcode
|
||||||
|
*
|
||||||
|
* When @p x has an indeterminate value, it outputs either the integer
|
||||||
|
* value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>)
|
||||||
|
* 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<typename CharT, typename Traits>
|
||||||
|
inline std::basic_ostream<CharT, Traits>&
|
||||||
|
operator<<(std::basic_ostream<CharT, Traits>& out, tribool x)
|
||||||
|
{
|
||||||
|
if (!indeterminate(x)) {
|
||||||
|
out << static_cast<bool>(x);
|
||||||
|
} else {
|
||||||
|
typename std::basic_ostream<CharT, Traits>::sentry cerberus(out);
|
||||||
|
if (cerberus) {
|
||||||
|
if (out.flags() & std::ios_base::boolalpha) {
|
||||||
|
#ifndef BOOST_NO_STD_LOCALE
|
||||||
|
if (BOOST_HAS_FACET(indeterminate_name<CharT>, out.getloc())) {
|
||||||
|
const indeterminate_name<CharT>& facet =
|
||||||
|
BOOST_USE_FACET(indeterminate_name<CharT>, out.getloc());
|
||||||
|
out << facet.name();
|
||||||
|
} else {
|
||||||
|
out << get_default_indeterminate_name<CharT>();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
out << get_default_indeterminate_name<CharT>();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Writes the indeterminate tribool value to a stream.
|
||||||
|
*
|
||||||
|
* This routine outputs either the integer
|
||||||
|
* value 2 (if <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>)
|
||||||
|
* 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<typename CharT, typename Traits>
|
||||||
|
inline std::basic_ostream<CharT, Traits>&
|
||||||
|
operator<<(std::basic_ostream<CharT, Traits>& out,
|
||||||
|
bool (*)(tribool, detail::indeterminate_t))
|
||||||
|
{ return out << tribool(indeterminate); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Reads a tribool value from a stream.
|
||||||
|
*
|
||||||
|
* When <tt>(out.flags() & std::ios_base::boolalpha) == 0</tt>, 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 <tt>(out.flags() & std::ios_base::boolalpha) != 0</tt>, 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<typename CharT, typename Traits>
|
||||||
|
inline std::basic_istream<CharT, Traits>&
|
||||||
|
operator>>(std::basic_istream<CharT, Traits>& in, tribool& x)
|
||||||
|
{
|
||||||
|
if (in.flags() & std::ios_base::boolalpha) {
|
||||||
|
typename std::basic_istream<CharT, Traits>::sentry cerberus(in);
|
||||||
|
if (cerberus) {
|
||||||
|
typedef std::basic_string<CharT> string_type;
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_LOCALE
|
||||||
|
const std::numpunct<CharT>& numpunct_facet =
|
||||||
|
BOOST_USE_FACET(std::numpunct<CharT>, in.getloc());
|
||||||
|
|
||||||
|
string_type falsename = numpunct_facet.falsename();
|
||||||
|
string_type truename = numpunct_facet.truename();
|
||||||
|
|
||||||
|
string_type othername;
|
||||||
|
if (BOOST_HAS_FACET(indeterminate_name<CharT>, in.getloc())) {
|
||||||
|
othername =
|
||||||
|
BOOST_USE_FACET(indeterminate_name<CharT>, in.getloc()).name();
|
||||||
|
} else {
|
||||||
|
othername = get_default_indeterminate_name<CharT>();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
string_type falsename = default_false_name<CharT>();
|
||||||
|
string_type truename = default_true_name<CharT>();
|
||||||
|
string_type othername = get_default_indeterminate_name<CharT>();
|
||||||
|
#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
|
22
boost/mp11.hpp
Normal file
22
boost/mp11.hpp
Normal file
|
@ -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 <boost/mp11/list.hpp>
|
||||||
|
#include <boost/mp11/algorithm.hpp>
|
||||||
|
#include <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/function.hpp>
|
||||||
|
#include <boost/mp11/map.hpp>
|
||||||
|
#include <boost/mp11/set.hpp>
|
||||||
|
#include <boost/mp11/bind.hpp>
|
||||||
|
#include <boost/mp11/integer_sequence.hpp>
|
||||||
|
#include <boost/mp11/tuple.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_HPP_INCLUDED
|
1111
boost/mp11/algorithm.hpp
Normal file
1111
boost/mp11/algorithm.hpp
Normal file
File diff suppressed because it is too large
Load diff
111
boost/mp11/bind.hpp
Normal file
111
boost/mp11/bind.hpp
Normal file
|
@ -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 <boost/mp11/algorithm.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_bind_front
|
||||||
|
template<template<class...> 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<class... U> using fn = typename mp_defer<F, T..., U...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>;
|
||||||
|
|
||||||
|
// mp_bind_back
|
||||||
|
template<template<class...> class F, class... T> struct mp_bind_back
|
||||||
|
{
|
||||||
|
template<class... U> using fn = typename mp_defer<F, U..., T...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>;
|
||||||
|
|
||||||
|
// mp_arg
|
||||||
|
template<std::size_t I> struct mp_arg
|
||||||
|
{
|
||||||
|
template<class... T> using fn = mp_at_c<mp_list<T...>, I>;
|
||||||
|
};
|
||||||
|
|
||||||
|
using _1 = mp_arg<0>;
|
||||||
|
using _2 = mp_arg<1>;
|
||||||
|
using _3 = mp_arg<2>;
|
||||||
|
using _4 = mp_arg<3>;
|
||||||
|
using _5 = mp_arg<4>;
|
||||||
|
using _6 = mp_arg<5>;
|
||||||
|
using _7 = mp_arg<6>;
|
||||||
|
using _8 = mp_arg<7>;
|
||||||
|
using _9 = mp_arg<8>;
|
||||||
|
|
||||||
|
// mp_bind
|
||||||
|
template<template<class...> class F, class... T> struct mp_bind;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class V, class... T> struct eval_bound_arg
|
||||||
|
{
|
||||||
|
using type = V;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t I, class... T> struct eval_bound_arg<mp_arg<I>, T...>
|
||||||
|
{
|
||||||
|
using type = typename mp_arg<I>::template fn<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind<F, U...>, T...>
|
||||||
|
{
|
||||||
|
using type = typename mp_bind<F, U...>::template fn<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_front<F, U...>, T...>
|
||||||
|
{
|
||||||
|
using type = typename mp_bind_front<F, U...>::template fn<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_back<F, U...>, T...>
|
||||||
|
{
|
||||||
|
using type = typename mp_bind_back<F, U...>::template fn<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> struct mp_bind
|
||||||
|
{
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 )
|
||||||
|
private:
|
||||||
|
|
||||||
|
template<class... U> struct _f { using type = F<typename detail::eval_bound_arg<T, U...>::type...>; };
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<class... U> using fn = typename _f<U...>::type;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class... U> using fn = F<typename detail::eval_bound_arg<T, U...>::type...>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED
|
139
boost/mp11/detail/config.hpp
Normal file
139
boost/mp11/detail/config.hpp
Normal file
|
@ -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(<shared_mutex>)
|
||||||
|
|
||||||
|
// 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
|
185
boost/mp11/detail/mp_append.hpp
Normal file
185
boost/mp11/detail/mp_append.hpp
Normal file
|
@ -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 <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_append<L...>
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... L> struct mp_append_impl;
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||||
|
|
||||||
|
template<class... L> struct mp_append_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_append_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_list<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
|
||||||
|
{
|
||||||
|
using type = L<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_append_impl<L1<T1...>, L2<T2...>>
|
||||||
|
{
|
||||||
|
using type = L1<T1..., T2...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>>
|
||||||
|
{
|
||||||
|
using type = L1<T1..., T2..., T3...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>>
|
||||||
|
{
|
||||||
|
using type = L1<T1..., T2..., T3..., T4...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, template<class...> class L5, class... T5, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, Lr...>
|
||||||
|
{
|
||||||
|
using type = typename mp_append_impl<L1<T1..., T2..., T3..., T4..., T5...>, Lr...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class L1 = mp_list<>, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
template<class...> class L1, class... T1,
|
||||||
|
template<class...> class L2, class... T2,
|
||||||
|
template<class...> class L3, class... T3,
|
||||||
|
template<class...> class L4, class... T4,
|
||||||
|
template<class...> class L5, class... T5,
|
||||||
|
template<class...> class L6, class... T6,
|
||||||
|
template<class...> class L7, class... T7,
|
||||||
|
template<class...> class L8, class... T8,
|
||||||
|
template<class...> class L9, class... T9,
|
||||||
|
template<class...> class L10, class... T10,
|
||||||
|
template<class...> class L11, class... T11>
|
||||||
|
|
||||||
|
struct append_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
|
||||||
|
{
|
||||||
|
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
|
||||||
|
class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>,
|
||||||
|
class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>,
|
||||||
|
class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>,
|
||||||
|
class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>,
|
||||||
|
class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>,
|
||||||
|
class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>,
|
||||||
|
class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>,
|
||||||
|
class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>,
|
||||||
|
class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>,
|
||||||
|
class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>,
|
||||||
|
class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<>
|
||||||
|
|
||||||
|
> struct append_111_impl
|
||||||
|
{
|
||||||
|
using type = typename append_11_impl<
|
||||||
|
|
||||||
|
typename append_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
|
||||||
|
typename append_11_impl<mp_list<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
|
||||||
|
typename append_11_impl<mp_list<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
|
||||||
|
|
||||||
|
>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
|
||||||
|
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
|
||||||
|
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
|
||||||
|
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
|
||||||
|
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
|
||||||
|
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
|
||||||
|
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
|
||||||
|
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
|
||||||
|
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
|
||||||
|
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
|
||||||
|
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
|
||||||
|
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
|
||||||
|
class... Lr
|
||||||
|
|
||||||
|
> struct append_inf_impl
|
||||||
|
{
|
||||||
|
using prefix = typename append_111_impl<
|
||||||
|
|
||||||
|
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
|
||||||
|
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
|
||||||
|
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
|
||||||
|
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
|
||||||
|
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
|
||||||
|
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
|
||||||
|
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
|
||||||
|
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
|
||||||
|
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
|
||||||
|
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
|
||||||
|
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
|
||||||
|
|
||||||
|
>::type;
|
||||||
|
|
||||||
|
using type = typename mp_append_impl<prefix, Lr...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||||
|
|
||||||
|
template<class... L>
|
||||||
|
struct mp_append_impl_cuda_workaround
|
||||||
|
{
|
||||||
|
using type = mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... L> struct mp_append_impl: mp_append_impl_cuda_workaround<L...>::type::template fn<L...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class... L> struct mp_append_impl: mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >::template fn<L...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
48
boost/mp11/detail/mp_copy_if.hpp
Normal file
48
boost/mp11/detail/mp_copy_if.hpp
Normal file
|
@ -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 <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_append.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_copy_if<L, P>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> struct mp_copy_if_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, template<class...> class P> struct mp_copy_if_impl<L<T...>, P>
|
||||||
|
{
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||||
|
template<class U> struct _f { using type = mp_if<P<U>, mp_list<U>, mp_list<>>; };
|
||||||
|
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||||
|
#else
|
||||||
|
template<class U> using _f = mp_if<P<U>, mp_list<U>, mp_list<>>;
|
||||||
|
using type = mp_append<L<>, _f<T>...>;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> using mp_copy_if = typename detail::mp_copy_if_impl<L, P>::type;
|
||||||
|
template<class L, class Q> using mp_copy_if_q = mp_copy_if<L, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
115
boost/mp11/detail/mp_count.hpp
Normal file
115
boost/mp11/detail/mp_count.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_plus.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_count<L, V>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class V> struct mp_count_impl;
|
||||||
|
|
||||||
|
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<(std::is_same<T, V>::value + ... + 0)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||||
|
|
||||||
|
constexpr std::size_t cx_plus()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(t1) + cx_plus(t...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
|
||||||
|
constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<mp_plus<std::is_same<T, V>...>::value>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class V> using mp_count = typename detail::mp_count_impl<L, V>::type;
|
||||||
|
|
||||||
|
// mp_count_if<L, P>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> struct mp_count_if_impl;
|
||||||
|
|
||||||
|
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<(mp_to_bool<P<T>>::value + ... + 0)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<cx_plus(mp_to_bool<P<T>>::value...)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||||
|
{
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||||
|
|
||||||
|
template<class T> struct _f { using type = mp_to_bool<P<T>>; };
|
||||||
|
using type = mp_size_t<mp_plus<typename _f<T>::type...>::value>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
using type = mp_size_t<mp_plus<mp_to_bool<P<T>>...>::value>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
|
||||||
|
template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
62
boost/mp11/detail/mp_fold.hpp
Normal file
62
boost/mp11/detail/mp_fold.hpp
Normal file
|
@ -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 <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_fold<L, V, F>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class V, template<class...> 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<template<class...> class L, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T...>, V, F>
|
||||||
|
{
|
||||||
|
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||||
|
using type = V;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<template<class...> class L, class V, template<class...> class F> struct mp_fold_impl<L<>, V, F>
|
||||||
|
{
|
||||||
|
using type = V;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<template<class...> class L, class T1, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T1, T...>, V, F>
|
||||||
|
{
|
||||||
|
using type = typename mp_fold_impl<L<T...>, F<V, T1>, F>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
|
||||||
|
{
|
||||||
|
using type = typename mp_fold_impl<L<T...>, F<F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
|
||||||
|
template<class L, class V, class Q> using mp_fold_q = mp_fold<L, V, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
39
boost/mp11/detail/mp_is_list.hpp
Normal file
39
boost/mp11/detail/mp_is_list.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_is_list<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_is_list_impl
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_is_list_impl<L<T...>>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_is_list = typename detail::mp_is_list_impl<L>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
24
boost/mp11/detail/mp_list.hpp
Normal file
24
boost/mp11/detail/mp_list.hpp
Normal file
|
@ -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<T...>
|
||||||
|
template<class... T> struct mp_list
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
43
boost/mp11/detail/mp_map_find.hpp
Normal file
43
boost/mp11/detail/mp_map_find.hpp
Normal file
|
@ -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 <boost/mp11/utility.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_map_find
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class M, class K> struct mp_map_find_impl;
|
||||||
|
|
||||||
|
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
|
||||||
|
{
|
||||||
|
using U = mp_inherit<mp_identity<T>...>;
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
|
||||||
|
static mp_identity<void> f( ... );
|
||||||
|
|
||||||
|
using V = decltype( f((U*)0) );
|
||||||
|
|
||||||
|
using type = typename V::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
51
boost/mp11/detail/mp_min_element.hpp
Normal file
51
boost/mp11/detail/mp_min_element.hpp
Normal file
|
@ -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 <boost/mp11/detail/mp_fold.hpp>
|
||||||
|
#include <boost/mp11/list.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_min_element<L, P>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<template<class...> class P> struct select_min
|
||||||
|
{
|
||||||
|
template<class T1, class T2> using fn = mp_if<P<T1, T2>, T1, T2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> using mp_min_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_min<P>>;
|
||||||
|
template<class L, class Q> using mp_min_element_q = mp_min_element<L, Q::template fn>;
|
||||||
|
|
||||||
|
// mp_max_element<L, P>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<template<class...> class P> struct select_max
|
||||||
|
{
|
||||||
|
template<class T1, class T2> using fn = mp_if<P<T2, T1>, T1, T2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> using mp_max_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_max<P>>;
|
||||||
|
template<class L, class Q> using mp_max_element_q = mp_max_element<L, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
81
boost/mp11/detail/mp_plus.hpp
Normal file
81
boost/mp11/detail/mp_plus.hpp
Normal file
|
@ -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 <boost/mp11/detail/config.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_plus
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||||
|
|
||||||
|
template<class... T> struct mp_plus_impl
|
||||||
|
{
|
||||||
|
static const auto _v = (T::value + ... + 0);
|
||||||
|
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class... T> struct mp_plus_impl;
|
||||||
|
|
||||||
|
template<> struct mp_plus_impl<>
|
||||||
|
{
|
||||||
|
using type = std::integral_constant<int, 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||||
|
|
||||||
|
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||||
|
{
|
||||||
|
static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||||
|
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||||
|
{
|
||||||
|
static const
|
||||||
|
decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
|
||||||
|
_v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||||
|
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||||
|
{
|
||||||
|
static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||||
|
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||||
|
{
|
||||||
|
static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||||
|
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
48
boost/mp11/detail/mp_remove_if.hpp
Normal file
48
boost/mp11/detail/mp_remove_if.hpp
Normal file
|
@ -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 <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_append.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_remove_if<L, P>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> struct mp_remove_if_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, template<class...> class P> struct mp_remove_if_impl<L<T...>, P>
|
||||||
|
{
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||||
|
template<class U> struct _f { using type = mp_if<P<U>, mp_list<>, mp_list<U>>; };
|
||||||
|
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||||
|
#else
|
||||||
|
template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
|
||||||
|
using type = mp_append<L<>, _f<T>...>;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class P> using mp_remove_if = typename detail::mp_remove_if_impl<L, P>::type;
|
||||||
|
template<class L, class Q> using mp_remove_if_q = mp_remove_if<L, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
32
boost/mp11/detail/mp_void.hpp
Normal file
32
boost/mp11/detail/mp_void.hpp
Normal file
|
@ -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<T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T> struct mp_void_impl
|
||||||
|
{
|
||||||
|
using type = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_void = typename detail::mp_void_impl<T...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
396
boost/mp11/detail/mp_with_index.hpp
Normal file
396
boost/mp11/detail/mp_with_index.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#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<std::size_t N> struct mp_with_index_impl_
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||||
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||||
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||||
|
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp_with_index_impl_<N-16>::template call<K+16>( i-16, std::forward<F>(f) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<0>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<1>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t /*i*/, F && f )
|
||||||
|
{
|
||||||
|
return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<2>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<3>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<4>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<5>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<6>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<7>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<8>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<9>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<10>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<11>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<12>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<13>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<14>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||||
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<15>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||||
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||||
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_with_index_impl_<16>
|
||||||
|
{
|
||||||
|
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
default: BOOST_MP11_UNREACHABLE();
|
||||||
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||||
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||||
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||||
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||||
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||||
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||||
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||||
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||||
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||||
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||||
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||||
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||||
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||||
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||||
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||||
|
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<std::size_t N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
assert( i < N );
|
||||||
|
return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||||
|
{
|
||||||
|
return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BOOST_MP11_CONSTEXPR14
|
||||||
|
#undef BOOST_MP11_UNREACHABLE
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
160
boost/mp11/detail/mpl_common.hpp
Normal file
160
boost/mp11/detail/mpl_common.hpp
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
#ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||||
|
#define BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||||
|
|
||||||
|
// Copyright 2017, 2019 Peter Dimov.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
//
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/mp11/list.hpp>
|
||||||
|
#include <boost/mp11/algorithm.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mpl
|
||||||
|
{
|
||||||
|
|
||||||
|
struct forward_iterator_tag;
|
||||||
|
|
||||||
|
namespace aux
|
||||||
|
{
|
||||||
|
|
||||||
|
struct mp11_tag {};
|
||||||
|
|
||||||
|
template<class L> struct mp11_iterator
|
||||||
|
{
|
||||||
|
using category = forward_iterator_tag;
|
||||||
|
|
||||||
|
using type = mp11::mp_first<L>;
|
||||||
|
using next = mp11_iterator<mp11::mp_rest<L>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aux
|
||||||
|
|
||||||
|
// at
|
||||||
|
|
||||||
|
template< typename Tag > struct at_impl;
|
||||||
|
|
||||||
|
template<> struct at_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L, class I> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_at<L, I>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// back
|
||||||
|
|
||||||
|
template< typename Tag > struct back_impl;
|
||||||
|
|
||||||
|
template<> struct back_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using N = mp11::mp_size<L>;
|
||||||
|
using type = mp11::mp_at_c<L, N::value - 1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// begin
|
||||||
|
|
||||||
|
template< typename Tag > struct begin_impl;
|
||||||
|
|
||||||
|
template<> struct begin_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = aux::mp11_iterator<L>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// clear
|
||||||
|
|
||||||
|
template< typename Tag > struct clear_impl;
|
||||||
|
|
||||||
|
template<> struct clear_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_clear<L>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// end
|
||||||
|
|
||||||
|
template< typename Tag > struct end_impl;
|
||||||
|
|
||||||
|
template<> struct end_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// front
|
||||||
|
|
||||||
|
template< typename Tag > struct front_impl;
|
||||||
|
|
||||||
|
template<> struct front_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_front<L>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// pop_front
|
||||||
|
|
||||||
|
template< typename Tag > struct pop_front_impl;
|
||||||
|
|
||||||
|
template<> struct pop_front_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_pop_front<L>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// push_back
|
||||||
|
|
||||||
|
template< typename Tag > struct push_back_impl;
|
||||||
|
|
||||||
|
template<> struct push_back_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L, class T> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_push_back<L, T>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// push_front
|
||||||
|
|
||||||
|
template< typename Tag > struct push_front_impl;
|
||||||
|
|
||||||
|
template<> struct push_front_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L, class T> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_push_front<L, T>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// size
|
||||||
|
|
||||||
|
template< typename Tag > struct size_impl;
|
||||||
|
|
||||||
|
template<> struct size_impl<aux::mp11_tag>
|
||||||
|
{
|
||||||
|
template<class L> struct apply
|
||||||
|
{
|
||||||
|
using type = mp11::mp_size<L>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mpl
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
226
boost/mp11/function.hpp
Normal file
226
boost/mp11/function.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_count.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_plus.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_min_element.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_void.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_void<T...>
|
||||||
|
// in detail/mp_void.hpp
|
||||||
|
|
||||||
|
// mp_and<T...>
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T> struct mp_and_impl;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<> struct mp_and_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct mp_and_impl<T>
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class... T> struct mp_and_impl<T1, T...>
|
||||||
|
{
|
||||||
|
using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class E = void> struct mp_and_impl
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mp_all<T...>
|
||||||
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||||
|
|
||||||
|
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
|
||||||
|
|
||||||
|
#elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||||
|
|
||||||
|
template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class... T> using mp_all = mp_and<mp_to_bool<T>...>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mp_or<T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T> struct mp_or_impl;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<> struct mp_or_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct mp_or_impl<T>
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class... T> struct mp_or_impl<T1, T...>
|
||||||
|
{
|
||||||
|
using type = mp_eval_if< T1, T1, mp_or, T... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// mp_any<T...>
|
||||||
|
// 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<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mp_same<T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T> struct mp_same_impl;
|
||||||
|
|
||||||
|
template<> struct mp_same_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class... T> struct mp_same_impl<T1, T...>
|
||||||
|
{
|
||||||
|
using type = mp_all<std::is_same<T1, T>...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type;
|
||||||
|
|
||||||
|
// mp_similar<T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T> struct mp_similar_impl;
|
||||||
|
|
||||||
|
template<> struct mp_similar_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct mp_similar_impl<T>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct mp_similar_impl<T, T>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class T2> struct mp_similar_impl<T1, T2>
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T1, class... T2> struct mp_similar_impl<L<T1...>, L<T2...>>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>>
|
||||||
|
{
|
||||||
|
using type = mp_true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...>
|
||||||
|
{
|
||||||
|
using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... T> using mp_similar = typename detail::mp_similar_impl<T...>::type;
|
||||||
|
|
||||||
|
#if BOOST_MP11_GCC
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mp_less<T1, T2>
|
||||||
|
template<class T1, class T2> 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<T...>
|
||||||
|
template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>;
|
||||||
|
|
||||||
|
// mp_max<T...>
|
||||||
|
template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
112
boost/mp11/integer_sequence.hpp
Normal file
112
boost/mp11/integer_sequence.hpp
Normal file
|
@ -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 <boost/mp11/version.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#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<class T, T... I> struct integer_sequence
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||||
|
|
||||||
|
template<class T, T N> using make_integer_sequence = __make_integer_seq<integer_sequence, T, N>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// detail::make_integer_sequence_impl
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
// iseq_if_c
|
||||||
|
template<bool C, class T, class E> struct iseq_if_c_impl;
|
||||||
|
|
||||||
|
template<class T, class E> struct iseq_if_c_impl<true, T, E>
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class E> struct iseq_if_c_impl<false, T, E>
|
||||||
|
{
|
||||||
|
using type = E;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
|
||||||
|
|
||||||
|
// iseq_identity
|
||||||
|
template<class T> struct iseq_identity
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class S1, class S2> struct append_integer_sequence;
|
||||||
|
|
||||||
|
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
|
||||||
|
{
|
||||||
|
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, T N> struct make_integer_sequence_impl;
|
||||||
|
|
||||||
|
template<class T, T N> struct make_integer_sequence_impl_
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
|
||||||
|
|
||||||
|
static T const M = N / 2;
|
||||||
|
static T const R = N % 2;
|
||||||
|
|
||||||
|
using S1 = typename make_integer_sequence_impl<T, M>::type;
|
||||||
|
using S2 = typename append_integer_sequence<S1, S1>::type;
|
||||||
|
using S3 = typename make_integer_sequence_impl<T, R>::type;
|
||||||
|
using S4 = typename append_integer_sequence<S2, S3>::type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using type = S4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// make_integer_sequence
|
||||||
|
template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
|
||||||
|
|
||||||
|
#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||||
|
|
||||||
|
// index_sequence
|
||||||
|
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
|
||||||
|
|
||||||
|
// make_index_sequence
|
||||||
|
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||||
|
|
||||||
|
// index_sequence_for
|
||||||
|
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
41
boost/mp11/integral.hpp
Normal file
41
boost/mp11/integral.hpp
Normal file
|
@ -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 <boost/mp11/version.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_bool
|
||||||
|
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
||||||
|
|
||||||
|
using mp_true = mp_bool<true>;
|
||||||
|
using mp_false = mp_bool<false>;
|
||||||
|
|
||||||
|
// mp_to_bool
|
||||||
|
template<class T> using mp_to_bool = mp_bool<static_cast<bool>( T::value )>;
|
||||||
|
|
||||||
|
// mp_not<T>
|
||||||
|
template<class T> using mp_not = mp_bool< !T::value >;
|
||||||
|
|
||||||
|
// mp_int
|
||||||
|
template<int I> using mp_int = std::integral_constant<int, I>;
|
||||||
|
|
||||||
|
// mp_size_t
|
||||||
|
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
335
boost/mp11/list.hpp
Normal file
335
boost/mp11/list.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_append.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_list_c<T, I...>
|
||||||
|
template<class T, T... I> using mp_list_c = mp_list<std::integral_constant<T, I>...>;
|
||||||
|
|
||||||
|
// mp_is_list<L>
|
||||||
|
// in detail/mp_is_list.hpp
|
||||||
|
|
||||||
|
// mp_size<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_size_impl
|
||||||
|
{
|
||||||
|
// An error "no type named 'type'" here means that the argument to mp_size is not a list
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
|
||||||
|
{
|
||||||
|
using type = mp_size_t<sizeof...(T)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
|
||||||
|
|
||||||
|
// mp_empty<L>
|
||||||
|
template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
|
||||||
|
|
||||||
|
// mp_assign<L1, L2>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L1, class L2> struct mp_assign_impl;
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
|
||||||
|
{
|
||||||
|
using type = L1<U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
|
||||||
|
|
||||||
|
// mp_clear<L>
|
||||||
|
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
|
||||||
|
|
||||||
|
// mp_front<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_front_impl
|
||||||
|
{
|
||||||
|
// An error "no type named 'type'" here means that the argument to mp_front
|
||||||
|
// is either not a list, or is an empty list
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
|
||||||
|
{
|
||||||
|
using type = T1;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
|
||||||
|
|
||||||
|
// mp_pop_front<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> 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<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
|
||||||
|
{
|
||||||
|
using type = L<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
|
||||||
|
|
||||||
|
// mp_first<L>
|
||||||
|
template<class L> using mp_first = mp_front<L>;
|
||||||
|
|
||||||
|
// mp_rest<L>
|
||||||
|
template<class L> using mp_rest = mp_pop_front<L>;
|
||||||
|
|
||||||
|
// mp_second<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_second_impl
|
||||||
|
{
|
||||||
|
// 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<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
|
||||||
|
{
|
||||||
|
using type = T2;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
|
||||||
|
|
||||||
|
// mp_third<L>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_third_impl
|
||||||
|
{
|
||||||
|
// 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<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
|
||||||
|
{
|
||||||
|
using type = T3;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
|
||||||
|
|
||||||
|
// mp_push_front<L, T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class... T> struct mp_push_front_impl
|
||||||
|
{
|
||||||
|
// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
|
||||||
|
{
|
||||||
|
using type = L<T..., U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
|
||||||
|
|
||||||
|
// mp_push_back<L, T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class... T> struct mp_push_back_impl
|
||||||
|
{
|
||||||
|
// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
|
||||||
|
{
|
||||||
|
using type = L<U..., T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
|
||||||
|
|
||||||
|
// mp_rename<L, B>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class A, template<class...> class B> struct mp_rename_impl
|
||||||
|
{
|
||||||
|
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
|
||||||
|
{
|
||||||
|
using type = B<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
|
||||||
|
|
||||||
|
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
|
||||||
|
|
||||||
|
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
|
||||||
|
|
||||||
|
// mp_replace_front<L, T>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class T> struct mp_replace_front_impl
|
||||||
|
{
|
||||||
|
// 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<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
|
||||||
|
{
|
||||||
|
using type = L<T, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
|
||||||
|
|
||||||
|
// mp_replace_first<L, T>
|
||||||
|
template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
|
||||||
|
|
||||||
|
// mp_replace_second<L, T>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class T> struct mp_replace_second_impl
|
||||||
|
{
|
||||||
|
// 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<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
|
||||||
|
{
|
||||||
|
using type = L<U1, T, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
|
||||||
|
|
||||||
|
// mp_replace_third<L, T>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, class T> struct mp_replace_third_impl
|
||||||
|
{
|
||||||
|
// 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<template<class...> class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl<L<U1, U2, U3, U...>, T>
|
||||||
|
{
|
||||||
|
using type = L<U1, U2, T, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
|
||||||
|
|
||||||
|
// mp_transform_front<L, F>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> 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<template<class...> class L, class U1, class... U, template<class...> class F> struct mp_transform_front_impl<L<U1, U...>, F>
|
||||||
|
{
|
||||||
|
using type = L<F<U1>, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class F> using mp_transform_front = typename detail::mp_transform_front_impl<L, F>::type;
|
||||||
|
template<class L, class Q> using mp_transform_front_q = mp_transform_front<L, Q::template fn>;
|
||||||
|
|
||||||
|
// mp_transform_first<L, F>
|
||||||
|
template<class L, template<class...> class F> using mp_transform_first = typename detail::mp_transform_front_impl<L, F>::type;
|
||||||
|
template<class L, class Q> using mp_transform_first_q = mp_transform_first<L, Q::template fn>;
|
||||||
|
|
||||||
|
// mp_transform_second<L, F>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> 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<template<class...> class L, class U1, class U2, class... U, template<class...> class F> struct mp_transform_second_impl<L<U1, U2, U...>, F>
|
||||||
|
{
|
||||||
|
using type = L<U1, F<U2>, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class F> using mp_transform_second = typename detail::mp_transform_second_impl<L, F>::type;
|
||||||
|
template<class L, class Q> using mp_transform_second_q = mp_transform_second<L, Q::template fn>;
|
||||||
|
|
||||||
|
// mp_transform_third<L, F>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L, template<class...> 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<template<class...> class L, class U1, class U2, class U3, class... U, template<class...> class F> struct mp_transform_third_impl<L<U1, U2, U3, U...>, F>
|
||||||
|
{
|
||||||
|
using type = L<U1, U2, F<U3>, U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, template<class...> class F> using mp_transform_third = typename detail::mp_transform_third_impl<L, F>::type;
|
||||||
|
template<class L, class Q> using mp_transform_third_q = mp_transform_third<L, Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
119
boost/mp11/map.hpp
Normal file
119
boost/mp11/map.hpp
Normal file
|
@ -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 <boost/mp11/detail/mp_map_find.hpp>
|
||||||
|
#include <boost/mp11/list.hpp>
|
||||||
|
#include <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/algorithm.hpp>
|
||||||
|
#include <boost/mp11/function.hpp>
|
||||||
|
#include <boost/mp11/set.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_map_contains<M, K>
|
||||||
|
template<class M, class K> using mp_map_contains = mp_not<std::is_same<mp_map_find<M, K>, void>>;
|
||||||
|
|
||||||
|
// mp_map_insert<M, T>
|
||||||
|
template<class M, class T> using mp_map_insert = mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;
|
||||||
|
|
||||||
|
// mp_map_replace<M, T>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class M, class T> struct mp_map_replace_impl;
|
||||||
|
|
||||||
|
template<template<class...> class M, class... U, class T> struct mp_map_replace_impl<M<U...>, T>
|
||||||
|
{
|
||||||
|
using K = mp_first<T>;
|
||||||
|
|
||||||
|
// mp_replace_if is inlined here using a struct _f because of msvc-14.0
|
||||||
|
|
||||||
|
template<class V> struct _f { using type = mp_if< std::is_same<mp_first<V>, K>, T, V >; };
|
||||||
|
|
||||||
|
using type = mp_if< mp_map_contains<M<U...>, K>, M<typename _f<U>::type...>, M<U..., T> >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class M, class T> using mp_map_replace = typename detail::mp_map_replace_impl<M, T>::type;
|
||||||
|
|
||||||
|
// mp_map_update<M, T, F>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class M, class T, template<class...> class F> struct mp_map_update_impl
|
||||||
|
{
|
||||||
|
template<class U> using _f = std::is_same<mp_first<T>, mp_first<U>>;
|
||||||
|
|
||||||
|
// _f3<L<X, Y...>> -> L<X, F<X, Y...>>
|
||||||
|
template<class L> using _f3 = mp_assign<L, mp_list<mp_first<L>, mp_rename<L, F> > >;
|
||||||
|
|
||||||
|
using type = mp_if< mp_map_contains<M, mp_first<T>>, mp_transform_if<_f, _f3, M>, mp_push_back<M, T> >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class M, class T, template<class...> class F> using mp_map_update = typename detail::mp_map_update_impl<M, T, F>::type;
|
||||||
|
template<class M, class T, class Q> using mp_map_update_q = mp_map_update<M, T, Q::template fn>;
|
||||||
|
|
||||||
|
// mp_map_erase<M, K>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class M, class K> struct mp_map_erase_impl
|
||||||
|
{
|
||||||
|
template<class T> using _f = std::is_same<mp_first<T>, K>;
|
||||||
|
using type = mp_remove_if<M, _f>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class M, class K> using mp_map_erase = typename detail::mp_map_erase_impl<M, K>::type;
|
||||||
|
|
||||||
|
// mp_map_keys<M>
|
||||||
|
template<class M> using mp_map_keys = mp_transform<mp_first, M>;
|
||||||
|
|
||||||
|
// mp_is_map<M>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class L> struct mp_is_map_element: mp_false
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class T1, class... T> struct mp_is_map_element<L<T1, T...>>: mp_true
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class M> using mp_keys_are_set = mp_is_set<mp_map_keys<M>>;
|
||||||
|
|
||||||
|
template<class M> struct mp_is_map_impl
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class M, class... T> struct mp_is_map_impl<M<T...>>
|
||||||
|
{
|
||||||
|
using type = mp_eval_if<mp_not<mp_all<mp_is_map_element<T>...>>, mp_false, mp_keys_are_set, M<T...>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class M> using mp_is_map = typename detail::mp_is_map_impl<M>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED
|
14
boost/mp11/mpl.hpp
Normal file
14
boost/mp11/mpl.hpp
Normal file
|
@ -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 <boost/mp11/mpl_list.hpp>
|
||||||
|
#include <boost/mp11/mpl_tuple.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_MPL_HPP_INCLUDED
|
28
boost/mp11/mpl_list.hpp
Normal file
28
boost/mp11/mpl_list.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||||
|
#define BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||||
|
|
||||||
|
// Copyright 2017, 2019 Peter Dimov.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
//
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/mp11/detail/mpl_common.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mpl
|
||||||
|
{
|
||||||
|
|
||||||
|
template< typename Sequence > struct sequence_tag;
|
||||||
|
|
||||||
|
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
|
||||||
|
{
|
||||||
|
using type = aux::mp11_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mpl
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
29
boost/mp11/mpl_tuple.hpp
Normal file
29
boost/mp11/mpl_tuple.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||||
|
#define BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||||
|
|
||||||
|
// Copyright 2017, 2019 Peter Dimov.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
//
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/mp11/detail/mpl_common.hpp>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mpl
|
||||||
|
{
|
||||||
|
|
||||||
|
template< typename Sequence > struct sequence_tag;
|
||||||
|
|
||||||
|
template<class... T> struct sequence_tag<std::tuple<T...>>
|
||||||
|
{
|
||||||
|
using type = aux::mp11_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mpl
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
188
boost/mp11/set.hpp
Normal file
188
boost/mp11/set.hpp
Normal file
|
@ -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 <boost/mp11/utility.hpp>
|
||||||
|
#include <boost/mp11/function.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_list.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_append.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_copy_if.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_remove_if.hpp>
|
||||||
|
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_set_contains<S, V>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class S, class V> struct mp_set_contains_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
|
||||||
|
{
|
||||||
|
using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...> > >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
|
||||||
|
|
||||||
|
// mp_set_push_back<S, T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class S, class... T> struct mp_set_push_back_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
|
||||||
|
{
|
||||||
|
using type = L<U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
|
||||||
|
{
|
||||||
|
using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
|
||||||
|
using type = typename mp_set_push_back_impl<S, T...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
|
||||||
|
|
||||||
|
// mp_set_push_front<S, T...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class S, class... T> struct mp_set_push_front_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U> struct mp_set_push_front_impl<L<U...>>
|
||||||
|
{
|
||||||
|
using type = L<U...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U, class T1> struct mp_set_push_front_impl<L<U...>, T1>
|
||||||
|
{
|
||||||
|
using type = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<T1, U...>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_front_impl<L<U...>, T1, T...>
|
||||||
|
{
|
||||||
|
using S = typename mp_set_push_front_impl<L<U...>, T...>::type;
|
||||||
|
using type = typename mp_set_push_front_impl<S, T1>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
|
||||||
|
|
||||||
|
// mp_is_set<S>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class S> struct mp_is_set_impl
|
||||||
|
{
|
||||||
|
using type = mp_false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_is_set_impl<L<T...>>
|
||||||
|
{
|
||||||
|
using type = mp_to_bool<std::is_same<mp_list<T...>, mp_set_push_back<mp_list<>, T...> > >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class S> using mp_is_set = typename detail::mp_is_set_impl<S>::type;
|
||||||
|
|
||||||
|
// mp_set_union<L...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... L> struct mp_set_union_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_set_union_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_list<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L, class... T> struct mp_set_union_impl<L<T...>>
|
||||||
|
{
|
||||||
|
using type = L<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_set_union_impl<L1<T1...>, L2<T2...>>
|
||||||
|
{
|
||||||
|
using type = mp_set_push_back<L1<T1...>, T2...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class L1, class... L> using mp_set_union_ = typename mp_set_union_impl<L1, mp_append<mp_list<>, L...>>::type;
|
||||||
|
|
||||||
|
template<class L1, class L2, class L3, class... L> struct mp_set_union_impl<L1, L2, L3, L...>: mp_defer<mp_set_union_, L1, L2, L3, L...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... L> using mp_set_union = typename detail::mp_set_union_impl<L...>::type;
|
||||||
|
|
||||||
|
// mp_set_intersection<S...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... S> struct in_all_sets
|
||||||
|
{
|
||||||
|
template<class T> using fn = mp_all< mp_set_contains<S, T>... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class L, class... S> using mp_set_intersection_ = mp_if< mp_all<mp_is_list<S>...>, mp_copy_if_q<L, detail::in_all_sets<S...>> >;
|
||||||
|
|
||||||
|
template<class... S> struct mp_set_intersection_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct mp_set_intersection_impl<>
|
||||||
|
{
|
||||||
|
using type = mp_list<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class L, class... S> struct mp_set_intersection_impl<L, S...>: mp_defer<mp_set_intersection_, L, S...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class... S> using mp_set_intersection = typename detail::mp_set_intersection_impl<S...>::type;
|
||||||
|
|
||||||
|
// mp_set_difference<L, S...>
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... S> struct in_any_set
|
||||||
|
{
|
||||||
|
template<class T> using fn = mp_any< mp_set_contains<S, T>... >;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class... S> using mp_set_difference = mp_if< mp_all<mp_is_list<S>...>, mp_remove_if_q<L, detail::in_any_set<S...>> >;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
|
96
boost/mp11/tuple.hpp
Normal file
96
boost/mp11/tuple.hpp
Normal file
|
@ -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 <boost/mp11/integer_sequence.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#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<class F, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
|
||||||
|
-> decltype( std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... ) )
|
||||||
|
{
|
||||||
|
return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class F, class Tp,
|
||||||
|
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
|
||||||
|
BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
|
||||||
|
-> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
|
||||||
|
{
|
||||||
|
return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct_from_tuple
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class T, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
|
||||||
|
{
|
||||||
|
return T( std::get<J>(std::forward<Tp>(tp))... );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class T, class Tp,
|
||||||
|
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
|
||||||
|
BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp )
|
||||||
|
{
|
||||||
|
return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// tuple_for_each
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Tp, std::size_t... J, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
|
||||||
|
{
|
||||||
|
using A = int[sizeof...(J)];
|
||||||
|
return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
|
||||||
|
{
|
||||||
|
return std::forward<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
|
||||||
|
{
|
||||||
|
using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
|
||||||
|
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if BOOST_MP11_MSVC
|
||||||
|
# pragma warning( pop )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_TUPLE_HPP_INCLUDED
|
236
boost/mp11/utility.hpp
Normal file
236
boost/mp11/utility.hpp
Normal file
|
@ -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 <boost/mp11/integral.hpp>
|
||||||
|
#include <boost/mp11/detail/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
|
// mp_identity
|
||||||
|
template<class T> struct mp_identity
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mp_identity_t
|
||||||
|
template<class T> using mp_identity_t = typename mp_identity<T>::type;
|
||||||
|
|
||||||
|
// mp_inherit
|
||||||
|
template<class... T> struct mp_inherit: T... {};
|
||||||
|
|
||||||
|
// mp_if, mp_if_c
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<bool C, class T, class... E> struct mp_if_c_impl
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class... E> struct mp_if_c_impl<true, T, E...>
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class E> struct mp_if_c_impl<false, T, E>
|
||||||
|
{
|
||||||
|
using type = E;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
|
||||||
|
template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
|
||||||
|
|
||||||
|
// mp_valid
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800
|
||||||
|
|
||||||
|
// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class...> using void_t = void;
|
||||||
|
|
||||||
|
template<class, template<class...> class F, class... T>
|
||||||
|
struct mp_valid_impl: mp_false {};
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T>
|
||||||
|
struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// implementation by Bruno Dutra (by the name is_evaluable)
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> struct mp_valid_impl
|
||||||
|
{
|
||||||
|
template<template<class...> class G, class = G<T...>> static mp_true check(int);
|
||||||
|
template<template<class...> class> static mp_false check(...);
|
||||||
|
|
||||||
|
using type = decltype(check<F>(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
|
||||||
|
|
||||||
|
// mp_defer
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> struct mp_defer_impl
|
||||||
|
{
|
||||||
|
using type = F<T...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mp_no_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
|
||||||
|
{
|
||||||
|
using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mp_eval_if, mp_eval_if_c
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<bool C, class T, template<class...> class F, class... U> struct mp_eval_if_c_impl;
|
||||||
|
|
||||||
|
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<true, T, F, U...>
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<false, T, F, U...>: mp_defer<F, U...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl<C, T, F, U...>::type;
|
||||||
|
template<class C, class T, template<class...> class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, F, U...>::type;
|
||||||
|
template<class C, class T, class Q, class... U> using mp_eval_if_q = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, Q::template fn, U...>::type;
|
||||||
|
|
||||||
|
// mp_eval_if_not
|
||||||
|
template<class C, class T, template<class...> class F, class... U> using mp_eval_if_not = mp_eval_if<mp_not<C>, T, F, U...>;
|
||||||
|
template<class C, class T, class Q, class... U> using mp_eval_if_not_q = mp_eval_if<mp_not<C>, T, Q::template fn, U...>;
|
||||||
|
|
||||||
|
// mp_eval_or
|
||||||
|
template<class T, template<class...> class F, class... U> using mp_eval_or = mp_eval_if_not<mp_valid<F, U...>, T, F, U...>;
|
||||||
|
template<class T, class Q, class... U> using mp_eval_or_q = mp_eval_or<T, Q::template fn, U...>;
|
||||||
|
|
||||||
|
// mp_cond
|
||||||
|
|
||||||
|
// so elegant; so doesn't work
|
||||||
|
// template<class C, class T, class... E> using mp_cond = mp_eval_if<C, T, mp_cond, E...>;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class C, class T, class... E> struct mp_cond_impl;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class C, class T, class... E> using mp_cond = typename detail::mp_cond_impl<C, T, E...>::type;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class C, class T, class... E> using mp_cond_ = mp_eval_if<C, T, mp_cond, E...>;
|
||||||
|
|
||||||
|
template<class C, class T, class... E> struct mp_cond_impl: mp_defer<mp_cond_, C, T, E...>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// mp_quote
|
||||||
|
template<template<class...> class F> struct mp_quote
|
||||||
|
{
|
||||||
|
// the indirection through mp_defer works around the language inability
|
||||||
|
// to expand T... into a fixed parameter list of an alias template
|
||||||
|
|
||||||
|
template<class... T> using fn = typename mp_defer<F, T...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mp_quote_trait
|
||||||
|
template<template<class...> class F> struct mp_quote_trait
|
||||||
|
{
|
||||||
|
template<class... T> using fn = typename F<T...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mp_invoke_q
|
||||||
|
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Q, class... T> struct mp_invoke_q_impl: mp_defer<Q::template fn, T...> {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_invoke_q = typename detail::mp_invoke_q_impl<Q, T...>::type;
|
||||||
|
|
||||||
|
#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 )
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_invoke_q = typename mp_defer<Q::template fn, T...>::type;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class Q, class... T> using mp_invoke_q = typename Q::template fn<T...>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// old name for mp_invoke_q retained for compatibility, but deprecated
|
||||||
|
template<class Q, class... T> using mp_invoke BOOST_MP11_DEPRECATED("please use mp_invoke_q") = mp_invoke_q<Q, T...>;
|
||||||
|
|
||||||
|
// mp_not_fn<P>
|
||||||
|
template<template<class...> class P> struct mp_not_fn
|
||||||
|
{
|
||||||
|
template<class... T> using fn = mp_not< mp_invoke_q<mp_quote<P>, T...> >;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
16
boost/mp11/version.hpp
Normal file
16
boost/mp11/version.hpp
Normal file
|
@ -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
|
Loading…
Reference in a new issue