Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:47

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //  Copyright Casey Carter 2016
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
0013 //
0014 
0015 #ifndef RANGES_V3_DETAIL_RANGE_ACCESS_HPP
0016 #define RANGES_V3_DETAIL_RANGE_ACCESS_HPP
0017 
0018 #include <cstddef>
0019 #include <utility>
0020 
0021 #include <meta/meta.hpp>
0022 
0023 #include <concepts/concepts.hpp>
0024 
0025 #include <range/v3/range_fwd.hpp>
0026 
0027 #include <range/v3/iterator/concepts.hpp>
0028 
0029 #include <range/v3/detail/prologue.hpp>
0030 
0031 namespace ranges
0032 {
0033     /// \addtogroup group-views
0034     /// @{
0035     struct range_access
0036     {
0037         /// \cond
0038     private:
0039         template<typename T>
0040         static std::false_type single_pass_2_(long);
0041         template<typename T>
0042         static typename T::single_pass single_pass_2_(int);
0043 
0044         template<typename T>
0045         struct single_pass_
0046         {
0047             using type = decltype(range_access::single_pass_2_<T>(42));
0048         };
0049 
0050         template<typename T>
0051         static std::false_type contiguous_2_(long);
0052         template<typename T>
0053         static typename T::contiguous contiguous_2_(int);
0054 
0055         template<typename T>
0056         struct contiguous_
0057         {
0058             using type = decltype(range_access::contiguous_2_<T>(42));
0059         };
0060 
0061         template<typename T>
0062         static basic_mixin<T> mixin_base_2_(long);
0063         template<typename T>
0064         static typename T::mixin mixin_base_2_(int);
0065 
0066         template<typename Cur>
0067         struct mixin_base_
0068         {
0069             using type = decltype(range_access::mixin_base_2_<Cur>(42));
0070         };
0071 
0072 
0073     public:
0074         template<typename Cur>
0075         using single_pass_t = meta::_t<single_pass_<Cur>>;
0076 
0077         template<typename Cur>
0078         using contiguous_t = meta::_t<contiguous_<Cur>>;
0079 
0080         template<typename Cur>
0081         using mixin_base_t = meta::_t<mixin_base_<Cur>>;
0082 
0083         // clang-format off
0084         template<typename Rng>
0085         static constexpr auto CPP_auto_fun(begin_cursor)(Rng &rng)
0086         (
0087             return rng.begin_cursor()
0088         )
0089         template<typename Rng>
0090         static constexpr auto CPP_auto_fun(end_cursor)(Rng &rng)
0091         (
0092             return rng.end_cursor()
0093         )
0094 
0095         template<typename Rng>
0096         static constexpr auto CPP_auto_fun(begin_adaptor)(Rng &rng)
0097         (
0098             return rng.begin_adaptor()
0099         )
0100         template<typename Rng>
0101         static constexpr auto CPP_auto_fun(end_adaptor)(Rng &rng)
0102         (
0103             return rng.end_adaptor()
0104         )
0105 
0106         template<typename Cur>
0107         static constexpr auto CPP_auto_fun(read)(Cur const &pos)
0108         (
0109             return pos.read()
0110         )
0111         template<typename Cur>
0112         static constexpr auto CPP_auto_fun(arrow)(Cur const &pos)
0113         (
0114             return pos.arrow()
0115         )
0116         template<typename Cur>
0117         static constexpr auto CPP_auto_fun(move)(Cur const &pos)
0118         (
0119             return pos.move()
0120         )
0121         template<typename Cur, typename T>
0122         static constexpr auto CPP_auto_fun(write)(Cur &pos, T &&t)
0123         (
0124             return pos.write((T &&) t)
0125         )
0126         template<typename Cur>
0127         static constexpr auto CPP_auto_fun(next)(Cur & pos)
0128         (
0129             return pos.next()
0130         )
0131         template<typename Cur, typename O>
0132         static constexpr auto CPP_auto_fun(equal)(Cur const &pos, O const &other)
0133         (
0134             return pos.equal(other)
0135         )
0136         template<typename Cur>
0137         static constexpr auto CPP_auto_fun(prev)(Cur & pos)
0138         (
0139             return pos.prev()
0140         )
0141         template<typename Cur, typename D>
0142         static constexpr auto CPP_auto_fun(advance)(Cur & pos, D n)
0143         (
0144             return pos.advance(n)
0145         )
0146         template<typename Cur, typename O>
0147         static constexpr auto CPP_auto_fun(distance_to)(Cur const &pos, O const &other)
0148         (
0149             return pos.distance_to(other)
0150         )
0151 
0152     private:
0153         template<typename Cur>
0154         using sized_cursor_difference_t = decltype(
0155             range_access::distance_to(std::declval<Cur>(), std::declval<Cur>()));
0156         // clang-format on
0157 
0158         template<typename T>
0159         static std::ptrdiff_t cursor_difference_2_(detail::ignore_t);
0160         template<typename T>
0161         static sized_cursor_difference_t<T> cursor_difference_2_(long);
0162         template<typename T>
0163         static typename T::difference_type cursor_difference_2_(int);
0164 
0165         template<typename T>
0166         using cursor_reference_t = decltype(std::declval<T const &>().read());
0167 
0168         template<typename T>
0169         static meta::id<uncvref_t<cursor_reference_t<T>>> cursor_value_2_(long);
0170         template<typename T>
0171         static meta::id<typename T::value_type> cursor_value_2_(int);
0172 
0173 #ifdef RANGES_WORKAROUND_CWG_1554
0174         template<typename Cur>
0175         struct cursor_difference
0176         {
0177             using type = decltype(range_access::cursor_difference_2_<Cur>(42));
0178         };
0179 
0180         template<typename Cur>
0181         struct cursor_value : decltype(range_access::cursor_value_2_<Cur>(42))
0182         {};
0183 #endif // RANGES_WORKAROUND_CWG_1554
0184     public:
0185 #ifdef RANGES_WORKAROUND_CWG_1554
0186         template<typename Cur>
0187         using cursor_difference_t = meta::_t<cursor_difference<Cur>>;
0188 
0189         template<typename Cur>
0190         using cursor_value_t = meta::_t<cursor_value<Cur>>;
0191 #else  // ^^^ workaround ^^^ / vvv no workaround vvv
0192         template<typename Cur>
0193         using cursor_difference_t = decltype(range_access::cursor_difference_2_<Cur>(42));
0194 
0195         template<typename Cur>
0196         using cursor_value_t = meta::_t<decltype(range_access::cursor_value_2_<Cur>(42))>;
0197 #endif // RANGES_WORKAROUND_CWG_1554
0198 
0199         template<typename Cur>
0200         static constexpr Cur & pos(basic_iterator<Cur> & it) noexcept
0201         {
0202             return it.pos();
0203         }
0204         template<typename Cur>
0205         static constexpr Cur const & pos(basic_iterator<Cur> const & it) noexcept
0206         {
0207             return it.pos();
0208         }
0209         template<typename Cur>
0210         static constexpr Cur && pos(basic_iterator<Cur> && it) noexcept
0211         {
0212             return detail::move(it.pos());
0213         }
0214 
0215         template<typename Cur>
0216         static constexpr Cur cursor(basic_iterator<Cur> it)
0217         {
0218             return std::move(it.pos());
0219         }
0220         /// endcond
0221     };
0222     /// @}
0223 
0224     /// \cond
0225     namespace detail
0226     {
0227         //
0228         // Concepts that the range cursor must model
0229         // clang-format off
0230         //
0231         /// \concept cursor
0232         /// \brief The \c cursor concept
0233         template<typename T>
0234         CPP_concept cursor =
0235             semiregular<T> && semiregular<range_access::mixin_base_t<T>> &&
0236             constructible_from<range_access::mixin_base_t<T>, T> &&
0237             constructible_from<range_access::mixin_base_t<T>, T const &>;
0238             // Axiom: mixin_base_t<T> has a member get(), accessible to derived classes,
0239             //   which perfectly-returns the contained cursor object and does not throw
0240             //   exceptions.
0241 
0242         /// \concept has_cursor_next_
0243         /// \brief The \c has_cursor_next_ concept
0244         template<typename T>
0245         CPP_requires(has_cursor_next_,
0246             requires(T & t)
0247             (
0248                 range_access::next(t)
0249             ));
0250         /// \concept has_cursor_next
0251         /// \brief The \c has_cursor_next concept
0252         template<typename T>
0253         CPP_concept has_cursor_next = CPP_requires_ref(detail::has_cursor_next_, T);
0254 
0255         /// \concept sentinel_for_cursor_
0256         /// \brief The \c sentinel_for_cursor_ concept
0257         template<typename S, typename C>
0258         CPP_requires(sentinel_for_cursor_,
0259             requires(S & s, C & c) //
0260             (
0261                 range_access::equal(c, s),
0262                 concepts::requires_<convertible_to<decltype(
0263                     range_access::equal(c, s)), bool>>
0264             ));
0265         /// \concept sentinel_for_cursor
0266         /// \brief The \c sentinel_for_cursor concept
0267         template<typename S, typename C>
0268         CPP_concept sentinel_for_cursor =
0269             semiregular<S> &&
0270             cursor<C> &&
0271             CPP_requires_ref(detail::sentinel_for_cursor_, S, C);
0272 
0273         /// \concept readable_cursor_
0274         /// \brief The \c readable_cursor_ concept
0275         template<typename T>
0276         CPP_requires(readable_cursor_,
0277             requires(T & t) //
0278             (
0279                 range_access::read(t)
0280             ));
0281         /// \concept readable_cursor
0282         /// \brief The \c readable_cursor concept
0283         template<typename T>
0284         CPP_concept readable_cursor = CPP_requires_ref(detail::readable_cursor_, T);
0285 
0286         /// \concept has_cursor_arrow_
0287         /// \brief The \c has_cursor_arrow_ concept
0288         template<typename T>
0289         CPP_requires(has_cursor_arrow_,
0290             requires(T const & t) //
0291             (
0292                 range_access::arrow(t)
0293             ));
0294         /// \concept has_cursor_arrow
0295         /// \brief The \c has_cursor_arrow concept
0296         template<typename T>
0297         CPP_concept has_cursor_arrow = CPP_requires_ref(detail::has_cursor_arrow_, T);
0298 
0299         /// \concept writable_cursor_
0300         /// \brief The \c writable_cursor_ concept
0301         template<typename T, typename U>
0302         CPP_requires(writable_cursor_,
0303             requires(T & t, U && u) //
0304             (
0305                 range_access::write(t, (U &&) u)
0306             ));
0307         /// \concept writable_cursor
0308         /// \brief The \c writable_cursor concept
0309         template<typename T, typename U>
0310         CPP_concept writable_cursor =
0311             CPP_requires_ref(detail::writable_cursor_, T, U);
0312 
0313         /// \concept sized_sentinel_for_cursor_
0314         /// \brief The \c sized_sentinel_for_cursor_ concept
0315         template<typename S, typename C>
0316         CPP_requires(sized_sentinel_for_cursor_,
0317             requires(S & s, C & c) //
0318             (
0319                 range_access::distance_to(c, s),
0320                 concepts::requires_<signed_integer_like_<decltype(
0321                     range_access::distance_to(c, s))>>
0322             )
0323         );
0324         /// \concept sized_sentinel_for_cursor
0325         /// \brief The \c sized_sentinel_for_cursor concept
0326         template<typename S, typename C>
0327         CPP_concept sized_sentinel_for_cursor =
0328             sentinel_for_cursor<S, C> &&
0329             CPP_requires_ref(detail::sized_sentinel_for_cursor_, S, C);
0330 
0331         /// \concept output_cursor
0332         /// \brief The \c output_cursor concept
0333         template<typename T, typename U>
0334         CPP_concept output_cursor =
0335             writable_cursor<T, U> && cursor<T>;
0336 
0337         /// \concept input_cursor
0338         /// \brief The \c input_cursor concept
0339         template<typename T>
0340         CPP_concept input_cursor =
0341             readable_cursor<T> && cursor<T> && has_cursor_next<T>;
0342 
0343         /// \concept forward_cursor
0344         /// \brief The \c forward_cursor concept
0345         template<typename T>
0346         CPP_concept forward_cursor =
0347             input_cursor<T> && sentinel_for_cursor<T, T> &&
0348             !range_access::single_pass_t<uncvref_t<T>>::value;
0349 
0350         /// \concept bidirectional_cursor_
0351         /// \brief The \c bidirectional_cursor_ concept
0352         template<typename T>
0353         CPP_requires(bidirectional_cursor_,
0354             requires(T & t) //
0355             (
0356                 range_access::prev(t)
0357             ));
0358         /// \concept bidirectional_cursor
0359         /// \brief The \c bidirectional_cursor concept
0360         template<typename T>
0361         CPP_concept bidirectional_cursor =
0362             forward_cursor<T> &&
0363             CPP_requires_ref(detail::bidirectional_cursor_, T);
0364 
0365         /// \concept random_access_cursor_
0366         /// \brief The \c random_access_cursor_ concept
0367         template<typename T>
0368         CPP_requires(random_access_cursor_,
0369             requires(T & t) //
0370             (
0371                 range_access::advance(t, range_access::distance_to(t, t))
0372             ));
0373         /// \concept random_access_cursor
0374         /// \brief The \c random_access_cursor concept
0375         template<typename T>
0376         CPP_concept random_access_cursor =
0377             bidirectional_cursor<T> && //
0378             sized_sentinel_for_cursor<T, T> && //
0379             CPP_requires_ref(detail::random_access_cursor_, T);
0380 
0381         template(class T)(
0382             requires std::is_lvalue_reference<T>::value)
0383         void is_lvalue_reference(T&&);
0384 
0385         /// \concept contiguous_cursor_
0386         /// \brief The \c contiguous_cursor_ concept
0387         template<typename T>
0388         CPP_requires(contiguous_cursor_,
0389             requires(T & t) //
0390             (
0391                 detail::is_lvalue_reference(range_access::read(t))
0392             ));
0393         /// \concept contiguous_cursor
0394         /// \brief The \c contiguous_cursor concept
0395         template<typename T>
0396         CPP_concept contiguous_cursor =
0397             random_access_cursor<T> && //
0398             range_access::contiguous_t<uncvref_t<T>>::value && //
0399             CPP_requires_ref(detail::contiguous_cursor_, T);
0400         // clang-format on
0401 
0402         template<typename Cur, bool IsReadable>
0403         RANGES_INLINE_VAR constexpr bool is_writable_cursor_ = true;
0404 
0405         template<typename Cur>
0406         RANGES_INLINE_VAR constexpr bool is_writable_cursor_<Cur, true> =
0407             (bool) writable_cursor<Cur, range_access::cursor_value_t<Cur>>;
0408 
0409         template<typename Cur>
0410         RANGES_INLINE_VAR constexpr bool is_writable_cursor_v =
0411             is_writable_cursor_<Cur, (bool)readable_cursor<Cur>>;
0412     } // namespace detail
0413     /// \endcond
0414 } // namespace ranges
0415 
0416 #include <range/v3/detail/epilogue.hpp>
0417 
0418 #endif