ranges_base.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. // Core concepts and definitions for <ranges> -*- C++ -*-
  2. // Copyright (C) 2019-2021 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::__class_or_enum;
  74. using std::__detail::__decay_copy;
  75. using std::__detail::__member_begin;
  76. using std::__detail::__adl_begin;
  77. struct _Begin
  78. {
  79. private:
  80. template<typename _Tp>
  81. static constexpr bool
  82. _S_noexcept()
  83. {
  84. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  85. return true;
  86. else if constexpr (__member_begin<_Tp>)
  87. return noexcept(__decay_copy(std::declval<_Tp&>().begin()));
  88. else
  89. return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
  90. }
  91. public:
  92. template<__maybe_borrowed_range _Tp>
  93. requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
  94. || __adl_begin<_Tp>
  95. constexpr auto
  96. operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
  97. {
  98. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  99. {
  100. static_assert(is_lvalue_reference_v<_Tp>);
  101. using _Up = remove_all_extents_t<remove_reference_t<_Tp>>;
  102. static_assert(sizeof(_Up) != 0, "not array of incomplete type");
  103. return __t + 0;
  104. }
  105. else if constexpr (__member_begin<_Tp>)
  106. return __t.begin();
  107. else
  108. return begin(__t);
  109. }
  110. };
  111. template<typename _Tp>
  112. concept __member_end = requires(_Tp& __t)
  113. {
  114. { __decay_copy(__t.end()) }
  115. -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  116. };
  117. void end(auto&) = delete;
  118. void end(const auto&) = delete;
  119. template<typename _Tp>
  120. concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
  121. && requires(_Tp& __t)
  122. {
  123. { __decay_copy(end(__t)) }
  124. -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  125. };
  126. struct _End
  127. {
  128. private:
  129. template<typename _Tp>
  130. static constexpr bool
  131. _S_noexcept()
  132. {
  133. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  134. return true;
  135. else if constexpr (__member_end<_Tp>)
  136. return noexcept(__decay_copy(std::declval<_Tp&>().end()));
  137. else
  138. return noexcept(__decay_copy(end(std::declval<_Tp&>())));
  139. }
  140. public:
  141. template<__maybe_borrowed_range _Tp>
  142. requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_end<_Tp>
  143. || __adl_end<_Tp>
  144. constexpr auto
  145. operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
  146. {
  147. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  148. {
  149. static_assert(is_lvalue_reference_v<_Tp>);
  150. return __t + extent_v<remove_reference_t<_Tp>>;
  151. }
  152. else if constexpr (__member_end<_Tp>)
  153. return __t.end();
  154. else
  155. return end(__t);
  156. }
  157. };
  158. template<typename _Tp>
  159. constexpr decltype(auto)
  160. __as_const(_Tp&& __t) noexcept
  161. {
  162. if constexpr (is_lvalue_reference_v<_Tp>)
  163. return static_cast<const remove_reference_t<_Tp>&>(__t);
  164. else
  165. return static_cast<const _Tp&&>(__t);
  166. }
  167. struct _CBegin
  168. {
  169. template<typename _Tp>
  170. constexpr auto
  171. operator()(_Tp&& __e) const
  172. noexcept(noexcept(_Begin{}(__cust_access::__as_const((_Tp&&)__e))))
  173. requires requires { _Begin{}(__cust_access::__as_const((_Tp&&)__e)); }
  174. {
  175. return _Begin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  176. }
  177. };
  178. struct _CEnd
  179. {
  180. template<typename _Tp>
  181. constexpr auto
  182. operator()(_Tp&& __e) const
  183. noexcept(noexcept(_End{}(__cust_access::__as_const((_Tp&&)__e))))
  184. requires requires { _End{}(__cust_access::__as_const((_Tp&&)__e)); }
  185. {
  186. return _End{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  187. }
  188. };
  189. template<typename _Tp>
  190. concept __member_rbegin = requires(_Tp& __t)
  191. {
  192. { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
  193. };
  194. void rbegin(auto&) = delete;
  195. void rbegin(const auto&) = delete;
  196. template<typename _Tp>
  197. concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
  198. && requires(_Tp& __t)
  199. {
  200. { __decay_copy(rbegin(__t)) } -> input_or_output_iterator;
  201. };
  202. template<typename _Tp>
  203. concept __reversable = requires(_Tp& __t)
  204. {
  205. { _Begin{}(__t) } -> bidirectional_iterator;
  206. { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
  207. };
  208. struct _RBegin
  209. {
  210. private:
  211. template<typename _Tp>
  212. static constexpr bool
  213. _S_noexcept()
  214. {
  215. if constexpr (__member_rbegin<_Tp>)
  216. return noexcept(__decay_copy(std::declval<_Tp&>().rbegin()));
  217. else if constexpr (__adl_rbegin<_Tp>)
  218. return noexcept(__decay_copy(rbegin(std::declval<_Tp&>())));
  219. else
  220. {
  221. if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
  222. {
  223. using _It = decltype(_End{}(std::declval<_Tp&>()));
  224. // std::reverse_iterator copy-initializes its member.
  225. return is_nothrow_copy_constructible_v<_It>;
  226. }
  227. else
  228. return false;
  229. }
  230. }
  231. public:
  232. template<__maybe_borrowed_range _Tp>
  233. requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
  234. constexpr auto
  235. operator()(_Tp&& __t) const
  236. noexcept(_S_noexcept<_Tp>())
  237. {
  238. if constexpr (__member_rbegin<_Tp>)
  239. return __t.rbegin();
  240. else if constexpr (__adl_rbegin<_Tp>)
  241. return rbegin(__t);
  242. else
  243. return std::make_reverse_iterator(_End{}(__t));
  244. }
  245. };
  246. template<typename _Tp>
  247. concept __member_rend = requires(_Tp& __t)
  248. {
  249. { __decay_copy(__t.rend()) }
  250. -> sentinel_for<decltype(_RBegin{}(__t))>;
  251. };
  252. void rend(auto&) = delete;
  253. void rend(const auto&) = delete;
  254. template<typename _Tp>
  255. concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
  256. && requires(_Tp& __t)
  257. {
  258. { __decay_copy(rend(__t)) }
  259. -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
  260. };
  261. struct _REnd
  262. {
  263. private:
  264. template<typename _Tp>
  265. static constexpr bool
  266. _S_noexcept()
  267. {
  268. if constexpr (__member_rend<_Tp>)
  269. return noexcept(__decay_copy(std::declval<_Tp&>().rend()));
  270. else if constexpr (__adl_rend<_Tp>)
  271. return noexcept(__decay_copy(rend(std::declval<_Tp&>())));
  272. else
  273. {
  274. if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
  275. {
  276. using _It = decltype(_Begin{}(std::declval<_Tp&>()));
  277. // std::reverse_iterator copy-initializes its member.
  278. return is_nothrow_copy_constructible_v<_It>;
  279. }
  280. else
  281. return false;
  282. }
  283. }
  284. public:
  285. template<__maybe_borrowed_range _Tp>
  286. requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
  287. constexpr auto
  288. operator()(_Tp&& __t) const
  289. noexcept(_S_noexcept<_Tp>())
  290. {
  291. if constexpr (__member_rend<_Tp>)
  292. return __t.rend();
  293. else if constexpr (__adl_rend<_Tp>)
  294. return rend(__t);
  295. else
  296. return std::make_reverse_iterator(_Begin{}(__t));
  297. }
  298. };
  299. struct _CRBegin
  300. {
  301. template<typename _Tp>
  302. constexpr auto
  303. operator()(_Tp&& __e) const
  304. noexcept(noexcept(_RBegin{}(__cust_access::__as_const((_Tp&&)__e))))
  305. requires requires { _RBegin{}(__cust_access::__as_const((_Tp&&)__e)); }
  306. {
  307. return _RBegin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  308. }
  309. };
  310. struct _CREnd
  311. {
  312. template<typename _Tp>
  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(std::forward<_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(std::forward<_Tp>(__t).size()) }
  326. -> __detail::__is_integer_like;
  327. };
  328. void size(auto&) = delete;
  329. void size(const auto&) = delete;
  330. template<typename _Tp>
  331. concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
  332. && !disable_sized_range<remove_cvref_t<_Tp>>
  333. && requires(_Tp&& __t)
  334. {
  335. { __decay_copy(size(std::forward<_Tp>(__t))) }
  336. -> __detail::__is_integer_like;
  337. };
  338. template<typename _Tp>
  339. concept __sentinel_size = requires(_Tp&& __t)
  340. {
  341. { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
  342. { _End{}(std::forward<_Tp>(__t)) }
  343. -> sized_sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  344. };
  345. struct _Size
  346. {
  347. private:
  348. template<typename _Tp>
  349. static constexpr bool
  350. _S_noexcept()
  351. {
  352. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  353. return true;
  354. else if constexpr (__member_size<_Tp>)
  355. return noexcept(__decay_copy(std::declval<_Tp>().size()));
  356. else if constexpr (__adl_size<_Tp>)
  357. return noexcept(__decay_copy(size(std::declval<_Tp>())));
  358. else if constexpr (__sentinel_size<_Tp>)
  359. return noexcept(_End{}(std::declval<_Tp>())
  360. - _Begin{}(std::declval<_Tp>()));
  361. }
  362. public:
  363. template<typename _Tp>
  364. requires is_bounded_array_v<remove_reference_t<_Tp>>
  365. || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
  366. constexpr auto
  367. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  368. {
  369. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  370. {
  371. return extent_v<remove_reference_t<_Tp>>;
  372. }
  373. else if constexpr (__member_size<_Tp>)
  374. return std::forward<_Tp>(__e).size();
  375. else if constexpr (__adl_size<_Tp>)
  376. return size(std::forward<_Tp>(__e));
  377. else if constexpr (__sentinel_size<_Tp>)
  378. return __detail::__to_unsigned_like(
  379. _End{}(std::forward<_Tp>(__e))
  380. - _Begin{}(std::forward<_Tp>(__e)));
  381. }
  382. };
  383. struct _SSize
  384. {
  385. template<typename _Tp>
  386. requires requires (_Tp&& __e)
  387. {
  388. _Begin{}(std::forward<_Tp>(__e));
  389. _Size{}(std::forward<_Tp>(__e));
  390. }
  391. constexpr auto
  392. operator()(_Tp&& __e) const
  393. noexcept(noexcept(_Size{}(std::forward<_Tp>(__e))))
  394. {
  395. using __iter_type = decltype(_Begin{}(std::forward<_Tp>(__e)));
  396. using __diff_type = iter_difference_t<__iter_type>;
  397. using __gnu_cxx::__int_traits;
  398. auto __size = _Size{}(std::forward<_Tp>(__e));
  399. if constexpr (integral<__diff_type>)
  400. {
  401. if constexpr (__int_traits<__diff_type>::__digits
  402. < __int_traits<ptrdiff_t>::__digits)
  403. return static_cast<ptrdiff_t>(__size);
  404. }
  405. return static_cast<__diff_type>(__size);
  406. }
  407. };
  408. template<typename _Tp>
  409. concept __member_empty = requires(_Tp&& __t)
  410. { bool(std::forward<_Tp>(__t).empty()); };
  411. template<typename _Tp>
  412. concept __size0_empty = requires(_Tp&& __t)
  413. { _Size{}(std::forward<_Tp>(__t)) == 0; };
  414. template<typename _Tp>
  415. concept __eq_iter_empty = requires(_Tp&& __t)
  416. {
  417. { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
  418. bool(_Begin{}(std::forward<_Tp>(__t))
  419. == _End{}(std::forward<_Tp>(__t)));
  420. };
  421. struct _Empty
  422. {
  423. private:
  424. template<typename _Tp>
  425. static constexpr bool
  426. _S_noexcept()
  427. {
  428. if constexpr (__member_empty<_Tp>)
  429. return noexcept(std::declval<_Tp>().empty());
  430. else if constexpr (__size0_empty<_Tp>)
  431. return noexcept(_Size{}(std::declval<_Tp>()) == 0);
  432. else
  433. return noexcept(bool(_Begin{}(std::declval<_Tp>())
  434. == _End{}(std::declval<_Tp>())));
  435. }
  436. public:
  437. template<typename _Tp>
  438. requires __member_empty<_Tp> || __size0_empty<_Tp>
  439. || __eq_iter_empty<_Tp>
  440. constexpr bool
  441. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  442. {
  443. if constexpr (__member_empty<_Tp>)
  444. return bool(std::forward<_Tp>(__e).empty());
  445. else if constexpr (__size0_empty<_Tp>)
  446. return _Size{}(std::forward<_Tp>(__e)) == 0;
  447. else
  448. return bool(_Begin{}(std::forward<_Tp>(__e))
  449. == _End{}(std::forward<_Tp>(__e)));
  450. }
  451. };
  452. template<typename _Tp>
  453. concept __pointer_to_object = is_pointer_v<_Tp>
  454. && is_object_v<remove_pointer_t<_Tp>>;
  455. template<typename _Tp>
  456. concept __member_data = is_lvalue_reference_v<_Tp>
  457. && requires(_Tp __t) { { __t.data() } -> __pointer_to_object; };
  458. template<typename _Tp>
  459. concept __begin_data = requires(_Tp&& __t)
  460. { { _Begin{}(std::forward<_Tp>(__t)) } -> contiguous_iterator; };
  461. struct _Data
  462. {
  463. private:
  464. template<typename _Tp>
  465. static constexpr bool
  466. _S_noexcept()
  467. {
  468. if constexpr (__member_data<_Tp>)
  469. return noexcept(__decay_copy(std::declval<_Tp>().data()));
  470. else
  471. return noexcept(_Begin{}(std::declval<_Tp>()));
  472. }
  473. public:
  474. template<__maybe_borrowed_range _Tp>
  475. requires __member_data<_Tp> || __begin_data<_Tp>
  476. constexpr auto
  477. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  478. {
  479. if constexpr (__member_data<_Tp>)
  480. return __e.data();
  481. else
  482. return std::to_address(_Begin{}(std::forward<_Tp>(__e)));
  483. }
  484. };
  485. struct _CData
  486. {
  487. template<typename _Tp>
  488. constexpr auto
  489. operator()(_Tp&& __e) const
  490. noexcept(noexcept(_Data{}(__cust_access::__as_const((_Tp&&)__e))))
  491. requires requires { _Data{}(__cust_access::__as_const((_Tp&&)__e)); }
  492. {
  493. return _Data{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  494. }
  495. };
  496. } // namespace __cust_access
  497. inline namespace __cust
  498. {
  499. inline constexpr __cust_access::_Begin begin{};
  500. inline constexpr __cust_access::_End end{};
  501. inline constexpr __cust_access::_CBegin cbegin{};
  502. inline constexpr __cust_access::_CEnd cend{};
  503. inline constexpr __cust_access::_RBegin rbegin{};
  504. inline constexpr __cust_access::_REnd rend{};
  505. inline constexpr __cust_access::_CRBegin crbegin{};
  506. inline constexpr __cust_access::_CREnd crend{};
  507. inline constexpr __cust_access::_Size size{};
  508. inline constexpr __cust_access::_SSize ssize{};
  509. inline constexpr __cust_access::_Empty empty{};
  510. inline constexpr __cust_access::_Data data{};
  511. inline constexpr __cust_access::_CData cdata{};
  512. }
  513. /// [range.range] The range concept.
  514. template<typename _Tp>
  515. concept range = requires(_Tp& __t)
  516. {
  517. ranges::begin(__t);
  518. ranges::end(__t);
  519. };
  520. /// [range.range] The borrowed_range concept.
  521. template<typename _Tp>
  522. concept borrowed_range
  523. = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
  524. template<typename _Tp>
  525. using iterator_t = std::__detail::__range_iter_t<_Tp>;
  526. template<range _Range>
  527. using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
  528. template<range _Range>
  529. using range_difference_t = iter_difference_t<iterator_t<_Range>>;
  530. template<range _Range>
  531. using range_value_t = iter_value_t<iterator_t<_Range>>;
  532. template<range _Range>
  533. using range_reference_t = iter_reference_t<iterator_t<_Range>>;
  534. template<range _Range>
  535. using range_rvalue_reference_t
  536. = iter_rvalue_reference_t<iterator_t<_Range>>;
  537. /// [range.sized] The sized_range concept.
  538. template<typename _Tp>
  539. concept sized_range = range<_Tp>
  540. && requires(_Tp& __t) { ranges::size(__t); };
  541. template<sized_range _Range>
  542. using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
  543. /// [range.view] The ranges::view_base type.
  544. struct view_base { };
  545. /// [range.view] The ranges::enable_view boolean.
  546. template<typename _Tp>
  547. inline constexpr bool enable_view = derived_from<_Tp, view_base>;
  548. /// [range.view] The ranges::view concept.
  549. template<typename _Tp>
  550. concept view
  551. = range<_Tp> && movable<_Tp> && default_initializable<_Tp>
  552. && enable_view<_Tp>;
  553. // [range.refinements]
  554. /// A range for which ranges::begin returns an output iterator.
  555. template<typename _Range, typename _Tp>
  556. concept output_range
  557. = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
  558. /// A range for which ranges::begin returns an input iterator.
  559. template<typename _Tp>
  560. concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
  561. /// A range for which ranges::begin returns a forward iterator.
  562. template<typename _Tp>
  563. concept forward_range
  564. = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
  565. /// A range for which ranges::begin returns a bidirectional iterator.
  566. template<typename _Tp>
  567. concept bidirectional_range
  568. = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
  569. /// A range for which ranges::begin returns a random access iterator.
  570. template<typename _Tp>
  571. concept random_access_range
  572. = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
  573. /// A range for which ranges::begin returns a contiguous iterator.
  574. template<typename _Tp>
  575. concept contiguous_range
  576. = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
  577. && requires(_Tp& __t)
  578. {
  579. { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
  580. };
  581. /// A range for which ranges::begin and ranges::end return the same type.
  582. template<typename _Tp>
  583. concept common_range
  584. = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
  585. /// A range which can be safely converted to a view.
  586. template<typename _Tp>
  587. concept viewable_range = range<_Tp>
  588. && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
  589. // [range.iter.ops] range iterator operations
  590. template<input_or_output_iterator _It>
  591. constexpr void
  592. advance(_It& __it, iter_difference_t<_It> __n)
  593. {
  594. if constexpr (random_access_iterator<_It>)
  595. __it += __n;
  596. else if constexpr (bidirectional_iterator<_It>)
  597. {
  598. if (__n > 0)
  599. {
  600. do
  601. {
  602. ++__it;
  603. }
  604. while (--__n);
  605. }
  606. else if (__n < 0)
  607. {
  608. do
  609. {
  610. --__it;
  611. }
  612. while (++__n);
  613. }
  614. }
  615. else
  616. {
  617. // cannot decrement a non-bidirectional iterator
  618. __glibcxx_assert(__n >= 0);
  619. while (__n-- > 0)
  620. ++__it;
  621. }
  622. }
  623. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  624. constexpr void
  625. advance(_It& __it, _Sent __bound)
  626. {
  627. if constexpr (assignable_from<_It&, _Sent>)
  628. __it = std::move(__bound);
  629. else if constexpr (sized_sentinel_for<_Sent, _It>)
  630. ranges::advance(__it, __bound - __it);
  631. else
  632. {
  633. while (__it != __bound)
  634. ++__it;
  635. }
  636. }
  637. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  638. constexpr iter_difference_t<_It>
  639. advance(_It& __it, iter_difference_t<_It> __n, _Sent __bound)
  640. {
  641. if constexpr (sized_sentinel_for<_Sent, _It>)
  642. {
  643. const auto __diff = __bound - __it;
  644. #ifdef __cpp_lib_is_constant_evaluated
  645. if (std::is_constant_evaluated()
  646. && !(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0)))
  647. throw "inconsistent directions for distance and bound";
  648. #endif
  649. // n and bound must not lead in opposite directions:
  650. __glibcxx_assert(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0));
  651. const auto __absdiff = __diff < 0 ? -__diff : __diff;
  652. const auto __absn = __n < 0 ? -__n : __n;;
  653. if (__absn >= __absdiff)
  654. {
  655. ranges::advance(__it, __bound);
  656. return __n - __diff;
  657. }
  658. else
  659. {
  660. ranges::advance(__it, __n);
  661. return 0;
  662. }
  663. }
  664. else if (__it == __bound || __n == 0)
  665. return iter_difference_t<_It>(0);
  666. else if (__n > 0)
  667. {
  668. iter_difference_t<_It> __m = 0;
  669. do
  670. {
  671. ++__it;
  672. ++__m;
  673. }
  674. while (__m != __n && __it != __bound);
  675. return __n - __m;
  676. }
  677. else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
  678. {
  679. iter_difference_t<_It> __m = 0;
  680. do
  681. {
  682. --__it;
  683. --__m;
  684. }
  685. while (__m != __n && __it != __bound);
  686. return __n - __m;
  687. }
  688. else
  689. {
  690. // cannot decrement a non-bidirectional iterator
  691. __glibcxx_assert(__n >= 0);
  692. return __n;
  693. }
  694. }
  695. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  696. constexpr iter_difference_t<_It>
  697. distance(_It __first, _Sent __last)
  698. {
  699. if constexpr (sized_sentinel_for<_Sent, _It>)
  700. return __last - __first;
  701. else
  702. {
  703. iter_difference_t<_It> __n = 0;
  704. while (__first != __last)
  705. {
  706. ++__first;
  707. ++__n;
  708. }
  709. return __n;
  710. }
  711. }
  712. template<range _Range>
  713. constexpr range_difference_t<_Range>
  714. distance(_Range&& __r)
  715. {
  716. if constexpr (sized_range<_Range>)
  717. return static_cast<range_difference_t<_Range>>(ranges::size(__r));
  718. else
  719. return ranges::distance(ranges::begin(__r), ranges::end(__r));
  720. }
  721. template<input_or_output_iterator _It>
  722. constexpr _It
  723. next(_It __x)
  724. {
  725. ++__x;
  726. return __x;
  727. }
  728. template<input_or_output_iterator _It>
  729. constexpr _It
  730. next(_It __x, iter_difference_t<_It> __n)
  731. {
  732. ranges::advance(__x, __n);
  733. return __x;
  734. }
  735. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  736. constexpr _It
  737. next(_It __x, _Sent __bound)
  738. {
  739. ranges::advance(__x, __bound);
  740. return __x;
  741. }
  742. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  743. constexpr _It
  744. next(_It __x, iter_difference_t<_It> __n, _Sent __bound)
  745. {
  746. ranges::advance(__x, __n, __bound);
  747. return __x;
  748. }
  749. template<bidirectional_iterator _It>
  750. constexpr _It
  751. prev(_It __x)
  752. {
  753. --__x;
  754. return __x;
  755. }
  756. template<bidirectional_iterator _It>
  757. constexpr _It
  758. prev(_It __x, iter_difference_t<_It> __n)
  759. {
  760. ranges::advance(__x, -__n);
  761. return __x;
  762. }
  763. template<bidirectional_iterator _It>
  764. constexpr _It
  765. prev(_It __x, iter_difference_t<_It> __n, _It __bound)
  766. {
  767. ranges::advance(__x, -__n, __bound);
  768. return __x;
  769. }
  770. /// Type returned by algorithms instead of a dangling iterator or subrange.
  771. struct dangling
  772. {
  773. constexpr dangling() noexcept = default;
  774. template<typename... _Args>
  775. constexpr dangling(_Args&&...) noexcept { }
  776. };
  777. template<range _Range>
  778. using borrowed_iterator_t = conditional_t<borrowed_range<_Range>,
  779. iterator_t<_Range>,
  780. dangling>;
  781. } // namespace ranges
  782. _GLIBCXX_END_NAMESPACE_VERSION
  783. } // namespace std
  784. #endif // library concepts
  785. #endif // C++20
  786. #endif // _GLIBCXX_RANGES_BASE_H