您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. // <range_access.h> -*- C++ -*-
  2. // Copyright (C) 2010-2020 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/range_access.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{iterator}
  23. */
  24. #ifndef _GLIBCXX_RANGE_ACCESS_H
  25. #define _GLIBCXX_RANGE_ACCESS_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus >= 201103L
  28. #include <initializer_list>
  29. #include <bits/iterator_concepts.h>
  30. #include <ext/numeric_traits.h>
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. /**
  35. * @brief Return an iterator pointing to the first element of
  36. * the container.
  37. * @param __cont Container.
  38. */
  39. template<typename _Container>
  40. inline _GLIBCXX17_CONSTEXPR auto
  41. begin(_Container& __cont) -> decltype(__cont.begin())
  42. { return __cont.begin(); }
  43. /**
  44. * @brief Return an iterator pointing to the first element of
  45. * the const container.
  46. * @param __cont Container.
  47. */
  48. template<typename _Container>
  49. inline _GLIBCXX17_CONSTEXPR auto
  50. begin(const _Container& __cont) -> decltype(__cont.begin())
  51. { return __cont.begin(); }
  52. /**
  53. * @brief Return an iterator pointing to one past the last element of
  54. * the container.
  55. * @param __cont Container.
  56. */
  57. template<typename _Container>
  58. inline _GLIBCXX17_CONSTEXPR auto
  59. end(_Container& __cont) -> decltype(__cont.end())
  60. { return __cont.end(); }
  61. /**
  62. * @brief Return an iterator pointing to one past the last element of
  63. * the const container.
  64. * @param __cont Container.
  65. */
  66. template<typename _Container>
  67. inline _GLIBCXX17_CONSTEXPR auto
  68. end(const _Container& __cont) -> decltype(__cont.end())
  69. { return __cont.end(); }
  70. /**
  71. * @brief Return an iterator pointing to the first element of the array.
  72. * @param __arr Array.
  73. */
  74. template<typename _Tp, size_t _Nm>
  75. inline _GLIBCXX14_CONSTEXPR _Tp*
  76. begin(_Tp (&__arr)[_Nm])
  77. { return __arr; }
  78. /**
  79. * @brief Return an iterator pointing to one past the last element
  80. * of the array.
  81. * @param __arr Array.
  82. */
  83. template<typename _Tp, size_t _Nm>
  84. inline _GLIBCXX14_CONSTEXPR _Tp*
  85. end(_Tp (&__arr)[_Nm])
  86. { return __arr + _Nm; }
  87. #if __cplusplus >= 201402L
  88. template<typename _Tp> class valarray;
  89. // These overloads must be declared for cbegin and cend to use them.
  90. template<typename _Tp> _Tp* begin(valarray<_Tp>&);
  91. template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
  92. template<typename _Tp> _Tp* end(valarray<_Tp>&);
  93. template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
  94. /**
  95. * @brief Return an iterator pointing to the first element of
  96. * the const container.
  97. * @param __cont Container.
  98. */
  99. template<typename _Container>
  100. inline constexpr auto
  101. cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
  102. -> decltype(std::begin(__cont))
  103. { return std::begin(__cont); }
  104. /**
  105. * @brief Return an iterator pointing to one past the last element of
  106. * the const container.
  107. * @param __cont Container.
  108. */
  109. template<typename _Container>
  110. inline constexpr auto
  111. cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
  112. -> decltype(std::end(__cont))
  113. { return std::end(__cont); }
  114. /**
  115. * @brief Return a reverse iterator pointing to the last element of
  116. * the container.
  117. * @param __cont Container.
  118. */
  119. template<typename _Container>
  120. inline _GLIBCXX17_CONSTEXPR auto
  121. rbegin(_Container& __cont) -> decltype(__cont.rbegin())
  122. { return __cont.rbegin(); }
  123. /**
  124. * @brief Return a reverse iterator pointing to the last element of
  125. * the const container.
  126. * @param __cont Container.
  127. */
  128. template<typename _Container>
  129. inline _GLIBCXX17_CONSTEXPR auto
  130. rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
  131. { return __cont.rbegin(); }
  132. /**
  133. * @brief Return a reverse iterator pointing one past the first element of
  134. * the container.
  135. * @param __cont Container.
  136. */
  137. template<typename _Container>
  138. inline _GLIBCXX17_CONSTEXPR auto
  139. rend(_Container& __cont) -> decltype(__cont.rend())
  140. { return __cont.rend(); }
  141. /**
  142. * @brief Return a reverse iterator pointing one past the first element of
  143. * the const container.
  144. * @param __cont Container.
  145. */
  146. template<typename _Container>
  147. inline _GLIBCXX17_CONSTEXPR auto
  148. rend(const _Container& __cont) -> decltype(__cont.rend())
  149. { return __cont.rend(); }
  150. /**
  151. * @brief Return a reverse iterator pointing to the last element of
  152. * the array.
  153. * @param __arr Array.
  154. */
  155. template<typename _Tp, size_t _Nm>
  156. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  157. rbegin(_Tp (&__arr)[_Nm])
  158. { return reverse_iterator<_Tp*>(__arr + _Nm); }
  159. /**
  160. * @brief Return a reverse iterator pointing one past the first element of
  161. * the array.
  162. * @param __arr Array.
  163. */
  164. template<typename _Tp, size_t _Nm>
  165. inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
  166. rend(_Tp (&__arr)[_Nm])
  167. { return reverse_iterator<_Tp*>(__arr); }
  168. /**
  169. * @brief Return a reverse iterator pointing to the last element of
  170. * the initializer_list.
  171. * @param __il initializer_list.
  172. */
  173. template<typename _Tp>
  174. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  175. rbegin(initializer_list<_Tp> __il)
  176. { return reverse_iterator<const _Tp*>(__il.end()); }
  177. /**
  178. * @brief Return a reverse iterator pointing one past the first element of
  179. * the initializer_list.
  180. * @param __il initializer_list.
  181. */
  182. template<typename _Tp>
  183. inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
  184. rend(initializer_list<_Tp> __il)
  185. { return reverse_iterator<const _Tp*>(__il.begin()); }
  186. /**
  187. * @brief Return a reverse iterator pointing to the last element of
  188. * the const container.
  189. * @param __cont Container.
  190. */
  191. template<typename _Container>
  192. inline _GLIBCXX17_CONSTEXPR auto
  193. crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont))
  194. { return std::rbegin(__cont); }
  195. /**
  196. * @brief Return a reverse iterator pointing one past the first element of
  197. * the const container.
  198. * @param __cont Container.
  199. */
  200. template<typename _Container>
  201. inline _GLIBCXX17_CONSTEXPR auto
  202. crend(const _Container& __cont) -> decltype(std::rend(__cont))
  203. { return std::rend(__cont); }
  204. #endif // C++14
  205. #if __cplusplus >= 201703L
  206. #define __cpp_lib_nonmember_container_access 201411
  207. /**
  208. * @brief Return the size of a container.
  209. * @param __cont Container.
  210. */
  211. template <typename _Container>
  212. constexpr auto
  213. size(const _Container& __cont) noexcept(noexcept(__cont.size()))
  214. -> decltype(__cont.size())
  215. { return __cont.size(); }
  216. /**
  217. * @brief Return the size of an array.
  218. */
  219. template <typename _Tp, size_t _Nm>
  220. constexpr size_t
  221. size(const _Tp (&)[_Nm]) noexcept
  222. { return _Nm; }
  223. /**
  224. * @brief Return whether a container is empty.
  225. * @param __cont Container.
  226. */
  227. template <typename _Container>
  228. [[nodiscard]] constexpr auto
  229. empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
  230. -> decltype(__cont.empty())
  231. { return __cont.empty(); }
  232. /**
  233. * @brief Return whether an array is empty (always false).
  234. */
  235. template <typename _Tp, size_t _Nm>
  236. [[nodiscard]] constexpr bool
  237. empty(const _Tp (&)[_Nm]) noexcept
  238. { return false; }
  239. /**
  240. * @brief Return whether an initializer_list is empty.
  241. * @param __il Initializer list.
  242. */
  243. template <typename _Tp>
  244. [[nodiscard]] constexpr bool
  245. empty(initializer_list<_Tp> __il) noexcept
  246. { return __il.size() == 0;}
  247. /**
  248. * @brief Return the data pointer of a container.
  249. * @param __cont Container.
  250. */
  251. template <typename _Container>
  252. constexpr auto
  253. data(_Container& __cont) noexcept(noexcept(__cont.data()))
  254. -> decltype(__cont.data())
  255. { return __cont.data(); }
  256. /**
  257. * @brief Return the data pointer of a const container.
  258. * @param __cont Container.
  259. */
  260. template <typename _Container>
  261. constexpr auto
  262. data(const _Container& __cont) noexcept(noexcept(__cont.data()))
  263. -> decltype(__cont.data())
  264. { return __cont.data(); }
  265. /**
  266. * @brief Return the data pointer of an array.
  267. * @param __array Array.
  268. */
  269. template <typename _Tp, size_t _Nm>
  270. constexpr _Tp*
  271. data(_Tp (&__array)[_Nm]) noexcept
  272. { return __array; }
  273. /**
  274. * @brief Return the data pointer of an initializer list.
  275. * @param __il Initializer list.
  276. */
  277. template <typename _Tp>
  278. constexpr const _Tp*
  279. data(initializer_list<_Tp> __il) noexcept
  280. { return __il.begin(); }
  281. #endif // C++17
  282. #if __cplusplus > 201703L
  283. #define __cpp_lib_ssize 201902L
  284. template<typename _Container>
  285. constexpr auto
  286. ssize(const _Container& __cont)
  287. noexcept(noexcept(__cont.size()))
  288. -> common_type_t<ptrdiff_t, make_signed_t<decltype(__cont.size())>>
  289. {
  290. using type = make_signed_t<decltype(__cont.size())>;
  291. return static_cast<common_type_t<ptrdiff_t, type>>(__cont.size());
  292. }
  293. template<typename _Tp, ptrdiff_t _Num>
  294. constexpr ptrdiff_t
  295. ssize(const _Tp (&)[_Num]) noexcept
  296. { return _Num; }
  297. #ifdef __cpp_lib_concepts
  298. namespace ranges
  299. {
  300. template<typename>
  301. inline constexpr bool disable_sized_range = false;
  302. template<typename _Tp>
  303. inline constexpr bool enable_borrowed_range = false;
  304. template<typename _Tp>
  305. extern const bool enable_view;
  306. namespace __detail
  307. {
  308. template<integral _Tp>
  309. constexpr make_unsigned_t<_Tp>
  310. __to_unsigned_like(_Tp __t) noexcept
  311. { return __t; }
  312. template<typename _Tp, bool _MaxDiff = same_as<_Tp, __max_diff_type>>
  313. using __make_unsigned_like_t
  314. = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>;
  315. // Part of the constraints of ranges::borrowed_range
  316. template<typename _Tp>
  317. concept __maybe_borrowed_range
  318. = is_lvalue_reference_v<_Tp>
  319. || enable_borrowed_range<remove_cvref_t<_Tp>>;
  320. } // namespace __detail
  321. namespace __cust_access
  322. {
  323. using std::ranges::__detail::__maybe_borrowed_range;
  324. using std::__detail::__class_or_enum;
  325. using std::__detail::__decay_copy;
  326. using std::__detail::__member_begin;
  327. using std::__detail::__adl_begin;
  328. struct _Begin
  329. {
  330. private:
  331. template<typename _Tp>
  332. static constexpr bool
  333. _S_noexcept()
  334. {
  335. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  336. return true;
  337. else if constexpr (__member_begin<_Tp>)
  338. return noexcept(__decay_copy(std::declval<_Tp&>().begin()));
  339. else
  340. return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
  341. }
  342. public:
  343. template<__maybe_borrowed_range _Tp>
  344. requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
  345. || __adl_begin<_Tp>
  346. constexpr auto
  347. operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
  348. {
  349. if constexpr (is_array_v<remove_reference_t<_Tp>>)
  350. {
  351. static_assert(is_lvalue_reference_v<_Tp>);
  352. using _Up = remove_all_extents_t<remove_reference_t<_Tp>>;
  353. static_assert(sizeof(_Up) != 0, "not array of incomplete type");
  354. return __t + 0;
  355. }
  356. else if constexpr (__member_begin<_Tp>)
  357. return __t.begin();
  358. else
  359. return begin(__t);
  360. }
  361. };
  362. template<typename _Tp>
  363. concept __member_end = requires(_Tp& __t)
  364. {
  365. { __decay_copy(__t.end()) }
  366. -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  367. };
  368. void end(auto&) = delete;
  369. void end(const auto&) = delete;
  370. template<typename _Tp>
  371. concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
  372. && requires(_Tp& __t)
  373. {
  374. { __decay_copy(end(__t)) }
  375. -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  376. };
  377. struct _End
  378. {
  379. private:
  380. template<typename _Tp>
  381. static constexpr bool
  382. _S_noexcept()
  383. {
  384. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  385. return true;
  386. else if constexpr (__member_end<_Tp>)
  387. return noexcept(__decay_copy(std::declval<_Tp&>().end()));
  388. else
  389. return noexcept(__decay_copy(end(std::declval<_Tp&>())));
  390. }
  391. public:
  392. template<__maybe_borrowed_range _Tp>
  393. requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_end<_Tp>
  394. || __adl_end<_Tp>
  395. constexpr auto
  396. operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
  397. {
  398. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  399. {
  400. static_assert(is_lvalue_reference_v<_Tp>);
  401. return __t + extent_v<remove_reference_t<_Tp>>;
  402. }
  403. else if constexpr (__member_end<_Tp>)
  404. return __t.end();
  405. else
  406. return end(__t);
  407. }
  408. };
  409. template<typename _Tp>
  410. constexpr decltype(auto)
  411. __as_const(_Tp&& __t) noexcept
  412. {
  413. if constexpr (is_lvalue_reference_v<_Tp>)
  414. return static_cast<const remove_reference_t<_Tp>&>(__t);
  415. else
  416. return static_cast<const _Tp&&>(__t);
  417. }
  418. struct _CBegin
  419. {
  420. template<typename _Tp>
  421. constexpr auto
  422. operator()(_Tp&& __e) const
  423. noexcept(noexcept(_Begin{}(__cust_access::__as_const((_Tp&&)__e))))
  424. requires requires { _Begin{}(__cust_access::__as_const((_Tp&&)__e)); }
  425. {
  426. return _Begin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  427. }
  428. };
  429. struct _CEnd
  430. {
  431. template<typename _Tp>
  432. constexpr auto
  433. operator()(_Tp&& __e) const
  434. noexcept(noexcept(_End{}(__cust_access::__as_const((_Tp&&)__e))))
  435. requires requires { _End{}(__cust_access::__as_const((_Tp&&)__e)); }
  436. {
  437. return _End{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  438. }
  439. };
  440. template<typename _Tp>
  441. concept __member_rbegin = requires(_Tp& __t)
  442. {
  443. { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
  444. };
  445. void rbegin(auto&) = delete;
  446. void rbegin(const auto&) = delete;
  447. template<typename _Tp>
  448. concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
  449. && requires(_Tp& __t)
  450. {
  451. { __decay_copy(rbegin(__t)) } -> input_or_output_iterator;
  452. };
  453. template<typename _Tp>
  454. concept __reversable = requires(_Tp& __t)
  455. {
  456. { _Begin{}(__t) } -> bidirectional_iterator;
  457. { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
  458. };
  459. struct _RBegin
  460. {
  461. private:
  462. template<typename _Tp>
  463. static constexpr bool
  464. _S_noexcept()
  465. {
  466. if constexpr (__member_rbegin<_Tp>)
  467. return noexcept(__decay_copy(std::declval<_Tp&>().rbegin()));
  468. else if constexpr (__adl_rbegin<_Tp>)
  469. return noexcept(__decay_copy(rbegin(std::declval<_Tp&>())));
  470. else
  471. {
  472. if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
  473. {
  474. using _It = decltype(_End{}(std::declval<_Tp&>()));
  475. // std::reverse_iterator copy-initializes its member.
  476. return is_nothrow_copy_constructible_v<_It>;
  477. }
  478. else
  479. return false;
  480. }
  481. }
  482. public:
  483. template<__maybe_borrowed_range _Tp>
  484. requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
  485. constexpr auto
  486. operator()(_Tp&& __t) const
  487. noexcept(_S_noexcept<_Tp>())
  488. {
  489. if constexpr (__member_rbegin<_Tp>)
  490. return __t.rbegin();
  491. else if constexpr (__adl_rbegin<_Tp>)
  492. return rbegin(__t);
  493. else
  494. return std::make_reverse_iterator(_End{}(__t));
  495. }
  496. };
  497. template<typename _Tp>
  498. concept __member_rend = requires(_Tp& __t)
  499. {
  500. { __decay_copy(__t.rend()) }
  501. -> sentinel_for<decltype(_RBegin{}(__t))>;
  502. };
  503. void rend(auto&) = delete;
  504. void rend(const auto&) = delete;
  505. template<typename _Tp>
  506. concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
  507. && requires(_Tp& __t)
  508. {
  509. { __decay_copy(rend(__t)) }
  510. -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
  511. };
  512. struct _REnd
  513. {
  514. private:
  515. template<typename _Tp>
  516. static constexpr bool
  517. _S_noexcept()
  518. {
  519. if constexpr (__member_rend<_Tp>)
  520. return noexcept(__decay_copy(std::declval<_Tp&>().rend()));
  521. else if constexpr (__adl_rend<_Tp>)
  522. return noexcept(__decay_copy(rend(std::declval<_Tp&>())));
  523. else
  524. {
  525. if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
  526. {
  527. using _It = decltype(_Begin{}(std::declval<_Tp&>()));
  528. // std::reverse_iterator copy-initializes its member.
  529. return is_nothrow_copy_constructible_v<_It>;
  530. }
  531. else
  532. return false;
  533. }
  534. }
  535. public:
  536. template<__maybe_borrowed_range _Tp>
  537. requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
  538. constexpr auto
  539. operator()(_Tp&& __t) const
  540. noexcept(_S_noexcept<_Tp>())
  541. {
  542. if constexpr (__member_rend<_Tp>)
  543. return __t.rend();
  544. else if constexpr (__adl_rend<_Tp>)
  545. return rend(__t);
  546. else
  547. return std::make_reverse_iterator(_Begin{}(__t));
  548. }
  549. };
  550. struct _CRBegin
  551. {
  552. template<typename _Tp>
  553. constexpr auto
  554. operator()(_Tp&& __e) const
  555. noexcept(noexcept(_RBegin{}(__cust_access::__as_const((_Tp&&)__e))))
  556. requires requires { _RBegin{}(__cust_access::__as_const((_Tp&&)__e)); }
  557. {
  558. return _RBegin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  559. }
  560. };
  561. struct _CREnd
  562. {
  563. template<typename _Tp>
  564. constexpr auto
  565. operator()(_Tp&& __e) const
  566. noexcept(noexcept(_REnd{}(__cust_access::__as_const((_Tp&&)__e))))
  567. requires requires { _REnd{}(__cust_access::__as_const((_Tp&&)__e)); }
  568. {
  569. return _REnd{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  570. }
  571. };
  572. template<typename _Tp>
  573. concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
  574. && requires(_Tp&& __t)
  575. {
  576. { __decay_copy(std::forward<_Tp>(__t).size()) }
  577. -> __detail::__is_integer_like;
  578. };
  579. void size(auto&) = delete;
  580. void size(const auto&) = delete;
  581. template<typename _Tp>
  582. concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
  583. && !disable_sized_range<remove_cvref_t<_Tp>>
  584. && requires(_Tp&& __t)
  585. {
  586. { __decay_copy(size(std::forward<_Tp>(__t))) }
  587. -> __detail::__is_integer_like;
  588. };
  589. template<typename _Tp>
  590. concept __sentinel_size = requires(_Tp&& __t)
  591. {
  592. { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
  593. { _End{}(std::forward<_Tp>(__t)) }
  594. -> sized_sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
  595. };
  596. struct _Size
  597. {
  598. private:
  599. template<typename _Tp>
  600. static constexpr bool
  601. _S_noexcept()
  602. {
  603. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  604. return true;
  605. else if constexpr (__member_size<_Tp>)
  606. return noexcept(__decay_copy(std::declval<_Tp>().size()));
  607. else if constexpr (__adl_size<_Tp>)
  608. return noexcept(__decay_copy(size(std::declval<_Tp>())));
  609. else if constexpr (__sentinel_size<_Tp>)
  610. return noexcept(_End{}(std::declval<_Tp>())
  611. - _Begin{}(std::declval<_Tp>()));
  612. }
  613. public:
  614. template<typename _Tp>
  615. requires is_bounded_array_v<remove_reference_t<_Tp>>
  616. || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
  617. constexpr auto
  618. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  619. {
  620. if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
  621. {
  622. return extent_v<remove_reference_t<_Tp>>;
  623. }
  624. else if constexpr (__member_size<_Tp>)
  625. return std::forward<_Tp>(__e).size();
  626. else if constexpr (__adl_size<_Tp>)
  627. return size(std::forward<_Tp>(__e));
  628. else if constexpr (__sentinel_size<_Tp>)
  629. return __detail::__to_unsigned_like(
  630. _End{}(std::forward<_Tp>(__e))
  631. - _Begin{}(std::forward<_Tp>(__e)));
  632. }
  633. };
  634. struct _SSize
  635. {
  636. template<typename _Tp>
  637. requires requires (_Tp&& __e)
  638. {
  639. _Begin{}(std::forward<_Tp>(__e));
  640. _Size{}(std::forward<_Tp>(__e));
  641. }
  642. constexpr auto
  643. operator()(_Tp&& __e) const
  644. noexcept(noexcept(_Size{}(std::forward<_Tp>(__e))))
  645. {
  646. using __iter_type = decltype(_Begin{}(std::forward<_Tp>(__e)));
  647. using __diff_type = iter_difference_t<__iter_type>;
  648. using __gnu_cxx::__int_traits;
  649. auto __size = _Size{}(std::forward<_Tp>(__e));
  650. if constexpr (integral<__diff_type>)
  651. {
  652. if constexpr (__int_traits<__diff_type>::__digits
  653. < __int_traits<ptrdiff_t>::__digits)
  654. return static_cast<ptrdiff_t>(__size);
  655. }
  656. return static_cast<__diff_type>(__size);
  657. }
  658. };
  659. template<typename _Tp>
  660. concept __member_empty = requires(_Tp&& __t)
  661. { bool(std::forward<_Tp>(__t).empty()); };
  662. template<typename _Tp>
  663. concept __size0_empty = requires(_Tp&& __t)
  664. { _Size{}(std::forward<_Tp>(__t)) == 0; };
  665. template<typename _Tp>
  666. concept __eq_iter_empty = requires(_Tp&& __t)
  667. {
  668. { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
  669. bool(_Begin{}(std::forward<_Tp>(__t))
  670. == _End{}(std::forward<_Tp>(__t)));
  671. };
  672. struct _Empty
  673. {
  674. private:
  675. template<typename _Tp>
  676. static constexpr bool
  677. _S_noexcept()
  678. {
  679. if constexpr (__member_empty<_Tp>)
  680. return noexcept(std::declval<_Tp>().empty());
  681. else if constexpr (__size0_empty<_Tp>)
  682. return noexcept(_Size{}(std::declval<_Tp>()) == 0);
  683. else
  684. return noexcept(bool(_Begin{}(std::declval<_Tp>())
  685. == _End{}(std::declval<_Tp>())));
  686. }
  687. public:
  688. template<typename _Tp>
  689. requires __member_empty<_Tp> || __size0_empty<_Tp>
  690. || __eq_iter_empty<_Tp>
  691. constexpr bool
  692. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  693. {
  694. if constexpr (__member_empty<_Tp>)
  695. return bool(std::forward<_Tp>(__e).empty());
  696. else if constexpr (__size0_empty<_Tp>)
  697. return _Size{}(std::forward<_Tp>(__e)) == 0;
  698. else
  699. return bool(_Begin{}(std::forward<_Tp>(__e))
  700. == _End{}(std::forward<_Tp>(__e)));
  701. }
  702. };
  703. template<typename _Tp>
  704. concept __pointer_to_object = is_pointer_v<_Tp>
  705. && is_object_v<remove_pointer_t<_Tp>>;
  706. template<typename _Tp>
  707. concept __member_data = is_lvalue_reference_v<_Tp>
  708. && requires(_Tp __t) { { __t.data() } -> __pointer_to_object; };
  709. template<typename _Tp>
  710. concept __begin_data = requires(_Tp&& __t)
  711. { { _Begin{}(std::forward<_Tp>(__t)) } -> contiguous_iterator; };
  712. struct _Data
  713. {
  714. private:
  715. template<typename _Tp>
  716. static constexpr bool
  717. _S_noexcept()
  718. {
  719. if constexpr (__member_data<_Tp>)
  720. return noexcept(__decay_copy(std::declval<_Tp>().data()));
  721. else
  722. return noexcept(_Begin{}(std::declval<_Tp>()));
  723. }
  724. public:
  725. template<__maybe_borrowed_range _Tp>
  726. requires __member_data<_Tp> || __begin_data<_Tp>
  727. constexpr auto
  728. operator()(_Tp&& __e) const noexcept(_S_noexcept<_Tp>())
  729. {
  730. if constexpr (__member_data<_Tp>)
  731. return __e.data();
  732. else
  733. return std::to_address(_Begin{}(std::forward<_Tp>(__e)));
  734. }
  735. };
  736. struct _CData
  737. {
  738. template<typename _Tp>
  739. constexpr auto
  740. operator()(_Tp&& __e) const
  741. noexcept(noexcept(_Data{}(__cust_access::__as_const((_Tp&&)__e))))
  742. requires requires { _Data{}(__cust_access::__as_const((_Tp&&)__e)); }
  743. {
  744. return _Data{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
  745. }
  746. };
  747. } // namespace __cust_access
  748. inline namespace __cust
  749. {
  750. inline constexpr __cust_access::_Begin begin{};
  751. inline constexpr __cust_access::_End end{};
  752. inline constexpr __cust_access::_CBegin cbegin{};
  753. inline constexpr __cust_access::_CEnd cend{};
  754. inline constexpr __cust_access::_RBegin rbegin{};
  755. inline constexpr __cust_access::_REnd rend{};
  756. inline constexpr __cust_access::_CRBegin crbegin{};
  757. inline constexpr __cust_access::_CREnd crend{};
  758. inline constexpr __cust_access::_Size size{};
  759. inline constexpr __cust_access::_SSize ssize{};
  760. inline constexpr __cust_access::_Empty empty{};
  761. inline constexpr __cust_access::_Data data{};
  762. inline constexpr __cust_access::_CData cdata{};
  763. }
  764. /// [range.range] The range concept.
  765. template<typename _Tp>
  766. concept range = requires(_Tp& __t)
  767. {
  768. ranges::begin(__t);
  769. ranges::end(__t);
  770. };
  771. /// [range.range] The borrowed_range concept.
  772. template<typename _Tp>
  773. concept borrowed_range
  774. = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
  775. template<typename _Tp>
  776. using iterator_t = std::__detail::__range_iter_t<_Tp>;
  777. template<range _Range>
  778. using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
  779. template<range _Range>
  780. using range_difference_t = iter_difference_t<iterator_t<_Range>>;
  781. template<range _Range>
  782. using range_value_t = iter_value_t<iterator_t<_Range>>;
  783. template<range _Range>
  784. using range_reference_t = iter_reference_t<iterator_t<_Range>>;
  785. template<range _Range>
  786. using range_rvalue_reference_t
  787. = iter_rvalue_reference_t<iterator_t<_Range>>;
  788. /// [range.sized] The sized_range concept.
  789. template<typename _Tp>
  790. concept sized_range = range<_Tp>
  791. && requires(_Tp& __t) { ranges::size(__t); };
  792. template<sized_range _Range>
  793. using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
  794. // [range.refinements]
  795. /// A range for which ranges::begin returns an output iterator.
  796. template<typename _Range, typename _Tp>
  797. concept output_range
  798. = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
  799. /// A range for which ranges::begin returns an input iterator.
  800. template<typename _Tp>
  801. concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
  802. /// A range for which ranges::begin returns a forward iterator.
  803. template<typename _Tp>
  804. concept forward_range
  805. = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
  806. /// A range for which ranges::begin returns a bidirectional iterator.
  807. template<typename _Tp>
  808. concept bidirectional_range
  809. = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
  810. /// A range for which ranges::begin returns a random access iterator.
  811. template<typename _Tp>
  812. concept random_access_range
  813. = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
  814. /// A range for which ranges::begin returns a contiguous iterator.
  815. template<typename _Tp>
  816. concept contiguous_range
  817. = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
  818. && requires(_Tp& __t)
  819. {
  820. { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
  821. };
  822. /// A range for which ranges::begin and ranges::end return the same type.
  823. template<typename _Tp>
  824. concept common_range
  825. = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
  826. // [range.iter.ops] range iterator operations
  827. template<input_or_output_iterator _It>
  828. constexpr void
  829. advance(_It& __it, iter_difference_t<_It> __n)
  830. {
  831. if constexpr (random_access_iterator<_It>)
  832. __it += __n;
  833. else if constexpr (bidirectional_iterator<_It>)
  834. {
  835. if (__n > 0)
  836. {
  837. do
  838. {
  839. ++__it;
  840. }
  841. while (--__n);
  842. }
  843. else if (__n < 0)
  844. {
  845. do
  846. {
  847. --__it;
  848. }
  849. while (++__n);
  850. }
  851. }
  852. else
  853. {
  854. #ifdef __cpp_lib_is_constant_evaluated
  855. if (std::is_constant_evaluated() && __n < 0)
  856. throw "attempt to decrement a non-bidirectional iterator";
  857. #endif
  858. __glibcxx_assert(__n >= 0);
  859. while (__n-- > 0)
  860. ++__it;
  861. }
  862. }
  863. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  864. constexpr void
  865. advance(_It& __it, _Sent __bound)
  866. {
  867. if constexpr (assignable_from<_It&, _Sent>)
  868. __it = std::move(__bound);
  869. else if constexpr (sized_sentinel_for<_Sent, _It>)
  870. ranges::advance(__it, __bound - __it);
  871. else
  872. {
  873. while (__it != __bound)
  874. ++__it;
  875. }
  876. }
  877. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  878. constexpr iter_difference_t<_It>
  879. advance(_It& __it, iter_difference_t<_It> __n, _Sent __bound)
  880. {
  881. if constexpr (sized_sentinel_for<_Sent, _It>)
  882. {
  883. const auto __diff = __bound - __it;
  884. #ifdef __cpp_lib_is_constant_evaluated
  885. if (std::is_constant_evaluated()
  886. && !(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0)))
  887. throw "inconsistent directions for distance and bound";
  888. #endif
  889. // n and bound must not lead in opposite directions:
  890. __glibcxx_assert(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0));
  891. const auto __absdiff = __diff < 0 ? -__diff : __diff;
  892. const auto __absn = __n < 0 ? -__n : __n;;
  893. if (__absn >= __absdiff)
  894. {
  895. ranges::advance(__it, __bound);
  896. return __n - __diff;
  897. }
  898. else
  899. {
  900. ranges::advance(__it, __n);
  901. return 0;
  902. }
  903. }
  904. else if (__it == __bound || __n == 0)
  905. return iter_difference_t<_It>(0);
  906. else if (__n > 0)
  907. {
  908. iter_difference_t<_It> __m = 0;
  909. do
  910. {
  911. ++__it;
  912. ++__m;
  913. }
  914. while (__m != __n && __it != __bound);
  915. return __n - __m;
  916. }
  917. else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
  918. {
  919. iter_difference_t<_It> __m = 0;
  920. do
  921. {
  922. --__it;
  923. --__m;
  924. }
  925. while (__m != __n && __it != __bound);
  926. return __n - __m;
  927. }
  928. else
  929. {
  930. #ifdef __cpp_lib_is_constant_evaluated
  931. if (std::is_constant_evaluated() && __n < 0)
  932. throw "attempt to decrement a non-bidirectional iterator";
  933. #endif
  934. __glibcxx_assert(__n >= 0);
  935. return __n;
  936. }
  937. }
  938. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  939. constexpr iter_difference_t<_It>
  940. distance(_It __first, _Sent __last)
  941. {
  942. if constexpr (sized_sentinel_for<_Sent, _It>)
  943. return __last - __first;
  944. else
  945. {
  946. iter_difference_t<_It> __n = 0;
  947. while (__first != __last)
  948. {
  949. ++__first;
  950. ++__n;
  951. }
  952. return __n;
  953. }
  954. }
  955. template<range _Range>
  956. constexpr range_difference_t<_Range>
  957. distance(_Range&& __r)
  958. {
  959. if constexpr (sized_range<_Range>)
  960. return static_cast<range_difference_t<_Range>>(ranges::size(__r));
  961. else
  962. return ranges::distance(ranges::begin(__r), ranges::end(__r));
  963. }
  964. template<input_or_output_iterator _It>
  965. constexpr _It
  966. next(_It __x)
  967. {
  968. ++__x;
  969. return __x;
  970. }
  971. template<input_or_output_iterator _It>
  972. constexpr _It
  973. next(_It __x, iter_difference_t<_It> __n)
  974. {
  975. ranges::advance(__x, __n);
  976. return __x;
  977. }
  978. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  979. constexpr _It
  980. next(_It __x, _Sent __bound)
  981. {
  982. ranges::advance(__x, __bound);
  983. return __x;
  984. }
  985. template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
  986. constexpr _It
  987. next(_It __x, iter_difference_t<_It> __n, _Sent __bound)
  988. {
  989. ranges::advance(__x, __n, __bound);
  990. return __x;
  991. }
  992. template<bidirectional_iterator _It>
  993. constexpr _It
  994. prev(_It __x)
  995. {
  996. --__x;
  997. return __x;
  998. }
  999. template<bidirectional_iterator _It>
  1000. constexpr _It
  1001. prev(_It __x, iter_difference_t<_It> __n)
  1002. {
  1003. ranges::advance(__x, -__n);
  1004. return __x;
  1005. }
  1006. template<bidirectional_iterator _It>
  1007. constexpr _It
  1008. prev(_It __x, iter_difference_t<_It> __n, _It __bound)
  1009. {
  1010. ranges::advance(__x, -__n, __bound);
  1011. return __x;
  1012. }
  1013. } // namespace ranges
  1014. #endif // library concepts
  1015. #endif // C++20
  1016. _GLIBCXX_END_NAMESPACE_VERSION
  1017. } // namespace
  1018. #endif // C++11
  1019. #endif // _GLIBCXX_RANGE_ACCESS_H