ranges_base.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. // Core concepts and definitions for <ranges> -*- C++ -*-
  2. // Copyright (C) 2019-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/ranges_base.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{ranges}
  23. */
  24. #ifndef _GLIBCXX_RANGES_BASE_H
  25. #define _GLIBCXX_RANGES_BASE_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus > 201703L
  28. #include <bits/iterator_concepts.h>
  29. #include <ext/numeric_traits.h>
  30. #include <bits/max_size_type.h>
  31. #ifdef __cpp_lib_concepts
  32. namespace std _GLIBCXX_VISIBILITY(default)
  33. {
  34. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  35. namespace ranges
  36. {
  37. template<typename>
  38. inline constexpr bool disable_sized_range = false;
  39. template<typename _Tp>
  40. inline constexpr bool enable_borrowed_range = false;
  41. namespace __detail
  42. {
  43. constexpr __max_size_type
  44. __to_unsigned_like(__max_size_type __t) noexcept
  45. { return __t; }
  46. constexpr __max_size_type
  47. __to_unsigned_like(__max_diff_type __t) noexcept
  48. { return __max_size_type(__t); }
  49. template<integral _Tp>
  50. constexpr auto
  51. __to_unsigned_like(_Tp __t) noexcept
  52. { return static_cast<make_unsigned_t<_Tp>>(__t); }
  53. #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
  54. constexpr unsigned __int128
  55. __to_unsigned_like(__int128 __t) noexcept
  56. { return __t; }
  57. constexpr unsigned __int128
  58. __to_unsigned_like(unsigned __int128 __t) noexcept
  59. { return __t; }
  60. #endif
  61. template<typename _Tp>
  62. using __make_unsigned_like_t
  63. = decltype(__detail::__to_unsigned_like(std::declval<_Tp>()));
  64. // Part of the constraints of ranges::borrowed_range
  65. template<typename _Tp>
  66. concept __maybe_borrowed_range
  67. = is_lvalue_reference_v<_Tp>
  68. || enable_borrowed_range<remove_cvref_t<_Tp>>;
  69. } // namespace __detail
  70. namespace __cust_access
  71. {
  72. using std::ranges::__detail::__maybe_borrowed_range;
  73. using std::__detail::__range_iter_t;
  74. struct _Begin
  75. {
  76. private:
  77. template<typename _Tp>
  78. static constexpr bool
  79. _S_noexcept()
  80. {
  81. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  82. return true;
  83. else if constexpr (__member_begin<_Tp>)
  84. return noexcept(__decay_copy(std::declval<_Tp&>().begin()));
  85. else
  86. return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
  87. }
  88. public:
  89. template<__maybe_borrowed_range _Tp>
  90. requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
  91. || __adl_begin<_Tp>
  92. constexpr auto
  93. operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
  94. {
  95. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  96. {
  97. static_assert(is_lvalue_reference_v<_Tp>);
  98. return __t + 0;
  99. }
  100. else if constexpr (__member_begin<_Tp>)
  101. return __t.begin();
  102. else
  103. return begin(__t);
  104. }
  105. };
  106. template<typename _Tp>
  107. concept __member_end = requires(_Tp& __t)
  108. {
  109. { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>;
  110. };
  111. // Poison pills so that unqualified lookup doesn't find std::end.
  112. void end(auto&) = delete;
  113. void end(const auto&) = delete;
  114. template<typename _Tp>
  115. concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
  116. && requires(_Tp& __t)
  117. {
  118. { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>;
  119. };
  120. struct _End
  121. {
  122. private:
  123. template<typename _Tp>
  124. static constexpr bool
  125. _S_noexcept()
  126. {
  127. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  128. return true;
  129. else if constexpr (__member_end<_Tp>)
  130. return noexcept(__decay_copy(std::declval<_Tp&>().end()));
  131. else
  132. return noexcept(__decay_copy(end(std::declval<_Tp&>())));
  133. }
  134. public:
  135. template<__maybe_borrowed_range _Tp>
  136. requires is_bounded_array_v<remove_reference_t<_Tp>>
  137. || __member_end<_Tp> || __adl_end<_Tp>
  138. constexpr auto
  139. operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
  140. {
  141. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  142. {
  143. static_assert(is_lvalue_reference_v<_Tp>);
  144. return __t + extent_v<remove_reference_t<_Tp>>;
  145. }
  146. else if constexpr (__member_end<_Tp>)
  147. return __t.end();
  148. else
  149. return end(__t);
  150. }
  151. };
  152. // If _To is an lvalue-reference, return const _Tp&, otherwise const _Tp&&.
  153. template<typename _To, typename _Tp>
  154. constexpr decltype(auto)
  155. __as_const(_Tp& __t) noexcept
  156. {
  157. static_assert(std::is_same_v<_To&, _Tp&>);
  158. if constexpr (is_lvalue_reference_v<_To>)
  159. return const_cast<const _Tp&>(__t);
  160. else
  161. return static_cast<const _Tp&&>(__t);
  162. }
  163. struct _CBegin
  164. {
  165. template<typename _Tp>
  166. [[nodiscard]]
  167. constexpr auto
  168. operator()(_Tp&& __e) const
  169. noexcept(noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e))))
  170. requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); }
  171. {
  172. return _Begin{}(__cust_access::__as_const<_Tp>(__e));
  173. }
  174. };
  175. struct _CEnd final
  176. {
  177. template<typename _Tp>
  178. [[nodiscard]]
  179. constexpr auto
  180. operator()(_Tp&& __e) const
  181. noexcept(noexcept(_End{}(__cust_access::__as_const<_Tp>(__e))))
  182. requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); }
  183. {
  184. return _End{}(__cust_access::__as_const<_Tp>(__e));
  185. }
  186. };
  187. template<typename _Tp>
  188. concept __member_rbegin = requires(_Tp& __t)
  189. {
  190. { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
  191. };
  192. void rbegin(auto&) = delete;
  193. void rbegin(const auto&) = delete;
  194. template<typename _Tp>
  195. concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
  196. && requires(_Tp& __t)
  197. {
  198. { __decay_copy(rbegin(__t)) } -> input_or_output_iterator;
  199. };
  200. template<typename _Tp>
  201. concept __reversable = requires(_Tp& __t)
  202. {
  203. { _Begin{}(__t) } -> bidirectional_iterator;
  204. { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
  205. };
  206. struct _RBegin
  207. {
  208. private:
  209. template<typename _Tp>
  210. static constexpr bool
  211. _S_noexcept()
  212. {
  213. if constexpr (__member_rbegin<_Tp>)
  214. return noexcept(__decay_copy(std::declval<_Tp&>().rbegin()));
  215. else if constexpr (__adl_rbegin<_Tp>)
  216. return noexcept(__decay_copy(rbegin(std::declval<_Tp&>())));
  217. else
  218. {
  219. if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
  220. {
  221. using _It = decltype(_End{}(std::declval<_Tp&>()));
  222. // std::reverse_iterator copy-initializes its member.
  223. return is_nothrow_copy_constructible_v<_It>;
  224. }
  225. else
  226. return false;
  227. }
  228. }
  229. public:
  230. template<__maybe_borrowed_range _Tp>
  231. requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
  232. constexpr auto
  233. operator()[[nodiscard]](_Tp&& __t) const
  234. noexcept(_S_noexcept<_Tp&>())
  235. {
  236. if constexpr (__member_rbegin<_Tp>)
  237. return __t.rbegin();
  238. else if constexpr (__adl_rbegin<_Tp>)
  239. return rbegin(__t);
  240. else
  241. return std::make_reverse_iterator(_End{}(__t));
  242. }
  243. };
  244. template<typename _Tp>
  245. concept __member_rend = requires(_Tp& __t)
  246. {
  247. { __decay_copy(__t.rend()) }
  248. -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
  249. };
  250. void rend(auto&) = delete;
  251. void rend(const auto&) = delete;
  252. template<typename _Tp>
  253. concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
  254. && requires(_Tp& __t)
  255. {
  256. { __decay_copy(rend(__t)) }
  257. -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
  258. };
  259. struct _REnd
  260. {
  261. private:
  262. template<typename _Tp>
  263. static constexpr bool
  264. _S_noexcept()
  265. {
  266. if constexpr (__member_rend<_Tp>)
  267. return noexcept(__decay_copy(std::declval<_Tp&>().rend()));
  268. else if constexpr (__adl_rend<_Tp>)
  269. return noexcept(__decay_copy(rend(std::declval<_Tp&>())));
  270. else
  271. {
  272. if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
  273. {
  274. using _It = decltype(_Begin{}(std::declval<_Tp&>()));
  275. // std::reverse_iterator copy-initializes its member.
  276. return is_nothrow_copy_constructible_v<_It>;
  277. }
  278. else
  279. return false;
  280. }
  281. }
  282. public:
  283. template<__maybe_borrowed_range _Tp>
  284. requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
  285. constexpr auto
  286. operator()[[nodiscard]](_Tp&& __t) const
  287. noexcept(_S_noexcept<_Tp&>())
  288. {
  289. if constexpr (__member_rend<_Tp>)
  290. return __t.rend();
  291. else if constexpr (__adl_rend<_Tp>)
  292. return rend(__t);
  293. else
  294. return std::make_reverse_iterator(_Begin{}(__t));
  295. }
  296. };
  297. struct _CRBegin
  298. {
  299. template<typename _Tp>
  300. [[nodiscard]]
  301. constexpr auto
  302. operator()(_Tp&& __e) const
  303. noexcept(noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e))))
  304. requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); }
  305. {
  306. return _RBegin{}(__cust_access::__as_const<_Tp>(__e));
  307. }
  308. };
  309. struct _CREnd
  310. {
  311. template<typename _Tp>
  312. [[nodiscard]]
  313. constexpr auto
  314. operator()(_Tp&& __e) const
  315. noexcept(noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e))))
  316. requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); }
  317. {
  318. return _REnd{}(__cust_access::__as_const<_Tp>(__e));
  319. }
  320. };
  321. template<typename _Tp>
  322. concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
  323. && requires(_Tp& __t)
  324. {
  325. { __decay_copy(__t.size()) } -> __detail::__is_integer_like;
  326. };
  327. void size(auto&) = delete;
  328. void size(const auto&) = delete;
  329. template<typename _Tp>
  330. concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
  331. && !disable_sized_range<remove_cvref_t<_Tp>>
  332. && requires(_Tp& __t)
  333. {
  334. { __decay_copy(size(__t)) } -> __detail::__is_integer_like;
  335. };
  336. template<typename _Tp>
  337. concept __sentinel_size = requires(_Tp& __t)
  338. {
  339. requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);
  340. { _Begin{}(__t) } -> forward_iterator;
  341. { _End{}(__t) } -> sized_sentinel_for<decltype(_Begin{}(__t))>;
  342. __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
  343. };
  344. struct _Size
  345. {
  346. private:
  347. template<typename _Tp>
  348. static constexpr bool
  349. _S_noexcept()
  350. {
  351. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  352. return true;
  353. else if constexpr (__member_size<_Tp>)
  354. return noexcept(__decay_copy(std::declval<_Tp&>().size()));
  355. else if constexpr (__adl_size<_Tp>)
  356. return noexcept(__decay_copy(size(std::declval<_Tp&>())));
  357. else if constexpr (__sentinel_size<_Tp>)
  358. return noexcept(_End{}(std::declval<_Tp&>())
  359. - _Begin{}(std::declval<_Tp&>()));
  360. }
  361. public:
  362. template<typename _Tp>
  363. requires is_bounded_array_v<remove_reference_t<_Tp>>
  364. || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
  365. constexpr auto
  366. operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
  367. {
  368. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  369. return extent_v<remove_reference_t<_Tp>>;
  370. else if constexpr (__member_size<_Tp>)
  371. return __t.size();
  372. else if constexpr (__adl_size<_Tp>)
  373. return size(__t);
  374. else if constexpr (__sentinel_size<_Tp>)
  375. return __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
  376. }
  377. };
  378. struct _SSize
  379. {
  380. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  381. // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E)
  382. template<typename _Tp>
  383. requires requires (_Tp& __t) { _Size{}(__t); }
  384. constexpr auto
  385. operator()[[nodiscard]](_Tp&& __t) const noexcept(noexcept(_Size{}(__t)))
  386. {
  387. auto __size = _Size{}(__t);
  388. using __size_type = decltype(__size);
  389. // Return the wider of ptrdiff_t and make-signed-like-t<__size_type>.
  390. if constexpr (integral<__size_type>)
  391. {
  392. using __gnu_cxx::__int_traits;
  393. if constexpr (__int_traits<__size_type>::__digits
  394. < __int_traits<ptrdiff_t>::__digits)
  395. return static_cast<ptrdiff_t>(__size);
  396. else
  397. return static_cast<make_signed_t<__size_type>>(__size);
  398. }
  399. #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
  400. // For strict-ansi modes integral<__int128> is false
  401. else if constexpr (__detail::__is_int128<__size_type>)
  402. return static_cast<__int128>(__size);
  403. #endif
  404. else // Must be one of __max_diff_type or __max_size_type.
  405. return __detail::__max_diff_type(__size);
  406. }
  407. };
  408. template<typename _Tp>
  409. concept __member_empty = requires(_Tp& __t) { bool(__t.empty()); };
  410. template<typename _Tp>
  411. concept __size0_empty = requires(_Tp& __t) { _Size{}(__t) == 0; };
  412. template<typename _Tp>
  413. concept __eq_iter_empty = requires(_Tp& __t)
  414. {
  415. requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);
  416. { _Begin{}(__t) } -> forward_iterator;
  417. bool(_Begin{}(__t) == _End{}(__t));
  418. };
  419. struct _Empty
  420. {
  421. private:
  422. template<typename _Tp>
  423. static constexpr bool
  424. _S_noexcept()
  425. {
  426. if constexpr (__member_empty<_Tp>)
  427. return noexcept(bool(std::declval<_Tp&>().empty()));
  428. else if constexpr (__size0_empty<_Tp>)
  429. return noexcept(_Size{}(std::declval<_Tp&>()) == 0);
  430. else
  431. return noexcept(bool(_Begin{}(std::declval<_Tp&>())
  432. == _End{}(std::declval<_Tp&>())));
  433. }
  434. public:
  435. template<typename _Tp>
  436. requires __member_empty<_Tp> || __size0_empty<_Tp>
  437. || __eq_iter_empty<_Tp>
  438. constexpr bool
  439. operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>())
  440. {
  441. if constexpr (__member_empty<_Tp>)
  442. return bool(__t.empty());
  443. else if constexpr (__size0_empty<_Tp>)
  444. return _Size{}(__t) == 0;
  445. else
  446. return bool(_Begin{}(__t) == _End{}(__t));
  447. }
  448. };
  449. template<typename _Tp>
  450. concept __pointer_to_object = is_pointer_v<_Tp>
  451. && is_object_v<remove_pointer_t<_Tp>>;
  452. template<typename _Tp>
  453. concept __member_data = requires(_Tp& __t)
  454. {
  455. { __decay_copy(__t.data()) } -> __pointer_to_object;
  456. };
  457. template<typename _Tp>
  458. concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;
  459. struct _Data
  460. {
  461. private:
  462. template<typename _Tp>
  463. static constexpr bool
  464. _S_noexcept()
  465. {
  466. if constexpr (__member_data<_Tp>)
  467. return noexcept(__decay_copy(std::declval<_Tp&>().data()));
  468. else
  469. return noexcept(_Begin{}(std::declval<_Tp&>()));
  470. }
  471. public:
  472. template<__maybe_borrowed_range _Tp>
  473. requires __member_data<_Tp> || __begin_data<_Tp>
  474. constexpr auto
  475. operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
  476. {
  477. if constexpr (__member_data<_Tp>)
  478. return __t.data();
  479. else
  480. return std::to_address(_Begin{}(__t));
  481. }
  482. };
  483. struct _CData
  484. {
  485. template<typename _Tp>
  486. [[nodiscard]]
  487. constexpr auto
  488. operator()(_Tp&& __e) const
  489. noexcept(noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e))))
  490. requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); }
  491. {
  492. return _Data{}(__cust_access::__as_const<_Tp>(__e));
  493. }
  494. };
  495. } // namespace __cust_access
  496. inline namespace __cust
  497. {
  498. inline constexpr __cust_access::_Begin begin{};
  499. inline constexpr __cust_access::_End end{};
  500. inline constexpr __cust_access::_CBegin cbegin{};
  501. inline constexpr __cust_access::_CEnd cend{};
  502. inline constexpr __cust_access::_RBegin rbegin{};
  503. inline constexpr __cust_access::_REnd rend{};
  504. inline constexpr __cust_access::_CRBegin crbegin{};
  505. inline constexpr __cust_access::_CREnd crend{};
  506. inline constexpr __cust_access::_Size size{};
  507. inline constexpr __cust_access::_SSize ssize{};
  508. inline constexpr __cust_access::_Empty empty{};
  509. inline constexpr __cust_access::_Data data{};
  510. inline constexpr __cust_access::_CData cdata{};
  511. }
  512. /// [range.range] The range concept.
  513. template<typename _Tp>
  514. concept range = requires(_Tp& __t)
  515. {
  516. ranges::begin(__t);
  517. ranges::end(__t);
  518. };
  519. /// [range.range] The borrowed_range concept.
  520. template<typename _Tp>
  521. concept borrowed_range
  522. = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
  523. template<typename _Tp>
  524. using iterator_t = std::__detail::__range_iter_t<_Tp>;
  525. template<range _Range>
  526. using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
  527. template<range _Range>
  528. using range_difference_t = iter_difference_t<iterator_t<_Range>>;
  529. template<range _Range>
  530. using range_value_t = iter_value_t<iterator_t<_Range>>;
  531. template<range _Range>
  532. using range_reference_t = iter_reference_t<iterator_t<_Range>>;
  533. template<range _Range>
  534. using range_rvalue_reference_t
  535. = iter_rvalue_reference_t<iterator_t<_Range>>;
  536. /// [range.sized] The sized_range concept.
  537. template<typename _Tp>
  538. concept sized_range = range<_Tp>
  539. && requires(_Tp& __t) { ranges::size(__t); };
  540. template<sized_range _Range>
  541. using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
  542. template<typename _Derived>
  543. requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
  544. class view_interface; // defined in <bits/ranges_util.h>
  545. namespace __detail
  546. {
  547. template<typename _Tp, typename _Up>
  548. requires (!same_as<_Tp, view_interface<_Up>>)
  549. void __is_derived_from_view_interface_fn(const _Tp&,
  550. const view_interface<_Up>&); // not defined
  551. // Returns true iff _Tp has exactly one public base class that's a
  552. // specialization of view_interface.
  553. template<typename _Tp>
  554. concept __is_derived_from_view_interface
  555. = requires (_Tp __t) { __is_derived_from_view_interface_fn(__t, __t); };
  556. } // namespace __detail
  557. /// [range.view] The ranges::view_base type.
  558. struct view_base { };
  559. /// [range.view] The ranges::enable_view boolean.
  560. template<typename _Tp>
  561. inline constexpr bool enable_view = derived_from<_Tp, view_base>
  562. || __detail::__is_derived_from_view_interface<_Tp>;
  563. /// [range.view] The ranges::view concept.
  564. template<typename _Tp>
  565. concept view
  566. = range<_Tp> && movable<_Tp> && enable_view<_Tp>;
  567. // [range.refinements]
  568. /// A range for which ranges::begin returns an output iterator.
  569. template<typename _Range, typename _Tp>
  570. concept output_range
  571. = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
  572. /// A range for which ranges::begin returns an input iterator.
  573. template<typename _Tp>
  574. concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
  575. /// A range for which ranges::begin returns a forward iterator.
  576. template<typename _Tp>
  577. concept forward_range
  578. = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
  579. /// A range for which ranges::begin returns a bidirectional iterator.
  580. template<typename _Tp>
  581. concept bidirectional_range
  582. = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
  583. /// A range for which ranges::begin returns a random access iterator.
  584. template<typename _Tp>
  585. concept random_access_range
  586. = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
  587. /// A range for which ranges::begin returns a contiguous iterator.
  588. template<typename _Tp>
  589. concept contiguous_range
  590. = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
  591. && requires(_Tp& __t)
  592. {
  593. { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
  594. };
  595. /// A range for which ranges::begin and ranges::end return the same type.
  596. template<typename _Tp>
  597. concept common_range
  598. = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
  599. namespace __detail
  600. {
  601. template<typename _Tp>
  602. inline constexpr bool __is_initializer_list = false;
  603. template<typename _Tp>
  604. inline constexpr bool __is_initializer_list<initializer_list<_Tp>> = true;
  605. } // namespace __detail
  606. /// A range which can be safely converted to a view.
  607. template<typename _Tp>
  608. concept viewable_range = range<_Tp>
  609. && ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>)
  610. || (!view<remove_cvref_t<_Tp>>
  611. && (is_lvalue_reference_v<_Tp>
  612. || (movable<remove_reference_t<_Tp>>
  613. && !__detail::__is_initializer_list<remove_cvref_t<_Tp>>))));
  614. // [range.iter.ops] range iterator operations
  615. struct __advance_fn final
  616. {
  617. template<input_or_output_iterator _It>
  618. constexpr void
  619. operator()(_It& __it, iter_difference_t<_It> __n) const
  620. {
  621. if constexpr (random_access_iterator<_It>)
  622. __it += __n;
  623. else if constexpr (bidirectional_iterator<_It>)
  624. {
  625. if (__n > 0)
  626. {
  627. do
  628. {
  629. ++__it;
  630. }
  631. while (--__n);
  632. }
  633. else if (__n < 0)
  634. {
  635. do
  636. {
  637. --__it;
  638. }
  639. while (++__n);
  640. }
  641. }
  642. else
  643. {
  644. // cannot decrement a non-bidirectional iterator
  645. __glibcxx_assert(__n >= 0);
  646. while (__n-- > 0)
  647. ++__it;
  648. }
  649. }
  650. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  651. constexpr void
  652. operator()(_It& __it, _Sent __bound) const
  653. {
  654. if constexpr (assignable_from<_It&, _Sent>)
  655. __it = std::move(__bound);
  656. else if constexpr (sized_sentinel_for<_Sent, _It>)
  657. (*this)(__it, __bound - __it);
  658. else
  659. {
  660. while (__it != __bound)
  661. ++__it;
  662. }
  663. }
  664. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  665. constexpr iter_difference_t<_It>
  666. operator()(_It& __it, iter_difference_t<_It> __n, _Sent __bound) const
  667. {
  668. if constexpr (sized_sentinel_for<_Sent, _It>)
  669. {
  670. const auto __diff = __bound - __it;
  671. if (__diff == 0)
  672. return __n;
  673. else if (__diff > 0 ? __n >= __diff : __n <= __diff)
  674. {
  675. (*this)(__it, __bound);
  676. return __n - __diff;
  677. }
  678. else if (__n != 0) [[likely]]
  679. {
  680. // n and bound must not lead in opposite directions:
  681. __glibcxx_assert(__n < 0 == __diff < 0);
  682. (*this)(__it, __n);
  683. return 0;
  684. }
  685. else
  686. return 0;
  687. }
  688. else if (__it == __bound || __n == 0)
  689. return __n;
  690. else if (__n > 0)
  691. {
  692. iter_difference_t<_It> __m = 0;
  693. do
  694. {
  695. ++__it;
  696. ++__m;
  697. }
  698. while (__m != __n && __it != __bound);
  699. return __n - __m;
  700. }
  701. else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
  702. {
  703. iter_difference_t<_It> __m = 0;
  704. do
  705. {
  706. --__it;
  707. --__m;
  708. }
  709. while (__m != __n && __it != __bound);
  710. return __n - __m;
  711. }
  712. else
  713. {
  714. // cannot decrement a non-bidirectional iterator
  715. __glibcxx_assert(__n >= 0);
  716. return __n;
  717. }
  718. }
  719. void operator&() const = delete;
  720. };
  721. inline constexpr __advance_fn advance{};
  722. struct __distance_fn final
  723. {
  724. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  725. requires (!sized_sentinel_for<_Sent, _It>)
  726. constexpr iter_difference_t<_It>
  727. operator()[[nodiscard]](_It __first, _Sent __last) const
  728. {
  729. iter_difference_t<_It> __n = 0;
  730. while (__first != __last)
  731. {
  732. ++__first;
  733. ++__n;
  734. }
  735. return __n;
  736. }
  737. template<input_or_output_iterator _It, sized_sentinel_for<_It> _Sent>
  738. [[nodiscard]]
  739. constexpr iter_difference_t<_It>
  740. operator()(const _It& __first, const _Sent& __last) const
  741. {
  742. return __last - __first;
  743. }
  744. template<range _Range>
  745. [[nodiscard]]
  746. constexpr range_difference_t<_Range>
  747. operator()(_Range&& __r) const
  748. {
  749. if constexpr (sized_range<_Range>)
  750. return static_cast<range_difference_t<_Range>>(ranges::size(__r));
  751. else
  752. return (*this)(ranges::begin(__r), ranges::end(__r));
  753. }
  754. void operator&() const = delete;
  755. };
  756. inline constexpr __distance_fn distance{};
  757. struct __next_fn final
  758. {
  759. template<input_or_output_iterator _It>
  760. [[nodiscard]]
  761. constexpr _It
  762. operator()(_It __x) const
  763. {
  764. ++__x;
  765. return __x;
  766. }
  767. template<input_or_output_iterator _It>
  768. [[nodiscard]]
  769. constexpr _It
  770. operator()(_It __x, iter_difference_t<_It> __n) const
  771. {
  772. ranges::advance(__x, __n);
  773. return __x;
  774. }
  775. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  776. [[nodiscard]]
  777. constexpr _It
  778. operator()(_It __x, _Sent __bound) const
  779. {
  780. ranges::advance(__x, __bound);
  781. return __x;
  782. }
  783. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  784. [[nodiscard]]
  785. constexpr _It
  786. operator()(_It __x, iter_difference_t<_It> __n, _Sent __bound) const
  787. {
  788. ranges::advance(__x, __n, __bound);
  789. return __x;
  790. }
  791. void operator&() const = delete;
  792. };
  793. inline constexpr __next_fn next{};
  794. struct __prev_fn final
  795. {
  796. template<bidirectional_iterator _It>
  797. [[nodiscard]]
  798. constexpr _It
  799. operator()(_It __x) const
  800. {
  801. --__x;
  802. return __x;
  803. }
  804. template<bidirectional_iterator _It>
  805. [[nodiscard]]
  806. constexpr _It
  807. operator()(_It __x, iter_difference_t<_It> __n) const
  808. {
  809. ranges::advance(__x, -__n);
  810. return __x;
  811. }
  812. template<bidirectional_iterator _It>
  813. [[nodiscard]]
  814. constexpr _It
  815. operator()(_It __x, iter_difference_t<_It> __n, _It __bound) const
  816. {
  817. ranges::advance(__x, -__n, __bound);
  818. return __x;
  819. }
  820. void operator&() const = delete;
  821. };
  822. inline constexpr __prev_fn prev{};
  823. /// Type returned by algorithms instead of a dangling iterator or subrange.
  824. struct dangling
  825. {
  826. constexpr dangling() noexcept = default;
  827. template<typename... _Args>
  828. constexpr dangling(_Args&&...) noexcept { }
  829. };
  830. template<range _Range>
  831. using borrowed_iterator_t = __conditional_t<borrowed_range<_Range>,
  832. iterator_t<_Range>,
  833. dangling>;
  834. } // namespace ranges
  835. _GLIBCXX_END_NAMESPACE_VERSION
  836. } // namespace std
  837. #endif // library concepts
  838. #endif // C++20
  839. #endif // _GLIBCXX_RANGES_BASE_H