operations.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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_ITERATOR_OPERATIONS_HPP
  14. #define RANGES_V3_ITERATOR_OPERATIONS_HPP
  15. #include <type_traits>
  16. #include <utility>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/iterator/concepts.hpp>
  19. #include <range/v3/iterator/traits.hpp>
  20. #include <range/v3/range/concepts.hpp>
  21. #include <range/v3/detail/prologue.hpp>
  22. namespace ranges
  23. {
  24. /// \addtogroup group-iterator
  25. /// @{
  26. /// \cond
  27. template<typename I>
  28. // requires input_or_output_iterator<I>
  29. struct counted_iterator;
  30. /// \endcond
  31. struct advance_fn
  32. {
  33. #if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
  34. template(typename I)(
  35. requires input_or_output_iterator<I>)
  36. constexpr void operator()(I & i, iter_difference_t<I> n) const
  37. // [[expects: n >= 0 || bidirectional_iterator<I>]]
  38. {
  39. if constexpr(random_access_iterator<I>)
  40. {
  41. i += n;
  42. }
  43. else
  44. {
  45. if constexpr(bidirectional_iterator<I>)
  46. for(; 0 > n; ++n)
  47. --i;
  48. RANGES_EXPECT(0 <= n);
  49. for(; 0 < n; --n)
  50. ++i;
  51. }
  52. }
  53. template(typename I, typename S)(
  54. requires sentinel_for<S, I>)
  55. constexpr void operator()(I & i, S bound) const
  56. // [[expects axiom: reachable(i, bound)]]
  57. {
  58. if constexpr(assignable_from<I &, S>)
  59. {
  60. i = std::move(bound);
  61. }
  62. else if constexpr(sized_sentinel_for<S, I>)
  63. {
  64. iter_difference_t<I> d = bound - i;
  65. RANGES_EXPECT(0 <= d);
  66. (*this)(i, d);
  67. }
  68. else
  69. while(i != bound)
  70. ++i;
  71. }
  72. template(typename I, typename S)(
  73. requires sentinel_for<S, I>)
  74. constexpr iter_difference_t<I> //
  75. operator()(I & i, iter_difference_t<I> n, S bound) const
  76. // [[expects axiom: 0 == n ||
  77. // (0 < n && reachable(i, bound)) ||
  78. // (0 > n && same_as<I, S> && bidirectional_iterator<I> && reachable(bound,
  79. // i))]]
  80. {
  81. if constexpr(sized_sentinel_for<S, I>)
  82. {
  83. if(0 == n)
  84. return 0;
  85. const auto d = bound - i;
  86. if constexpr(bidirectional_iterator<I> && same_as<I, S>)
  87. {
  88. RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
  89. if(0 <= n ? d <= n : d >= n)
  90. {
  91. i = std::move(bound);
  92. return n - d;
  93. }
  94. }
  95. else
  96. {
  97. RANGES_EXPECT(0 <= n && 0 <= d);
  98. if(d <= n)
  99. {
  100. (*this)(i, std::move(bound));
  101. return n - d;
  102. }
  103. }
  104. (*this)(i, n);
  105. return 0;
  106. }
  107. else
  108. {
  109. if constexpr(bidirectional_iterator<I> && same_as<I, S>)
  110. {
  111. if(0 > n)
  112. {
  113. do
  114. {
  115. --i;
  116. ++n;
  117. } while(0 != n && i != bound);
  118. return n;
  119. }
  120. }
  121. RANGES_EXPECT(0 <= n);
  122. while(0 != n && i != bound)
  123. {
  124. ++i;
  125. --n;
  126. }
  127. return n;
  128. }
  129. }
  130. #else
  131. private:
  132. template<typename I>
  133. static constexpr void n_(I & i, iter_difference_t<I> n, std::input_iterator_tag);
  134. template<typename I>
  135. static constexpr void n_(I & i, iter_difference_t<I> n,
  136. std::bidirectional_iterator_tag);
  137. template<typename I>
  138. static constexpr void n_(I & i, iter_difference_t<I> n,
  139. std::random_access_iterator_tag);
  140. template<typename I, typename S>
  141. static constexpr void to_impl_(I & i, S s, sentinel_tag);
  142. template<typename I, typename S>
  143. static constexpr void to_impl_(I & i, S s, sized_sentinel_tag);
  144. template<typename I, typename S>
  145. static constexpr void to_(I & i, S s, std::true_type); // assignable
  146. template<typename I, typename S>
  147. static constexpr void to_(I & i, S s, std::false_type); // !assignable
  148. template<typename I, typename S>
  149. static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
  150. S bound, sentinel_tag,
  151. std::input_iterator_tag);
  152. template<typename I>
  153. static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
  154. I bound, sentinel_tag,
  155. std::bidirectional_iterator_tag);
  156. template<typename I, typename S, typename Concept>
  157. static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
  158. S bound, sized_sentinel_tag,
  159. Concept);
  160. public:
  161. // Advance a certain number of steps:
  162. template(typename I)(
  163. requires input_or_output_iterator<I>)
  164. constexpr void operator()(I & i, iter_difference_t<I> n) const
  165. {
  166. advance_fn::n_(i, n, iterator_tag_of<I>{});
  167. }
  168. // Advance to a certain position:
  169. template(typename I, typename S)(
  170. requires sentinel_for<S, I>)
  171. constexpr void operator()(I & i, S s) const
  172. {
  173. advance_fn::to_(
  174. i, static_cast<S &&>(s), meta::bool_<assignable_from<I &, S>>());
  175. }
  176. // Advance a certain number of times, with a bound:
  177. template(typename I, typename S)(
  178. requires sentinel_for<S, I>)
  179. constexpr iter_difference_t<I> //
  180. operator()(I & it, iter_difference_t<I> n, S bound) const
  181. {
  182. return advance_fn::bounded_(it,
  183. n,
  184. static_cast<S &&>(bound),
  185. sentinel_tag_of<S, I>(),
  186. iterator_tag_of<I>());
  187. }
  188. #endif
  189. template(typename I)(
  190. requires input_or_output_iterator<I>)
  191. constexpr void operator()(counted_iterator<I> & i, iter_difference_t<I> n) const;
  192. };
  193. /// \sa `advance_fn`
  194. RANGES_INLINE_VARIABLE(advance_fn, advance)
  195. #if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
  196. template<typename I>
  197. constexpr void advance_fn::n_(I & i, iter_difference_t<I> n, std::input_iterator_tag)
  198. {
  199. RANGES_EXPECT(n >= 0);
  200. for(; n > 0; --n)
  201. ++i;
  202. }
  203. template<typename I>
  204. constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
  205. std::bidirectional_iterator_tag)
  206. {
  207. if(n > 0)
  208. for(; n > 0; --n)
  209. ++i;
  210. else
  211. for(; n < 0; ++n)
  212. --i;
  213. }
  214. template<typename I>
  215. constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
  216. std::random_access_iterator_tag)
  217. {
  218. i += n;
  219. }
  220. template<typename I, typename S>
  221. constexpr void advance_fn::to_impl_(I & i, S s, sentinel_tag)
  222. {
  223. while(i != s)
  224. ++i;
  225. }
  226. template<typename I, typename S>
  227. constexpr void advance_fn::to_impl_(I & i, S s, sized_sentinel_tag)
  228. {
  229. iter_difference_t<I> d = s - i;
  230. RANGES_EXPECT(0 <= d);
  231. advance(i, d);
  232. }
  233. // Advance to a certain position:
  234. template<typename I, typename S>
  235. constexpr void advance_fn::to_(I & i, S s, std::true_type)
  236. {
  237. i = static_cast<S &&>(s);
  238. }
  239. template<typename I, typename S>
  240. constexpr void advance_fn::to_(I & i, S s, std::false_type)
  241. {
  242. advance_fn::to_impl_(i, static_cast<S &&>(s), sentinel_tag_of<S, I>());
  243. }
  244. template<typename I, typename S>
  245. constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
  246. S bound, sentinel_tag,
  247. std::input_iterator_tag)
  248. {
  249. RANGES_EXPECT(0 <= n);
  250. for(; 0 != n && it != bound; --n)
  251. ++it;
  252. return n;
  253. }
  254. template<typename I>
  255. constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
  256. I bound, sentinel_tag,
  257. std::bidirectional_iterator_tag)
  258. {
  259. if(0 <= n)
  260. for(; 0 != n && it != bound; --n)
  261. ++it;
  262. else
  263. for(; 0 != n && it != bound; ++n)
  264. --it;
  265. return n;
  266. }
  267. template<typename I, typename S, typename Concept>
  268. constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
  269. S bound, sized_sentinel_tag,
  270. Concept)
  271. {
  272. RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
  273. if(n == 0)
  274. return 0;
  275. iter_difference_t<I> d = bound - it;
  276. RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
  277. if(0 <= n ? n >= d : n <= d)
  278. {
  279. advance(it, static_cast<S &&>(bound));
  280. return n - d;
  281. }
  282. advance(it, n);
  283. return 0;
  284. }
  285. #endif
  286. struct next_fn
  287. {
  288. template(typename I)(
  289. requires input_or_output_iterator<I>)
  290. constexpr I operator()(I it) const
  291. {
  292. return ++it;
  293. }
  294. template(typename I)(
  295. requires input_or_output_iterator<I>)
  296. constexpr I operator()(I it, iter_difference_t<I> n) const
  297. {
  298. advance(it, n);
  299. return it;
  300. }
  301. template(typename I, typename S)(
  302. requires sentinel_for<S, I>)
  303. constexpr I operator()(I it, S s) const
  304. {
  305. advance(it, static_cast<S &&>(s));
  306. return it;
  307. }
  308. template(typename I, typename S)(
  309. requires sentinel_for<S, I>)
  310. constexpr I operator()(I it, iter_difference_t<I> n, S bound) const
  311. {
  312. advance(it, n, static_cast<S &&>(bound));
  313. return it;
  314. }
  315. };
  316. /// \sa `next_fn`
  317. RANGES_INLINE_VARIABLE(next_fn, next)
  318. struct prev_fn
  319. {
  320. template(typename I)(
  321. requires bidirectional_iterator<I>)
  322. constexpr I operator()(I it) const
  323. {
  324. return --it;
  325. }
  326. template(typename I)(
  327. requires bidirectional_iterator<I>)
  328. constexpr I operator()(I it, iter_difference_t<I> n) const
  329. {
  330. advance(it, -n);
  331. return it;
  332. }
  333. template(typename I)(
  334. requires bidirectional_iterator<I>)
  335. constexpr I operator()(I it, iter_difference_t<I> n, I bound) const
  336. {
  337. advance(it, -n, static_cast<I &&>(bound));
  338. return it;
  339. }
  340. };
  341. /// \sa `prev_fn`
  342. RANGES_INLINE_VARIABLE(prev_fn, prev)
  343. struct iter_enumerate_fn
  344. {
  345. private:
  346. template(typename I, typename S)(
  347. requires (!sized_sentinel_for<I, I>)) //
  348. static constexpr std::pair<iter_difference_t<I>, I> //
  349. impl_i(I first, S last, sentinel_tag)
  350. {
  351. iter_difference_t<I> d = 0;
  352. for(; first != last; ++first)
  353. ++d;
  354. return {d, first};
  355. }
  356. template(typename I, typename S)(
  357. requires sized_sentinel_for<I, I>)
  358. static constexpr std::pair<iter_difference_t<I>, I> //
  359. impl_i(I first, S end_, sentinel_tag)
  360. {
  361. I last = ranges::next(first, end_);
  362. auto n = static_cast<iter_difference_t<I>>(last - first);
  363. RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
  364. return {n, last};
  365. }
  366. template<typename I, typename S>
  367. static constexpr std::pair<iter_difference_t<I>, I> //
  368. impl_i(I first, S last, sized_sentinel_tag)
  369. {
  370. auto n = static_cast<iter_difference_t<I>>(last - first);
  371. RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
  372. return {n, ranges::next(first, last)};
  373. }
  374. public:
  375. template(typename I, typename S)(
  376. requires sentinel_for<S, I>)
  377. constexpr std::pair<iter_difference_t<I>, I> operator()(I first, S last) const
  378. {
  379. return iter_enumerate_fn::impl_i(static_cast<I &&>(first),
  380. static_cast<S &&>(last),
  381. sentinel_tag_of<S, I>());
  382. }
  383. };
  384. /// \sa `iter_enumerate_fn`
  385. RANGES_INLINE_VARIABLE(iter_enumerate_fn, iter_enumerate)
  386. struct iter_distance_fn
  387. {
  388. private:
  389. template<typename I, typename S>
  390. static constexpr iter_difference_t<I> impl_i(I first, S last, sentinel_tag)
  391. {
  392. return iter_enumerate(static_cast<I &&>(first), static_cast<S &&>(last))
  393. .first;
  394. }
  395. template<typename I, typename S>
  396. static constexpr iter_difference_t<I> impl_i(I first, S last, sized_sentinel_tag)
  397. {
  398. auto n = static_cast<iter_difference_t<I>>(last - first);
  399. RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
  400. return n;
  401. }
  402. public:
  403. template(typename I, typename S)(
  404. requires input_or_output_iterator<I> AND sentinel_for<S, I>)
  405. constexpr iter_difference_t<I> operator()(I first, S last) const
  406. {
  407. return iter_distance_fn::impl_i(static_cast<I &&>(first),
  408. static_cast<S &&>(last),
  409. sentinel_tag_of<S, I>());
  410. }
  411. };
  412. /// \sa `iter_distance_fn`
  413. RANGES_INLINE_VARIABLE(iter_distance_fn, iter_distance)
  414. struct iter_distance_compare_fn
  415. {
  416. private:
  417. template<typename I, typename S>
  418. static constexpr int impl_i(I first, S last, iter_difference_t<I> n, sentinel_tag)
  419. {
  420. if(n < 0)
  421. return 1;
  422. for(; n > 0; --n, ++first)
  423. {
  424. if(first == last)
  425. return -1;
  426. }
  427. return first == last ? 0 : 1;
  428. }
  429. template<typename I, typename S>
  430. static constexpr int impl_i(I first, S last, iter_difference_t<I> n,
  431. sized_sentinel_tag)
  432. {
  433. iter_difference_t<I> dist = last - first;
  434. if(n < dist)
  435. return 1;
  436. if(dist < n)
  437. return -1;
  438. return 0;
  439. }
  440. public:
  441. template(typename I, typename S)(
  442. requires input_iterator<I> AND sentinel_for<S, I>)
  443. constexpr int operator()(I first, S last, iter_difference_t<I> n) const
  444. {
  445. return iter_distance_compare_fn::impl_i(static_cast<I &&>(first),
  446. static_cast<S &&>(last),
  447. n,
  448. sentinel_tag_of<S, I>());
  449. }
  450. };
  451. /// \sa `iter_distance_compare_fn`
  452. RANGES_INLINE_VARIABLE(iter_distance_compare_fn, iter_distance_compare)
  453. // Like distance(b,e), but guaranteed to be O(1)
  454. struct iter_size_fn
  455. {
  456. template(typename I, typename S)(
  457. requires sized_sentinel_for<S, I>)
  458. constexpr meta::_t<std::make_unsigned<iter_difference_t<I>>> //
  459. operator()(I const & first, S last) const
  460. {
  461. using size_type = meta::_t<std::make_unsigned<iter_difference_t<I>>>;
  462. iter_difference_t<I> n = last - first;
  463. RANGES_EXPECT(0 <= n);
  464. return static_cast<size_type>(n);
  465. }
  466. };
  467. /// \sa `iter_size_fn`
  468. RANGES_INLINE_VARIABLE(iter_size_fn, iter_size)
  469. /// \cond
  470. namespace adl_uncounted_recounted_detail
  471. {
  472. template<typename I>
  473. constexpr I uncounted(I i)
  474. {
  475. return i;
  476. }
  477. template<typename I>
  478. constexpr I recounted(I const &, I i, iter_difference_t<I>)
  479. {
  480. return i;
  481. }
  482. struct uncounted_fn
  483. {
  484. template<typename I>
  485. constexpr auto operator()(I i) const -> decltype(uncounted((I &&) i))
  486. {
  487. return uncounted((I &&) i);
  488. }
  489. };
  490. struct recounted_fn
  491. {
  492. template<typename I, typename J>
  493. constexpr auto operator()(I i, J j, iter_difference_t<J> n) const
  494. -> decltype(recounted((I &&) i, (J &&) j, n))
  495. {
  496. return recounted((I &&) i, (J &&) j, n);
  497. }
  498. };
  499. } // namespace adl_uncounted_recounted_detail
  500. /// \endcond
  501. RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::uncounted_fn, uncounted)
  502. RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::recounted_fn, recounted)
  503. struct enumerate_fn : iter_enumerate_fn
  504. {
  505. private:
  506. template<typename Rng>
  507. static constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> impl_r(
  508. Rng & rng, range_tag, range_tag)
  509. {
  510. return iter_enumerate(begin(rng), end(rng));
  511. }
  512. template<typename Rng>
  513. static constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> impl_r(
  514. Rng & rng, common_range_tag, sized_range_tag)
  515. {
  516. return {static_cast<range_difference_t<Rng>>(size(rng)), end(rng)};
  517. }
  518. public:
  519. using iter_enumerate_fn::operator();
  520. template(typename Rng)(
  521. requires range<Rng>)
  522. constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> operator()(Rng && rng) const
  523. {
  524. // Better not be trying to compute the distance of an infinite range:
  525. RANGES_EXPECT(!is_infinite<Rng>::value);
  526. return enumerate_fn::impl_r(
  527. rng, common_range_tag_of<Rng>(), sized_range_tag_of<Rng>());
  528. }
  529. };
  530. /// \sa `enumerate_fn`
  531. RANGES_INLINE_VARIABLE(enumerate_fn, enumerate)
  532. struct distance_fn : iter_distance_fn
  533. {
  534. private:
  535. template<typename Rng>
  536. static range_difference_t<Rng> impl_r(Rng & rng, range_tag)
  537. {
  538. return enumerate(rng).first;
  539. }
  540. template<typename Rng>
  541. static constexpr range_difference_t<Rng> impl_r(Rng & rng, sized_range_tag)
  542. {
  543. return static_cast<range_difference_t<Rng>>(size(rng));
  544. }
  545. public:
  546. using iter_distance_fn::operator();
  547. template(typename Rng)(
  548. requires range<Rng>)
  549. constexpr range_difference_t<Rng> operator()(Rng && rng) const
  550. {
  551. // Better not be trying to compute the distance of an infinite range:
  552. RANGES_EXPECT(!is_infinite<Rng>::value);
  553. return distance_fn::impl_r(rng, sized_range_tag_of<Rng>());
  554. }
  555. };
  556. /// \sa `distance_fn`
  557. RANGES_INLINE_VARIABLE(distance_fn, distance)
  558. // The interface of distance_compare is taken from Util.listLengthCmp in the GHC API.
  559. struct distance_compare_fn : iter_distance_compare_fn
  560. {
  561. private:
  562. template<typename Rng>
  563. static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n, range_tag)
  564. {
  565. // Infinite ranges are always compared to be larger than a finite number.
  566. return is_infinite<Rng>::value
  567. ? 1
  568. : iter_distance_compare(begin(rng), end(rng), n);
  569. }
  570. template<typename Rng>
  571. static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n, sized_range_tag)
  572. {
  573. auto dist = distance(rng); // O(1) since rng is a sized_range
  574. if(dist > n)
  575. return 1;
  576. else if(dist < n)
  577. return -1;
  578. else
  579. return 0;
  580. }
  581. public:
  582. using iter_distance_compare_fn::operator();
  583. template(typename Rng)(
  584. requires range<Rng>)
  585. constexpr int operator()(Rng && rng, range_difference_t<Rng> n) const
  586. {
  587. return distance_compare_fn::impl_r(rng, n, sized_range_tag_of<Rng>());
  588. }
  589. };
  590. /// \sa `distance_compare_fn`
  591. RANGES_INLINE_VARIABLE(distance_compare_fn, distance_compare)
  592. namespace cpp20
  593. {
  594. using ranges::advance;
  595. using ranges::distance;
  596. using ranges::next;
  597. using ranges::prev;
  598. } // namespace cpp20
  599. /// @}
  600. } // namespace ranges
  601. #include <range/v3/detail/epilogue.hpp>
  602. #endif // RANGES_V3_ITERATOR_OPERATIONS_HPP