mirror of https://github.com/axmolengine/axmol.git
279 lines
9.8 KiB
Plaintext
279 lines
9.8 KiB
Plaintext
// Range v3 library
|
|
//
|
|
// Copyright Eric Niebler 2018-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_STD_ITERATOR
|
|
#define RANGES_V3_STD_ITERATOR
|
|
|
|
#if defined(__GNUC__)
|
|
#include_next <iterator>
|
|
#elif defined(_MSC_VER)
|
|
#include <../include/iterator> // HACKHACK
|
|
#else
|
|
#error "Cannot use range-v3 STL deep integration on this platform."
|
|
#endif
|
|
|
|
#if RANGES_DEEP_STL_INTEGRATION
|
|
|
|
#include <range/v3/detail/config.hpp>
|
|
#include <std/detail/associated_types.hpp>
|
|
|
|
#include <range/v3/detail/prologue.hpp>
|
|
|
|
namespace ranges
|
|
{
|
|
template<typename I>
|
|
struct incrementable_traits;
|
|
|
|
template<typename I>
|
|
struct indirectly_readable_traits;
|
|
|
|
/// \cond
|
|
namespace detail
|
|
{
|
|
template<typename I>
|
|
typename incrementable_traits<I>::difference_type cpp17_difference_type_(int);
|
|
template<typename I>
|
|
void cpp17_difference_type_(long);
|
|
|
|
template<typename I>
|
|
typename I::pointer cpp17_pointer_type_(int);
|
|
template<typename I>
|
|
auto cpp17_pointer_type_(long, I *pi = nullptr) -> decltype(pi->operator->());
|
|
template<typename I>
|
|
void cpp17_pointer_type_(...);
|
|
|
|
template<typename I>
|
|
typename I::reference cpp17_reference_type_(int);
|
|
template<typename I>
|
|
auto cpp17_reference_type_(long, I *pi = nullptr) -> decltype(**pi);
|
|
|
|
template<typename I>
|
|
auto cpp17_iterator_category_4_(long)
|
|
{
|
|
return std::bidirectional_iterator_tag{};
|
|
}
|
|
// Satisfies Cpp17RandomAccessIterator?
|
|
template<typename I>
|
|
auto cpp17_iterator_category_4_(
|
|
int,
|
|
I *pi = nullptr,
|
|
typename incrementable_traits<I>::difference_type d = 0,
|
|
always_<
|
|
void,
|
|
int[RANGES_IS_SAME(decltype(*pi += d), I &)],
|
|
int[RANGES_IS_SAME(decltype(*pi -= d), I &)],
|
|
int[RANGES_IS_SAME(decltype(*pi + d), I)],
|
|
int[RANGES_IS_SAME(decltype(*pi - d), I)],
|
|
int[RANGES_IS_SAME(decltype(d + *pi), I)],
|
|
int[RANGES_IS_SAME(decltype(*pi - *pi), decltype(d))],
|
|
int[RANGES_IS_SAME(decltype((*pi)[d]), decltype(**pi))],
|
|
decltype(*pi < *pi ? true : false),
|
|
decltype(*pi > *pi ? true : false),
|
|
decltype(*pi <= *pi ? true : false),
|
|
decltype(*pi >= *pi ? true : false)
|
|
> * = nullptr)
|
|
{
|
|
return std::random_access_iterator_tag{};
|
|
}
|
|
|
|
template<typename I>
|
|
auto cpp17_iterator_category_3_(long)
|
|
{
|
|
return std::forward_iterator_tag{};
|
|
}
|
|
// Satisfies Cpp17BidirectionalIterator?
|
|
template<typename I>
|
|
auto cpp17_iterator_category_3_(
|
|
int,
|
|
I *pi = nullptr,
|
|
void (*fn)(I const &) = nullptr,
|
|
always_<
|
|
void,
|
|
decltype(fn((*pi)--)), // i-- convertible to I const &
|
|
int[RANGES_IS_SAME(decltype(--*pi), I &)], // --i has type I &
|
|
// *i has the same type as *i--
|
|
int[RANGES_IS_SAME(decltype(**pi), decltype(*(*pi)--))]
|
|
> * = nullptr)
|
|
{
|
|
return cpp17_iterator_category_4_<I>(0);
|
|
}
|
|
|
|
template<typename I>
|
|
auto cpp17_iterator_category_2_(long)
|
|
{
|
|
return std::input_iterator_tag{};
|
|
}
|
|
// Satisfies Cpp17ForwardIterator?
|
|
template<typename I>
|
|
auto cpp17_iterator_category_2_(
|
|
int,
|
|
I *pi = nullptr,
|
|
void (*fn)(I const &) = nullptr,
|
|
typename indirectly_readable_traits<I>::value_type *pv = nullptr,
|
|
typename indirectly_readable_traits<I>::value_type const *pcv = nullptr,
|
|
always_<
|
|
void,
|
|
decltype(I{}), // Default constructible
|
|
decltype(fn((*pi)++)), // i++ convertible to I const &
|
|
// *i has the same type as *i++
|
|
int[RANGES_IS_SAME(decltype(**pi), decltype(*(*pi)++))],
|
|
// *i is a real reference to value_type
|
|
#ifdef RANGES_WORKAROUND_MSVC_793042
|
|
enable_if_t<RANGES_IS_SAME(decltype(**pi), decltype(*pv)) ||
|
|
RANGES_IS_SAME(decltype(**pi), decltype(*pcv)) ||
|
|
RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type &&) ||
|
|
RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type const &&)>
|
|
#else // ^^^ workaround / no workaround vvv
|
|
int[RANGES_IS_SAME(decltype(**pi), decltype(*pv)) ||
|
|
RANGES_IS_SAME(decltype(**pi), decltype(*pcv)) ||
|
|
RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type &&) ||
|
|
RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type const &&)]
|
|
#endif // RANGES_WORKAROUND_MSVC_793042
|
|
> * = nullptr)
|
|
{
|
|
return cpp17_iterator_category_3_<I>(0);
|
|
}
|
|
|
|
template<typename I>
|
|
using cpp17_readable_iterator_category_t =
|
|
decltype(detail::cpp17_iterator_category_2_<I>(0));
|
|
|
|
template<typename I>
|
|
auto cpp17_iterator_category_(long)
|
|
{
|
|
return cpp17_iterator_category_2_<I>(0);
|
|
}
|
|
// Explicitly declares its category?
|
|
template<typename I>
|
|
typename I::iterator_category cpp17_iterator_category_(int)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
template<typename I>
|
|
auto std_iterator_traits_impl_2_(long)
|
|
{
|
|
return std_output_iterator_traits<
|
|
decltype(detail::cpp17_difference_type_<I>(0))>{};
|
|
}
|
|
// Satisfies Cpp17InputIterator?
|
|
template<typename I>
|
|
auto std_iterator_traits_impl_2_(
|
|
int,
|
|
I *pi = nullptr,
|
|
typename incrementable_traits<I>::difference_type d = 0,
|
|
typename indirectly_readable_traits<I>::value_type const *pcv = nullptr,
|
|
always_<
|
|
void,
|
|
int[decltype(d)(-1) < decltype(d)(0)], // signed difference type
|
|
decltype(decltype(*pcv)(**pi)), // sensible reference/value type
|
|
decltype(decltype(*pcv)(*(*pi)++)), // sensible post-increment result
|
|
decltype(*pi == *pi ? true : false), // equality comparable
|
|
decltype(*pi != *pi ? true : false) // " "
|
|
> * = nullptr)
|
|
{
|
|
using D = typename incrementable_traits<I>::difference_type;
|
|
struct yes_traits
|
|
{
|
|
using difference_type = D;
|
|
using value_type = typename indirectly_readable_traits<I>::value_type;
|
|
using reference = decltype(cpp17_reference_type_<I>(0));
|
|
using pointer = decltype(cpp17_pointer_type_<I>(0));
|
|
using iterator_category = decltype(cpp17_iterator_category_<I>(0));
|
|
};
|
|
struct no_traits
|
|
{};
|
|
return conditional_t<is_integral_<D>(0), yes_traits, no_traits>{};
|
|
}
|
|
|
|
template<typename I>
|
|
nil_ std_iterator_traits_impl_(long)
|
|
{
|
|
return {};
|
|
}
|
|
// Satisfies Cpp17Iterator?
|
|
template<typename I>
|
|
auto std_iterator_traits_impl_(
|
|
int,
|
|
I *pi = nullptr,
|
|
void (*nv)(...) = nullptr,
|
|
always_<
|
|
void,
|
|
decltype(nv(**pi)),
|
|
int[RANGES_IS_SAME(decltype(++*pi), I &)],
|
|
decltype(nv(*(*pi)++))
|
|
> * = nullptr)
|
|
{
|
|
return std_iterator_traits_impl_2_<I>(0);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr bool has_iterator_typedefs_impl_(
|
|
int,
|
|
always_<
|
|
void,
|
|
typename T::difference_type,
|
|
typename T::value_type,
|
|
typename T::pointer,
|
|
typename T::reference,
|
|
typename T::iterator_category
|
|
> * = nullptr)
|
|
{
|
|
return true;
|
|
}
|
|
template<typename T>
|
|
constexpr bool has_iterator_typedefs_impl_(long)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
/// \endcond
|
|
} // namespace ranges
|
|
|
|
// Hijack the primary std::iterator_traits template from each of the 3 major
|
|
// standard library implementations
|
|
RANGES_BEGIN_NAMESPACE_STD
|
|
RANGES_BEGIN_NAMESPACE_VERSION
|
|
#if defined(__GLIBCXX__)
|
|
template<typename I>
|
|
struct __iterator_traits<
|
|
I,
|
|
::ranges::detail::enable_if_t<!::ranges::detail::has_iterator_typedefs_impl_<I>(0)>>
|
|
: decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
|
|
{};
|
|
#elif defined(_LIBCPP_VERSION)
|
|
template<typename I>
|
|
struct __iterator_traits<I, false> // doesn't have I::iterator_category
|
|
: decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
|
|
{};
|
|
#elif defined(_MSVC_STL_VERSION)
|
|
template<typename I>
|
|
struct _Iterator_traits_base<
|
|
I,
|
|
#ifdef RANGES_WORKAROUND_MSVC_792338
|
|
::ranges::detail::enable_if_t<decltype(bool_constant<
|
|
!::ranges::detail::has_iterator_typedefs_impl_<I>(0)>{})::value>>
|
|
#else // ^^^ workaround / no workaround vvv
|
|
::ranges::detail::enable_if_t<!::ranges::detail::has_iterator_typedefs_impl_<I>(0)>>
|
|
#endif // RANGES_WORKAROUND_MSVC_792338
|
|
: decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
|
|
{};
|
|
#endif
|
|
RANGES_END_NAMESPACE_VERSION
|
|
RANGES_END_NAMESPACE_STD
|
|
|
|
#include <range/v3/detail/epilogue.hpp>
|
|
|
|
#endif // RANGES_DEEP_STL_INTEGRATION
|
|
|
|
#endif // RANGES_V3_STD_ITERATOR
|