File indexing completed on 2025-01-18 10:09:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef RANGES_V3_VIEW_ANY_VIEW_HPP
0016 #define RANGES_V3_VIEW_ANY_VIEW_HPP
0017
0018 #include <type_traits>
0019 #include <typeinfo>
0020 #include <utility>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/iterator/default_sentinel.hpp>
0025 #include <range/v3/range/access.hpp>
0026 #include <range/v3/range/concepts.hpp>
0027 #include <range/v3/range/traits.hpp>
0028 #include <range/v3/utility/addressof.hpp>
0029 #include <range/v3/utility/memory.hpp>
0030 #include <range/v3/view/all.hpp>
0031 #include <range/v3/view/facade.hpp>
0032
0033 #include <range/v3/detail/prologue.hpp>
0034
0035 RANGES_DIAGNOSTIC_PUSH
0036 RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
0037 RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
0038
0039 namespace ranges
0040 {
0041
0042
0043 enum class category
0044 {
0045 none = 0,
0046 input = 1,
0047 forward = 3,
0048 bidirectional = 7,
0049 random_access = 15,
0050 mask = random_access,
0051
0052 sized = 16,
0053 };
0054
0055
0056
0057
0058
0059 constexpr category operator&(category lhs, category rhs) noexcept
0060 {
0061 return static_cast<category>(
0062 static_cast<meta::_t<std::underlying_type<category>>>(lhs) &
0063 static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0064 }
0065
0066 constexpr category operator|(category lhs, category rhs) noexcept
0067 {
0068 return static_cast<category>(
0069 static_cast<meta::_t<std::underlying_type<category>>>(lhs) |
0070 static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0071 }
0072
0073 constexpr category operator^(category lhs, category rhs) noexcept
0074 {
0075 return static_cast<category>(
0076 static_cast<meta::_t<std::underlying_type<category>>>(lhs) ^
0077 static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0078 }
0079
0080 constexpr category operator~(category lhs) noexcept
0081 {
0082 return static_cast<category>(
0083 ~static_cast<meta::_t<std::underlying_type<category>>>(lhs));
0084 }
0085
0086 constexpr category & operator&=(category & lhs, category rhs) noexcept
0087 {
0088 return (lhs = lhs & rhs);
0089 }
0090
0091 constexpr category & operator|=(category & lhs, category rhs) noexcept
0092 {
0093 return (lhs = lhs | rhs);
0094 }
0095
0096 constexpr category & operator^=(category & lhs, category rhs) noexcept
0097 {
0098 return (lhs = lhs ^ rhs);
0099 }
0100
0101
0102
0103
0104 template<typename Rng>
0105 constexpr category get_categories() noexcept
0106 {
0107 return (input_range<Rng> ? category::input : category::none) |
0108 (forward_range<Rng> ? category::forward : category::none) |
0109 (bidirectional_range<Rng> ? category::bidirectional : category::none) |
0110 (random_access_range<Rng> ? category::random_access : category::none) |
0111 (sized_range<Rng> ? category::sized : category::none);
0112 }
0113
0114
0115 namespace detail
0116 {
0117
0118 template<typename>
0119 struct rtti_tag
0120 {};
0121
0122 struct any_ref
0123 {
0124 any_ref() = default;
0125 template<typename T>
0126 constexpr any_ref(T & obj) noexcept
0127 : obj_(detail::addressof(obj))
0128 #ifndef NDEBUG
0129 , info_(&typeid(rtti_tag<T>))
0130 #endif
0131 {}
0132 template<typename T>
0133 T & get() const noexcept
0134 {
0135 RANGES_ASSERT(obj_ && info_ && *info_ == typeid(rtti_tag<T>));
0136 return *const_cast<T *>(static_cast<T const volatile *>(obj_));
0137 }
0138
0139 private:
0140 void const volatile * obj_ = nullptr;
0141 #ifndef NDEBUG
0142 std::type_info const * info_ = nullptr;
0143 #endif
0144 };
0145
0146 template<typename Base>
0147 struct cloneable : Base
0148 {
0149 using Base::Base;
0150 virtual ~cloneable() override = default;
0151 cloneable() = default;
0152 cloneable(cloneable const &) = delete;
0153 cloneable & operator=(cloneable const &) = delete;
0154 virtual std::unique_ptr<cloneable> clone() const = 0;
0155 };
0156
0157
0158
0159
0160 template(typename Rng, typename Ref)(
0161 concept (any_compatible_range_)(Rng, Ref),
0162 convertible_to<range_reference_t<Rng>, Ref>
0163 );
0164
0165
0166 template<typename Rng, typename Ref>
0167 CPP_concept any_compatible_range =
0168 CPP_concept_ref(detail::any_compatible_range_, Rng, Ref);
0169
0170
0171 template<typename Rng, typename = void>
0172 struct any_view_sentinel_impl
0173 : private box<sentinel_t<Rng>, any_view_sentinel_impl<Rng>>
0174 {
0175 private:
0176 using box_t = typename any_view_sentinel_impl::box;
0177
0178 public:
0179 any_view_sentinel_impl() = default;
0180 any_view_sentinel_impl(Rng & rng)
0181 : box_t(ranges::end(rng))
0182 {}
0183 void init(Rng & rng) noexcept
0184 {
0185 box_t::get() = ranges::end(rng);
0186 }
0187 sentinel_t<Rng> const & get(Rng &) const noexcept
0188 {
0189 return box_t::get();
0190 }
0191 };
0192
0193 template<typename Rng>
0194 struct any_view_sentinel_impl<
0195 Rng, meta::void_<decltype(ranges::end(std::declval<Rng const &>()))>>
0196 {
0197 any_view_sentinel_impl() = default;
0198 any_view_sentinel_impl(Rng &) noexcept
0199 {}
0200 void init(Rng &) noexcept
0201 {}
0202 sentinel_t<Rng> get(Rng & rng) const noexcept
0203 {
0204 return ranges::end(rng);
0205 }
0206 };
0207
0208 template<typename Ref, bool Sized = false>
0209 struct any_input_view_interface
0210 {
0211 virtual ~any_input_view_interface() = default;
0212 virtual void init() = 0;
0213 virtual bool done() = 0;
0214 virtual Ref read() const = 0;
0215 virtual void next() = 0;
0216 };
0217 template<typename Ref>
0218 struct any_input_view_interface<Ref, true> : any_input_view_interface<Ref, false>
0219 {
0220 virtual std::size_t size() = 0;
0221 };
0222
0223 template<typename Ref>
0224 struct any_input_cursor
0225 {
0226 using single_pass = std::true_type;
0227
0228 any_input_cursor() = default;
0229 constexpr any_input_cursor(any_input_view_interface<Ref> & view) noexcept
0230 : view_{detail::addressof(view)}
0231 {}
0232 Ref read() const
0233 {
0234 return view_->read();
0235 }
0236 void next()
0237 {
0238 view_->next();
0239 }
0240 bool equal(any_input_cursor const &) const noexcept
0241 {
0242 return true;
0243 }
0244 bool equal(default_sentinel_t) const
0245 {
0246 return !view_ || view_->done();
0247 }
0248
0249 private:
0250 any_input_view_interface<Ref> * view_ = nullptr;
0251 };
0252
0253 template<typename Rng, typename Ref, bool Sized = false>
0254 struct RANGES_EMPTY_BASES any_input_view_impl
0255 : any_input_view_interface<Ref, Sized>
0256 , private any_view_sentinel_impl<Rng>
0257 {
0258 CPP_assert(any_compatible_range<Rng, Ref>);
0259 CPP_assert(!Sized || (bool)sized_range<Rng>);
0260
0261 explicit any_input_view_impl(Rng rng)
0262 : rng_{std::move(rng)}
0263 {}
0264 any_input_view_impl(any_input_view_impl const &) = delete;
0265 any_input_view_impl & operator=(any_input_view_impl const &) = delete;
0266
0267 private:
0268 using sentinel_box_t = any_view_sentinel_impl<Rng>;
0269
0270 virtual void init() override
0271 {
0272 sentinel_box_t::init(rng_);
0273 current_ = ranges::begin(rng_);
0274 }
0275 virtual bool done() override
0276 {
0277 return current_ == sentinel_box_t::get(rng_);
0278 }
0279 virtual Ref read() const override
0280 {
0281 return *current_;
0282 }
0283 virtual void next() override
0284 {
0285 ++current_;
0286 }
0287 std::size_t size()
0288 {
0289 return static_cast<std::size_t>(ranges::size(rng_));
0290 }
0291
0292 RANGES_NO_UNIQUE_ADDRESS Rng rng_;
0293 RANGES_NO_UNIQUE_ADDRESS iterator_t<Rng> current_{};
0294 };
0295
0296 template<typename Ref, category Cat = category::forward, typename enable = void>
0297 struct any_cursor_interface;
0298
0299 template<typename Ref, category Cat>
0300 struct any_cursor_interface<
0301 Ref, Cat, meta::if_c<(Cat & category::mask) == category::forward>>
0302 {
0303 virtual ~any_cursor_interface() = default;
0304 virtual any_ref iter()
0305 const = 0;
0306 virtual Ref read() const = 0;
0307 virtual bool equal(any_cursor_interface const &) const = 0;
0308 virtual void next() = 0;
0309 };
0310
0311 template<typename Ref, category Cat>
0312 struct any_cursor_interface<
0313 Ref, Cat, meta::if_c<(Cat & category::mask) == category::bidirectional>>
0314 : any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>
0315 {
0316 virtual void prev() = 0;
0317 };
0318
0319 template<typename Ref, category Cat>
0320 struct any_cursor_interface<
0321 Ref, Cat, meta::if_c<(Cat & category::mask) == category::random_access>>
0322 : any_cursor_interface<Ref, (Cat & ~category::mask) | category::bidirectional>
0323 {
0324 virtual void advance(std::ptrdiff_t) = 0;
0325 virtual std::ptrdiff_t distance_to(any_cursor_interface const &) const = 0;
0326 };
0327
0328 template<typename Ref, category Cat>
0329 using any_cloneable_cursor_interface = cloneable<any_cursor_interface<Ref, Cat>>;
0330
0331 template<typename I, typename Ref, category Cat>
0332 struct any_cursor_impl : any_cloneable_cursor_interface<Ref, Cat>
0333 {
0334 CPP_assert(convertible_to<iter_reference_t<I>, Ref>);
0335 CPP_assert((Cat & category::forward) == category::forward);
0336
0337 any_cursor_impl() = default;
0338 any_cursor_impl(I it)
0339 : it_{std::move(it)}
0340 {}
0341
0342 private:
0343 using Forward =
0344 any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>;
0345
0346 I it_;
0347
0348 any_ref iter() const override
0349 {
0350 return it_;
0351 }
0352 Ref read() const override
0353 {
0354 return *it_;
0355 }
0356 bool equal(Forward const & that_) const override
0357 {
0358 auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
0359 return that.it_ == it_;
0360 }
0361 void next() override
0362 {
0363 ++it_;
0364 }
0365 std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> clone()
0366 const override
0367 {
0368 return detail::make_unique<any_cursor_impl>(it_);
0369 }
0370 void prev()
0371 {
0372 --it_;
0373 }
0374 void advance(std::ptrdiff_t n)
0375 {
0376 it_ += n;
0377 }
0378 std::ptrdiff_t distance_to(
0379 any_cursor_interface<Ref, Cat> const & that_) const
0380 {
0381 auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
0382 return static_cast<std::ptrdiff_t>(that.it_ - it_);
0383 }
0384 };
0385
0386 struct fully_erased_view
0387 {
0388 virtual bool at_end(
0389 any_ref) = 0;
0390
0391 protected:
0392 ~fully_erased_view() = default;
0393 };
0394
0395 struct any_sentinel
0396 {
0397 any_sentinel() = default;
0398 constexpr explicit any_sentinel(fully_erased_view & view) noexcept
0399 : view_{&view}
0400 {}
0401
0402 private:
0403 template<typename, category>
0404 friend struct any_cursor;
0405
0406 fully_erased_view * view_ = nullptr;
0407 };
0408
0409 template<typename Ref, category Cat>
0410 struct any_cursor
0411 {
0412 private:
0413 CPP_assert((Cat & category::forward) == category::forward);
0414
0415 std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> ptr_;
0416
0417 template<typename Rng>
0418 using impl_t = any_cursor_impl<iterator_t<Rng>, Ref, Cat>;
0419
0420 public:
0421 any_cursor() = default;
0422 template(typename Rng)(
0423 requires (!same_as<detail::decay_t<Rng>, any_cursor>) AND
0424 forward_range<Rng> AND
0425 any_compatible_range<Rng, Ref>)
0426 explicit any_cursor(Rng && rng)
0427 : ptr_{detail::make_unique<impl_t<Rng>>(begin(rng))}
0428 {}
0429 any_cursor(any_cursor &&) = default;
0430 any_cursor(any_cursor const & that)
0431 : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
0432 {}
0433 any_cursor & operator=(any_cursor &&) = default;
0434 any_cursor & operator=(any_cursor const & that)
0435 {
0436 ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
0437 return *this;
0438 }
0439 Ref read() const
0440 {
0441 RANGES_EXPECT(ptr_);
0442 return ptr_->read();
0443 }
0444 bool equal(any_cursor const & that) const
0445 {
0446 RANGES_EXPECT(!ptr_ == !that.ptr_);
0447 return !ptr_ || ptr_->equal(*that.ptr_);
0448 }
0449 bool equal(any_sentinel const & that) const
0450 {
0451 RANGES_EXPECT(!ptr_ == !that.view_);
0452 return !ptr_ || that.view_->at_end(ptr_->iter());
0453 }
0454 void next()
0455 {
0456 RANGES_EXPECT(ptr_);
0457 ptr_->next();
0458 }
0459 CPP_member
0460 auto prev()
0461 -> CPP_ret(void)(
0462 requires (category::bidirectional == (Cat & category::bidirectional)))
0463 {
0464 RANGES_EXPECT(ptr_);
0465 ptr_->prev();
0466 }
0467 CPP_member
0468 auto advance(std::ptrdiff_t n)
0469 -> CPP_ret(void)(
0470 requires (category::random_access == (Cat & category::random_access)))
0471 {
0472 RANGES_EXPECT(ptr_);
0473 ptr_->advance(n);
0474 }
0475 CPP_member
0476 auto distance_to(any_cursor const & that) const
0477 -> CPP_ret(std::ptrdiff_t)(
0478 requires (category::random_access == (Cat & category::random_access)))
0479 {
0480 RANGES_EXPECT(!ptr_ == !that.ptr_);
0481 return !ptr_ ? 0 : ptr_->distance_to(*that.ptr_);
0482 }
0483 };
0484
0485 template<typename Ref, category Cat,
0486 bool = (Cat & category::sized) == category::sized>
0487 struct any_view_interface : fully_erased_view
0488 {
0489 CPP_assert((Cat & category::forward) == category::forward);
0490
0491 virtual ~any_view_interface() = default;
0492 virtual any_cursor<Ref, Cat> begin_cursor() = 0;
0493 };
0494 template<typename Ref, category Cat>
0495 struct any_view_interface<Ref, Cat, true> : any_view_interface<Ref, Cat, false>
0496 {
0497 virtual std::size_t size() = 0;
0498 };
0499
0500 template<typename Ref, category Cat>
0501 using any_cloneable_view_interface = cloneable<any_view_interface<Ref, Cat>>;
0502
0503 template<typename Rng, typename Ref, category Cat>
0504 struct RANGES_EMPTY_BASES any_view_impl
0505 : any_cloneable_view_interface<Ref, Cat>
0506 , private box<Rng, any_view_impl<Rng, Ref, Cat>>
0507 , private any_view_sentinel_impl<Rng>
0508 {
0509 CPP_assert((Cat & category::forward) == category::forward);
0510 CPP_assert(any_compatible_range<Rng, Ref>);
0511 CPP_assert((Cat & category::sized) == category::none ||
0512 (bool)sized_range<Rng>);
0513
0514 any_view_impl() = default;
0515 any_view_impl(Rng rng)
0516 : range_box_t{std::move(rng)}
0517 , sentinel_box_t{range_box_t::get()}
0518
0519 {}
0520
0521 private:
0522 using range_box_t = box<Rng, any_view_impl>;
0523 using sentinel_box_t = any_view_sentinel_impl<Rng>;
0524
0525 any_cursor<Ref, Cat> begin_cursor() override
0526 {
0527 return any_cursor<Ref, Cat>{range_box_t::get()};
0528 }
0529 bool at_end(any_ref it_) override
0530 {
0531 auto & it = it_.get<iterator_t<Rng> const>();
0532 return it == sentinel_box_t::get(range_box_t::get());
0533 }
0534 std::unique_ptr<any_cloneable_view_interface<Ref, Cat>> clone() const override
0535 {
0536 return detail::make_unique<any_view_impl>(range_box_t::get());
0537 }
0538 std::size_t size()
0539 {
0540 return static_cast<std::size_t>(ranges::size(range_box_t::get()));
0541 }
0542 };
0543 }
0544
0545
0546
0547
0548 template<typename Ref, category Cat = category::input, typename enable = void>
0549 struct any_view
0550 : view_facade<any_view<Ref, Cat>,
0551 (Cat & category::sized) == category::sized ? finite : unknown>
0552 {
0553 friend range_access;
0554 CPP_assert((Cat & category::forward) == category::forward);
0555
0556 any_view() = default;
0557 template(typename Rng)(
0558 requires
0559 (!same_as<detail::decay_t<Rng>, any_view>) AND
0560 input_range<Rng> AND
0561 detail::any_compatible_range<Rng, Ref>)
0562 any_view(Rng && rng)
0563 : any_view(static_cast<Rng &&>(rng),
0564 meta::bool_<(get_categories<Rng>() & Cat) == Cat>{})
0565 {}
0566 any_view(any_view &&) = default;
0567 any_view(any_view const & that)
0568 : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
0569 {}
0570 any_view & operator=(any_view &&) = default;
0571 any_view & operator=(any_view const & that)
0572 {
0573 ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
0574 return *this;
0575 }
0576
0577 CPP_member
0578 auto size()
0579 -> CPP_ret(std::size_t)(
0580 requires (category::sized == (Cat & category::sized)))
0581 {
0582 return ptr_ ? ptr_->size() : 0;
0583 }
0584
0585 private:
0586 template<typename Rng>
0587 using impl_t = detail::any_view_impl<views::all_t<Rng>, Ref, Cat>;
0588 template<typename Rng>
0589 any_view(Rng && rng, std::true_type)
0590 : ptr_{detail::make_unique<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
0591 {}
0592 template<typename Rng>
0593 any_view(Rng &&, std::false_type)
0594 {
0595 static_assert(
0596 (get_categories<Rng>() & Cat) == Cat,
0597 "The range passed to any_view() does not model the requested category");
0598 }
0599
0600 detail::any_cursor<Ref, Cat> begin_cursor()
0601 {
0602 return ptr_ ? ptr_->begin_cursor() : detail::value_init{};
0603 }
0604 detail::any_sentinel end_cursor() noexcept
0605 {
0606 return detail::any_sentinel{*ptr_};
0607 }
0608
0609 std::unique_ptr<detail::any_cloneable_view_interface<Ref, Cat>> ptr_;
0610 };
0611
0612
0613 template<typename Ref, category Cat>
0614 struct any_view<Ref, Cat, meta::if_c<(Cat & category::forward) == category::input>>
0615 : view_facade<any_view<Ref, Cat, void>,
0616 (Cat & category::sized) == category::sized ? finite : unknown>
0617 {
0618 friend range_access;
0619
0620 any_view() = default;
0621 template(typename Rng)(
0622 requires
0623 (!same_as<detail::decay_t<Rng>, any_view>) AND
0624 input_range<Rng> AND
0625 detail::any_compatible_range<Rng, Ref>)
0626 any_view(Rng && rng)
0627 : ptr_{std::make_shared<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
0628 {}
0629
0630 CPP_member
0631 auto size()
0632 -> CPP_ret(std::size_t)(
0633 requires (category::sized == (Cat & category::sized)))
0634 {
0635 return ptr_ ? ptr_->size() : 0;
0636 }
0637
0638 private:
0639 template<typename Rng>
0640 using impl_t =
0641 detail::any_input_view_impl<views::all_t<Rng>, Ref,
0642 (Cat & category::sized) == category::sized>;
0643
0644 detail::any_input_cursor<Ref> begin_cursor()
0645 {
0646 if(!ptr_)
0647 return {};
0648
0649 ptr_->init();
0650 return detail::any_input_cursor<Ref>{*ptr_};
0651 }
0652
0653 std::shared_ptr<detail::any_input_view_interface<Ref, (Cat & category::sized) ==
0654 category::sized>>
0655 ptr_;
0656 };
0657
0658 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0659 template(typename Rng)(
0660 requires view_<Rng>)
0661 any_view(Rng &&)
0662 ->any_view<range_reference_t<Rng>, get_categories<Rng>()>;
0663 #endif
0664
0665 template<typename Ref>
0666 using any_input_view RANGES_DEPRECATED(
0667 "Use any_view<Ref, category::input> instead.") = any_view<Ref, category::input>;
0668
0669 template<typename Ref>
0670 using any_forward_view RANGES_DEPRECATED(
0671 "Use any_view<Ref, category::forward> instead.") =
0672 any_view<Ref, category::forward>;
0673
0674 template<typename Ref>
0675 using any_bidirectional_view RANGES_DEPRECATED(
0676 "Use any_view<Ref, category::bidirectional> instead.") =
0677 any_view<Ref, category::bidirectional>;
0678
0679 template<typename Ref>
0680 using any_random_access_view RANGES_DEPRECATED(
0681 "Use any_view<Ref, category::random_access> instead.") =
0682 any_view<Ref, category::random_access>;
0683 }
0684
0685 #include <range/v3/detail/satisfy_boost_range.hpp>
0686 RANGES_SATISFY_BOOST_RANGE(::ranges::any_view)
0687
0688 RANGES_DIAGNOSTIC_POP
0689
0690 #include <range/v3/detail/epilogue.hpp>
0691
0692 #endif