interface.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  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_INTERFACE_HPP
  14. #define RANGES_V3_VIEW_INTERFACE_HPP
  15. #include <iosfwd>
  16. #include <meta/meta.hpp>
  17. #include <concepts/concepts.hpp>
  18. #include <range/v3/range_fwd.hpp>
  19. #include <range/v3/iterator/common_iterator.hpp>
  20. #include <range/v3/iterator/operations.hpp>
  21. #include <range/v3/range/access.hpp>
  22. #include <range/v3/range/concepts.hpp>
  23. #include <range/v3/range/primitives.hpp>
  24. #include <range/v3/range/traits.hpp>
  25. #include <range/v3/detail/prologue.hpp>
  26. #if defined(RANGES_WORKAROUND_GCC_91525)
  27. #define CPP_template_gcc_workaround CPP_template_sfinae
  28. #else
  29. #define CPP_template_gcc_workaround template
  30. #endif
  31. namespace ranges
  32. {
  33. /// \cond
  34. namespace detail
  35. {
  36. template<typename From, typename To = From>
  37. struct slice_bounds
  38. {
  39. From from;
  40. To to;
  41. template(typename F, typename T)(
  42. requires convertible_to<F, From> AND convertible_to<T, To>)
  43. constexpr slice_bounds(F f, T t)
  44. : from(static_cast<From>(f))
  45. , to(static_cast<To>(t))
  46. {}
  47. };
  48. template<typename Int>
  49. struct from_end_
  50. {
  51. Int dist_;
  52. constexpr explicit from_end_(Int dist)
  53. : dist_(dist)
  54. {}
  55. template(typename Other)(
  56. requires integer_like_<Other> AND explicitly_convertible_to<Other, Int>)
  57. constexpr operator from_end_<Other>() const
  58. {
  59. return from_end_<Other>{static_cast<Other>(dist_)};
  60. }
  61. };
  62. template<typename Rng>
  63. using from_end_of_t = from_end_<range_difference_t<Rng>>;
  64. // clang-format off
  65. /// \concept _can_empty_
  66. /// \brief The \c _can_empty_ concept
  67. template<typename Rng>
  68. CPP_requires(_can_empty_,
  69. requires(Rng & rng) //
  70. (
  71. ranges::empty(rng)
  72. ));
  73. /// \concept can_empty_
  74. /// \brief The \c can_empty_ concept
  75. template<typename Rng>
  76. CPP_concept can_empty_ = //
  77. CPP_requires_ref(detail::_can_empty_, Rng);
  78. // clang-format on
  79. template<cardinality C>
  80. RANGES_INLINE_VAR constexpr bool has_fixed_size_ = (C >= 0 || C == infinite);
  81. template<bool>
  82. struct dependent_
  83. {
  84. template<typename T>
  85. using invoke = T;
  86. };
  87. template<typename Stream, typename Rng>
  88. Stream & print_rng_(Stream & sout, Rng & rng)
  89. {
  90. sout << '[';
  91. auto it = ranges::begin(rng);
  92. auto const e = ranges::end(rng);
  93. if(it != e)
  94. {
  95. for(;;)
  96. {
  97. sout << *it;
  98. if(++it == e)
  99. break;
  100. sout << ',';
  101. }
  102. }
  103. sout << ']';
  104. return sout;
  105. }
  106. } // namespace detail
  107. /// \endcond
  108. /// \addtogroup group-views
  109. /// @{
  110. template<typename Derived, cardinality Cardinality /* = finite*/>
  111. struct view_interface : basic_view<Cardinality>
  112. {
  113. protected:
  114. template<bool B>
  115. using D = meta::invoke<detail::dependent_<B>, Derived>;
  116. constexpr Derived & derived() noexcept
  117. {
  118. CPP_assert(derived_from<Derived, view_interface>);
  119. return static_cast<Derived &>(*this);
  120. }
  121. /// \overload
  122. constexpr Derived const & derived() const noexcept
  123. {
  124. CPP_assert(derived_from<Derived, view_interface>);
  125. return static_cast<Derived const &>(*this);
  126. }
  127. public:
  128. view_interface() = default;
  129. view_interface(view_interface &&) = default;
  130. view_interface(view_interface const &) = default;
  131. view_interface & operator=(view_interface &&) = default;
  132. view_interface & operator=(view_interface const &) = default;
  133. /// \brief Test whether a range can be empty:
  134. CPP_member
  135. constexpr auto empty() const noexcept //
  136. -> CPP_ret(bool)(
  137. requires (detail::has_fixed_size_<Cardinality>))
  138. {
  139. return Cardinality == 0;
  140. }
  141. /// \overload
  142. template(bool True = true)(
  143. requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
  144. (!forward_range<D<True>>) AND sized_range<D<True>>)
  145. constexpr bool empty() //
  146. noexcept(noexcept(bool(ranges::size(std::declval<D<True> &>()) == 0)))
  147. {
  148. return ranges::size(derived()) == 0;
  149. }
  150. /// \overload
  151. template(bool True = true)(
  152. requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
  153. (!forward_range<D<True> const>) AND sized_range<D<True> const>)
  154. constexpr bool empty() const //
  155. noexcept(noexcept(bool(ranges::size(std::declval<D<True> const &>()) == 0)))
  156. {
  157. return ranges::size(derived()) == 0;
  158. }
  159. /// \overload
  160. template(bool True = true)(
  161. requires True AND (!detail::has_fixed_size_<Cardinality>) AND
  162. forward_range<D<True>>)
  163. constexpr bool empty() noexcept(
  164. noexcept(bool(ranges::begin(std::declval<D<True> &>()) ==
  165. ranges::end(std::declval<D<True> &>()))))
  166. {
  167. return bool(ranges::begin(derived()) == ranges::end(derived()));
  168. }
  169. /// \overload
  170. template(bool True = true)(
  171. requires True AND (!detail::has_fixed_size_<Cardinality>) AND
  172. forward_range<D<True> const>)
  173. constexpr bool empty() const
  174. noexcept(noexcept(bool(ranges::begin(std::declval<D<True> const &>()) ==
  175. ranges::end(std::declval<D<True> const &>()))))
  176. {
  177. return bool(ranges::begin(derived()) == ranges::end(derived()));
  178. }
  179. CPP_template_gcc_workaround(bool True = true)(
  180. requires True && detail::can_empty_<D<True>>) // clang-format off
  181. constexpr explicit operator bool()
  182. noexcept(noexcept(ranges::empty(std::declval<D<True> &>())))
  183. {
  184. return !ranges::empty(derived());
  185. }
  186. // clang-format on
  187. /// \overload
  188. CPP_template_gcc_workaround(bool True = true)(
  189. requires True && detail::can_empty_<D<True> const>) // clang-format off
  190. constexpr explicit operator bool() const
  191. noexcept(noexcept(ranges::empty(std::declval<D<True> const &>())))
  192. {
  193. return !ranges::empty(derived());
  194. }
  195. // clang-format on
  196. /// If the size of the range is known at compile-time and finite,
  197. /// return it.
  198. template(bool True = true, int = 42)(
  199. requires True AND (Cardinality >= 0)) //
  200. static constexpr std::size_t size() noexcept
  201. {
  202. return static_cast<std::size_t>(Cardinality);
  203. }
  204. /// If `sized_sentinel_for<sentinel_t<Derived>, iterator_t<Derived>>` is
  205. /// satisfied, and if `Derived` is a `forward_range`, then return
  206. /// `end - begin` cast to an unsigned integer.
  207. template(bool True = true)(
  208. requires True AND (Cardinality < 0) AND
  209. sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>> AND
  210. forward_range<D<True>>)
  211. constexpr detail::iter_size_t<iterator_t<D<True>>> size()
  212. {
  213. using size_type = detail::iter_size_t<iterator_t<D<True>>>;
  214. return static_cast<size_type>(derived().end() - derived().begin());
  215. }
  216. /// \overload
  217. template(bool True = true)(
  218. requires True AND (Cardinality < 0) AND
  219. sized_sentinel_for<sentinel_t<D<True> const>,
  220. iterator_t<D<True> const>> AND
  221. forward_range<D<True> const>)
  222. constexpr detail::iter_size_t<iterator_t<D<True>>> size() const //
  223. {
  224. using size_type = detail::iter_size_t<iterator_t<D<True>>>;
  225. return static_cast<size_type>(derived().end() - derived().begin());
  226. }
  227. /// Access the first element in a range:
  228. template(bool True = true)(
  229. requires True AND forward_range<D<True>>)
  230. constexpr range_reference_t<D<True>> front()
  231. {
  232. return *derived().begin();
  233. }
  234. /// \overload
  235. template(bool True = true)(
  236. requires True AND forward_range<D<True> const>)
  237. constexpr range_reference_t<D<True> const> front() const
  238. {
  239. return *derived().begin();
  240. }
  241. /// Access the last element in a range:
  242. template(bool True = true)(
  243. requires True AND common_range<D<True>> AND bidirectional_range<D<True>>)
  244. constexpr range_reference_t<D<True>> back()
  245. {
  246. return *prev(derived().end());
  247. }
  248. /// \overload
  249. template(bool True = true)(
  250. requires True AND common_range<D<True> const> AND
  251. bidirectional_range<D<True> const>)
  252. constexpr range_reference_t<D<True> const> back() const
  253. {
  254. return *prev(derived().end());
  255. }
  256. /// Simple indexing:
  257. template(bool True = true)(
  258. requires True AND random_access_range<D<True>>)
  259. constexpr range_reference_t<D<True>> operator[](range_difference_t<D<True>> n)
  260. {
  261. return derived().begin()[n];
  262. }
  263. /// \overload
  264. template(bool True = true)(
  265. requires True AND random_access_range<D<True> const>)
  266. constexpr range_reference_t<D<True> const> //
  267. operator[](range_difference_t<D<True>> n) const
  268. {
  269. return derived().begin()[n];
  270. }
  271. /// Returns a pointer to the block of memory
  272. /// containing the elements of a contiguous range:
  273. template(bool True = true)(
  274. requires True AND contiguous_iterator<iterator_t<D<True>>>)
  275. constexpr std::add_pointer_t<range_reference_t<D<True>>> data() //
  276. {
  277. return std::addressof(*ranges::begin(derived()));
  278. }
  279. /// \overload
  280. template(bool True = true)(
  281. requires True AND contiguous_iterator<iterator_t<D<True> const>>)
  282. constexpr std::add_pointer_t<range_reference_t<D<True> const>> data() const //
  283. {
  284. return std::addressof(*ranges::begin(derived()));
  285. }
  286. /// Returns a reference to the element at specified location pos, with bounds
  287. /// checking.
  288. template(bool True = true)(
  289. requires True AND random_access_range<D<True>> AND sized_range<D<True>>)
  290. constexpr range_reference_t<D<True>> at(range_difference_t<D<True>> n)
  291. {
  292. using size_type = range_size_t<Derived>;
  293. if(n < 0 || size_type(n) >= ranges::size(derived()))
  294. {
  295. throw std::out_of_range("view_interface::at");
  296. }
  297. return derived().begin()[n];
  298. }
  299. /// \overload
  300. template(bool True = true)(
  301. requires True AND random_access_range<D<True> const> AND
  302. sized_range<D<True> const>)
  303. constexpr range_reference_t<D<True> const> at(range_difference_t<D<True>> n) const
  304. {
  305. using size_type = range_size_t<Derived const>;
  306. if(n < 0 || size_type(n) >= ranges::size(derived()))
  307. {
  308. throw std::out_of_range("view_interface::at");
  309. }
  310. return derived().begin()[n];
  311. }
  312. /// Python-ic slicing:
  313. // rng[{4,6}]
  314. template(bool True = true, typename Slice = views::slice_fn)(
  315. requires True AND input_range<D<True> &>)
  316. constexpr auto
  317. operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &
  318. {
  319. return Slice{}(derived(), offs.from, offs.to);
  320. }
  321. /// \overload
  322. template(bool True = true, typename Slice = views::slice_fn)(
  323. requires True AND input_range<D<True> const &>)
  324. constexpr auto
  325. operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) const &
  326. {
  327. return Slice{}(derived(), offs.from, offs.to);
  328. }
  329. /// \overload
  330. template(bool True = true, typename Slice = views::slice_fn)(
  331. requires True AND input_range<D<True>>)
  332. constexpr auto
  333. operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &&
  334. {
  335. return Slice{}(detail::move(derived()), offs.from, offs.to);
  336. }
  337. // rng[{4,end-2}]
  338. /// \overload
  339. template(bool True = true, typename Slice = views::slice_fn)(
  340. requires True AND input_range<D<True> &> AND sized_range<D<True> &>)
  341. constexpr auto //
  342. operator[](detail::slice_bounds<range_difference_t<D<True>>,
  343. detail::from_end_of_t<D<True>>> offs) &
  344. {
  345. return Slice{}(derived(), offs.from, offs.to);
  346. }
  347. /// \overload
  348. template(bool True = true, typename Slice = views::slice_fn)(
  349. requires True AND input_range<D<True> const &> AND
  350. sized_range<D<True> const &>)
  351. constexpr auto //
  352. operator[](detail::slice_bounds<range_difference_t<D<True>>,
  353. detail::from_end_of_t<D<True>>> offs) const &
  354. {
  355. return Slice{}(derived(), offs.from, offs.to);
  356. }
  357. /// \overload
  358. template(bool True = true, typename Slice = views::slice_fn)(
  359. requires True AND input_range<D<True>> AND sized_range<D<True>>)
  360. constexpr auto //
  361. operator[](detail::slice_bounds<range_difference_t<D<True>>,
  362. detail::from_end_of_t<D<True>>> offs) &&
  363. {
  364. return Slice{}(detail::move(derived()), offs.from, offs.to);
  365. }
  366. // rng[{end-4,end-2}]
  367. /// \overload
  368. template(bool True = true, typename Slice = views::slice_fn)(
  369. requires True AND (forward_range<D<True> &> ||
  370. (input_range<D<True> &> && sized_range<D<True> &>))) //
  371. constexpr auto //
  372. operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
  373. detail::from_end_of_t<D<True>>> offs) &
  374. {
  375. return Slice{}(derived(), offs.from, offs.to);
  376. }
  377. /// \overload
  378. template(bool True = true, typename Slice = views::slice_fn)(
  379. requires True AND
  380. (forward_range<D<True> const &> ||
  381. (input_range<D<True> const &> && sized_range<D<True> const &>))) //
  382. constexpr auto //
  383. operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
  384. detail::from_end_of_t<D<True>>> offs) const &
  385. {
  386. return Slice{}(derived(), offs.from, offs.to);
  387. }
  388. /// \overload
  389. template(bool True = true, typename Slice = views::slice_fn)(
  390. requires True AND
  391. (forward_range<D<True>> ||
  392. (input_range<D<True>> && sized_range<D<True>>))) //
  393. constexpr auto //
  394. operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
  395. detail::from_end_of_t<D<True>>> offs) &&
  396. {
  397. return Slice{}(detail::move(derived()), offs.from, offs.to);
  398. }
  399. // rng[{4,end}]
  400. /// \overload
  401. template(bool True = true, typename Slice = views::slice_fn)(
  402. requires True AND input_range<D<True> &>)
  403. constexpr auto //
  404. operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &
  405. {
  406. return Slice{}(derived(), offs.from, offs.to);
  407. }
  408. /// \overload
  409. template(bool True = true, typename Slice = views::slice_fn)(
  410. requires True AND input_range<D<True> const &>)
  411. constexpr auto //
  412. operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) const &
  413. {
  414. return Slice{}(derived(), offs.from, offs.to);
  415. }
  416. /// \overload
  417. template(bool True = true, typename Slice = views::slice_fn)(
  418. requires True AND input_range<D<True>>)
  419. constexpr auto //
  420. operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &&
  421. {
  422. return Slice{}(detail::move(derived()), offs.from, offs.to);
  423. }
  424. // rng[{end-4,end}]
  425. /// \overload
  426. template(bool True = true, typename Slice = views::slice_fn)(
  427. requires True AND
  428. (forward_range<D<True> &> ||
  429. (input_range<D<True> &> && sized_range<D<True> &>))) //
  430. constexpr auto //
  431. operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &
  432. {
  433. return Slice{}(derived(), offs.from, offs.to);
  434. }
  435. /// \overload
  436. template(bool True = true, typename Slice = views::slice_fn)(
  437. requires True AND
  438. (forward_range<D<True> const &> ||
  439. (input_range<D<True> const &> && sized_range<D<True> const &>))) //
  440. constexpr auto //
  441. operator[](
  442. detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) const &
  443. {
  444. return Slice{}(derived(), offs.from, offs.to);
  445. }
  446. /// \overload
  447. template(bool True = true, typename Slice = views::slice_fn)(
  448. requires True AND
  449. (forward_range<D<True>> ||
  450. (input_range<D<True>> && sized_range<D<True>>))) //
  451. constexpr auto //
  452. operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &&
  453. {
  454. return Slice{}(detail::move(derived()), offs.from, offs.to);
  455. }
  456. private:
  457. #ifndef RANGES_V3_DISABLE_IO
  458. /// \brief Print a range to an ostream
  459. template<bool True = true>
  460. friend auto operator<<(std::ostream & sout, Derived const & rng)
  461. -> CPP_broken_friend_ret(std::ostream &)(
  462. requires True && input_range<D<True> const>)
  463. {
  464. return detail::print_rng_(sout, rng);
  465. }
  466. /// \overload
  467. template<bool True = true>
  468. friend auto operator<<(std::ostream & sout, Derived & rng)
  469. -> CPP_broken_friend_ret(std::ostream &)(
  470. requires True && (!range<D<True> const>) && input_range<D<True>>)
  471. {
  472. return detail::print_rng_(sout, rng);
  473. }
  474. /// \overload
  475. template<bool True = true>
  476. friend auto operator<<(std::ostream & sout, Derived && rng)
  477. -> CPP_broken_friend_ret(std::ostream &)(
  478. requires True && (!range<D<True> const>) && input_range<D<True>>)
  479. {
  480. return detail::print_rng_(sout, rng);
  481. }
  482. #endif
  483. };
  484. namespace cpp20
  485. {
  486. template(typename Derived)(
  487. requires std::is_class<Derived>::value AND
  488. same_as<Derived, meta::_t<std::remove_cv<Derived>>>)
  489. using view_interface = ranges::view_interface<Derived, ranges::unknown>;
  490. }
  491. /// @}
  492. } // namespace ranges
  493. #include <range/v3/detail/epilogue.hpp>
  494. #endif