any_view.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-present
  5. // Copyright Casey Carter 2017
  6. //
  7. // Use, modification and distribution is subject to the
  8. // Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // Project home: https://github.com/ericniebler/range-v3
  13. //
  14. #ifndef RANGES_V3_VIEW_ANY_VIEW_HPP
  15. #define RANGES_V3_VIEW_ANY_VIEW_HPP
  16. #include <type_traits>
  17. #include <typeinfo>
  18. #include <utility>
  19. #include <range/v3/range_fwd.hpp>
  20. #include <range/v3/iterator/default_sentinel.hpp>
  21. #include <range/v3/range/access.hpp>
  22. #include <range/v3/range/concepts.hpp>
  23. #include <range/v3/range/traits.hpp>
  24. #include <range/v3/utility/addressof.hpp>
  25. #include <range/v3/utility/memory.hpp>
  26. #include <range/v3/view/all.hpp>
  27. #include <range/v3/view/facade.hpp>
  28. #include <range/v3/detail/prologue.hpp>
  29. RANGES_DIAGNOSTIC_PUSH
  30. RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
  31. RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
  32. namespace ranges
  33. {
  34. /// \brief An enum that denotes the supported subset of range concepts supported by a
  35. /// range.
  36. enum class category
  37. {
  38. none = 0, ///<\brief No concepts met.
  39. input = 1, ///<\brief satisfies ranges::concepts::input_range
  40. forward = 3, ///<\brief satisfies ranges::concepts::forward_range
  41. bidirectional = 7, ///<\brief satisfies ranges::concepts::bidirectional_range
  42. random_access = 15, ///<\brief satisfies ranges::concepts::random_access_range
  43. mask = random_access, ///<\brief Mask away any properties other than iterator
  44. ///< category
  45. sized = 16, ///<\brief satisfies ranges::concepts::sized_range
  46. };
  47. /** \name Binary operators for ranges::category
  48. * \relates ranges::category
  49. * \{
  50. */
  51. constexpr category operator&(category lhs, category rhs) noexcept
  52. {
  53. return static_cast<category>(
  54. static_cast<meta::_t<std::underlying_type<category>>>(lhs) &
  55. static_cast<meta::_t<std::underlying_type<category>>>(rhs));
  56. }
  57. constexpr category operator|(category lhs, category rhs) noexcept
  58. {
  59. return static_cast<category>(
  60. static_cast<meta::_t<std::underlying_type<category>>>(lhs) |
  61. static_cast<meta::_t<std::underlying_type<category>>>(rhs));
  62. }
  63. constexpr category operator^(category lhs, category rhs) noexcept
  64. {
  65. return static_cast<category>(
  66. static_cast<meta::_t<std::underlying_type<category>>>(lhs) ^
  67. static_cast<meta::_t<std::underlying_type<category>>>(rhs));
  68. }
  69. constexpr category operator~(category lhs) noexcept
  70. {
  71. return static_cast<category>(
  72. ~static_cast<meta::_t<std::underlying_type<category>>>(lhs));
  73. }
  74. constexpr category & operator&=(category & lhs, category rhs) noexcept
  75. {
  76. return (lhs = lhs & rhs);
  77. }
  78. constexpr category & operator|=(category & lhs, category rhs) noexcept
  79. {
  80. return (lhs = lhs | rhs);
  81. }
  82. constexpr category & operator^=(category & lhs, category rhs) noexcept
  83. {
  84. return (lhs = lhs ^ rhs);
  85. }
  86. //!\}
  87. /// \brief For a given range, return a ranges::category enum with the satisfied
  88. /// concepts.
  89. template<typename Rng>
  90. constexpr category get_categories() noexcept
  91. {
  92. return (input_range<Rng> ? category::input : category::none) |
  93. (forward_range<Rng> ? category::forward : category::none) |
  94. (bidirectional_range<Rng> ? category::bidirectional : category::none) |
  95. (random_access_range<Rng> ? category::random_access : category::none) |
  96. (sized_range<Rng> ? category::sized : category::none);
  97. }
  98. /// \cond
  99. namespace detail
  100. {
  101. // workaround the fact that typeid ignores cv-qualifiers
  102. template<typename>
  103. struct rtti_tag
  104. {};
  105. struct any_ref
  106. {
  107. any_ref() = default;
  108. template<typename T>
  109. constexpr any_ref(T & obj) noexcept
  110. : obj_(detail::addressof(obj))
  111. #ifndef NDEBUG
  112. , info_(&typeid(rtti_tag<T>))
  113. #endif
  114. {}
  115. template<typename T>
  116. T & get() const noexcept
  117. {
  118. RANGES_ASSERT(obj_ && info_ && *info_ == typeid(rtti_tag<T>));
  119. return *const_cast<T *>(static_cast<T const volatile *>(obj_));
  120. }
  121. private:
  122. void const volatile * obj_ = nullptr;
  123. #ifndef NDEBUG
  124. std::type_info const * info_ = nullptr;
  125. #endif
  126. };
  127. template<typename Base>
  128. struct cloneable : Base
  129. {
  130. using Base::Base;
  131. virtual ~cloneable() override = default;
  132. cloneable() = default;
  133. cloneable(cloneable const &) = delete;
  134. cloneable & operator=(cloneable const &) = delete;
  135. virtual std::unique_ptr<cloneable> clone() const = 0;
  136. };
  137. // clang-format off
  138. /// \concept any_compatible_range_
  139. /// \brief The \c any_compatible_range_ concept
  140. template(typename Rng, typename Ref)(
  141. concept (any_compatible_range_)(Rng, Ref),
  142. convertible_to<range_reference_t<Rng>, Ref>
  143. );
  144. /// \concept any_compatible_range
  145. /// \brief The \c any_compatible_range concept
  146. template<typename Rng, typename Ref>
  147. CPP_concept any_compatible_range =
  148. CPP_concept_ref(detail::any_compatible_range_, Rng, Ref);
  149. // clang-format on
  150. template<typename Rng, typename = void>
  151. struct any_view_sentinel_impl
  152. : private box<sentinel_t<Rng>, any_view_sentinel_impl<Rng>>
  153. {
  154. private:
  155. using box_t = typename any_view_sentinel_impl::box;
  156. public:
  157. any_view_sentinel_impl() = default;
  158. any_view_sentinel_impl(Rng & rng)
  159. : box_t(ranges::end(rng))
  160. {}
  161. void init(Rng & rng) noexcept
  162. {
  163. box_t::get() = ranges::end(rng);
  164. }
  165. sentinel_t<Rng> const & get(Rng &) const noexcept
  166. {
  167. return box_t::get();
  168. }
  169. };
  170. template<typename Rng>
  171. struct any_view_sentinel_impl<
  172. Rng, meta::void_<decltype(ranges::end(std::declval<Rng const &>()))>>
  173. {
  174. any_view_sentinel_impl() = default;
  175. any_view_sentinel_impl(Rng &) noexcept
  176. {}
  177. void init(Rng &) noexcept
  178. {}
  179. sentinel_t<Rng> get(Rng & rng) const noexcept
  180. {
  181. return ranges::end(rng);
  182. }
  183. };
  184. template<typename Ref, bool Sized = false>
  185. struct any_input_view_interface
  186. {
  187. virtual ~any_input_view_interface() = default;
  188. virtual void init() = 0;
  189. virtual bool done() = 0;
  190. virtual Ref read() const = 0;
  191. virtual void next() = 0;
  192. };
  193. template<typename Ref>
  194. struct any_input_view_interface<Ref, true> : any_input_view_interface<Ref, false>
  195. {
  196. virtual std::size_t size() = 0;
  197. };
  198. template<typename Ref>
  199. struct any_input_cursor
  200. {
  201. using single_pass = std::true_type;
  202. any_input_cursor() = default;
  203. constexpr any_input_cursor(any_input_view_interface<Ref> & view) noexcept
  204. : view_{detail::addressof(view)}
  205. {}
  206. Ref read() const
  207. {
  208. return view_->read();
  209. }
  210. void next()
  211. {
  212. view_->next();
  213. }
  214. bool equal(any_input_cursor const &) const noexcept
  215. {
  216. return true;
  217. }
  218. bool equal(default_sentinel_t) const
  219. {
  220. return !view_ || view_->done();
  221. }
  222. private:
  223. any_input_view_interface<Ref> * view_ = nullptr;
  224. };
  225. template<typename Rng, typename Ref, bool Sized = false>
  226. struct RANGES_EMPTY_BASES any_input_view_impl
  227. : any_input_view_interface<Ref, Sized>
  228. , private any_view_sentinel_impl<Rng>
  229. {
  230. CPP_assert(any_compatible_range<Rng, Ref>);
  231. CPP_assert(!Sized || (bool)sized_range<Rng>);
  232. explicit any_input_view_impl(Rng rng)
  233. : rng_{std::move(rng)}
  234. {}
  235. any_input_view_impl(any_input_view_impl const &) = delete;
  236. any_input_view_impl & operator=(any_input_view_impl const &) = delete;
  237. private:
  238. using sentinel_box_t = any_view_sentinel_impl<Rng>;
  239. virtual void init() override
  240. {
  241. sentinel_box_t::init(rng_);
  242. current_ = ranges::begin(rng_);
  243. }
  244. virtual bool done() override
  245. {
  246. return current_ == sentinel_box_t::get(rng_);
  247. }
  248. virtual Ref read() const override
  249. {
  250. return *current_;
  251. }
  252. virtual void next() override
  253. {
  254. ++current_;
  255. }
  256. std::size_t size() // override-ish
  257. {
  258. return static_cast<std::size_t>(ranges::size(rng_));
  259. }
  260. RANGES_NO_UNIQUE_ADDRESS Rng rng_;
  261. RANGES_NO_UNIQUE_ADDRESS iterator_t<Rng> current_{};
  262. };
  263. template<typename Ref, category Cat = category::forward, typename enable = void>
  264. struct any_cursor_interface;
  265. template<typename Ref, category Cat>
  266. struct any_cursor_interface<
  267. Ref, Cat, meta::if_c<(Cat & category::mask) == category::forward>>
  268. {
  269. virtual ~any_cursor_interface() = default;
  270. virtual any_ref iter()
  271. const = 0; // returns a const ref to the cursor's wrapped iterator
  272. virtual Ref read() const = 0;
  273. virtual bool equal(any_cursor_interface const &) const = 0;
  274. virtual void next() = 0;
  275. };
  276. template<typename Ref, category Cat>
  277. struct any_cursor_interface<
  278. Ref, Cat, meta::if_c<(Cat & category::mask) == category::bidirectional>>
  279. : any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>
  280. {
  281. virtual void prev() = 0;
  282. };
  283. template<typename Ref, category Cat>
  284. struct any_cursor_interface<
  285. Ref, Cat, meta::if_c<(Cat & category::mask) == category::random_access>>
  286. : any_cursor_interface<Ref, (Cat & ~category::mask) | category::bidirectional>
  287. {
  288. virtual void advance(std::ptrdiff_t) = 0;
  289. virtual std::ptrdiff_t distance_to(any_cursor_interface const &) const = 0;
  290. };
  291. template<typename Ref, category Cat>
  292. using any_cloneable_cursor_interface = cloneable<any_cursor_interface<Ref, Cat>>;
  293. template<typename I, typename Ref, category Cat>
  294. struct any_cursor_impl : any_cloneable_cursor_interface<Ref, Cat>
  295. {
  296. CPP_assert(convertible_to<iter_reference_t<I>, Ref>);
  297. CPP_assert((Cat & category::forward) == category::forward);
  298. any_cursor_impl() = default;
  299. any_cursor_impl(I it)
  300. : it_{std::move(it)}
  301. {}
  302. private:
  303. using Forward =
  304. any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>;
  305. I it_;
  306. any_ref iter() const override
  307. {
  308. return it_;
  309. }
  310. Ref read() const override
  311. {
  312. return *it_;
  313. }
  314. bool equal(Forward const & that_) const override
  315. {
  316. auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
  317. return that.it_ == it_;
  318. }
  319. void next() override
  320. {
  321. ++it_;
  322. }
  323. std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> clone()
  324. const override
  325. {
  326. return detail::make_unique<any_cursor_impl>(it_);
  327. }
  328. void prev() // override (sometimes; it's complicated)
  329. {
  330. --it_;
  331. }
  332. void advance(std::ptrdiff_t n) // override-ish
  333. {
  334. it_ += n;
  335. }
  336. std::ptrdiff_t distance_to(
  337. any_cursor_interface<Ref, Cat> const & that_) const // override-ish
  338. {
  339. auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
  340. return static_cast<std::ptrdiff_t>(that.it_ - it_);
  341. }
  342. };
  343. struct fully_erased_view
  344. {
  345. virtual bool at_end(
  346. any_ref) = 0; // any_ref is a const ref to a wrapped iterator
  347. // to be compared to the erased view's last sentinel
  348. protected:
  349. ~fully_erased_view() = default;
  350. };
  351. struct any_sentinel
  352. {
  353. any_sentinel() = default;
  354. constexpr explicit any_sentinel(fully_erased_view & view) noexcept
  355. : view_{&view}
  356. {}
  357. private:
  358. template<typename, category>
  359. friend struct any_cursor;
  360. fully_erased_view * view_ = nullptr;
  361. };
  362. template<typename Ref, category Cat>
  363. struct any_cursor
  364. {
  365. private:
  366. CPP_assert((Cat & category::forward) == category::forward);
  367. std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> ptr_;
  368. template<typename Rng>
  369. using impl_t = any_cursor_impl<iterator_t<Rng>, Ref, Cat>;
  370. public:
  371. any_cursor() = default;
  372. template(typename Rng)(
  373. requires (!same_as<detail::decay_t<Rng>, any_cursor>) AND
  374. forward_range<Rng> AND
  375. any_compatible_range<Rng, Ref>)
  376. explicit any_cursor(Rng && rng)
  377. : ptr_{detail::make_unique<impl_t<Rng>>(begin(rng))}
  378. {}
  379. any_cursor(any_cursor &&) = default;
  380. any_cursor(any_cursor const & that)
  381. : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
  382. {}
  383. any_cursor & operator=(any_cursor &&) = default;
  384. any_cursor & operator=(any_cursor const & that)
  385. {
  386. ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
  387. return *this;
  388. }
  389. Ref read() const
  390. {
  391. RANGES_EXPECT(ptr_);
  392. return ptr_->read();
  393. }
  394. bool equal(any_cursor const & that) const
  395. {
  396. RANGES_EXPECT(!ptr_ == !that.ptr_);
  397. return !ptr_ || ptr_->equal(*that.ptr_);
  398. }
  399. bool equal(any_sentinel const & that) const
  400. {
  401. RANGES_EXPECT(!ptr_ == !that.view_);
  402. return !ptr_ || that.view_->at_end(ptr_->iter());
  403. }
  404. void next()
  405. {
  406. RANGES_EXPECT(ptr_);
  407. ptr_->next();
  408. }
  409. CPP_member
  410. auto prev() //
  411. -> CPP_ret(void)(
  412. requires (category::bidirectional == (Cat & category::bidirectional)))
  413. {
  414. RANGES_EXPECT(ptr_);
  415. ptr_->prev();
  416. }
  417. CPP_member
  418. auto advance(std::ptrdiff_t n) //
  419. -> CPP_ret(void)(
  420. requires (category::random_access == (Cat & category::random_access)))
  421. {
  422. RANGES_EXPECT(ptr_);
  423. ptr_->advance(n);
  424. }
  425. CPP_member
  426. auto distance_to(any_cursor const & that) const //
  427. -> CPP_ret(std::ptrdiff_t)(
  428. requires (category::random_access == (Cat & category::random_access)))
  429. {
  430. RANGES_EXPECT(!ptr_ == !that.ptr_);
  431. return !ptr_ ? 0 : ptr_->distance_to(*that.ptr_);
  432. }
  433. };
  434. template<typename Ref, category Cat,
  435. bool = (Cat & category::sized) == category::sized>
  436. struct any_view_interface : fully_erased_view
  437. {
  438. CPP_assert((Cat & category::forward) == category::forward);
  439. virtual ~any_view_interface() = default;
  440. virtual any_cursor<Ref, Cat> begin_cursor() = 0;
  441. };
  442. template<typename Ref, category Cat>
  443. struct any_view_interface<Ref, Cat, true> : any_view_interface<Ref, Cat, false>
  444. {
  445. virtual std::size_t size() = 0;
  446. };
  447. template<typename Ref, category Cat>
  448. using any_cloneable_view_interface = cloneable<any_view_interface<Ref, Cat>>;
  449. template<typename Rng, typename Ref, category Cat>
  450. struct RANGES_EMPTY_BASES any_view_impl
  451. : any_cloneable_view_interface<Ref, Cat>
  452. , private box<Rng, any_view_impl<Rng, Ref, Cat>>
  453. , private any_view_sentinel_impl<Rng>
  454. {
  455. CPP_assert((Cat & category::forward) == category::forward);
  456. CPP_assert(any_compatible_range<Rng, Ref>);
  457. CPP_assert((Cat & category::sized) == category::none ||
  458. (bool)sized_range<Rng>);
  459. any_view_impl() = default;
  460. any_view_impl(Rng rng)
  461. : range_box_t{std::move(rng)}
  462. , sentinel_box_t{range_box_t::get()}
  463. // NB: initialization order dependence
  464. {}
  465. private:
  466. using range_box_t = box<Rng, any_view_impl>;
  467. using sentinel_box_t = any_view_sentinel_impl<Rng>;
  468. any_cursor<Ref, Cat> begin_cursor() override
  469. {
  470. return any_cursor<Ref, Cat>{range_box_t::get()};
  471. }
  472. bool at_end(any_ref it_) override
  473. {
  474. auto & it = it_.get<iterator_t<Rng> const>();
  475. return it == sentinel_box_t::get(range_box_t::get());
  476. }
  477. std::unique_ptr<any_cloneable_view_interface<Ref, Cat>> clone() const override
  478. {
  479. return detail::make_unique<any_view_impl>(range_box_t::get());
  480. }
  481. std::size_t size() // override-ish
  482. {
  483. return static_cast<std::size_t>(ranges::size(range_box_t::get()));
  484. }
  485. };
  486. } // namespace detail
  487. /// \endcond
  488. /// \brief A type-erased view
  489. /// \ingroup group-views
  490. template<typename Ref, category Cat = category::input, typename enable = void>
  491. struct any_view
  492. : view_facade<any_view<Ref, Cat>,
  493. (Cat & category::sized) == category::sized ? finite : unknown>
  494. {
  495. friend range_access;
  496. CPP_assert((Cat & category::forward) == category::forward);
  497. any_view() = default;
  498. template(typename Rng)(
  499. requires //
  500. (!same_as<detail::decay_t<Rng>, any_view>) AND
  501. input_range<Rng> AND
  502. detail::any_compatible_range<Rng, Ref>)
  503. any_view(Rng && rng)
  504. : any_view(static_cast<Rng &&>(rng),
  505. meta::bool_<(get_categories<Rng>() & Cat) == Cat>{})
  506. {}
  507. any_view(any_view &&) = default;
  508. any_view(any_view const & that)
  509. : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
  510. {}
  511. any_view & operator=(any_view &&) = default;
  512. any_view & operator=(any_view const & that)
  513. {
  514. ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
  515. return *this;
  516. }
  517. CPP_member
  518. auto size() //
  519. -> CPP_ret(std::size_t)(
  520. requires (category::sized == (Cat & category::sized)))
  521. {
  522. return ptr_ ? ptr_->size() : 0;
  523. }
  524. private:
  525. template<typename Rng>
  526. using impl_t = detail::any_view_impl<views::all_t<Rng>, Ref, Cat>;
  527. template<typename Rng>
  528. any_view(Rng && rng, std::true_type)
  529. : ptr_{detail::make_unique<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
  530. {}
  531. template<typename Rng>
  532. any_view(Rng &&, std::false_type)
  533. {
  534. static_assert(
  535. (get_categories<Rng>() & Cat) == Cat,
  536. "The range passed to any_view() does not model the requested category");
  537. }
  538. detail::any_cursor<Ref, Cat> begin_cursor()
  539. {
  540. return ptr_ ? ptr_->begin_cursor() : detail::value_init{};
  541. }
  542. detail::any_sentinel end_cursor() noexcept
  543. {
  544. return detail::any_sentinel{*ptr_};
  545. }
  546. std::unique_ptr<detail::any_cloneable_view_interface<Ref, Cat>> ptr_;
  547. };
  548. // input and not forward
  549. template<typename Ref, category Cat>
  550. struct any_view<Ref, Cat, meta::if_c<(Cat & category::forward) == category::input>>
  551. : view_facade<any_view<Ref, Cat, void>,
  552. (Cat & category::sized) == category::sized ? finite : unknown>
  553. {
  554. friend range_access;
  555. any_view() = default;
  556. template(typename Rng)(
  557. requires //
  558. (!same_as<detail::decay_t<Rng>, any_view>) AND
  559. input_range<Rng> AND
  560. detail::any_compatible_range<Rng, Ref>)
  561. any_view(Rng && rng)
  562. : ptr_{std::make_shared<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
  563. {}
  564. CPP_member
  565. auto size() //
  566. -> CPP_ret(std::size_t)(
  567. requires (category::sized == (Cat & category::sized)))
  568. {
  569. return ptr_ ? ptr_->size() : 0;
  570. }
  571. private:
  572. template<typename Rng>
  573. using impl_t =
  574. detail::any_input_view_impl<views::all_t<Rng>, Ref,
  575. (Cat & category::sized) == category::sized>;
  576. detail::any_input_cursor<Ref> begin_cursor()
  577. {
  578. if(!ptr_)
  579. return {};
  580. ptr_->init();
  581. return detail::any_input_cursor<Ref>{*ptr_};
  582. }
  583. std::shared_ptr<detail::any_input_view_interface<Ref, (Cat & category::sized) ==
  584. category::sized>>
  585. ptr_;
  586. };
  587. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  588. template(typename Rng)(
  589. requires view_<Rng>)
  590. any_view(Rng &&)
  591. ->any_view<range_reference_t<Rng>, get_categories<Rng>()>;
  592. #endif
  593. template<typename Ref>
  594. using any_input_view RANGES_DEPRECATED(
  595. "Use any_view<Ref, category::input> instead.") = any_view<Ref, category::input>;
  596. template<typename Ref>
  597. using any_forward_view RANGES_DEPRECATED(
  598. "Use any_view<Ref, category::forward> instead.") =
  599. any_view<Ref, category::forward>;
  600. template<typename Ref>
  601. using any_bidirectional_view RANGES_DEPRECATED(
  602. "Use any_view<Ref, category::bidirectional> instead.") =
  603. any_view<Ref, category::bidirectional>;
  604. template<typename Ref>
  605. using any_random_access_view RANGES_DEPRECATED(
  606. "Use any_view<Ref, category::random_access> instead.") =
  607. any_view<Ref, category::random_access>;
  608. } // namespace ranges
  609. #include <range/v3/detail/satisfy_boost_range.hpp>
  610. RANGES_SATISFY_BOOST_RANGE(::ranges::any_view)
  611. RANGES_DIAGNOSTIC_POP
  612. #include <range/v3/detail/epilogue.hpp>
  613. #endif