init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
allhaileris
2026-02-16 15:50:16 +03:00
commit afb81b8278
13816 changed files with 3689732 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
// Range v3 library
//
// Copyright Casey Carter 2018
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
#ifndef RANGES_V3_DETAIL_ADL_GET_HPP
#define RANGES_V3_DETAIL_ADL_GET_HPP
#include <cstddef>
#include <concepts/concepts.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \cond
namespace detail
{
namespace _adl_get_
{
template<typename>
void get();
template<std::size_t I, typename TupleLike>
constexpr auto adl_get(TupleLike && t) noexcept
-> decltype(get<I>(static_cast<TupleLike &&>(t)))
{
return get<I>(static_cast<TupleLike &&>(t));
}
template<typename T, typename TupleLike>
constexpr auto adl_get(TupleLike && t) noexcept
-> decltype(get<T>(static_cast<TupleLike &&>(t)))
{
return get<T>(static_cast<TupleLike &&>(t));
}
} // namespace _adl_get_
using _adl_get_::adl_get;
} // namespace detail
namespace _tuple_wrapper_
{
template<typename TupleLike>
struct forward_tuple_interface : TupleLike
{
forward_tuple_interface() = default;
using TupleLike::TupleLike;
#if !defined(__clang__) || __clang_major__ > 3
CPP_member
constexpr CPP_ctor(forward_tuple_interface)(TupleLike && base)( //
noexcept(std::is_nothrow_move_constructible<TupleLike>::value) //
requires move_constructible<TupleLike>)
: TupleLike(static_cast<TupleLike &&>(base))
{}
CPP_member
constexpr CPP_ctor(forward_tuple_interface)(TupleLike const & base)( //
noexcept(std::is_nothrow_copy_constructible<TupleLike>::value) //
requires copy_constructible<TupleLike>)
: TupleLike(base)
{}
#else
// Clang 3.x have a problem with inheriting constructors
// that causes the declarations in the preceeding PP block to get
// instantiated too early.
template(typename B = TupleLike)(
requires move_constructible<B>)
constexpr forward_tuple_interface(TupleLike && base) noexcept(
std::is_nothrow_move_constructible<TupleLike>::value)
: TupleLike(static_cast<TupleLike &&>(base))
{}
template(typename B = TupleLike)(
requires copy_constructible<B>)
constexpr forward_tuple_interface(TupleLike const & base) noexcept(
std::is_nothrow_copy_constructible<TupleLike>::value)
: TupleLike(base)
{}
#endif
// clang-format off
template<std::size_t I, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> &wb)
(
return detail::adl_get<I>(static_cast<U &>(wb))
)
template<std::size_t I, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> const &wb)
(
return detail::adl_get<I>(static_cast<U const &>(wb))
)
template<std::size_t I, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> &&wb)
(
return detail::adl_get<I>(static_cast<U &&>(wb))
)
template<std::size_t I, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> const &&wb)
(
return detail::adl_get<I>(static_cast<U const &&>(wb))
)
template<typename T, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> &wb)
(
return detail::adl_get<T>(static_cast<U &>(wb))
)
template<typename T, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> const &wb)
(
return detail::adl_get<T>(static_cast<U const &>(wb))
)
template<typename T, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> &&wb)
(
return detail::adl_get<T>(static_cast<U &&>(wb))
)
template<typename T, typename U = TupleLike>
friend constexpr auto CPP_auto_fun(get)(
forward_tuple_interface<TupleLike> const &&wb)
(
return detail::adl_get<T>(static_cast<U const &&>(wb))
)
// clang-format on
};
} // namespace _tuple_wrapper_
/// \endcond
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif // RANGES_V3_DETAIL_ADL_GET_HPP

View File

@@ -0,0 +1,759 @@
// Range v3 library
//
// Copyright Eric Niebler 2013-present
// Copyright Casey Carter 2016
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_CONFIG_HPP
#define RANGES_V3_DETAIL_CONFIG_HPP
// Grab some version information.
#ifndef __has_include
#include <iosfwd>
#elif __has_include(<version>)
#include <version>
#else
#include <iosfwd>
#endif
#if(defined(NDEBUG) && !defined(RANGES_ENSURE_MSG)) || \
(!defined(NDEBUG) && !defined(RANGES_ASSERT) && \
((defined(__GNUC__) && !defined(__clang__) && \
(__GNUC__ < 5 || defined(__MINGW32__))) || \
defined(_MSVC_STL_VERSION)))
#include <cstdio>
#include <cstdlib>
namespace ranges
{
namespace detail
{
template<typename = void>
[[noreturn]] void assert_failure(char const * file, int line, char const * msg)
{
std::fprintf(stderr, "%s(%d): %s\n", file, line, msg);
std::abort();
}
} // namespace detail
} // namespace ranges
#endif
#ifndef RANGES_ASSERT
// Always use our hand-rolled assert implementation on older GCCs, which do
// not allow assert to be used in a constant expression, and on MSVC whose
// assert is not marked [[noreturn]].
#if !defined(NDEBUG) && ((defined(__GNUC__) && !defined(__clang__) && \
(__GNUC__ < 5 || defined(__MINGW32__))) || \
defined(_MSVC_STL_VERSION))
#define RANGES_ASSERT(...) \
static_cast<void>((__VA_ARGS__) \
? void(0) \
: ::ranges::detail::assert_failure( \
__FILE__, __LINE__, "assertion failed: " #__VA_ARGS__))
#else
#include <cassert>
#define RANGES_ASSERT assert
#endif
#endif
#include <meta/meta_fwd.hpp>
#ifndef RANGES_ASSUME
#if defined(__clang__) || defined(__GNUC__)
#define RANGES_ASSUME(COND) static_cast<void>((COND) ? void(0) : __builtin_unreachable())
#elif defined(_MSC_VER)
#define RANGES_ASSUME(COND) static_cast<void>(__assume(COND))
#else
#define RANGES_ASSUME(COND) static_cast<void>(COND)
#endif
#endif // RANGES_ASSUME
#ifndef RANGES_EXPECT
#ifdef NDEBUG
#define RANGES_EXPECT(COND) RANGES_ASSUME(COND)
#else // NDEBUG
#define RANGES_EXPECT(COND) RANGES_ASSERT(COND)
#endif // NDEBUG
#endif // RANGES_EXPECT
#ifndef RANGES_ENSURE_MSG
#if defined(NDEBUG)
#define RANGES_ENSURE_MSG(COND, MSG) \
static_cast<void>((COND) ? void(0) \
: ::ranges::detail::assert_failure( \
__FILE__, __LINE__, "ensure failed: " MSG))
#else
#define RANGES_ENSURE_MSG(COND, MSG) RANGES_ASSERT((COND) && MSG)
#endif
#endif
#ifndef RANGES_ENSURE
#define RANGES_ENSURE(...) RANGES_ENSURE_MSG((__VA_ARGS__), #__VA_ARGS__)
#endif
#define RANGES_DECLTYPE_AUTO_RETURN(...) \
->decltype(__VA_ARGS__) \
{ \
return (__VA_ARGS__); \
} \
/**/
#define RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT(...) \
noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__)))->decltype(__VA_ARGS__) \
{ \
return (__VA_ARGS__); \
} \
/**/
#define RANGES_AUTO_RETURN_NOEXCEPT(...) \
noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) \
{ \
return (__VA_ARGS__); \
} \
/**/
#define RANGES_DECLTYPE_NOEXCEPT(...) \
noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__)))->decltype(__VA_ARGS__) /**/
// Non-portable forward declarations of standard containers
#define RANGES_BEGIN_NAMESPACE_STD META_BEGIN_NAMESPACE_STD
#define RANGES_END_NAMESPACE_STD META_END_NAMESPACE_STD
#define RANGES_BEGIN_NAMESPACE_VERSION META_BEGIN_NAMESPACE_VERSION
#define RANGES_END_NAMESPACE_VERSION META_END_NAMESPACE_VERSION
#define RANGES_BEGIN_NAMESPACE_CONTAINER META_BEGIN_NAMESPACE_CONTAINER
#define RANGES_END_NAMESPACE_CONTAINER META_END_NAMESPACE_CONTAINER
// Database of feature versions
#define RANGES_CXX_STATIC_ASSERT_11 200410L
#define RANGES_CXX_STATIC_ASSERT_14 RANGES_CXX_STATIC_ASSERT_11
#define RANGES_CXX_STATIC_ASSERT_17 201411L
#define RANGES_CXX_VARIABLE_TEMPLATES_11 0L
#define RANGES_CXX_VARIABLE_TEMPLATES_14 201304L
#define RANGES_CXX_VARIABLE_TEMPLATES_17 RANGES_CXX_VARIABLE_TEMPLATES_14
#define RANGES_CXX_ATTRIBUTE_DEPRECATED_11 0L
#define RANGES_CXX_ATTRIBUTE_DEPRECATED_14 201309L
#define RANGES_CXX_ATTRIBUTE_DEPRECATED_17 RANGES_CXX_ATTRIBUTE_DEPRECATED_14
#define RANGES_CXX_CONSTEXPR_11 200704L
#define RANGES_CXX_CONSTEXPR_14 201304L
#define RANGES_CXX_CONSTEXPR_17 201603L
#define RANGES_CXX_CONSTEXPR_20 201907L
#define RANGES_CXX_CONSTEXPR_LAMBDAS 201603L
#define RANGES_CXX_RANGE_BASED_FOR_11 200907L
#define RANGES_CXX_RANGE_BASED_FOR_14 RANGES_CXX_RANGE_BASED_FOR_11
#define RANGES_CXX_RANGE_BASED_FOR_17 201603L
#define RANGES_CXX_LIB_IS_FINAL_11 0L
#define RANGES_CXX_LIB_IS_FINAL_14 201402L
#define RANGES_CXX_LIB_IS_FINAL_17 RANGES_CXX_LIB_IS_FINAL_14
#define RANGES_CXX_RETURN_TYPE_DEDUCTION_11 0L
#define RANGES_CXX_RETURN_TYPE_DEDUCTION_14 201304L
#define RANGES_CXX_RETURN_TYPE_DEDUCTION_17 RANGES_CXX_RETURN_TYPE_DEDUCTION_14
#define RANGES_CXX_GENERIC_LAMBDAS_11 0L
#define RANGES_CXX_GENERIC_LAMBDAS_14 201304L
#define RANGES_CXX_GENERIC_LAMBDAS_17 RANGES_CXX_GENERIC_LAMBDAS_14
#define RANGES_CXX_STD_11 201103L
#define RANGES_CXX_STD_14 201402L
#define RANGES_CXX_STD_17 201703L
#define RANGES_CXX_THREAD_LOCAL_PRE_STANDARD \
200000L // Arbitrary number between 0 and C++11
#define RANGES_CXX_THREAD_LOCAL_11 RANGES_CXX_STD_11
#define RANGES_CXX_THREAD_LOCAL_14 RANGES_CXX_THREAD_LOCAL_11
#define RANGES_CXX_THREAD_LOCAL_17 RANGES_CXX_THREAD_LOCAL_14
#define RANGES_CXX_INLINE_VARIABLES_11 0L
#define RANGES_CXX_INLINE_VARIABLES_14 0L
#define RANGES_CXX_INLINE_VARIABLES_17 201606L
#define RANGES_CXX_COROUTINES_11 0L
#define RANGES_CXX_COROUTINES_14 0L
#define RANGES_CXX_COROUTINES_17 0L
#define RANGES_CXX_COROUTINES_TS1 201703L
#define RANGES_CXX_DEDUCTION_GUIDES_11 0L
#define RANGES_CXX_DEDUCTION_GUIDES_14 0L
#define RANGES_CXX_DEDUCTION_GUIDES_17 201606L
#define RANGES_CXX_IF_CONSTEXPR_11 0L
#define RANGES_CXX_IF_CONSTEXPR_14 0L
#define RANGES_CXX_IF_CONSTEXPR_17 201606L
#define RANGES_CXX_ALIGNED_NEW_11 0L
#define RANGES_CXX_ALIGNED_NEW_14 0L
#define RANGES_CXX_ALIGNED_NEW_17 201606L
// Implementation-specific diagnostic control
#if defined(_MSC_VER) && !defined(__clang__)
#define RANGES_DIAGNOSTIC_PUSH __pragma(warning(push))
#define RANGES_DIAGNOSTIC_POP __pragma(warning(pop))
#define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS __pragma(warning(disable : 4068))
#define RANGES_DIAGNOSTIC_IGNORE(X) \
RANGES_DIAGNOSTIC_IGNORE_PRAGMAS __pragma(warning(disable : X))
#define RANGES_DIAGNOSTIC_IGNORE_SHADOWING RANGES_DIAGNOSTIC_IGNORE(4456)
#define RANGES_DIAGNOSTIC_IGNORE_INDENTATION
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
#define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS RANGES_DIAGNOSTIC_IGNORE(4099)
#define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
#define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
#define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY
#define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
#define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT
#define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
#define RANGES_DIAGNOSTIC_IGNORE_FLOAT_CONVERSION
#define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE
#define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
#define RANGES_DIAGNOSTIC_IGNORE_RANGE_LOOP_ANALYSIS
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS RANGES_DIAGNOSTIC_IGNORE(4996)
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE
#define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
// Ignores both "divide by zero" and "mod by zero":
#define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO RANGES_DIAGNOSTIC_IGNORE(4723 4724)
#define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH RANGES_DIAGNOSTIC_IGNORE(4146)
#define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION RANGES_DIAGNOSTIC_IGNORE(4244)
#define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS \
RANGES_DIAGNOSTIC_IGNORE(4522)
#define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE
#define RANGES_DIAGNOSTIC_KEYWORD_MACRO
#define RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
#define RANGES_CXX_VER _MSVC_LANG
#if _MSC_VER < 1920 || _MSVC_LANG < 201703L
#error range-v3 requires Visual Studio 2019 with the /std:c++17 (or /std:c++latest) and /permissive- options.
#endif
#if _MSC_VER < 1927
#define RANGES_WORKAROUND_MSVC_895622 // Error when phase 1 name binding finds only
// deleted function
#if _MSC_VER < 1925
#define RANGES_WORKAROUND_MSVC_779708 // ADL for operands of function type [No workaround]
#if _MSC_VER < 1923
#define RANGES_WORKAROUND_MSVC_573728 // rvalues of array types bind to lvalue references
// [no workaround]
#define RANGES_WORKAROUND_MSVC_934330 // Deduction guide not correctly preferred to copy
// deduction candidate [No workaround]
#if _MSC_VER < 1922
#define RANGES_WORKAROUND_MSVC_756601 // constexpr friend non-template erroneously
// rejected with C3615
#define RANGES_WORKAROUND_MSVC_793042 // T[0] sometimes accepted as a valid type in SFINAE
// context
#if _MSC_VER < 1921
#define RANGES_WORKAROUND_MSVC_785522 // SFINAE failure for error in immediate context
#define RANGES_WORKAROUND_MSVC_786376 // Assertion casting anonymous union member in
// trailing-return-type
#define RANGES_WORKAROUND_MSVC_787074 // Over-eager substitution of dependent type in
// non-instantiated nested class template
#define RANGES_WORKAROUND_MSVC_790554 // Assert for return type that uses dependent
// default non-type template argument
#endif // _MSC_VER < 1921
#endif // _MSC_VER < 1922
#endif // _MSC_VER < 1923
#endif // _MSC_VER < 1925
#endif // _MSC_VER < 1926
#if 1 // Fixed in 1920, but more bugs hiding behind workaround
#define RANGES_WORKAROUND_MSVC_701385 // Yet another alias expansion error
#endif
#define RANGES_WORKAROUND_MSVC_249830 // constexpr and arguments that aren't subject to
// lvalue-to-rvalue conversion
#define RANGES_WORKAROUND_MSVC_677925 // Bogus C2676 "binary '++': '_Ty' does not define
// this operator"
#define RANGES_WORKAROUND_MSVC_683388 // decltype(*i) is incorrectly an rvalue reference
// for pointer-to-array i
#define RANGES_WORKAROUND_MSVC_688606 // SFINAE failing to account for access control
// during specialization matching
#define RANGES_WORKAROUND_MSVC_786312 // Yet another mixed-pack-expansion failure
#define RANGES_WORKAROUND_MSVC_792338 // Failure to match specialization enabled via call
// to constexpr function
#define RANGES_WORKAROUND_MSVC_835948 // Silent bad codegen destroying sized_generator [No
// workaround]
#define RANGES_WORKAROUND_MSVC_934264 // Explicitly-defaulted inherited default
// constructor is not correctly implicitly constexpr
#if _MSVC_LANG <= 201703L
#define RANGES_WORKAROUND_MSVC_OLD_LAMBDA
#endif
#if _MSVC_LANG <= 201703L
#define RANGES_WORKAROUND_MSVC_UNUSABLE_SPAN // MSVC provides a <span> header that is
// guarded against use with std <= 17
#endif
#elif defined(__GNUC__) || defined(__clang__)
#define RANGES_PRAGMA(X) _Pragma(#X)
#define RANGES_DIAGNOSTIC_PUSH RANGES_PRAGMA(GCC diagnostic push)
#define RANGES_DIAGNOSTIC_POP RANGES_PRAGMA(GCC diagnostic pop)
#define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS RANGES_PRAGMA(GCC diagnostic ignored "-Wpragmas")
#define RANGES_DIAGNOSTIC_IGNORE(X) \
RANGES_DIAGNOSTIC_IGNORE_PRAGMAS \
RANGES_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
RANGES_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \
RANGES_PRAGMA(GCC diagnostic ignored X)
#define RANGES_DIAGNOSTIC_IGNORE_SHADOWING RANGES_DIAGNOSTIC_IGNORE("-Wshadow")
#define RANGES_DIAGNOSTIC_IGNORE_INDENTATION \
RANGES_DIAGNOSTIC_IGNORE("-Wmisleading-indentation")
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL \
RANGES_DIAGNOSTIC_IGNORE("-Wundefined-internal")
#define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS \
RANGES_DIAGNOSTIC_IGNORE("-Wmismatched-tags")
#define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION \
RANGES_DIAGNOSTIC_IGNORE("-Wsign-conversion")
#define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL RANGES_DIAGNOSTIC_IGNORE("-Wfloat-equal")
#define RANGES_DIAGNOSTIC_IGNORE_FLOAT_CONVERSION RANGES_DIAGNOSTIC_IGNORE("-Wfloat-conversion")
#define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES \
RANGES_DIAGNOSTIC_IGNORE("-Wmissing-braces")
#define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS \
RANGES_DIAGNOSTIC_IGNORE("-Wglobal-constructors")
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL \
RANGES_DIAGNOSTIC_IGNORE("-Wunneeded-internal-declaration")
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER \
RANGES_DIAGNOSTIC_IGNORE("-Wunneeded-member-function")
#define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY \
RANGES_DIAGNOSTIC_IGNORE("-Wzero-length-array")
#define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT RANGES_DIAGNOSTIC_IGNORE("-Wc++1z-compat")
#define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT RANGES_DIAGNOSTIC_IGNORE("-Wc++2a-compat")
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE \
RANGES_DIAGNOSTIC_IGNORE("-Wundefined-func-template")
#define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE \
RANGES_DIAGNOSTIC_IGNORE("-Winconsistent-missing-override")
#define RANGES_DIAGNOSTIC_IGNORE_RANGE_LOOP_ANALYSIS \
RANGES_DIAGNOSTIC_IGNORE("-Wrange-loop-analysis")
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \
RANGES_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations")
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE \
RANGES_DIAGNOSTIC_IGNORE("-Wdeprecated-this-capture")
#define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME \
RANGES_DIAGNOSTIC_IGNORE("-Winit-list-lifetime")
#define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
#define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
#define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION
#define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS
#define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE \
RANGES_DIAGNOSTIC_IGNORE("-Wvoid-ptr-dereference")
#define RANGES_DIAGNOSTIC_KEYWORD_MACRO RANGES_DIAGNOSTIC_IGNORE("-Wkeyword-macro")
#define RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE RANGES_DIAGNOSTIC_IGNORE("-Wsuggest-override")
#define RANGES_WORKAROUND_CWG_1554
#ifdef __clang__
#if __clang_major__ < 4
#define RANGES_WORKAROUND_CLANG_23135 // constexpr leads to premature instantiation on
// clang-3.x
#endif
#if (__clang_major__ >= 7 && __clang_major__ <= 9) || defined(__apple_build_version__)
#define RANGES_WORKAROUND_CLANG_43400 // template friend is redefinition of itself
#endif
#else // __GNUC__
#if __GNUC__ < 6
#define RANGES_WORKAROUND_GCC_UNFILED0 /* Workaround old GCC name lookup bug */
#endif
#if __GNUC__ == 7 || __GNUC__ == 8
#define RANGES_WORKAROUND_GCC_91525 /* Workaround strange GCC ICE */
#endif
#if __GNUC__ >= 9
#if __GNUC__ == 9 && __GNUC_MINOR__ < 3 && __cplusplus == RANGES_CXX_STD_17
#define RANGES_WORKAROUND_GCC_91923 // Failure-to-SFINAE with class type NTTP in C++17
#endif
#endif
#endif
#else
#define RANGES_DIAGNOSTIC_PUSH
#define RANGES_DIAGNOSTIC_POP
#define RANGES_DIAGNOSTIC_IGNORE_PRAGMAS
#define RANGES_DIAGNOSTIC_IGNORE_SHADOWING
#define RANGES_DIAGNOSTIC_IGNORE_INDENTATION
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
#define RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
#define RANGES_DIAGNOSTIC_IGNORE_GLOBAL_CONSTRUCTORS
#define RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_INTERNAL
#define RANGES_DIAGNOSTIC_IGNORE_UNNEEDED_MEMBER
#define RANGES_DIAGNOSTIC_IGNORE_ZERO_LENGTH_ARRAY
#define RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
#define RANGES_DIAGNOSTIC_IGNORE_CXX2A_COMPAT
#define RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
#define RANGES_DIAGNOSTIC_IGNORE_MISSING_BRACES
#define RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE
#define RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
#define RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_THIS_CAPTURE
#define RANGES_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
#define RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
#define RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
#define RANGES_DIAGNOSTIC_IGNORE_TRUNCATION
#define RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS
#define RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE
#define RANGES_DIAGNOSTIC_KEYWORD_MACRO
#define RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
#endif
// Configuration via feature-test macros, with fallback to __cplusplus
#ifndef RANGES_CXX_VER
#define RANGES_CXX_VER __cplusplus
#endif
#define RANGES_CXX_FEATURE_CONCAT2(y, z) RANGES_CXX_##y##_##z
#define RANGES_CXX_FEATURE_CONCAT(y, z) RANGES_CXX_FEATURE_CONCAT2(y, z)
#if RANGES_CXX_VER >= RANGES_CXX_STD_17
#define RANGES_CXX_STD RANGES_CXX_STD_17
#define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 17)
#elif RANGES_CXX_VER >= RANGES_CXX_STD_14
#define RANGES_CXX_STD RANGES_CXX_STD_14
#define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 14)
#else
#define RANGES_CXX_STD RANGES_CXX_STD_11
#define RANGES_CXX_FEATURE(x) RANGES_CXX_FEATURE_CONCAT(x, 11)
#endif
#ifndef RANGES_CXX_STATIC_ASSERT
#ifdef __cpp_static_assert
#define RANGES_CXX_STATIC_ASSERT __cpp_static_assert
#else
#define RANGES_CXX_STATIC_ASSERT RANGES_CXX_FEATURE(STATIC_ASSERT)
#endif
#endif
#ifndef RANGES_CXX_VARIABLE_TEMPLATES
#ifdef __cpp_variable_templates
#define RANGES_CXX_VARIABLE_TEMPLATES __cpp_variable_templates
#else
#define RANGES_CXX_VARIABLE_TEMPLATES RANGES_CXX_FEATURE(VARIABLE_TEMPLATES)
#endif
#endif
#if(defined(__cpp_lib_type_trait_variable_templates) && \
__cpp_lib_type_trait_variable_templates > 0) || \
RANGES_CXX_VER >= RANGES_CXX_STD_17
#define RANGES_CXX_TRAIT_VARIABLE_TEMPLATES 1
#else
#define RANGES_CXX_TRAIT_VARIABLE_TEMPLATES 0
#endif
#ifndef RANGES_CXX_ATTRIBUTE_DEPRECATED
#ifdef __has_cpp_attribute
#define RANGES_CXX_ATTRIBUTE_DEPRECATED __has_cpp_attribute(deprecated)
#elif defined(__cpp_attribute_deprecated)
#define RANGES_CXX_ATTRIBUTE_DEPRECATED __cpp_attribute_deprecated
#else
#define RANGES_CXX_ATTRIBUTE_DEPRECATED RANGES_CXX_FEATURE(ATTRIBUTE_DEPRECATED)
#endif
#endif
#ifndef RANGES_CXX_CONSTEXPR
#ifdef __cpp_constexpr
#define RANGES_CXX_CONSTEXPR __cpp_constexpr
#else
#define RANGES_CXX_CONSTEXPR RANGES_CXX_FEATURE(CONSTEXPR)
#endif
#endif
#ifndef RANGES_CXX_RANGE_BASED_FOR
#ifdef __cpp_range_based_for
#define RANGES_CXX_RANGE_BASED_FOR __cpp_range_based_for
#else
#define RANGES_CXX_RANGE_BASED_FOR RANGES_CXX_FEATURE(RANGE_BASED_FOR)
#endif
#endif
#ifndef RANGES_CXX_LIB_IS_FINAL
#include <type_traits>
#ifdef __cpp_lib_is_final
#define RANGES_CXX_LIB_IS_FINAL __cpp_lib_is_final
#else
#define RANGES_CXX_LIB_IS_FINAL RANGES_CXX_FEATURE(LIB_IS_FINAL)
#endif
#endif
#ifndef RANGES_CXX_RETURN_TYPE_DEDUCTION
#ifdef __cpp_return_type_deduction
#define RANGES_CXX_RETURN_TYPE_DEDUCTION __cpp_return_type_deduction
#else
#define RANGES_CXX_RETURN_TYPE_DEDUCTION RANGES_CXX_FEATURE(RETURN_TYPE_DEDUCTION)
#endif
#endif
#ifndef RANGES_CXX_GENERIC_LAMBDAS
#ifdef __cpp_generic_lambdas
#define RANGES_CXX_GENERIC_LAMBDAS __cpp_generic_lambdas
#else
#define RANGES_CXX_GENERIC_LAMBDAS RANGES_CXX_FEATURE(GENERIC_LAMBDAS)
#endif
#endif
#ifndef RANGES_CXX_THREAD_LOCAL
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED <= 70100
#define RANGES_CXX_THREAD_LOCAL 0
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) || \
(defined(__clang__) && (defined(__CYGWIN__) || defined(__apple_build_version__)))
// BUGBUG avoid unresolved __cxa_thread_atexit
#define RANGES_CXX_THREAD_LOCAL RANGES_CXX_THREAD_LOCAL_PRE_STANDARD
#else
#define RANGES_CXX_THREAD_LOCAL RANGES_CXX_FEATURE(THREAD_LOCAL)
#endif
#endif
#if !defined(RANGES_DEPRECATED) && !defined(RANGES_DISABLE_DEPRECATED_WARNINGS)
#if defined(__GNUC__) && !defined(__clang__)
// GCC's support for [[deprecated("message")]] is unusably buggy.
#define RANGES_DEPRECATED(MSG) __attribute__((deprecated(MSG)))
#elif RANGES_CXX_ATTRIBUTE_DEPRECATED && \
!((defined(__clang__) || defined(__GNUC__)) && RANGES_CXX_STD < RANGES_CXX_STD_14)
#define RANGES_DEPRECATED(MSG) [[deprecated(MSG)]]
#elif defined(__clang__) || defined(__GNUC__)
#define RANGES_DEPRECATED(MSG) __attribute__((deprecated(MSG)))
#endif
#endif
#ifndef RANGES_DEPRECATED
#define RANGES_DEPRECATED(MSG)
#endif
#if !defined(RANGES_DEPRECATED_HEADER) && !defined(RANGES_DISABLE_DEPRECATED_WARNINGS)
#ifdef __GNUC__
#define RANGES_DEPRECATED_HEADER(MSG) RANGES_PRAGMA(GCC warning MSG)
#elif defined(_MSC_VER)
#define RANGES_STRINGIZE_(MSG) #MSG
#define RANGES_STRINGIZE(MSG) RANGES_STRINGIZE_(MSG)
#define RANGES_DEPRECATED_HEADER(MSG) \
__pragma(message(__FILE__ "(" RANGES_STRINGIZE(__LINE__) ") : Warning: " MSG))
#endif
#else
#define RANGES_DEPRECATED_HEADER(MSG) /**/
#endif
// #ifndef RANGES_DEPRECATED_HEADER
// #define RANGES_DEPRECATED_HEADER(MSG)
// #endif
#ifndef RANGES_CXX_COROUTINES
#if defined(__cpp_coroutines) && defined(__has_include)
#if __has_include(<coroutine>)
#define RANGES_CXX_COROUTINES __cpp_coroutines
#define RANGES_COROUTINES_HEADER <coroutine>
#define RANGES_COROUTINES_NS std
#elif __has_include(<experimental/coroutine>)
#define RANGES_CXX_COROUTINES __cpp_coroutines
#define RANGES_COROUTINES_HEADER <experimental/coroutine>
#define RANGES_COROUTINES_NS std::experimental
#endif
#endif
#ifndef RANGES_CXX_COROUTINES
#define RANGES_CXX_COROUTINES RANGES_CXX_FEATURE(COROUTINES)
#endif
#endif
#ifdef NDEBUG
#define RANGES_NDEBUG_CONSTEXPR constexpr
#else
#define RANGES_NDEBUG_CONSTEXPR inline
#endif
#ifndef RANGES_CXX_INLINE_VARIABLES
#ifdef __cpp_inline_variables
#define RANGES_CXX_INLINE_VARIABLES __cpp_inline_variables
#elif defined(__clang__) && (__clang_major__ == 3 && __clang_minor__ == 9) && \
RANGES_CXX_VER > RANGES_CXX_STD_14
// Clang 3.9 supports inline variables in C++17 mode, but doesn't define
// __cpp_inline_variables
#define RANGES_CXX_INLINE_VARIABLES RANGES_CXX_INLINE_VARIABLES_17
#else
#define RANGES_CXX_INLINE_VARIABLES RANGES_CXX_FEATURE(INLINE_VARIABLES)
#endif // __cpp_inline_variables
#endif // RANGES_CXX_INLINE_VARIABLES
#if RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17 && \
!defined(RANGES_DOXYGEN_INVOKED)
#define RANGES_INLINE_VAR
#define RANGES_INLINE_VARIABLE(type, name) \
namespace \
{ \
constexpr auto & name = ::ranges::static_const<type>::value; \
}
#else // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_INLINE_VAR inline
#define RANGES_INLINE_VARIABLE(type, name) \
inline constexpr type name{}; \
/**/
#endif // RANGES_CXX_INLINE_VARIABLES
#if defined(RANGES_DOXYGEN_INVOKED)
#define RANGES_DEFINE_CPO(type, name) \
inline constexpr type name{}; \
/**/
#elif RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_DEFINE_CPO(type, name) \
namespace \
{ \
constexpr auto & name = ::ranges::static_const<type>::value; \
} \
/**/
#else // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_DEFINE_CPO(type, name) \
namespace _ \
{ \
inline constexpr type name{}; \
} \
using namespace _; \
/**/
#endif // RANGES_CXX_INLINE_VARIABLES
#ifndef RANGES_DOXYGEN_INVOKED
#define RANGES_HIDDEN_DETAIL(...) __VA_ARGS__
#else
#define RANGES_HIDDEN_DETAIL(...)
#endif
#ifndef RANGES_DOXYGEN_INVOKED
#define RANGES_ADL_BARRIER_FOR(S) S##_ns
#define RANGES_STRUCT_WITH_ADL_BARRIER(S) \
_ranges_adl_barrier_noop_; \
namespace RANGES_ADL_BARRIER_FOR(S) \
{ \
struct S; \
} \
using RANGES_ADL_BARRIER_FOR(S)::S; \
struct RANGES_ADL_BARRIER_FOR(S)::S /**/
#else
#define RANGES_ADL_BARRIER_FOR(S)
#define RANGES_STRUCT_WITH_ADL_BARRIER(S) S
#endif
#ifndef RANGES_DOXYGEN_INVOKED
#define RANGES_FUNC_BEGIN(NAME) \
struct NAME##_fn \
{
#define RANGES_FUNC_END(NAME) \
} \
; \
RANGES_INLINE_VARIABLE(NAME##_fn, NAME)
#define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
#define RANGES_FUNC_CONST_(...) (__VA_ARGS__) const
#else
#define RANGES_FUNC_BEGIN(NAME)
#define RANGES_FUNC_END(NAME)
#define RANGES_FUNC(NAME) NAME
#endif
#ifndef RANGES_CXX_DEDUCTION_GUIDES
#if defined(__clang__) && defined(__apple_build_version__)
// Apple's clang version doesn't do deduction guides very well.
#define RANGES_CXX_DEDUCTION_GUIDES 0
#elif defined(__cpp_deduction_guides)
#define RANGES_CXX_DEDUCTION_GUIDES __cpp_deduction_guides
#else
#define RANGES_CXX_DEDUCTION_GUIDES RANGES_CXX_FEATURE(DEDUCTION_GUIDES)
#endif // __cpp_deduction_guides
#endif // RANGES_CXX_DEDUCTION_GUIDES
// __VA_OPT__
#ifndef RANGES_CXX_VA_OPT
#if __cplusplus > 201703L
#define RANGES_CXX_THIRD_ARG_(A, B, C, ...) C
#define RANGES_CXX_VA_OPT_I_(...) RANGES_CXX_THIRD_ARG_(__VA_OPT__(, ), 1, 0, ?)
#define RANGES_CXX_VA_OPT RANGES_CXX_VA_OPT_I_(?)
#else
#define RANGES_CXX_VA_OPT 0
#endif
#endif // RANGES_CXX_VA_OPT
#ifndef RANGES_CXX_IF_CONSTEXPR
#ifdef __cpp_if_constexpr
#define RANGES_CXX_IF_CONSTEXPR __cpp_if_constexpr
#else
#define RANGES_CXX_IF_CONSTEXPR RANGES_CXX_FEATURE(IF_CONSTEXPR)
#endif
#endif // RANGES_CXX_IF_CONSTEXPR
// Its not enough for the compiler to support this; the stdlib must support it too.
#ifndef RANGES_CXX_ALIGNED_NEW
#if(!defined(_LIBCPP_VERSION) || \
(_LIBCPP_VERSION >= 4000 && !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION))) && \
(!defined(__GLIBCXX__) || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7))
#if defined(__cpp_aligned_new)
#define RANGES_CXX_ALIGNED_NEW __cpp_aligned_new
#else
#define RANGES_CXX_ALIGNED_NEW RANGES_CXX_FEATURE(ALIGNED_NEW)
#endif
#else // _LIBCPP_VERSION < 4000 || __GLIBCXX__ < 20170502
#define RANGES_CXX_ALIGNED_NEW 0L
#endif
#endif // RANGES_CXX_ALIGNED_NEW
#if defined(__clang__)
#define RANGES_IS_SAME(...) __is_same(__VA_ARGS__)
#elif defined(__GNUC__) && __GNUC__ >= 6
#define RANGES_IS_SAME(...) __is_same_as(__VA_ARGS__)
#elif RANGES_CXX_TRAIT_VARIABLE_TEMPLATES
#define RANGES_IS_SAME(...) std::is_same_v<__VA_ARGS__>
#else
#define RANGES_IS_SAME(...) std::is_same<__VA_ARGS__>::value
#endif
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93667
#if defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address) && \
!(defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 10)
#define RANGES_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else
#define RANGES_NO_UNIQUE_ADDRESS
#endif
#if defined(__clang__)
#if __has_attribute(no_sanitize)
#define RANGES_INTENDED_MODULAR_ARITHMETIC \
__attribute__((__no_sanitize__("unsigned-integer-overflow")))
#else
#define RANGES_INTENDED_MODULAR_ARITHMETIC
#endif
#else
#define RANGES_INTENDED_MODULAR_ARITHMETIC
#endif
#ifndef RANGES_CONSTEXPR_IF
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
#define RANGES_CONSTEXPR_IF(...) false) \
{} else if constexpr(__VA_ARGS__
#else
#define RANGES_CONSTEXPR_IF(...) __VA_ARGS__
#endif
#endif // RANGES_CONSTEXPR_IF
#if !defined(RANGES_BROKEN_CPO_LOOKUP) && !defined(RANGES_DOXYGEN_INVOKED) && \
(defined(RANGES_WORKAROUND_GCC_UNFILED0) || defined(RANGES_WORKAROUND_MSVC_895622))
#define RANGES_BROKEN_CPO_LOOKUP 1
#endif
#ifndef RANGES_BROKEN_CPO_LOOKUP
#define RANGES_BROKEN_CPO_LOOKUP 0
#endif
#ifndef RANGES_NODISCARD
#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
#if defined(__clang__) && __cplusplus < 201703L
// clang complains about using nodiscard in C++14 mode.
#define RANGES_NODISCARD \
RANGES_DIAGNOSTIC_PUSH \
RANGES_DIAGNOSTIC_IGNORE("-Wc++1z-extensions") \
[[nodiscard]] RANGES_DIAGNOSTIC_POP /**/
#else
#define RANGES_NODISCARD [[nodiscard]]
#endif
#else
#define RANGES_NODISCARD
#endif
#endif
#ifndef RANGES_EMPTY_BASES
#ifdef _MSC_VER
#define RANGES_EMPTY_BASES __declspec(empty_bases)
#else
#define RANGES_EMPTY_BASES
#endif
#endif
#endif

View File

@@ -0,0 +1,22 @@
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_PROLOGUE_INCLUDED
#error "Including epilogue, but prologue not included!"
#endif
#undef RANGES_PROLOGUE_INCLUDED
#undef template
#undef AND
#undef declval
RANGES_DIAGNOSTIC_POP

View File

@@ -0,0 +1,47 @@
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_PROLOGUE_HPP
#define RANGES_V3_DETAIL_PROLOGUE_HPP
#include <range/v3/detail/config.hpp>
#endif
#ifdef RANGES_PROLOGUE_INCLUDED
#error "Prologue already included!"
#endif
#define RANGES_PROLOGUE_INCLUDED
RANGES_DIAGNOSTIC_PUSH
#ifdef RANGES_FEWER_WARNINGS
RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
RANGES_DIAGNOSTIC_IGNORE_INDENTATION
RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
#endif
RANGES_DIAGNOSTIC_KEYWORD_MACRO
#define template(...) \
CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \
template<__VA_ARGS__ CPP_TEMPLATE_AUX_ \
#define AND CPP_and
/// \cond
#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
// noexcept is part of the type system
#define declval(...) static_cast<__VA_ARGS__(*)() noexcept>(nullptr)()
#else
// noexcept is not part of the type system
#define declval(...) static_cast<__VA_ARGS__(*)()>(nullptr)()
#endif
/// \cond

View File

@@ -0,0 +1,418 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2014-present
// Copyright Casey Carter 2016
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_RANGE_ACCESS_HPP
#define RANGES_V3_DETAIL_RANGE_ACCESS_HPP
#include <cstddef>
#include <utility>
#include <meta/meta.hpp>
#include <concepts/concepts.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-views
/// @{
struct range_access
{
/// \cond
private:
template<typename T>
static std::false_type single_pass_2_(long);
template<typename T>
static typename T::single_pass single_pass_2_(int);
template<typename T>
struct single_pass_
{
using type = decltype(range_access::single_pass_2_<T>(42));
};
template<typename T>
static std::false_type contiguous_2_(long);
template<typename T>
static typename T::contiguous contiguous_2_(int);
template<typename T>
struct contiguous_
{
using type = decltype(range_access::contiguous_2_<T>(42));
};
template<typename T>
static basic_mixin<T> mixin_base_2_(long);
template<typename T>
static typename T::mixin mixin_base_2_(int);
template<typename Cur>
struct mixin_base_
{
using type = decltype(range_access::mixin_base_2_<Cur>(42));
};
public:
template<typename Cur>
using single_pass_t = meta::_t<single_pass_<Cur>>;
template<typename Cur>
using contiguous_t = meta::_t<contiguous_<Cur>>;
template<typename Cur>
using mixin_base_t = meta::_t<mixin_base_<Cur>>;
// clang-format off
template<typename Rng>
static constexpr auto CPP_auto_fun(begin_cursor)(Rng &rng)
(
return rng.begin_cursor()
)
template<typename Rng>
static constexpr auto CPP_auto_fun(end_cursor)(Rng &rng)
(
return rng.end_cursor()
)
template<typename Rng>
static constexpr auto CPP_auto_fun(begin_adaptor)(Rng &rng)
(
return rng.begin_adaptor()
)
template<typename Rng>
static constexpr auto CPP_auto_fun(end_adaptor)(Rng &rng)
(
return rng.end_adaptor()
)
template<typename Cur>
static constexpr auto CPP_auto_fun(read)(Cur const &pos)
(
return pos.read()
)
template<typename Cur>
static constexpr auto CPP_auto_fun(arrow)(Cur const &pos)
(
return pos.arrow()
)
template<typename Cur>
static constexpr auto CPP_auto_fun(move)(Cur const &pos)
(
return pos.move()
)
template<typename Cur, typename T>
static constexpr auto CPP_auto_fun(write)(Cur &pos, T &&t)
(
return pos.write((T &&) t)
)
template<typename Cur>
static constexpr auto CPP_auto_fun(next)(Cur & pos)
(
return pos.next()
)
template<typename Cur, typename O>
static constexpr auto CPP_auto_fun(equal)(Cur const &pos, O const &other)
(
return pos.equal(other)
)
template<typename Cur>
static constexpr auto CPP_auto_fun(prev)(Cur & pos)
(
return pos.prev()
)
template<typename Cur, typename D>
static constexpr auto CPP_auto_fun(advance)(Cur & pos, D n)
(
return pos.advance(n)
)
template<typename Cur, typename O>
static constexpr auto CPP_auto_fun(distance_to)(Cur const &pos, O const &other)
(
return pos.distance_to(other)
)
private:
template<typename Cur>
using sized_cursor_difference_t = decltype(
range_access::distance_to(std::declval<Cur>(), std::declval<Cur>()));
// clang-format on
template<typename T>
static std::ptrdiff_t cursor_difference_2_(detail::ignore_t);
template<typename T>
static sized_cursor_difference_t<T> cursor_difference_2_(long);
template<typename T>
static typename T::difference_type cursor_difference_2_(int);
template<typename T>
using cursor_reference_t = decltype(std::declval<T const &>().read());
template<typename T>
static meta::id<uncvref_t<cursor_reference_t<T>>> cursor_value_2_(long);
template<typename T>
static meta::id<typename T::value_type> cursor_value_2_(int);
#ifdef RANGES_WORKAROUND_CWG_1554
template<typename Cur>
struct cursor_difference
{
using type = decltype(range_access::cursor_difference_2_<Cur>(42));
};
template<typename Cur>
struct cursor_value : decltype(range_access::cursor_value_2_<Cur>(42))
{};
#endif // RANGES_WORKAROUND_CWG_1554
public:
#ifdef RANGES_WORKAROUND_CWG_1554
template<typename Cur>
using cursor_difference_t = meta::_t<cursor_difference<Cur>>;
template<typename Cur>
using cursor_value_t = meta::_t<cursor_value<Cur>>;
#else // ^^^ workaround ^^^ / vvv no workaround vvv
template<typename Cur>
using cursor_difference_t = decltype(range_access::cursor_difference_2_<Cur>(42));
template<typename Cur>
using cursor_value_t = meta::_t<decltype(range_access::cursor_value_2_<Cur>(42))>;
#endif // RANGES_WORKAROUND_CWG_1554
template<typename Cur>
static constexpr Cur & pos(basic_iterator<Cur> & it) noexcept
{
return it.pos();
}
template<typename Cur>
static constexpr Cur const & pos(basic_iterator<Cur> const & it) noexcept
{
return it.pos();
}
template<typename Cur>
static constexpr Cur && pos(basic_iterator<Cur> && it) noexcept
{
return detail::move(it.pos());
}
template<typename Cur>
static constexpr Cur cursor(basic_iterator<Cur> it)
{
return std::move(it.pos());
}
/// endcond
};
/// @}
/// \cond
namespace detail
{
//
// Concepts that the range cursor must model
// clang-format off
//
/// \concept cursor
/// \brief The \c cursor concept
template<typename T>
CPP_concept cursor =
semiregular<T> && semiregular<range_access::mixin_base_t<T>> &&
constructible_from<range_access::mixin_base_t<T>, T> &&
constructible_from<range_access::mixin_base_t<T>, T const &>;
// Axiom: mixin_base_t<T> has a member get(), accessible to derived classes,
// which perfectly-returns the contained cursor object and does not throw
// exceptions.
/// \concept has_cursor_next_
/// \brief The \c has_cursor_next_ concept
template<typename T>
CPP_requires(has_cursor_next_,
requires(T & t)
(
range_access::next(t)
));
/// \concept has_cursor_next
/// \brief The \c has_cursor_next concept
template<typename T>
CPP_concept has_cursor_next = CPP_requires_ref(detail::has_cursor_next_, T);
/// \concept sentinel_for_cursor_
/// \brief The \c sentinel_for_cursor_ concept
template<typename S, typename C>
CPP_requires(sentinel_for_cursor_,
requires(S & s, C & c) //
(
range_access::equal(c, s),
concepts::requires_<convertible_to<decltype(
range_access::equal(c, s)), bool>>
));
/// \concept sentinel_for_cursor
/// \brief The \c sentinel_for_cursor concept
template<typename S, typename C>
CPP_concept sentinel_for_cursor =
semiregular<S> &&
cursor<C> &&
CPP_requires_ref(detail::sentinel_for_cursor_, S, C);
/// \concept readable_cursor_
/// \brief The \c readable_cursor_ concept
template<typename T>
CPP_requires(readable_cursor_,
requires(T & t) //
(
range_access::read(t)
));
/// \concept readable_cursor
/// \brief The \c readable_cursor concept
template<typename T>
CPP_concept readable_cursor = CPP_requires_ref(detail::readable_cursor_, T);
/// \concept has_cursor_arrow_
/// \brief The \c has_cursor_arrow_ concept
template<typename T>
CPP_requires(has_cursor_arrow_,
requires(T const & t) //
(
range_access::arrow(t)
));
/// \concept has_cursor_arrow
/// \brief The \c has_cursor_arrow concept
template<typename T>
CPP_concept has_cursor_arrow = CPP_requires_ref(detail::has_cursor_arrow_, T);
/// \concept writable_cursor_
/// \brief The \c writable_cursor_ concept
template<typename T, typename U>
CPP_requires(writable_cursor_,
requires(T & t, U && u) //
(
range_access::write(t, (U &&) u)
));
/// \concept writable_cursor
/// \brief The \c writable_cursor concept
template<typename T, typename U>
CPP_concept writable_cursor =
CPP_requires_ref(detail::writable_cursor_, T, U);
/// \concept sized_sentinel_for_cursor_
/// \brief The \c sized_sentinel_for_cursor_ concept
template<typename S, typename C>
CPP_requires(sized_sentinel_for_cursor_,
requires(S & s, C & c) //
(
range_access::distance_to(c, s),
concepts::requires_<signed_integer_like_<decltype(
range_access::distance_to(c, s))>>
)
);
/// \concept sized_sentinel_for_cursor
/// \brief The \c sized_sentinel_for_cursor concept
template<typename S, typename C>
CPP_concept sized_sentinel_for_cursor =
sentinel_for_cursor<S, C> &&
CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
/// \concept output_cursor
/// \brief The \c output_cursor concept
template<typename T, typename U>
CPP_concept output_cursor =
writable_cursor<T, U> && cursor<T>;
/// \concept input_cursor
/// \brief The \c input_cursor concept
template<typename T>
CPP_concept input_cursor =
readable_cursor<T> && cursor<T> && has_cursor_next<T>;
/// \concept forward_cursor
/// \brief The \c forward_cursor concept
template<typename T>
CPP_concept forward_cursor =
input_cursor<T> && sentinel_for_cursor<T, T> &&
!range_access::single_pass_t<uncvref_t<T>>::value;
/// \concept bidirectional_cursor_
/// \brief The \c bidirectional_cursor_ concept
template<typename T>
CPP_requires(bidirectional_cursor_,
requires(T & t) //
(
range_access::prev(t)
));
/// \concept bidirectional_cursor
/// \brief The \c bidirectional_cursor concept
template<typename T>
CPP_concept bidirectional_cursor =
forward_cursor<T> &&
CPP_requires_ref(detail::bidirectional_cursor_, T);
/// \concept random_access_cursor_
/// \brief The \c random_access_cursor_ concept
template<typename T>
CPP_requires(random_access_cursor_,
requires(T & t) //
(
range_access::advance(t, range_access::distance_to(t, t))
));
/// \concept random_access_cursor
/// \brief The \c random_access_cursor concept
template<typename T>
CPP_concept random_access_cursor =
bidirectional_cursor<T> && //
sized_sentinel_for_cursor<T, T> && //
CPP_requires_ref(detail::random_access_cursor_, T);
template(class T)(
requires std::is_lvalue_reference<T>::value)
void is_lvalue_reference(T&&);
/// \concept contiguous_cursor_
/// \brief The \c contiguous_cursor_ concept
template<typename T>
CPP_requires(contiguous_cursor_,
requires(T & t) //
(
detail::is_lvalue_reference(range_access::read(t))
));
/// \concept contiguous_cursor
/// \brief The \c contiguous_cursor concept
template<typename T>
CPP_concept contiguous_cursor =
random_access_cursor<T> && //
range_access::contiguous_t<uncvref_t<T>>::value && //
CPP_requires_ref(detail::contiguous_cursor_, T);
// clang-format on
template<typename Cur, bool IsReadable>
RANGES_INLINE_VAR constexpr bool is_writable_cursor_ = true;
template<typename Cur>
RANGES_INLINE_VAR constexpr bool is_writable_cursor_<Cur, true> =
(bool) writable_cursor<Cur, range_access::cursor_value_t<Cur>>;
template<typename Cur>
RANGES_INLINE_VAR constexpr bool is_writable_cursor_v =
is_writable_cursor_<Cur, (bool)readable_cursor<Cur>>;
} // namespace detail
/// \endcond
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,87 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_SATISFY_BOOST_RANGE_HPP
#define RANGES_V3_DETAIL_SATISFY_BOOST_RANGE_HPP
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/traits.hpp>
#ifndef RANGES_DOXYGEN_INVOKED
namespace boost
{
/// \brief Boost Range specialisation point, for making Boost ranges out of range-v3
/// views
template<typename T, typename U>
struct range_mutable_iterator;
/// \brief Boost Range specialisation point, for making Boost ranges out of range-v3
/// views
template<typename T, typename U>
struct range_const_iterator;
/// \brief Boost Range specialisation point, for making Boost ranges out of range-v3
/// views
template<typename T>
struct range_value;
/// \brief Boost Range specialisation point, for making Boost ranges out of range-v3
/// views
template<typename T>
struct range_size;
} // namespace boost
/// \brief Macro specialising Boost Range metafunctions for the specified view
#define RANGES_SATISFY_BOOST_RANGE(view_name) \
namespace boost \
{ \
template<typename... Ts> \
struct range_mutable_iterator< \
view_name<Ts...>, \
::meta::if_c<(bool)::ranges::common_range<view_name<Ts...>>>> \
{ \
using type = ::ranges::iterator_t<view_name<Ts...>>; \
}; \
template<typename... Ts> \
struct range_const_iterator< \
view_name<Ts...>, \
::meta::if_c<(bool)::ranges::common_range<view_name<Ts...> const>>> \
{ \
using type = ::ranges::iterator_t<view_name<Ts...> const>; \
}; \
template<typename... Ts> \
struct range_value<view_name<Ts...>> \
{ \
using type = ::ranges::range_value_t<view_name<Ts...>>; \
}; \
template<typename... Ts> \
struct range_size<view_name<Ts...>> \
: ::meta::if_c<(bool)::ranges::common_range<view_name<Ts...>>, \
::meta::defer<::ranges::range_size_t, view_name<Ts...>>, \
::meta::nil_> \
{}; \
template<typename... Ts> \
struct range_size<view_name<Ts...> const> \
: ::meta::if_c<(bool)::ranges::common_range<view_name<Ts...> const>, \
::meta::defer<::ranges::range_size_t, view_name<Ts...> const>, \
::meta::nil_> \
{}; \
}
#else
#define RANGES_SATISFY_BOOST_RANGE(view_name)
#endif
#endif

View File

@@ -0,0 +1,893 @@
// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_VARIANT_HPP
#define RANGES_V3_DETAIL_VARIANT_HPP
#include <iterator>
#include <memory>
#include <new>
#include <stdexcept>
#include <tuple>
#include <type_traits>
#include <utility>
#include <meta/meta.hpp>
#include <concepts/concepts.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/functional/compose.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/get.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
template<std::size_t I>
struct emplaced_index_t;
template<std::size_t I>
struct emplaced_index_t : meta::size_t<I>
{};
#if RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17
namespace
{
template<std::size_t I>
constexpr auto & emplaced_index = static_const<emplaced_index_t<I>>::value;
}
#else // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
template<std::size_t I>
inline constexpr emplaced_index_t<I> emplaced_index{};
#endif // RANGES_CXX_INLINE_VARIABLES
struct bad_variant_access : std::logic_error
{
explicit bad_variant_access(std::string const & what_arg)
: std::logic_error(what_arg)
{}
explicit bad_variant_access(char const * what_arg)
: std::logic_error(what_arg)
{}
};
template<typename T, std::size_t Index>
struct indexed_element
{
private:
std::add_pointer_t<T> t_;
public:
constexpr explicit indexed_element(T & t) noexcept
: t_(std::addressof(t))
{}
constexpr T & get() const noexcept
{
return *t_;
}
};
template<typename T, std::size_t Index>
struct indexed_element<T &&, Index>
{
private:
T * t_;
public:
constexpr explicit indexed_element(T && t) noexcept
: t_(std::addressof(t))
{}
constexpr T && get() const noexcept
{
return static_cast<T &&>(*t_);
}
};
template<std::size_t Index>
struct indexed_element<void, Index>
{
void get() const noexcept
{}
};
/// \cond
namespace detail
{
struct indexed_element_fn;
template(typename I, typename S, typename O)(
requires (!sized_sentinel_for<S, I>)) //
O uninitialized_copy(I first, S last, O out)
{
for(; first != last; ++first, ++out)
::new((void *)std::addressof(*out)) iter_value_t<O>(*first);
return out;
}
template(typename I, typename S, typename O)(
requires sized_sentinel_for<S, I>)
O uninitialized_copy(I first, S last, O out)
{
return std::uninitialized_copy_n(first, (last - first), out);
}
template<typename I, typename O>
O uninitialized_copy(I first, I last, O out)
{
return std::uninitialized_copy(first, last, out);
}
template<typename T, typename Index>
struct indexed_datum
{
private:
template<typename, typename>
friend struct indexed_datum;
T datum_;
public:
CPP_member
constexpr CPP_ctor(indexed_datum)()( //
noexcept(std::is_nothrow_default_constructible<T>::value) //
requires default_constructible<T>)
: datum_{}
{}
template(typename... Ts)(
requires constructible_from<T, Ts...> AND (sizeof...(Ts) != 0)) //
constexpr indexed_datum(Ts &&... ts) noexcept(
std::is_nothrow_constructible<T, Ts...>::value)
: datum_(static_cast<Ts &&>(ts)...)
{}
template(typename U)(
requires (!same_as<T, U>) AND convertible_to<U, T>)
constexpr indexed_datum(indexed_datum<U, Index> that) //
noexcept(std::is_nothrow_constructible<T, U>::value) //
: datum_(std::move(that.datum_))
{}
constexpr auto ref() noexcept
{
return indexed_element<T, Index::value>{datum_};
}
constexpr auto ref() const noexcept
{
return indexed_element<T const, Index::value>{datum_};
}
constexpr T & get() noexcept
{
return datum_;
}
constexpr T const & get() const noexcept
{
return datum_;
}
};
template<typename T, std::size_t N, typename Index>
struct indexed_datum<T[N], Index>;
template<typename T, typename Index>
struct indexed_datum<T &, Index>
{
private:
template<typename, typename>
friend struct indexed_datum;
T * t_;
public:
constexpr indexed_datum(T & t) noexcept
: t_(std::addressof(t))
{}
constexpr T & get() const noexcept
{
return *t_;
}
constexpr auto ref() const noexcept
{
return indexed_element<T &, Index::value>{*t_};
}
};
template<typename T, typename Index>
struct indexed_datum<T &&, Index>
{
private:
template<typename, typename>
friend struct indexed_datum;
T * t_;
public:
constexpr indexed_datum(T && t) noexcept
: t_(std::addressof(t))
{}
constexpr T && get() const noexcept
{
return static_cast<T &&>(*t_);
}
constexpr auto ref() const noexcept
{
return indexed_element<T &&, Index::value>{static_cast<T &&>(*t_)};
}
};
template<typename Index>
struct indexed_datum<void, Index>
{
void get() const noexcept
{}
constexpr indexed_element<void, Index::value> ref() const noexcept
{
return {};
}
};
template<std::size_t Index, typename... Ts>
using variant_datum_t =
detail::indexed_datum<meta::at_c<meta::list<Ts...>, Index>,
meta::size_t<Index>>;
using variant_nil = indexed_datum<void, meta::npos>;
template<typename Ts,
bool Trivial = meta::apply<
meta::quote<meta::and_>,
meta::transform<Ts, meta::quote<std::is_trivially_destructible>>>::
type::value>
struct variant_data_
{
using type = indexed_datum<void, meta::npos>;
};
template<typename T, typename... Ts>
struct variant_data_<meta::list<T, Ts...>, true>
{
struct type
{
using head_t = T;
using tail_t = meta::_t<variant_data_<meta::list<Ts...>>>;
union
{
head_t head;
tail_t tail;
};
type() noexcept
{}
template<typename... Args>
constexpr type(meta::size_t<0>, Args &&... args) noexcept(
std::is_nothrow_constructible<head_t, Args...>::value)
: head{((Args &&) args)...}
{}
template<std::size_t N, typename... Args>
constexpr type(meta::size_t<N>, Args &&... args) noexcept(
std::is_nothrow_constructible<tail_t, meta::size_t<N - 1>,
Args...>::value)
: tail{meta::size_t<N - 1>{}, ((Args &&) args)...}
{}
};
};
template<typename T, typename... Ts>
struct variant_data_<meta::list<T, Ts...>, false>
{
struct type
{
using head_t = T;
using tail_t = meta::_t<variant_data_<meta::list<Ts...>>>;
union
{
head_t head;
tail_t tail;
};
type() noexcept
{}
~type()
{}
template<typename... Args>
constexpr type(meta::size_t<0>, Args &&... args) noexcept(
std::is_nothrow_constructible<head_t, Args...>::value)
: head{((Args &&) args)...}
{}
template<std::size_t N, typename... Args>
constexpr type(meta::size_t<N>, Args &&... args) noexcept(
std::is_nothrow_constructible<tail_t, meta::size_t<N - 1>,
Args...>::value)
: tail{meta::size_t<N - 1>{}, ((Args &&) args)...}
{}
};
};
template<typename... Ts>
using variant_data = meta::_t<variant_data_<meta::transform<
meta::list<Ts...>, meta::as_list<meta::make_index_sequence<sizeof...(Ts)>>,
meta::quote<indexed_datum>>>>;
inline std::size_t variant_move_copy_(std::size_t, variant_nil, variant_nil)
{
return 0;
}
template<typename Data0, typename Data1>
std::size_t variant_move_copy_(std::size_t n, Data0 & self, Data1 && that)
{
using Head = typename Data0::head_t;
return 0 == n
? ((void)::new((void *)&self.head) Head(((Data1 &&) that).head), 0)
: variant_move_copy_(n - 1, self.tail, ((Data1 &&) that).tail) + 1;
}
constexpr bool variant_equal_(std::size_t, variant_nil, variant_nil)
{
return true;
}
template<typename Data0, typename Data1>
constexpr bool variant_equal_(std::size_t n, Data0 const & self,
Data1 const & that)
{
return n == 0 ? self.head.get() == that.head.get()
: variant_equal_(n - 1, self.tail, that.tail);
}
template<typename Fun, typename Proj = indexed_element_fn>
constexpr int variant_visit_(std::size_t, variant_nil, Fun, Proj = {})
{
return (RANGES_EXPECT(false), 0);
}
template<typename Data, typename Fun, typename Proj = indexed_element_fn>
constexpr int variant_visit_(std::size_t n, Data & self, Fun fun, Proj proj = {})
{
return 0 == n ? ((void)invoke(fun, invoke(proj, self.head)), 0)
: detail::variant_visit_(
n - 1, self.tail, detail::move(fun), detail::move(proj));
}
struct get_datum_fn
{
template<typename T>
decltype(auto) operator()(T && t) const noexcept
{
return t.get();
}
};
struct indexed_element_fn
{
template<typename T>
decltype(auto) operator()(T && t) const noexcept
{
return t.ref();
}
};
struct empty_variant_tag
{};
struct variant_core_access
{
template<typename... Ts>
static constexpr variant_data<Ts...> & data(variant<Ts...> & var) noexcept
{
return var.data_();
}
template<typename... Ts>
static constexpr variant_data<Ts...> const & data(
variant<Ts...> const & var) noexcept
{
return var.data_();
}
template<typename... Ts>
static constexpr variant_data<Ts...> && data(variant<Ts...> && var) noexcept
{
return detail::move(var.data_());
}
template<typename... Ts>
static variant<Ts...> make_empty(meta::id<variant<Ts...>> = {}) noexcept
{
return variant<Ts...>{empty_variant_tag{}};
}
};
struct delete_fn
{
template<typename T>
void operator()(T const & t) const noexcept
{
t.~T();
}
};
template<std::size_t N, typename... Ts>
struct construct_fn
{
std::tuple<Ts...> args_;
template<typename U, std::size_t... Is>
void construct_(U & u, meta::index_sequence<Is...>) noexcept(
std::is_nothrow_constructible<U, Ts...>::value)
{
::new((void *)std::addressof(u))
U(static_cast<Ts &&>(std::get<Is>(args_))...);
}
construct_fn(Ts &&... ts) noexcept(
std::is_nothrow_constructible<std::tuple<Ts...>, Ts...>::value)
: args_{static_cast<Ts &&>(ts)...}
{}
template<typename U, std::size_t M>
[[noreturn]] meta::if_c<N != M> operator()(
indexed_datum<U, meta::size_t<M>> &) noexcept
{
RANGES_EXPECT(false);
}
template<typename U>
meta::if_<std::is_object<U>> operator()(
indexed_datum<U, meta::size_t<N>> &
u) noexcept(std::is_nothrow_constructible<U, Ts...>::value)
{
this->construct_(u.get(), meta::make_index_sequence<sizeof...(Ts)>{});
}
template<typename U>
meta::if_<meta::not_<std::is_object<U>>> operator()(
indexed_datum<U, meta::size_t<N>> &
u) noexcept(std::is_nothrow_constructible<detail::decay_t<U>,
Ts...>::value)
{
this->construct_(u, meta::make_index_sequence<sizeof...(Ts)>{});
}
};
template<typename T, std::size_t N>
struct get_fn
{
T ** t_;
template<typename U, std::size_t M>
[[noreturn]] meta::if_c<M != N> operator()(indexed_element<U, M>) const
{
throw bad_variant_access("bad variant access");
}
template<typename U>
void operator()(indexed_element<U, N> t) const noexcept
{
*t_ = std::addressof(t.get());
}
template<typename U>
void operator()(indexed_element<U &&, N> t) const noexcept
{
U && u = t.get();
*t_ = std::addressof(u);
}
void operator()(indexed_element<void, N>) const noexcept
{}
};
template<typename Variant, std::size_t N>
struct emplace_fn
{
Variant * var_;
// clang-format off
template<typename...Ts>
auto CPP_auto_fun(operator())(Ts &&...ts) (const)
(
return var_->template emplace<N>(static_cast<Ts &&>(ts)...)
)
// clang-format on
};
template<typename Fun, typename Variant>
struct variant_visitor
{
Fun fun_;
Variant * var_;
// clang-format off
template<typename U, std::size_t N>
auto CPP_auto_fun(operator())(indexed_element<U, N> u)
(
return compose(emplace_fn<Variant, N>{var_}, fun_)(u)
)
// clang-format on
};
template<typename Variant, typename Fun>
variant_visitor<Fun, Variant> make_variant_visitor(
Variant & var,
Fun fun) noexcept(std::is_nothrow_move_constructible<Fun>::value)
{
return {detail::move(fun), &var};
}
template<typename To, typename From>
struct unique_visitor;
template<typename... To, typename... From>
struct unique_visitor<variant<To...>, variant<From...>>
{
variant<To...> * var_;
template<typename T, std::size_t N>
void operator()(indexed_element<T, N> t) const
{
using E = meta::at_c<meta::list<From...>, N>;
static_assert(RANGES_IS_SAME(T const, E const),
"Is indexed_element broken?");
using F = meta::find<meta::list<To...>, E>;
static constexpr std::size_t M = sizeof...(To) - F::size();
compose(emplace_fn<variant<To...>, M>{var_}, get_datum_fn{})(t);
}
};
template<typename T>
constexpr T & variant_deref_(T * t) noexcept
{
return *t;
}
inline void variant_deref_(void const volatile *) noexcept
{}
template<typename Variant>
struct variant_get
{
//////////////////////////////////////////////////////////////////////////////
// get
template<std::size_t N>
friend meta::_t<
std::add_lvalue_reference<meta::at_c<meta::as_list<Variant>, N>>>
get(Variant & var)
{
using elem_t = meta::_t<
std::remove_reference<meta::at_c<meta::as_list<Variant>, N>>>;
elem_t * elem = nullptr;
auto & data_var = detail::variant_core_access::data(var);
detail::variant_visit_(
var.index(), data_var, detail::get_fn<elem_t, N>{&elem});
return detail::variant_deref_(elem);
}
template<std::size_t N>
friend meta::_t<
std::add_lvalue_reference<meta::at_c<meta::as_list<Variant>, N> const>>
get(Variant const & var)
{
using elem_t = meta::_t<
std::remove_reference<meta::at_c<meta::as_list<Variant>, N> const>>;
elem_t * elem = nullptr;
auto & data_var = detail::variant_core_access::data(var);
detail::variant_visit_(
var.index(), data_var, detail::get_fn<elem_t, N>{&elem});
return detail::variant_deref_(elem);
}
template<std::size_t N>
friend meta::_t<
std::add_rvalue_reference<meta::at_c<meta::as_list<Variant>, N>>>
get(Variant && var)
{
using elem_t = meta::_t<
std::remove_reference<meta::at_c<meta::as_list<Variant>, N>>>;
elem_t * elem = nullptr;
auto & data_var = detail::variant_core_access::data(var);
detail::variant_visit_(
var.index(), data_var, detail::get_fn<elem_t, N>{&elem});
using res_t = meta::_t<
std::add_rvalue_reference<meta::at_c<meta::as_list<Variant>, N>>>;
return static_cast<res_t>(detail::variant_deref_(elem));
}
};
template<typename Variant,
bool Trivial = std::is_trivially_destructible<meta::apply<
meta::quote<variant_data>, meta::as_list<Variant>>>::value>
struct variant_base : variant_get<Variant>
{
~variant_base()
{
static_cast<Variant *>(this)->clear_();
}
};
template<typename... Ts>
struct variant_base<variant<Ts...>, true> : variant_get<variant<Ts...>>
{};
template<typename Fun, typename Types, typename Indices, typename = void>
struct variant_visit_results
{};
template<typename Fun, typename... Ts, std::size_t... Is>
struct variant_visit_results<
Fun, meta::list<Ts...>, meta::index_sequence<Is...>,
meta::void_<invoke_result_t<Fun &, indexed_element<Ts, Is>>...>>
{
using type = variant<invoke_result_t<Fun &, indexed_element<Ts, Is>>...>;
};
template<typename Fun, typename... Ts>
using variant_visit_results_t =
meta::_t<variant_visit_results<Fun, meta::list<Ts...>,
meta::make_index_sequence<sizeof...(Ts)>>>;
} // namespace detail
/// \endcond
/// \addtogroup group-utility
/// @{
template<typename... Ts>
struct variant
: private detail::variant_data<Ts...>
, private detail::variant_base<variant<Ts...>>
{
private:
friend detail::variant_core_access;
template<typename...>
friend struct variant;
friend detail::variant_base<variant, false>;
template<std::size_t Index>
using datum_t = detail::variant_datum_t<Index, Ts...>;
template<typename T>
using add_const_t = meta::if_<std::is_void<T>, void, T const>;
using unbox_fn = detail::get_datum_fn;
detail::variant_data<Ts...> & data_() & noexcept
{
return *this;
}
detail::variant_data<Ts...> const & data_() const & noexcept
{
return *this;
}
detail::variant_data<Ts...> && data_() && noexcept
{
return static_cast<detail::variant_data<Ts...> &&>(*this);
}
std::size_t index_;
void clear_() noexcept
{
if(valid())
{
detail::variant_visit_(index_, data_(), detail::delete_fn{}, identity{});
index_ = (std::size_t)-1;
}
}
template<typename That>
void assign_(That && that)
{
if(that.valid())
index_ = detail::variant_move_copy_(
that.index_, data_(), ((That &&) that).data_());
}
constexpr variant(detail::empty_variant_tag) noexcept
: detail::variant_data<Ts...>{}
, index_((std::size_t)-1)
{}
template(typename... Args)(
requires (sizeof...(Args) == sizeof...(Ts))) //
static constexpr bool all_convertible_to(int) noexcept
{
return and_v<convertible_to<Args, Ts>...>;
}
template<typename... Args>
static constexpr bool all_convertible_to(long) noexcept
{
return false;
}
public:
CPP_member
constexpr CPP_ctor(variant)()( //
noexcept(std::is_nothrow_default_constructible<datum_t<0>>::value) //
requires default_constructible<datum_t<0>>)
: variant{emplaced_index<0>}
{}
template(std::size_t N, typename... Args)(
requires constructible_from<datum_t<N>, Args...>)
constexpr variant(emplaced_index_t<N>, Args &&... args) noexcept(
std::is_nothrow_constructible<datum_t<N>, Args...>::value)
: detail::variant_data<Ts...>{meta::size_t<N>{}, static_cast<Args &&>(args)...}
, index_(N)
{}
template(std::size_t N, typename T, typename... Args)(
requires constructible_from<datum_t<N>, std::initializer_list<T> &,
Args...>)
constexpr variant(
emplaced_index_t<N>, std::initializer_list<T> il,
Args &&... args) noexcept(std::
is_nothrow_constructible<
datum_t<N>, std::initializer_list<T> &,
Args...>::value)
: detail::variant_data<Ts...>{meta::size_t<N>{},
il,
static_cast<Args &&>(args)...}
, index_(N)
{}
template(std::size_t N)(
requires constructible_from<datum_t<N>, meta::nil_>)
constexpr variant(emplaced_index_t<N>, meta::nil_)
noexcept(std::is_nothrow_constructible<datum_t<N>, meta::nil_>::value)
: detail::variant_data<Ts...>{meta::size_t<N>{}, meta::nil_{}}
, index_(N)
{}
variant(variant && that)
: detail::variant_data<Ts...>{}
, index_(detail::variant_move_copy_(that.index(), data_(),
std::move(that.data_())))
{}
variant(variant const & that)
: detail::variant_data<Ts...>{}
, index_(detail::variant_move_copy_(that.index(), data_(), that.data_()))
{}
template(typename... Args)(
requires (!same_as<variant<Args...>, variant>) AND
(all_convertible_to<Args...>(0))) //
variant(variant<Args...> that)
: detail::variant_data<Ts...>{}
, index_(detail::variant_move_copy_(that.index(), data_(),
std::move(that.data_())))
{}
variant & operator=(variant && that)
{
// TODO do a simple move assign when index()==that.index()
this->clear_();
this->assign_(detail::move(that));
return *this;
}
variant & operator=(variant const & that)
{
// TODO do a simple copy assign when index()==that.index()
this->clear_();
this->assign_(that);
return *this;
}
template(typename... Args)(
requires (!same_as<variant<Args...>, variant>) AND
(all_convertible_to<Args...>(0)))
variant & operator=(variant<Args...> that)
{
// TODO do a simple copy assign when index()==that.index() //
this->clear_();
this->assign_(that);
return *this;
}
static constexpr std::size_t size() noexcept
{
return sizeof...(Ts);
}
template(std::size_t N, typename... Args)(
requires constructible_from<datum_t<N>, Args...>)
void emplace(Args &&... args)
{
this->clear_();
detail::construct_fn<N, Args &&...> fn{static_cast<Args &&>(args)...};
detail::variant_visit_(N, data_(), std::ref(fn), identity{});
index_ = N;
}
constexpr bool valid() const noexcept
{
return index() != (std::size_t)-1;
}
constexpr std::size_t index() const noexcept
{
return index_;
}
template<typename Fun>
detail::variant_visit_results_t<composed<Fun, unbox_fn>, Ts...> visit(Fun fun)
{
detail::variant_visit_results_t<composed<Fun, unbox_fn>, Ts...> res{
detail::empty_variant_tag{}};
detail::variant_visit_(index_,
data_(),
detail::make_variant_visitor(
res, compose(detail::move(fun), unbox_fn{})));
return res;
}
template<typename Fun>
detail::variant_visit_results_t<composed<Fun, unbox_fn>, add_const_t<Ts>...>
visit(Fun fun) const
{
detail::variant_visit_results_t<composed<Fun, unbox_fn>, add_const_t<Ts>...>
res{detail::empty_variant_tag{}};
detail::variant_visit_(index_,
data_(),
detail::make_variant_visitor(
res, compose(detail::move(fun), unbox_fn{})));
return res;
}
template<typename Fun>
detail::variant_visit_results_t<Fun, Ts...> visit_i(Fun fun)
{
detail::variant_visit_results_t<Fun, Ts...> res{detail::empty_variant_tag{}};
detail::variant_visit_(
index_, data_(), detail::make_variant_visitor(res, detail::move(fun)));
return res;
}
template<typename Fun>
detail::variant_visit_results_t<Fun, add_const_t<Ts>...> visit_i(Fun fun) const
{
detail::variant_visit_results_t<Fun, add_const_t<Ts>...> res{
detail::empty_variant_tag{}};
detail::variant_visit_(
index_, data_(), detail::make_variant_visitor(res, detail::move(fun)));
return res;
}
};
template(typename... Ts, typename... Us)(
requires and_v<equality_comparable_with<Ts, Us>...>)
bool operator==(variant<Ts...> const & lhs, variant<Us...> const & rhs)
{
return (!lhs.valid() && !rhs.valid()) ||
(lhs.index() == rhs.index() &&
detail::variant_equal_(lhs.index(),
detail::variant_core_access::data(lhs),
detail::variant_core_access::data(rhs)));
}
template(typename... Ts, typename... Us)(
requires and_v<equality_comparable_with<Ts, Us>...>)
bool operator!=(variant<Ts...> const & lhs, variant<Us...> const & rhs)
{
return !(lhs == rhs);
}
//////////////////////////////////////////////////////////////////////////////////////
// emplace
template(std::size_t N, typename... Ts, typename... Args)(
requires constructible_from<detail::variant_datum_t<N, Ts...>, Args...>)
void emplace(variant<Ts...> & var, Args &&... args)
{
var.template emplace<N>(static_cast<Args &&>(args)...);
}
//////////////////////////////////////////////////////////////////////////////////////
// variant_unique
template<typename Var>
struct variant_unique
{};
template<typename... Ts>
struct variant_unique<variant<Ts...>>
{
using type = meta::apply<meta::quote<variant>, meta::unique<meta::list<Ts...>>>;
};
template<typename Var>
using variant_unique_t = meta::_t<variant_unique<Var>>;
//////////////////////////////////////////////////////////////////////////////////////
// unique_variant
template<typename... Ts>
variant_unique_t<variant<Ts...>> unique_variant(variant<Ts...> const & var)
{
using From = variant<Ts...>;
using To = variant_unique_t<From>;
auto res = detail::variant_core_access::make_empty(meta::id<To>{});
var.visit_i(detail::unique_visitor<To, From>{&res});
RANGES_EXPECT(res.valid());
return res;
}
/// @}
} // namespace ranges
RANGES_DIAGNOSTIC_PUSH
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
namespace std
{
template<typename... Ts>
struct tuple_size<::ranges::variant<Ts...>> : tuple_size<tuple<Ts...>>
{};
template<size_t I, typename... Ts>
struct tuple_element<I, ::ranges::variant<Ts...>> : tuple_element<I, tuple<Ts...>>
{};
} // namespace std
RANGES_DIAGNOSTIC_POP
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,83 @@
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_DETAIL_WITH_BRACED_INIT_ARGS_HPP
#define RANGES_V3_DETAIL_WITH_BRACED_INIT_ARGS_HPP
#include <initializer_list>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \cond
namespace detail
{
// Accepts initializer_lists as either the first or second parameter, or both,
// and forwards on to an implementation.
template<typename ImplFn>
struct with_braced_init_args : ImplFn
{
private:
constexpr ImplFn const & base() const
{
return *this;
}
public:
using ImplFn::operator();
template<typename V0, typename... Args>
constexpr invoke_result_t<ImplFn const &, std::initializer_list<V0>, Args...>
operator()(std::initializer_list<V0> && rng0, Args &&... args) const
{
return base()(static_cast<std::initializer_list<V0> &&>(rng0),
static_cast<Args &&>(args)...);
}
/// \overload
template<typename Rng0, typename V1, typename... Args>
constexpr invoke_result_t<ImplFn const &,
Rng0,
std::initializer_list<V1>,
Args...> //
operator()(Rng0 && rng0, std::initializer_list<V1> && rng1, Args &&... args)
const
{
return base()( //
static_cast<Rng0 &&>(rng0),
static_cast<std::initializer_list<V1> &&>(rng1),
static_cast<Args &&>(args)...);
}
/// \overload
template<typename V0, typename V1, typename... Args>
constexpr invoke_result_t<ImplFn const &,
std::initializer_list<V0>,
std::initializer_list<V1>,
Args...>
operator()(std::initializer_list<V0> && rng0,
std::initializer_list<V1> && rng1,
Args &&... args) const
{
return base()( //
static_cast<std::initializer_list<V0> &&>(rng0),
static_cast<std::initializer_list<V1> &&>(rng1),
static_cast<Args &&>(args)...);
}
};
} // namespace detail
/// \endcond
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif