File indexing completed on 2025-01-18 10:09:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
0034
0035 struct range_access
0036 {
0037
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
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
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
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
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
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
0221 };
0222
0223
0224
0225 namespace detail
0226 {
0227
0228
0229
0230
0231
0232
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
0239
0240
0241
0242
0243
0244 template<typename T>
0245 CPP_requires(has_cursor_next_,
0246 requires(T & t)
0247 (
0248 range_access::next(t)
0249 ));
0250
0251
0252 template<typename T>
0253 CPP_concept has_cursor_next = CPP_requires_ref(detail::has_cursor_next_, T);
0254
0255
0256
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
0266
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
0274
0275 template<typename T>
0276 CPP_requires(readable_cursor_,
0277 requires(T & t)
0278 (
0279 range_access::read(t)
0280 ));
0281
0282
0283 template<typename T>
0284 CPP_concept readable_cursor = CPP_requires_ref(detail::readable_cursor_, T);
0285
0286
0287
0288 template<typename T>
0289 CPP_requires(has_cursor_arrow_,
0290 requires(T const & t)
0291 (
0292 range_access::arrow(t)
0293 ));
0294
0295
0296 template<typename T>
0297 CPP_concept has_cursor_arrow = CPP_requires_ref(detail::has_cursor_arrow_, T);
0298
0299
0300
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
0308
0309 template<typename T, typename U>
0310 CPP_concept writable_cursor =
0311 CPP_requires_ref(detail::writable_cursor_, T, U);
0312
0313
0314
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
0325
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
0332
0333 template<typename T, typename U>
0334 CPP_concept output_cursor =
0335 writable_cursor<T, U> && cursor<T>;
0336
0337
0338
0339 template<typename T>
0340 CPP_concept input_cursor =
0341 readable_cursor<T> && cursor<T> && has_cursor_next<T>;
0342
0343
0344
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
0351
0352 template<typename T>
0353 CPP_requires(bidirectional_cursor_,
0354 requires(T & t)
0355 (
0356 range_access::prev(t)
0357 ));
0358
0359
0360 template<typename T>
0361 CPP_concept bidirectional_cursor =
0362 forward_cursor<T> &&
0363 CPP_requires_ref(detail::bidirectional_cursor_, T);
0364
0365
0366
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
0374
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
0386
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
0394
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
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 }
0413
0414 }
0415
0416 #include <range/v3/detail/epilogue.hpp>
0417
0418 #endif