You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

any_view.hpp 23KB

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