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.

563 satır
22KB

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