Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/std/iterator is written in an unsupported language. File is not indexed.

0001 // Range v3 library
0002 //
0003 //  Copyright Eric Niebler 2018-present
0004 //
0005 //  Use, modification and distribution is subject to the
0006 //  Boost Software License, Version 1.0. (See accompanying
0007 //  file LICENSE_1_0.txt or copy at
0008 //  http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // Project home: https://github.com/ericniebler/range-v3
0011 //
0012 
0013 #ifndef RANGES_V3_STD_ITERATOR
0014 #define RANGES_V3_STD_ITERATOR
0015 
0016 #if defined(__GNUC__)
0017 #include_next <iterator>
0018 #elif defined(_MSC_VER)
0019 #include <../include/iterator> // HACKHACK
0020 #else
0021 #error "Cannot use range-v3 STL deep integration on this platform."
0022 #endif
0023 
0024 #if RANGES_DEEP_STL_INTEGRATION
0025 
0026 #include <range/v3/detail/config.hpp>
0027 #include <std/detail/associated_types.hpp>
0028 
0029 #include <range/v3/detail/prologue.hpp>
0030 
0031 namespace ranges
0032 {
0033     template<typename I>
0034     struct incrementable_traits;
0035 
0036     template<typename I>
0037     struct indirectly_readable_traits;
0038 
0039     /// \cond
0040     namespace detail
0041     {
0042         template<typename I>
0043         typename incrementable_traits<I>::difference_type cpp17_difference_type_(int);
0044         template<typename I>
0045         void cpp17_difference_type_(long);
0046 
0047         template<typename I>
0048         typename I::pointer cpp17_pointer_type_(int);
0049         template<typename I>
0050         auto cpp17_pointer_type_(long, I *pi = nullptr) -> decltype(pi->operator->());
0051         template<typename I>
0052         void cpp17_pointer_type_(...);
0053 
0054         template<typename I>
0055         typename I::reference cpp17_reference_type_(int);
0056         template<typename I>
0057         auto cpp17_reference_type_(long, I *pi = nullptr) -> decltype(**pi);
0058 
0059         template<typename I>
0060         auto cpp17_iterator_category_4_(long)
0061         {
0062             return std::bidirectional_iterator_tag{};
0063         }
0064         // Satisfies Cpp17RandomAccessIterator?
0065         template<typename I>
0066         auto cpp17_iterator_category_4_(
0067             int,
0068             I *pi = nullptr,
0069             typename incrementable_traits<I>::difference_type d = 0,
0070             always_<
0071                 void,
0072                 int[RANGES_IS_SAME(decltype(*pi += d), I &)],
0073                 int[RANGES_IS_SAME(decltype(*pi -= d), I &)],
0074                 int[RANGES_IS_SAME(decltype(*pi + d), I)],
0075                 int[RANGES_IS_SAME(decltype(*pi - d), I)],
0076                 int[RANGES_IS_SAME(decltype(d + *pi), I)],
0077                 int[RANGES_IS_SAME(decltype(*pi - *pi), decltype(d))],
0078                 int[RANGES_IS_SAME(decltype((*pi)[d]), decltype(**pi))],
0079                 decltype(*pi < *pi ? true : false),
0080                 decltype(*pi > *pi ? true : false),
0081                 decltype(*pi <= *pi ? true : false),
0082                 decltype(*pi >= *pi ? true : false)
0083             > * = nullptr)
0084         {
0085             return std::random_access_iterator_tag{};
0086         }
0087 
0088         template<typename I>
0089         auto cpp17_iterator_category_3_(long)
0090         {
0091             return std::forward_iterator_tag{};
0092         }
0093         // Satisfies Cpp17BidirectionalIterator?
0094         template<typename I>
0095         auto cpp17_iterator_category_3_(
0096             int,
0097             I *pi = nullptr,
0098             void (*fn)(I const &) = nullptr,
0099             always_<
0100                 void,
0101                 decltype(fn((*pi)--)), // i-- convertible to I const &
0102                 int[RANGES_IS_SAME(decltype(--*pi), I &)], // --i has type I &
0103                 // *i has the same type as *i--
0104                 int[RANGES_IS_SAME(decltype(**pi), decltype(*(*pi)--))]
0105             > * = nullptr)
0106         {
0107             return cpp17_iterator_category_4_<I>(0);
0108         }
0109 
0110         template<typename I>
0111         auto cpp17_iterator_category_2_(long)
0112         {
0113             return std::input_iterator_tag{};
0114         }
0115         // Satisfies Cpp17ForwardIterator?
0116         template<typename I>
0117         auto cpp17_iterator_category_2_(
0118             int,
0119             I *pi = nullptr,
0120             void (*fn)(I const &) = nullptr,
0121             typename indirectly_readable_traits<I>::value_type *pv = nullptr,
0122             typename indirectly_readable_traits<I>::value_type const *pcv = nullptr,
0123             always_<
0124                 void,
0125                 decltype(I{}), // Default constructible
0126                 decltype(fn((*pi)++)), // i++ convertible to I const &
0127                 // *i has the same type as *i++
0128                 int[RANGES_IS_SAME(decltype(**pi), decltype(*(*pi)++))],
0129                 // *i is a real reference to value_type
0130 #ifdef RANGES_WORKAROUND_MSVC_793042
0131                 enable_if_t<RANGES_IS_SAME(decltype(**pi), decltype(*pv)) ||
0132                             RANGES_IS_SAME(decltype(**pi), decltype(*pcv)) ||
0133                             RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type &&) ||
0134                             RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type const &&)>
0135 #else // ^^^ workaround / no workaround vvv
0136                 int[RANGES_IS_SAME(decltype(**pi), decltype(*pv)) ||
0137                     RANGES_IS_SAME(decltype(**pi), decltype(*pcv)) ||
0138                     RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type &&) ||
0139                     RANGES_IS_SAME(decltype(**pi), typename indirectly_readable_traits<I>::value_type const &&)]
0140 #endif // RANGES_WORKAROUND_MSVC_793042
0141             > * = nullptr)
0142         {
0143             return cpp17_iterator_category_3_<I>(0);
0144         }
0145 
0146         template<typename I>
0147         using cpp17_readable_iterator_category_t =
0148             decltype(detail::cpp17_iterator_category_2_<I>(0));
0149 
0150         template<typename I>
0151         auto cpp17_iterator_category_(long)
0152         {
0153             return cpp17_iterator_category_2_<I>(0);
0154         }
0155         // Explicitly declares its category?
0156         template<typename I>
0157         typename I::iterator_category cpp17_iterator_category_(int)
0158         {
0159             return {};
0160         }
0161 
0162         template<typename I>
0163         auto std_iterator_traits_impl_2_(long)
0164         {
0165             return std_output_iterator_traits<
0166                 decltype(detail::cpp17_difference_type_<I>(0))>{};
0167         }
0168         // Satisfies Cpp17InputIterator?
0169         template<typename I>
0170         auto std_iterator_traits_impl_2_(
0171             int,
0172             I *pi = nullptr,
0173             typename incrementable_traits<I>::difference_type d = 0,
0174             typename indirectly_readable_traits<I>::value_type const *pcv = nullptr,
0175             always_<
0176                 void,
0177                 int[decltype(d)(-1) < decltype(d)(0)], // signed difference type
0178                 decltype(decltype(*pcv)(**pi)),        // sensible reference/value type
0179                 decltype(decltype(*pcv)(*(*pi)++)),    // sensible post-increment result
0180                 decltype(*pi == *pi ? true : false),   // equality comparable
0181                 decltype(*pi != *pi ? true : false)    //     "        "
0182             > * = nullptr)
0183         {
0184             using D = typename incrementable_traits<I>::difference_type;
0185             struct yes_traits
0186             {
0187                 using difference_type = D;
0188                 using value_type = typename indirectly_readable_traits<I>::value_type;
0189                 using reference = decltype(cpp17_reference_type_<I>(0));
0190                 using pointer = decltype(cpp17_pointer_type_<I>(0));
0191                 using iterator_category = decltype(cpp17_iterator_category_<I>(0));
0192             };
0193             struct no_traits
0194             {};
0195             return conditional_t<is_integral_<D>(0), yes_traits, no_traits>{};
0196         }
0197 
0198         template<typename I>
0199         nil_ std_iterator_traits_impl_(long)
0200         {
0201             return {};
0202         }
0203         // Satisfies Cpp17Iterator?
0204         template<typename I>
0205         auto std_iterator_traits_impl_(
0206             int,
0207             I *pi = nullptr,
0208             void (*nv)(...) = nullptr,
0209             always_<
0210                 void,
0211                 decltype(nv(**pi)),
0212                 int[RANGES_IS_SAME(decltype(++*pi), I &)],
0213                 decltype(nv(*(*pi)++))
0214             > * = nullptr)
0215         {
0216             return std_iterator_traits_impl_2_<I>(0);
0217         }
0218 
0219         template<typename T>
0220         constexpr bool has_iterator_typedefs_impl_(
0221             int,
0222             always_<
0223                 void,
0224                 typename T::difference_type,
0225                 typename T::value_type,
0226                 typename T::pointer,
0227                 typename T::reference,
0228                 typename T::iterator_category
0229             > * = nullptr)
0230         {
0231             return true;
0232         }
0233         template<typename T>
0234         constexpr bool has_iterator_typedefs_impl_(long)
0235         {
0236             return false;
0237         }
0238     }
0239     /// \endcond
0240 } // namespace ranges
0241 
0242 // Hijack the primary std::iterator_traits template from each of the 3 major
0243 // standard library implementations
0244 RANGES_BEGIN_NAMESPACE_STD
0245 RANGES_BEGIN_NAMESPACE_VERSION
0246 #if defined(__GLIBCXX__)
0247     template<typename I>
0248     struct __iterator_traits<
0249         I,
0250         ::ranges::detail::enable_if_t<!::ranges::detail::has_iterator_typedefs_impl_<I>(0)>>
0251       : decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
0252     {};
0253 #elif defined(_LIBCPP_VERSION)
0254     template<typename I>
0255     struct __iterator_traits<I, false> // doesn't have I::iterator_category
0256       : decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
0257     {};
0258 #elif defined(_MSVC_STL_VERSION)
0259     template<typename I>
0260     struct _Iterator_traits_base<
0261         I,
0262 #ifdef RANGES_WORKAROUND_MSVC_792338
0263         ::ranges::detail::enable_if_t<decltype(bool_constant<
0264             !::ranges::detail::has_iterator_typedefs_impl_<I>(0)>{})::value>>
0265 #else // ^^^ workaround / no workaround vvv
0266         ::ranges::detail::enable_if_t<!::ranges::detail::has_iterator_typedefs_impl_<I>(0)>>
0267 #endif // RANGES_WORKAROUND_MSVC_792338
0268       : decltype(::ranges::detail::std_iterator_traits_impl_<I>(0))
0269     {};
0270 #endif
0271 RANGES_END_NAMESPACE_VERSION
0272 RANGES_END_NAMESPACE_STD
0273 
0274 #include <range/v3/detail/epilogue.hpp>
0275 
0276 #endif // RANGES_DEEP_STL_INTEGRATION
0277 
0278 #endif // RANGES_V3_STD_ITERATOR