| 
							- // 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>
 - 
 - namespace ranges
 - {
 -     template<typename I>
 -     struct incrementable_traits;
 - 
 -     template<typename I>
 -     struct 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 readable_traits<I>::value_type *pv = nullptr,
 -             typename 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 readable_traits<I>::value_type &&) ||
 -                             RANGES_IS_SAME(decltype(**pi), typename 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 readable_traits<I>::value_type &&) ||
 -                     RANGES_IS_SAME(decltype(**pi), typename 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 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 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 if_then_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
 - }
 - 
 - // 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
 - 
 - #endif // RANGES_DEEP_STL_INTEGRATION
 - 
 - #endif // RANGES_V3_STD_ITERATOR
 
 
  |