adaptor.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_VIEW_ADAPTOR_HPP
  14. #define RANGES_V3_VIEW_ADAPTOR_HPP
  15. #include <meta/meta.hpp>
  16. #include <concepts/concepts.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/iterator/concepts.hpp>
  19. #include <range/v3/iterator/operations.hpp>
  20. #include <range/v3/iterator/traits.hpp>
  21. #include <range/v3/range/primitives.hpp>
  22. #include <range/v3/range/traits.hpp>
  23. #include <range/v3/utility/compressed_pair.hpp>
  24. #include <range/v3/view/all.hpp>
  25. #include <range/v3/view/facade.hpp>
  26. #include <range/v3/detail/prologue.hpp>
  27. namespace ranges
  28. {
  29. /// \cond
  30. namespace detail
  31. {
  32. template<typename Derived>
  33. using begin_adaptor_t = detail::decay_t<decltype(
  34. range_access::begin_adaptor(std::declval<Derived &>()))>;
  35. template<typename Derived>
  36. using end_adaptor_t = detail::decay_t<decltype(
  37. range_access::end_adaptor(std::declval<Derived &>()))>;
  38. template<typename Derived>
  39. using adapted_iterator_t = detail::decay_t<decltype(
  40. std::declval<begin_adaptor_t<Derived>>().begin(std::declval<Derived &>()))>;
  41. template<typename Derived>
  42. using adapted_sentinel_t = detail::decay_t<decltype(
  43. std::declval<end_adaptor_t<Derived>>().end(std::declval<Derived &>()))>;
  44. struct adaptor_base_current_mem_fn
  45. {};
  46. template<typename BaseIter, typename Adapt>
  47. constexpr int which_adaptor_value_(priority_tag<0>)
  48. {
  49. return 0;
  50. }
  51. template<typename BaseIter, typename Adapt>
  52. constexpr always_<int, decltype(Adapt::read(std::declval<BaseIter const &>(),
  53. adaptor_base_current_mem_fn{}))> //
  54. which_adaptor_value_(priority_tag<1>)
  55. {
  56. return 1;
  57. }
  58. template<typename BaseIter, typename Adapt>
  59. constexpr always_<int, typename Adapt::value_type> //
  60. which_adaptor_value_(priority_tag<2>)
  61. {
  62. return 2;
  63. }
  64. template<typename BaseIter, typename Adapt,
  65. int = detail::which_adaptor_value_<BaseIter, Adapt>(priority_tag<2>{})>
  66. struct adaptor_value_type_
  67. {
  68. compressed_pair<BaseIter, Adapt> data_;
  69. };
  70. template<typename BaseIter, typename Adapt>
  71. struct adaptor_value_type_<BaseIter, Adapt, 1>
  72. {
  73. using value_type = iter_value_t<BaseIter>;
  74. compressed_pair<BaseIter, Adapt> data_;
  75. };
  76. template<typename BaseIter, typename Adapt>
  77. struct adaptor_value_type_<BaseIter, Adapt, 2>
  78. {
  79. #ifdef RANGES_WORKAROUND_MSVC_688606
  80. using value_type = typename indirectly_readable_traits<Adapt>::value_type;
  81. #else // ^^^ workaround ^^^ / vvv no workaround vvv
  82. using value_type = typename Adapt::value_type;
  83. #endif // RANGES_WORKAROUND_MSVC_688606
  84. compressed_pair<BaseIter, Adapt> data_;
  85. };
  86. } // namespace detail
  87. /// \endcond
  88. /// \addtogroup group-views
  89. /// @{
  90. template<typename BaseIt, typename Adapt>
  91. struct adaptor_cursor;
  92. template<typename BaseSent, typename Adapt>
  93. struct base_adaptor_sentinel;
  94. struct adaptor_base
  95. {
  96. adaptor_base() = default;
  97. adaptor_base(adaptor_base &&) = default;
  98. adaptor_base(adaptor_base const &) = default;
  99. adaptor_base & operator=(adaptor_base &&) = default;
  100. adaptor_base & operator=(adaptor_base const &) = default;
  101. adaptor_base(detail::ignore_t, detail::ignore_t = {}, detail::ignore_t = {})
  102. {}
  103. // clang-format off
  104. template<typename Rng>
  105. static constexpr auto CPP_auto_fun(begin)(Rng &rng)
  106. (
  107. return ranges::begin(rng.base())
  108. )
  109. template<typename Rng>
  110. static constexpr auto CPP_auto_fun(end)(Rng &rng)
  111. (
  112. return ranges::end(rng.base())
  113. )
  114. // clang-format on
  115. template(typename I)(
  116. requires equality_comparable<I>)
  117. static bool equal(I const & it0, I const & it1)
  118. {
  119. return it0 == it1;
  120. }
  121. template(typename I)(
  122. requires input_or_output_iterator<I>)
  123. static iter_reference_t<I> read(I const & it,
  124. detail::adaptor_base_current_mem_fn = {})
  125. noexcept(noexcept(iter_reference_t<I>(*it)))
  126. {
  127. return *it;
  128. }
  129. template(typename I)(
  130. requires input_or_output_iterator<I>)
  131. static void next(I & it)
  132. {
  133. ++it;
  134. }
  135. template(typename I)(
  136. requires bidirectional_iterator<I>)
  137. static void prev(I & it)
  138. {
  139. --it;
  140. }
  141. template(typename I)(
  142. requires random_access_iterator<I>)
  143. static void advance(I & it, iter_difference_t<I> n)
  144. {
  145. it += n;
  146. }
  147. template(typename I)(
  148. requires sized_sentinel_for<I, I>)
  149. static iter_difference_t<I> distance_to(I const & it0, I const & it1)
  150. {
  151. return it1 - it0;
  152. }
  153. template(typename I, typename S)(
  154. requires sentinel_for<S, I>)
  155. static constexpr bool empty(I const & it, S const & last)
  156. {
  157. return it == last;
  158. }
  159. };
  160. // Build a sentinel out of a sentinel into the adapted range, and an
  161. // adaptor that customizes behavior.
  162. template<typename BaseSent, typename Adapt>
  163. struct base_adaptor_sentinel
  164. {
  165. private:
  166. template<typename, typename>
  167. friend struct adaptor_cursor;
  168. RANGES_NO_UNIQUE_ADDRESS compressed_pair<BaseSent, Adapt> data_;
  169. public:
  170. base_adaptor_sentinel() = default;
  171. base_adaptor_sentinel(BaseSent sent, Adapt adapt)
  172. : data_{std::move(sent), std::move(adapt)}
  173. {}
  174. // All sentinels into adapted ranges have a base() member for fetching
  175. // the underlying sentinel.
  176. BaseSent base() const
  177. {
  178. return data_.first();
  179. }
  180. protected:
  181. // Adaptor accessor
  182. Adapt & get()
  183. {
  184. return data_.second();
  185. }
  186. Adapt const & get() const
  187. {
  188. return data_.second();
  189. }
  190. };
  191. /// \cond
  192. namespace detail
  193. {
  194. template<typename BaseSent, typename Adapt>
  195. meta::id<base_adaptor_sentinel<BaseSent, Adapt>> base_adaptor_sentinel_2_(long);
  196. template<typename BaseSent, typename Adapt>
  197. meta::id<typename Adapt::template mixin<base_adaptor_sentinel<BaseSent, Adapt>>>
  198. base_adaptor_sentinel_2_(int);
  199. template<typename BaseSent, typename Adapt>
  200. struct base_adaptor_sentinel_
  201. : decltype(base_adaptor_sentinel_2_<BaseSent, Adapt>(42))
  202. {};
  203. template<typename BaseSent, typename Adapt>
  204. using adaptor_sentinel_ = meta::_t<base_adaptor_sentinel_<BaseSent, Adapt>>;
  205. } // namespace detail
  206. /// \endcond
  207. template<typename BaseSent, typename Adapt>
  208. struct adaptor_sentinel : detail::adaptor_sentinel_<BaseSent, Adapt>
  209. {
  210. using detail::adaptor_sentinel_<BaseSent, Adapt>::adaptor_sentinel_;
  211. };
  212. // Build a cursor out of an iterator into the adapted range, and an
  213. // adaptor that customizes behavior.
  214. template<typename BaseIter, typename Adapt>
  215. struct adaptor_cursor : private detail::adaptor_value_type_<BaseIter, Adapt>
  216. {
  217. private:
  218. friend range_access;
  219. template<typename, typename>
  220. friend struct adaptor_cursor;
  221. using base_t = detail::adaptor_value_type_<BaseIter, Adapt>;
  222. using single_pass = meta::bool_<(bool)range_access::single_pass_t<Adapt>() ||
  223. (bool)single_pass_iterator_<BaseIter>>;
  224. struct basic_adaptor_mixin : basic_mixin<adaptor_cursor>
  225. {
  226. basic_adaptor_mixin() = default;
  227. #ifndef _MSC_VER
  228. using basic_mixin<adaptor_cursor>::basic_mixin;
  229. #else
  230. constexpr explicit basic_adaptor_mixin(adaptor_cursor && cur)
  231. : basic_mixin<adaptor_cursor>(static_cast<adaptor_cursor &&>(cur))
  232. {}
  233. constexpr explicit basic_adaptor_mixin(adaptor_cursor const & cur)
  234. : basic_mixin<adaptor_cursor>(cur)
  235. {}
  236. #endif
  237. // All iterators into adapted ranges have a base() member for fetching
  238. // the underlying iterator.
  239. BaseIter base() const
  240. {
  241. return basic_adaptor_mixin::basic_mixin::get().data_.first();
  242. }
  243. protected:
  244. // Adaptor accessor
  245. Adapt & get()
  246. {
  247. return basic_adaptor_mixin::basic_mixin::get().data_.second();
  248. }
  249. const Adapt & get() const
  250. {
  251. return basic_adaptor_mixin::basic_mixin::get().data_.second();
  252. }
  253. };
  254. template<typename Adapt_>
  255. static meta::id<basic_adaptor_mixin> basic_adaptor_mixin_2_(long);
  256. template<typename Adapt_>
  257. static meta::id<typename Adapt_::template mixin<basic_adaptor_mixin>>
  258. basic_adaptor_mixin_2_(int);
  259. using mixin = meta::_t<decltype(basic_adaptor_mixin_2_<Adapt>(42))>;
  260. template<typename A = Adapt, typename R = decltype(std::declval<A const &>().read(
  261. std::declval<BaseIter const &>()))>
  262. R read() const noexcept(
  263. noexcept(std::declval<A const &>().read(std::declval<BaseIter const &>())))
  264. {
  265. using V = range_access::cursor_value_t<adaptor_cursor>;
  266. static_assert(common_reference_with<R &&, V &>,
  267. "In your adaptor, you've specified a value type that does not "
  268. "share a common reference type with the return type of read.");
  269. return this->data_.second().read(this->data_.first());
  270. }
  271. template<typename A = Adapt, typename = decltype(std::declval<A &>().next(
  272. std::declval<BaseIter &>()))>
  273. void next()
  274. {
  275. this->data_.second().next(this->data_.first());
  276. }
  277. template<typename A = Adapt,
  278. typename = decltype(std::declval<A const &>().equal(
  279. std::declval<BaseIter const &>(), std::declval<BaseIter const &>(),
  280. std::declval<A const &>()))>
  281. bool equal_(adaptor_cursor const & that, int) const
  282. {
  283. return this->data_.second().equal(
  284. this->data_.first(), that.data_.first(), that.data_.second());
  285. }
  286. template<typename A = Adapt,
  287. typename = decltype(std::declval<A const &>().equal(
  288. std::declval<BaseIter const &>(), std::declval<BaseIter const &>()))>
  289. bool equal_(adaptor_cursor const & that, long) const
  290. {
  291. return this->data_.second().equal(this->data_.first(), that.data_.first());
  292. }
  293. template<typename C = adaptor_cursor>
  294. auto equal(adaptor_cursor const & that) const
  295. -> decltype(std::declval<C const &>().equal_(that, 42))
  296. {
  297. return this->equal_(that, 42);
  298. }
  299. template<typename S, typename A,
  300. typename = decltype(std::declval<A const &>().empty(
  301. std::declval<BaseIter const &>(), std::declval<Adapt const &>(),
  302. std::declval<S const &>()))>
  303. constexpr bool equal_(adaptor_sentinel<S, A> const & that, int) const
  304. {
  305. return that.data_.second().empty(
  306. this->data_.first(), this->data_.second(), that.data_.first());
  307. }
  308. template<typename S, typename A,
  309. typename = decltype(std::declval<A const &>().empty(
  310. std::declval<BaseIter const &>(), std::declval<S const &>()))>
  311. constexpr bool equal_(adaptor_sentinel<S, A> const & that, long) const
  312. {
  313. return that.data_.second().empty(this->data_.first(), that.data_.first());
  314. }
  315. template<typename S, typename A>
  316. constexpr auto equal(adaptor_sentinel<S, A> const & that) const
  317. -> decltype(std::declval<adaptor_cursor const &>().equal_(that, 42))
  318. {
  319. return this->equal_(that, 42);
  320. }
  321. template<typename A = Adapt, typename = decltype(std::declval<A &>().prev(
  322. std::declval<BaseIter &>()))>
  323. void prev()
  324. {
  325. this->data_.second().prev(this->data_.first());
  326. }
  327. template<typename A = Adapt, typename = decltype(std::declval<A &>().advance(
  328. std::declval<BaseIter &>(), 0))>
  329. void advance(iter_difference_t<BaseIter> n)
  330. {
  331. this->data_.second().advance(this->data_.first(), n);
  332. }
  333. template<typename A = Adapt,
  334. typename R = decltype(std::declval<A const &>().distance_to(
  335. std::declval<BaseIter const &>(), std::declval<BaseIter const &>(),
  336. std::declval<A const &>()))>
  337. R distance_to_(adaptor_cursor const & that, int) const
  338. {
  339. return this->data_.second().distance_to(
  340. this->data_.first(), that.data_.first(), that.data_.second());
  341. }
  342. template<typename A = Adapt,
  343. typename R = decltype(std::declval<A const &>().distance_to(
  344. std::declval<BaseIter const &>(), std::declval<BaseIter const &>()))>
  345. R distance_to_(adaptor_cursor const & that, long) const
  346. {
  347. return this->data_.second().distance_to(this->data_.first(),
  348. that.data_.first());
  349. }
  350. template<typename C = adaptor_cursor>
  351. auto distance_to(adaptor_cursor const & that) const
  352. -> decltype(std::declval<C const &>().distance_to_(that, 42))
  353. {
  354. return this->distance_to_(that, 42);
  355. }
  356. // If the adaptor has an iter_move function, use it.
  357. template<typename A = Adapt,
  358. typename X = decltype(std::declval<A const &>().iter_move(
  359. std::declval<BaseIter const &>()))>
  360. X iter_move_(int) const noexcept(noexcept(
  361. std::declval<A const &>().iter_move(std::declval<BaseIter const &>())))
  362. {
  363. using V = range_access::cursor_value_t<adaptor_cursor>;
  364. using R = decltype(this->data_.second().read(this->data_.first()));
  365. static_assert(
  366. common_reference_with<X &&, V const &>,
  367. "In your adaptor, the result of your iter_move member function does "
  368. "not share a common reference with your value type.");
  369. static_assert(
  370. common_reference_with<R &&, X &&>,
  371. "In your adaptor, the result of your iter_move member function does "
  372. "not share a common reference with the result of your read member "
  373. "function.");
  374. return this->data_.second().iter_move(this->data_.first());
  375. }
  376. // If there is no iter_move member and the adaptor has not overridden the read
  377. // member function, then dispatch to the base iterator's iter_move function.
  378. template<typename A = Adapt,
  379. typename R = decltype(std::declval<A const &>().read(
  380. std::declval<BaseIter const &>(),
  381. detail::adaptor_base_current_mem_fn{})),
  382. typename X = iter_rvalue_reference_t<BaseIter>>
  383. X iter_move_(long) const
  384. noexcept(noexcept(X(ranges::iter_move(std::declval<BaseIter const &>()))))
  385. {
  386. return ranges::iter_move(this->data_.first());
  387. }
  388. // If the adaptor does not have an iter_move function but overrides the read
  389. // member function, apply std::move to the result of calling read.
  390. template<typename A = Adapt,
  391. typename R = decltype(
  392. std::declval<A const &>().read(std::declval<BaseIter const &>())),
  393. typename X = aux::move_t<R>>
  394. X iter_move_(detail::ignore_t) const noexcept(noexcept(X(static_cast<X &&>(
  395. std::declval<A const &>().read(std::declval<BaseIter const &>())))))
  396. {
  397. using V = range_access::cursor_value_t<adaptor_cursor>;
  398. static_assert(
  399. common_reference_with<X &&, V const &>,
  400. "In your adaptor, you've specified a value type that does not share a "
  401. "common "
  402. "reference type with the result of moving the result of the read member "
  403. "function. Consider defining an iter_move function in your adaptor.");
  404. return static_cast<X &&>(this->data_.second().read(this->data_.first()));
  405. }
  406. // Gives users a way to override the default iter_move function in their adaptors.
  407. auto move() const
  408. noexcept(noexcept(std::declval<const adaptor_cursor &>().iter_move_(42)))
  409. -> decltype(std::declval<const adaptor_cursor &>().iter_move_(42))
  410. {
  411. return iter_move_(42);
  412. }
  413. public:
  414. adaptor_cursor() = default;
  415. adaptor_cursor(BaseIter iter, Adapt adapt)
  416. : base_t{{std::move(iter), std::move(adapt)}}
  417. {}
  418. template(typename OtherIter, typename OtherAdapt)(
  419. requires //
  420. (!same_as<adaptor_cursor<OtherIter, OtherAdapt>, adaptor_cursor>) AND
  421. convertible_to<OtherIter, BaseIter> AND
  422. convertible_to<OtherAdapt, Adapt>)
  423. adaptor_cursor(adaptor_cursor<OtherIter, OtherAdapt> that)
  424. : base_t{{std::move(that.data_.first()), std::move(that.data_.second())}}
  425. {}
  426. };
  427. template<typename D>
  428. using adaptor_cursor_t =
  429. adaptor_cursor<detail::adapted_iterator_t<D>, detail::begin_adaptor_t<D>>;
  430. template<typename D>
  431. using adaptor_sentinel_t = meta::if_c<
  432. same_as<detail::adapted_iterator_t<D>, detail::adapted_sentinel_t<D>> &&
  433. same_as<detail::begin_adaptor_t<D>, detail::end_adaptor_t<D>>,
  434. adaptor_cursor_t<D>,
  435. adaptor_sentinel<detail::adapted_sentinel_t<D>, detail::end_adaptor_t<D>>>;
  436. template<typename Derived, typename BaseRng,
  437. cardinality Cardinality /*= range_cardinality<BaseRng>::value*/>
  438. struct view_adaptor : view_facade<Derived, Cardinality>
  439. {
  440. private:
  441. friend Derived;
  442. friend range_access;
  443. friend adaptor_base;
  444. CPP_assert(viewable_range<BaseRng>);
  445. using base_range_t = views::all_t<BaseRng>;
  446. using view_facade<Derived, Cardinality>::derived;
  447. base_range_t rng_;
  448. constexpr adaptor_base begin_adaptor() const noexcept
  449. {
  450. return {};
  451. }
  452. constexpr adaptor_base end_adaptor() const noexcept
  453. {
  454. return {};
  455. }
  456. template<typename D>
  457. static constexpr adaptor_cursor_t<D> begin_cursor_(D & d) noexcept(noexcept(
  458. adaptor_cursor_t<D>{std::declval<detail::begin_adaptor_t<D> &>().begin(d),
  459. range_access::begin_adaptor(d)}))
  460. {
  461. auto adapt = range_access::begin_adaptor(d);
  462. auto pos = adapt.begin(d);
  463. return {std::move(pos), std::move(adapt)};
  464. }
  465. template(typename D = Derived)(
  466. requires same_as<D, Derived>)
  467. constexpr auto begin_cursor() noexcept(
  468. noexcept(view_adaptor::begin_cursor_(std::declval<D &>())))
  469. -> decltype(view_adaptor::begin_cursor_(std::declval<D &>()))
  470. {
  471. return view_adaptor::begin_cursor_(derived());
  472. }
  473. template(typename D = Derived)(
  474. requires same_as<D, Derived> AND range<base_range_t const>)
  475. constexpr auto begin_cursor() const
  476. noexcept(noexcept(view_adaptor::begin_cursor_(std::declval<D const &>())))
  477. -> decltype(view_adaptor::begin_cursor_(std::declval<D const &>()))
  478. {
  479. return view_adaptor::begin_cursor_(derived());
  480. }
  481. template<typename D>
  482. static constexpr adaptor_sentinel_t<D> end_cursor_(D & d) noexcept(noexcept(
  483. adaptor_sentinel_t<D>{std::declval<detail::end_adaptor_t<D> &>().end(d),
  484. range_access::end_adaptor(d)}))
  485. {
  486. auto adapt = range_access::end_adaptor(d);
  487. auto pos = adapt.end(d);
  488. return {std::move(pos), std::move(adapt)};
  489. }
  490. template(typename D = Derived)(
  491. requires same_as<D, Derived>)
  492. constexpr auto end_cursor() noexcept(
  493. noexcept(view_adaptor::end_cursor_(std::declval<D &>())))
  494. -> decltype(view_adaptor::end_cursor_(std::declval<D &>()))
  495. {
  496. return view_adaptor::end_cursor_(derived());
  497. }
  498. template(typename D = Derived)(
  499. requires same_as<D, Derived> AND range<base_range_t const>)
  500. constexpr auto end_cursor() const noexcept(
  501. noexcept(view_adaptor::end_cursor_(std::declval<D const &>())))
  502. -> decltype(view_adaptor::end_cursor_(std::declval<D const &>()))
  503. {
  504. return view_adaptor::end_cursor_(derived());
  505. }
  506. protected:
  507. ~view_adaptor() = default;
  508. public:
  509. view_adaptor() = default;
  510. view_adaptor(view_adaptor &&) = default;
  511. view_adaptor(view_adaptor const &) = default;
  512. view_adaptor & operator=(view_adaptor &&) = default;
  513. view_adaptor & operator=(view_adaptor const &) = default;
  514. constexpr explicit view_adaptor(BaseRng && rng)
  515. : rng_(views::all(static_cast<BaseRng &&>(rng)))
  516. {}
  517. constexpr base_range_t & base() noexcept
  518. {
  519. return rng_;
  520. }
  521. /// \overload
  522. constexpr base_range_t const & base() const noexcept
  523. {
  524. return rng_;
  525. }
  526. };
  527. /// @}
  528. } // namespace ranges
  529. #include <range/v3/detail/epilogue.hpp>
  530. #endif