iterator_concepts.h 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. // Concepts and traits for use with iterators -*- C++ -*-
  2. // Copyright (C) 2019-2023 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/iterator_concepts.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 _ITERATOR_CONCEPTS_H
  25. #define _ITERATOR_CONCEPTS_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus >= 202002L
  28. #include <concepts>
  29. #include <bits/ptr_traits.h> // to_address
  30. #include <bits/ranges_cmp.h> // identity, ranges::less
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. /** A sentinel type that can be used to check for the end of a range.
  35. *
  36. * For some iterator types the past-the-end sentinel value is independent
  37. * of the underlying sequence, and a default sentinel can be used with them.
  38. * For example, a `std::counted_iterator` keeps a count of how many elements
  39. * remain, and so checking for the past-the-end value only requires checking
  40. * if that count has reached zero. A past-the-end `std::istream_iterator` is
  41. * equal to the default-constructed value, which can be easily checked.
  42. *
  43. * Comparing iterators of these types to `std::default_sentinel` is a
  44. * convenient way to check if the end has been reached.
  45. *
  46. * @since C++20
  47. */
  48. struct default_sentinel_t { };
  49. /// A default sentinel value.
  50. inline constexpr default_sentinel_t default_sentinel{};
  51. #if __cpp_lib_concepts
  52. struct input_iterator_tag;
  53. struct output_iterator_tag;
  54. struct forward_iterator_tag;
  55. struct bidirectional_iterator_tag;
  56. struct random_access_iterator_tag;
  57. struct contiguous_iterator_tag;
  58. template<typename _Iterator>
  59. struct iterator_traits;
  60. template<typename _Tp> requires is_object_v<_Tp>
  61. struct iterator_traits<_Tp*>;
  62. template<typename _Iterator, typename>
  63. struct __iterator_traits;
  64. namespace __detail
  65. {
  66. template<typename _Tp>
  67. using __with_ref = _Tp&;
  68. template<typename _Tp>
  69. concept __can_reference = requires { typename __with_ref<_Tp>; };
  70. template<typename _Tp>
  71. concept __dereferenceable = requires(_Tp& __t)
  72. {
  73. { *__t } -> __can_reference;
  74. };
  75. } // namespace __detail
  76. template<__detail::__dereferenceable _Tp>
  77. using iter_reference_t = decltype(*std::declval<_Tp&>());
  78. namespace ranges
  79. {
  80. namespace __cust_imove
  81. {
  82. void iter_move();
  83. template<typename _Tp>
  84. concept __adl_imove
  85. = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>)
  86. && requires(_Tp&& __t) { iter_move(static_cast<_Tp&&>(__t)); };
  87. struct _IMove
  88. {
  89. private:
  90. template<typename _Tp>
  91. struct __result
  92. { using type = iter_reference_t<_Tp>; };
  93. template<typename _Tp>
  94. requires __adl_imove<_Tp>
  95. struct __result<_Tp>
  96. { using type = decltype(iter_move(std::declval<_Tp>())); };
  97. template<typename _Tp>
  98. requires (!__adl_imove<_Tp>)
  99. && is_lvalue_reference_v<iter_reference_t<_Tp>>
  100. struct __result<_Tp>
  101. { using type = remove_reference_t<iter_reference_t<_Tp>>&&; };
  102. template<typename _Tp>
  103. static constexpr bool
  104. _S_noexcept()
  105. {
  106. if constexpr (__adl_imove<_Tp>)
  107. return noexcept(iter_move(std::declval<_Tp>()));
  108. else
  109. return noexcept(*std::declval<_Tp>());
  110. }
  111. public:
  112. // The result type of iter_move(std::declval<_Tp>())
  113. template<std::__detail::__dereferenceable _Tp>
  114. using __type = typename __result<_Tp>::type;
  115. template<std::__detail::__dereferenceable _Tp>
  116. [[nodiscard]]
  117. constexpr __type<_Tp>
  118. operator()(_Tp&& __e) const
  119. noexcept(_S_noexcept<_Tp>())
  120. {
  121. if constexpr (__adl_imove<_Tp>)
  122. return iter_move(static_cast<_Tp&&>(__e));
  123. else if constexpr (is_lvalue_reference_v<iter_reference_t<_Tp>>)
  124. return static_cast<__type<_Tp>>(*__e);
  125. else
  126. return *__e;
  127. }
  128. };
  129. } // namespace __cust_imove
  130. inline namespace __cust
  131. {
  132. inline constexpr __cust_imove::_IMove iter_move{};
  133. } // inline namespace __cust
  134. } // namespace ranges
  135. template<__detail::__dereferenceable _Tp>
  136. requires __detail::
  137. __can_reference<ranges::__cust_imove::_IMove::__type<_Tp&>>
  138. using iter_rvalue_reference_t
  139. = ranges::__cust_imove::_IMove::__type<_Tp&>;
  140. template<typename> struct incrementable_traits { };
  141. template<typename _Tp> requires is_object_v<_Tp>
  142. struct incrementable_traits<_Tp*>
  143. { using difference_type = ptrdiff_t; };
  144. template<typename _Iter>
  145. struct incrementable_traits<const _Iter>
  146. : incrementable_traits<_Iter> { };
  147. template<typename _Tp> requires requires { typename _Tp::difference_type; }
  148. struct incrementable_traits<_Tp>
  149. { using difference_type = typename _Tp::difference_type; };
  150. template<typename _Tp>
  151. requires (!requires { typename _Tp::difference_type; }
  152. && requires(const _Tp& __a, const _Tp& __b)
  153. { { __a - __b } -> integral; })
  154. struct incrementable_traits<_Tp>
  155. {
  156. using difference_type
  157. = make_signed_t<decltype(std::declval<_Tp>() - std::declval<_Tp>())>;
  158. };
  159. #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
  160. // __int128 is incrementable even if !integral<__int128>
  161. template<>
  162. struct incrementable_traits<__int128>
  163. { using difference_type = __int128; };
  164. template<>
  165. struct incrementable_traits<unsigned __int128>
  166. { using difference_type = __int128; };
  167. #endif
  168. namespace __detail
  169. {
  170. // An iterator such that iterator_traits<_Iter> names a specialization
  171. // generated from the primary template.
  172. template<typename _Iter>
  173. concept __primary_traits_iter
  174. = __is_base_of(__iterator_traits<_Iter, void>, iterator_traits<_Iter>);
  175. template<typename _Iter, typename _Tp>
  176. struct __iter_traits_impl
  177. { using type = iterator_traits<_Iter>; };
  178. template<typename _Iter, typename _Tp>
  179. requires __primary_traits_iter<_Iter>
  180. struct __iter_traits_impl<_Iter, _Tp>
  181. { using type = _Tp; };
  182. // ITER_TRAITS
  183. template<typename _Iter, typename _Tp = _Iter>
  184. using __iter_traits = typename __iter_traits_impl<_Iter, _Tp>::type;
  185. template<typename _Tp>
  186. using __iter_diff_t = typename
  187. __iter_traits<_Tp, incrementable_traits<_Tp>>::difference_type;
  188. } // namespace __detail
  189. template<typename _Tp>
  190. using iter_difference_t = __detail::__iter_diff_t<remove_cvref_t<_Tp>>;
  191. namespace __detail
  192. {
  193. template<typename> struct __cond_value_type { };
  194. template<typename _Tp> requires is_object_v<_Tp>
  195. struct __cond_value_type<_Tp>
  196. { using value_type = remove_cv_t<_Tp>; };
  197. template<typename _Tp>
  198. concept __has_member_value_type
  199. = requires { typename _Tp::value_type; };
  200. template<typename _Tp>
  201. concept __has_member_element_type
  202. = requires { typename _Tp::element_type; };
  203. } // namespace __detail
  204. template<typename> struct indirectly_readable_traits { };
  205. template<typename _Tp>
  206. struct indirectly_readable_traits<_Tp*>
  207. : __detail::__cond_value_type<_Tp>
  208. { };
  209. template<typename _Iter> requires is_array_v<_Iter>
  210. struct indirectly_readable_traits<_Iter>
  211. { using value_type = remove_cv_t<remove_extent_t<_Iter>>; };
  212. template<typename _Iter>
  213. struct indirectly_readable_traits<const _Iter>
  214. : indirectly_readable_traits<_Iter>
  215. { };
  216. template<__detail::__has_member_value_type _Tp>
  217. struct indirectly_readable_traits<_Tp>
  218. : __detail::__cond_value_type<typename _Tp::value_type>
  219. { };
  220. template<__detail::__has_member_element_type _Tp>
  221. struct indirectly_readable_traits<_Tp>
  222. : __detail::__cond_value_type<typename _Tp::element_type>
  223. { };
  224. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  225. // 3446. indirectly_readable_traits ambiguity for types with both [...]
  226. template<__detail::__has_member_value_type _Tp>
  227. requires __detail::__has_member_element_type<_Tp>
  228. && same_as<remove_cv_t<typename _Tp::element_type>,
  229. remove_cv_t<typename _Tp::value_type>>
  230. struct indirectly_readable_traits<_Tp>
  231. : __detail::__cond_value_type<typename _Tp::value_type>
  232. { };
  233. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  234. // 3541. indirectly_readable_traits should be SFINAE-friendly for all types
  235. template<__detail::__has_member_value_type _Tp>
  236. requires __detail::__has_member_element_type<_Tp>
  237. struct indirectly_readable_traits<_Tp>
  238. { };
  239. namespace __detail
  240. {
  241. template<typename _Tp>
  242. using __iter_value_t = typename
  243. __iter_traits<_Tp, indirectly_readable_traits<_Tp>>::value_type;
  244. } // namespace __detail
  245. template<typename _Tp>
  246. using iter_value_t = __detail::__iter_value_t<remove_cvref_t<_Tp>>;
  247. namespace __detail
  248. {
  249. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  250. // 3420. cpp17-iterator should check [type] looks like an iterator first
  251. template<typename _Iter>
  252. concept __cpp17_iterator = requires(_Iter __it)
  253. {
  254. { *__it } -> __can_reference;
  255. { ++__it } -> same_as<_Iter&>;
  256. { *__it++ } -> __can_reference;
  257. } && copyable<_Iter>;
  258. template<typename _Iter>
  259. concept __cpp17_input_iterator = __cpp17_iterator<_Iter>
  260. && equality_comparable<_Iter>
  261. && requires(_Iter __it)
  262. {
  263. typename incrementable_traits<_Iter>::difference_type;
  264. typename indirectly_readable_traits<_Iter>::value_type;
  265. typename common_reference_t<iter_reference_t<_Iter>&&,
  266. typename indirectly_readable_traits<_Iter>::value_type&>;
  267. typename common_reference_t<decltype(*__it++)&&,
  268. typename indirectly_readable_traits<_Iter>::value_type&>;
  269. requires signed_integral<
  270. typename incrementable_traits<_Iter>::difference_type>;
  271. };
  272. template<typename _Iter>
  273. concept __cpp17_fwd_iterator = __cpp17_input_iterator<_Iter>
  274. && constructible_from<_Iter>
  275. && is_lvalue_reference_v<iter_reference_t<_Iter>>
  276. && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
  277. typename indirectly_readable_traits<_Iter>::value_type>
  278. && requires(_Iter __it)
  279. {
  280. { __it++ } -> convertible_to<const _Iter&>;
  281. { *__it++ } -> same_as<iter_reference_t<_Iter>>;
  282. };
  283. template<typename _Iter>
  284. concept __cpp17_bidi_iterator = __cpp17_fwd_iterator<_Iter>
  285. && requires(_Iter __it)
  286. {
  287. { --__it } -> same_as<_Iter&>;
  288. { __it-- } -> convertible_to<const _Iter&>;
  289. { *__it-- } -> same_as<iter_reference_t<_Iter>>;
  290. };
  291. template<typename _Iter>
  292. concept __cpp17_randacc_iterator = __cpp17_bidi_iterator<_Iter>
  293. && totally_ordered<_Iter>
  294. && requires(_Iter __it,
  295. typename incrementable_traits<_Iter>::difference_type __n)
  296. {
  297. { __it += __n } -> same_as<_Iter&>;
  298. { __it -= __n } -> same_as<_Iter&>;
  299. { __it + __n } -> same_as<_Iter>;
  300. { __n + __it } -> same_as<_Iter>;
  301. { __it - __n } -> same_as<_Iter>;
  302. { __it - __it } -> same_as<decltype(__n)>;
  303. { __it[__n] } -> convertible_to<iter_reference_t<_Iter>>;
  304. };
  305. template<typename _Iter>
  306. concept __iter_with_nested_types = requires {
  307. typename _Iter::iterator_category;
  308. typename _Iter::value_type;
  309. typename _Iter::difference_type;
  310. typename _Iter::reference;
  311. };
  312. template<typename _Iter>
  313. concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>;
  314. template<typename _Iter>
  315. concept __iter_without_category
  316. = !requires { typename _Iter::iterator_category; };
  317. } // namespace __detail
  318. template<typename _Iterator>
  319. requires __detail::__iter_with_nested_types<_Iterator>
  320. struct __iterator_traits<_Iterator, void>
  321. {
  322. private:
  323. template<typename _Iter>
  324. struct __ptr
  325. { using type = void; };
  326. template<typename _Iter> requires requires { typename _Iter::pointer; }
  327. struct __ptr<_Iter>
  328. { using type = typename _Iter::pointer; };
  329. public:
  330. using iterator_category = typename _Iterator::iterator_category;
  331. using value_type = typename _Iterator::value_type;
  332. using difference_type = typename _Iterator::difference_type;
  333. using pointer = typename __ptr<_Iterator>::type;
  334. using reference = typename _Iterator::reference;
  335. };
  336. template<typename _Iterator>
  337. requires __detail::__iter_without_nested_types<_Iterator>
  338. && __detail::__cpp17_input_iterator<_Iterator>
  339. struct __iterator_traits<_Iterator, void>
  340. {
  341. private:
  342. template<typename _Iter>
  343. struct __cat
  344. { using type = input_iterator_tag; };
  345. template<typename _Iter>
  346. requires requires { typename _Iter::iterator_category; }
  347. struct __cat<_Iter>
  348. { using type = typename _Iter::iterator_category; };
  349. template<typename _Iter>
  350. requires __detail::__iter_without_category<_Iter>
  351. && __detail::__cpp17_randacc_iterator<_Iter>
  352. struct __cat<_Iter>
  353. { using type = random_access_iterator_tag; };
  354. template<typename _Iter>
  355. requires __detail::__iter_without_category<_Iter>
  356. && __detail::__cpp17_bidi_iterator<_Iter>
  357. struct __cat<_Iter>
  358. { using type = bidirectional_iterator_tag; };
  359. template<typename _Iter>
  360. requires __detail::__iter_without_category<_Iter>
  361. && __detail::__cpp17_fwd_iterator<_Iter>
  362. struct __cat<_Iter>
  363. { using type = forward_iterator_tag; };
  364. template<typename _Iter>
  365. struct __ptr
  366. { using type = void; };
  367. template<typename _Iter> requires requires { typename _Iter::pointer; }
  368. struct __ptr<_Iter>
  369. { using type = typename _Iter::pointer; };
  370. template<typename _Iter>
  371. requires (!requires { typename _Iter::pointer; }
  372. && requires(_Iter& __it) { __it.operator->(); })
  373. struct __ptr<_Iter>
  374. { using type = decltype(std::declval<_Iter&>().operator->()); };
  375. template<typename _Iter>
  376. struct __ref
  377. { using type = iter_reference_t<_Iter>; };
  378. template<typename _Iter> requires requires { typename _Iter::reference; }
  379. struct __ref<_Iter>
  380. { using type = typename _Iter::reference; };
  381. public:
  382. using iterator_category = typename __cat<_Iterator>::type;
  383. using value_type
  384. = typename indirectly_readable_traits<_Iterator>::value_type;
  385. using difference_type
  386. = typename incrementable_traits<_Iterator>::difference_type;
  387. using pointer = typename __ptr<_Iterator>::type;
  388. using reference = typename __ref<_Iterator>::type;
  389. };
  390. template<typename _Iterator>
  391. requires __detail::__iter_without_nested_types<_Iterator>
  392. && __detail::__cpp17_iterator<_Iterator>
  393. struct __iterator_traits<_Iterator, void>
  394. {
  395. private:
  396. template<typename _Iter>
  397. struct __diff
  398. { using type = void; };
  399. template<typename _Iter>
  400. requires requires
  401. { typename incrementable_traits<_Iter>::difference_type; }
  402. struct __diff<_Iter>
  403. {
  404. using type = typename incrementable_traits<_Iter>::difference_type;
  405. };
  406. public:
  407. using iterator_category = output_iterator_tag;
  408. using value_type = void;
  409. using difference_type = typename __diff<_Iterator>::type;
  410. using pointer = void;
  411. using reference = void;
  412. };
  413. namespace __detail
  414. {
  415. template<typename _Iter>
  416. struct __iter_concept_impl;
  417. // ITER_CONCEPT(I) is ITER_TRAITS(I)::iterator_concept if that is valid.
  418. template<typename _Iter>
  419. requires requires { typename __iter_traits<_Iter>::iterator_concept; }
  420. struct __iter_concept_impl<_Iter>
  421. { using type = typename __iter_traits<_Iter>::iterator_concept; };
  422. // Otherwise, ITER_TRAITS(I)::iterator_category if that is valid.
  423. template<typename _Iter>
  424. requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
  425. && requires { typename __iter_traits<_Iter>::iterator_category; })
  426. struct __iter_concept_impl<_Iter>
  427. { using type = typename __iter_traits<_Iter>::iterator_category; };
  428. // Otherwise, random_access_tag if iterator_traits<I> is not specialized.
  429. template<typename _Iter>
  430. requires (!requires { typename __iter_traits<_Iter>::iterator_concept; }
  431. && !requires { typename __iter_traits<_Iter>::iterator_category; }
  432. && __primary_traits_iter<_Iter>)
  433. struct __iter_concept_impl<_Iter>
  434. { using type = random_access_iterator_tag; };
  435. // Otherwise, there is no ITER_CONCEPT(I) type.
  436. template<typename _Iter>
  437. struct __iter_concept_impl
  438. { };
  439. // ITER_CONCEPT
  440. template<typename _Iter>
  441. using __iter_concept = typename __iter_concept_impl<_Iter>::type;
  442. template<typename _In>
  443. concept __indirectly_readable_impl = requires
  444. {
  445. typename iter_value_t<_In>;
  446. typename iter_reference_t<_In>;
  447. typename iter_rvalue_reference_t<_In>;
  448. requires same_as<iter_reference_t<const _In>,
  449. iter_reference_t<_In>>;
  450. requires same_as<iter_rvalue_reference_t<const _In>,
  451. iter_rvalue_reference_t<_In>>;
  452. }
  453. && common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&>
  454. && common_reference_with<iter_reference_t<_In>&&,
  455. iter_rvalue_reference_t<_In>&&>
  456. && common_reference_with<iter_rvalue_reference_t<_In>&&,
  457. const iter_value_t<_In>&>;
  458. } // namespace __detail
  459. /// Requirements for types that are readable by applying operator*.
  460. template<typename _In>
  461. concept indirectly_readable
  462. = __detail::__indirectly_readable_impl<remove_cvref_t<_In>>;
  463. template<indirectly_readable _Tp>
  464. using iter_common_reference_t
  465. = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
  466. /// Requirements for writing a value into an iterator's referenced object.
  467. template<typename _Out, typename _Tp>
  468. concept indirectly_writable = requires(_Out&& __o, _Tp&& __t)
  469. {
  470. *__o = std::forward<_Tp>(__t);
  471. *std::forward<_Out>(__o) = std::forward<_Tp>(__t);
  472. const_cast<const iter_reference_t<_Out>&&>(*__o)
  473. = std::forward<_Tp>(__t);
  474. const_cast<const iter_reference_t<_Out>&&>(*std::forward<_Out>(__o))
  475. = std::forward<_Tp>(__t);
  476. };
  477. namespace ranges::__detail
  478. {
  479. class __max_diff_type;
  480. class __max_size_type;
  481. __extension__
  482. template<typename _Tp>
  483. concept __is_signed_int128
  484. #if __SIZEOF_INT128__
  485. = same_as<_Tp, __int128>;
  486. #else
  487. = false;
  488. #endif
  489. __extension__
  490. template<typename _Tp>
  491. concept __is_unsigned_int128
  492. #if __SIZEOF_INT128__
  493. = same_as<_Tp, unsigned __int128>;
  494. #else
  495. = false;
  496. #endif
  497. template<typename _Tp>
  498. concept __cv_bool = same_as<const volatile _Tp, const volatile bool>;
  499. template<typename _Tp>
  500. concept __integral_nonbool = integral<_Tp> && !__cv_bool<_Tp>;
  501. template<typename _Tp>
  502. concept __is_int128 = __is_signed_int128<_Tp> || __is_unsigned_int128<_Tp>;
  503. template<typename _Tp>
  504. concept __is_integer_like = __integral_nonbool<_Tp>
  505. || __is_int128<_Tp>
  506. || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>;
  507. template<typename _Tp>
  508. concept __is_signed_integer_like = signed_integral<_Tp>
  509. || __is_signed_int128<_Tp>
  510. || same_as<_Tp, __max_diff_type>;
  511. } // namespace ranges::__detail
  512. namespace __detail { using ranges::__detail::__is_signed_integer_like; }
  513. /// Requirements on types that can be incremented with ++.
  514. template<typename _Iter>
  515. concept weakly_incrementable = movable<_Iter>
  516. && requires(_Iter __i)
  517. {
  518. typename iter_difference_t<_Iter>;
  519. requires __detail::__is_signed_integer_like<iter_difference_t<_Iter>>;
  520. { ++__i } -> same_as<_Iter&>;
  521. __i++;
  522. };
  523. template<typename _Iter>
  524. concept incrementable = regular<_Iter> && weakly_incrementable<_Iter>
  525. && requires(_Iter __i) { { __i++ } -> same_as<_Iter>; };
  526. template<typename _Iter>
  527. concept input_or_output_iterator
  528. = requires(_Iter __i) { { *__i } -> __detail::__can_reference; }
  529. && weakly_incrementable<_Iter>;
  530. template<typename _Sent, typename _Iter>
  531. concept sentinel_for = semiregular<_Sent>
  532. && input_or_output_iterator<_Iter>
  533. && __detail::__weakly_eq_cmp_with<_Sent, _Iter>;
  534. template<typename _Sent, typename _Iter>
  535. inline constexpr bool disable_sized_sentinel_for = false;
  536. template<typename _Sent, typename _Iter>
  537. concept sized_sentinel_for = sentinel_for<_Sent, _Iter>
  538. && !disable_sized_sentinel_for<remove_cv_t<_Sent>, remove_cv_t<_Iter>>
  539. && requires(const _Iter& __i, const _Sent& __s)
  540. {
  541. { __s - __i } -> same_as<iter_difference_t<_Iter>>;
  542. { __i - __s } -> same_as<iter_difference_t<_Iter>>;
  543. };
  544. template<typename _Iter>
  545. concept input_iterator = input_or_output_iterator<_Iter>
  546. && indirectly_readable<_Iter>
  547. && requires { typename __detail::__iter_concept<_Iter>; }
  548. && derived_from<__detail::__iter_concept<_Iter>, input_iterator_tag>;
  549. template<typename _Iter, typename _Tp>
  550. concept output_iterator = input_or_output_iterator<_Iter>
  551. && indirectly_writable<_Iter, _Tp>
  552. && requires(_Iter __i, _Tp&& __t) { *__i++ = std::forward<_Tp>(__t); };
  553. template<typename _Iter>
  554. concept forward_iterator = input_iterator<_Iter>
  555. && derived_from<__detail::__iter_concept<_Iter>, forward_iterator_tag>
  556. && incrementable<_Iter> && sentinel_for<_Iter, _Iter>;
  557. template<typename _Iter>
  558. concept bidirectional_iterator = forward_iterator<_Iter>
  559. && derived_from<__detail::__iter_concept<_Iter>,
  560. bidirectional_iterator_tag>
  561. && requires(_Iter __i)
  562. {
  563. { --__i } -> same_as<_Iter&>;
  564. { __i-- } -> same_as<_Iter>;
  565. };
  566. template<typename _Iter>
  567. concept random_access_iterator = bidirectional_iterator<_Iter>
  568. && derived_from<__detail::__iter_concept<_Iter>,
  569. random_access_iterator_tag>
  570. && totally_ordered<_Iter> && sized_sentinel_for<_Iter, _Iter>
  571. && requires(_Iter __i, const _Iter __j,
  572. const iter_difference_t<_Iter> __n)
  573. {
  574. { __i += __n } -> same_as<_Iter&>;
  575. { __j + __n } -> same_as<_Iter>;
  576. { __n + __j } -> same_as<_Iter>;
  577. { __i -= __n } -> same_as<_Iter&>;
  578. { __j - __n } -> same_as<_Iter>;
  579. { __j[__n] } -> same_as<iter_reference_t<_Iter>>;
  580. };
  581. template<typename _Iter>
  582. concept contiguous_iterator = random_access_iterator<_Iter>
  583. && derived_from<__detail::__iter_concept<_Iter>, contiguous_iterator_tag>
  584. && is_lvalue_reference_v<iter_reference_t<_Iter>>
  585. && same_as<iter_value_t<_Iter>, remove_cvref_t<iter_reference_t<_Iter>>>
  586. && requires(const _Iter& __i)
  587. {
  588. { std::to_address(__i) }
  589. -> same_as<add_pointer_t<iter_reference_t<_Iter>>>;
  590. };
  591. // [indirectcallable], indirect callable requirements
  592. // [indirectcallable.indirectinvocable], indirect callables
  593. template<typename _Fn, typename _Iter>
  594. concept indirectly_unary_invocable = indirectly_readable<_Iter>
  595. && copy_constructible<_Fn> && invocable<_Fn&, iter_value_t<_Iter>&>
  596. && invocable<_Fn&, iter_reference_t<_Iter>>
  597. && invocable<_Fn&, iter_common_reference_t<_Iter>>
  598. && common_reference_with<invoke_result_t<_Fn&, iter_value_t<_Iter>&>,
  599. invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
  600. template<typename _Fn, typename _Iter>
  601. concept indirectly_regular_unary_invocable = indirectly_readable<_Iter>
  602. && copy_constructible<_Fn>
  603. && regular_invocable<_Fn&, iter_value_t<_Iter>&>
  604. && regular_invocable<_Fn&, iter_reference_t<_Iter>>
  605. && regular_invocable<_Fn&, iter_common_reference_t<_Iter>>
  606. && common_reference_with<invoke_result_t<_Fn&, iter_value_t<_Iter>&>,
  607. invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
  608. template<typename _Fn, typename _Iter>
  609. concept indirect_unary_predicate = indirectly_readable<_Iter>
  610. && copy_constructible<_Fn> && predicate<_Fn&, iter_value_t<_Iter>&>
  611. && predicate<_Fn&, iter_reference_t<_Iter>>
  612. && predicate<_Fn&, iter_common_reference_t<_Iter>>;
  613. template<typename _Fn, typename _I1, typename _I2>
  614. concept indirect_binary_predicate
  615. = indirectly_readable<_I1> && indirectly_readable<_I2>
  616. && copy_constructible<_Fn>
  617. && predicate<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
  618. && predicate<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
  619. && predicate<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
  620. && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
  621. && predicate<_Fn&, iter_common_reference_t<_I1>,
  622. iter_common_reference_t<_I2>>;
  623. template<typename _Fn, typename _I1, typename _I2 = _I1>
  624. concept indirect_equivalence_relation
  625. = indirectly_readable<_I1> && indirectly_readable<_I2>
  626. && copy_constructible<_Fn>
  627. && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
  628. && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
  629. && equivalence_relation<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
  630. && equivalence_relation<_Fn&, iter_reference_t<_I1>,
  631. iter_reference_t<_I2>>
  632. && equivalence_relation<_Fn&, iter_common_reference_t<_I1>,
  633. iter_common_reference_t<_I2>>;
  634. template<typename _Fn, typename _I1, typename _I2 = _I1>
  635. concept indirect_strict_weak_order
  636. = indirectly_readable<_I1> && indirectly_readable<_I2>
  637. && copy_constructible<_Fn>
  638. && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&>
  639. && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>>
  640. && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&>
  641. && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
  642. && strict_weak_order<_Fn&, iter_common_reference_t<_I1>,
  643. iter_common_reference_t<_I2>>;
  644. template<typename _Fn, typename... _Is>
  645. requires (indirectly_readable<_Is> && ...)
  646. && invocable<_Fn, iter_reference_t<_Is>...>
  647. using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Is>...>;
  648. namespace __detail
  649. {
  650. template<typename _Iter, typename _Proj>
  651. struct __projected
  652. {
  653. struct __type
  654. {
  655. using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>;
  656. indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
  657. };
  658. };
  659. template<weakly_incrementable _Iter, typename _Proj>
  660. struct __projected<_Iter, _Proj>
  661. {
  662. struct __type
  663. {
  664. using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>;
  665. using difference_type = iter_difference_t<_Iter>;
  666. indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
  667. };
  668. };
  669. } // namespace __detail
  670. /// [projected], projected
  671. template<indirectly_readable _Iter,
  672. indirectly_regular_unary_invocable<_Iter> _Proj>
  673. using projected = typename __detail::__projected<_Iter, _Proj>::__type;
  674. // [alg.req], common algorithm requirements
  675. /// [alg.req.ind.move], concept `indirectly_movable`
  676. template<typename _In, typename _Out>
  677. concept indirectly_movable = indirectly_readable<_In>
  678. && indirectly_writable<_Out, iter_rvalue_reference_t<_In>>;
  679. template<typename _In, typename _Out>
  680. concept indirectly_movable_storable = indirectly_movable<_In, _Out>
  681. && indirectly_writable<_Out, iter_value_t<_In>>
  682. && movable<iter_value_t<_In>>
  683. && constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>>
  684. && assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;
  685. /// [alg.req.ind.copy], concept `indirectly_copyable`
  686. template<typename _In, typename _Out>
  687. concept indirectly_copyable = indirectly_readable<_In>
  688. && indirectly_writable<_Out, iter_reference_t<_In>>;
  689. template<typename _In, typename _Out>
  690. concept indirectly_copyable_storable = indirectly_copyable<_In, _Out>
  691. && indirectly_writable<_Out, iter_value_t<_In>&>
  692. && indirectly_writable<_Out, const iter_value_t<_In>&>
  693. && indirectly_writable<_Out, iter_value_t<_In>&&>
  694. && indirectly_writable<_Out, const iter_value_t<_In>&&>
  695. && copyable<iter_value_t<_In>>
  696. && constructible_from<iter_value_t<_In>, iter_reference_t<_In>>
  697. && assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>;
  698. namespace ranges
  699. {
  700. namespace __cust_iswap
  701. {
  702. template<typename _It1, typename _It2>
  703. void iter_swap(_It1, _It2) = delete;
  704. template<typename _Tp, typename _Up>
  705. concept __adl_iswap
  706. = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>
  707. || std::__detail::__class_or_enum<remove_reference_t<_Up>>)
  708. && requires(_Tp&& __t, _Up&& __u) {
  709. iter_swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
  710. };
  711. template<typename _Xp, typename _Yp>
  712. constexpr iter_value_t<_Xp>
  713. __iter_exchange_move(_Xp&& __x, _Yp&& __y)
  714. noexcept(noexcept(iter_value_t<_Xp>(iter_move(__x)))
  715. && noexcept(*__x = iter_move(__y)))
  716. {
  717. iter_value_t<_Xp> __old_value(iter_move(__x));
  718. *__x = iter_move(__y);
  719. return __old_value;
  720. }
  721. struct _IterSwap
  722. {
  723. private:
  724. template<typename _Tp, typename _Up>
  725. static constexpr bool
  726. _S_noexcept()
  727. {
  728. if constexpr (__adl_iswap<_Tp, _Up>)
  729. return noexcept(iter_swap(std::declval<_Tp>(),
  730. std::declval<_Up>()));
  731. else if constexpr (indirectly_readable<_Tp>
  732. && indirectly_readable<_Up>
  733. && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
  734. return noexcept(ranges::swap(*std::declval<_Tp>(),
  735. *std::declval<_Up>()));
  736. else
  737. return noexcept(*std::declval<_Tp>()
  738. = __iter_exchange_move(std::declval<_Up>(),
  739. std::declval<_Tp>()));
  740. }
  741. public:
  742. template<typename _Tp, typename _Up>
  743. requires __adl_iswap<_Tp, _Up>
  744. || (indirectly_readable<remove_reference_t<_Tp>>
  745. && indirectly_readable<remove_reference_t<_Up>>
  746. && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
  747. || (indirectly_movable_storable<_Tp, _Up>
  748. && indirectly_movable_storable<_Up, _Tp>)
  749. constexpr void
  750. operator()(_Tp&& __e1, _Up&& __e2) const
  751. noexcept(_S_noexcept<_Tp, _Up>())
  752. {
  753. if constexpr (__adl_iswap<_Tp, _Up>)
  754. iter_swap(static_cast<_Tp&&>(__e1), static_cast<_Up&&>(__e2));
  755. else if constexpr (indirectly_readable<_Tp>
  756. && indirectly_readable<_Up>
  757. && swappable_with<iter_reference_t<_Tp>, iter_reference_t<_Up>>)
  758. ranges::swap(*__e1, *__e2);
  759. else
  760. *__e1 = __iter_exchange_move(__e2, __e1);
  761. }
  762. };
  763. } // namespace __cust_iswap
  764. inline namespace __cust
  765. {
  766. inline constexpr __cust_iswap::_IterSwap iter_swap{};
  767. } // inline namespace __cust
  768. } // namespace ranges
  769. /// [alg.req.ind.swap], concept `indirectly_swappable`
  770. template<typename _I1, typename _I2 = _I1>
  771. concept indirectly_swappable
  772. = indirectly_readable<_I1> && indirectly_readable<_I2>
  773. && requires(const _I1 __i1, const _I2 __i2)
  774. {
  775. ranges::iter_swap(__i1, __i1);
  776. ranges::iter_swap(__i2, __i2);
  777. ranges::iter_swap(__i1, __i2);
  778. ranges::iter_swap(__i2, __i1);
  779. };
  780. /// [alg.req.ind.cmp], concept `indirectly_comparable`
  781. template<typename _I1, typename _I2, typename _Rel, typename _P1 = identity,
  782. typename _P2 = identity>
  783. concept indirectly_comparable
  784. = indirect_binary_predicate<_Rel, projected<_I1, _P1>,
  785. projected<_I2, _P2>>;
  786. /// [alg.req.permutable], concept `permutable`
  787. template<typename _Iter>
  788. concept permutable = forward_iterator<_Iter>
  789. && indirectly_movable_storable<_Iter, _Iter>
  790. && indirectly_swappable<_Iter, _Iter>;
  791. /// [alg.req.mergeable], concept `mergeable`
  792. template<typename _I1, typename _I2, typename _Out,
  793. typename _Rel = ranges::less, typename _P1 = identity,
  794. typename _P2 = identity>
  795. concept mergeable = input_iterator<_I1> && input_iterator<_I2>
  796. && weakly_incrementable<_Out> && indirectly_copyable<_I1, _Out>
  797. && indirectly_copyable<_I2, _Out>
  798. && indirect_strict_weak_order<_Rel, projected<_I1, _P1>,
  799. projected<_I2, _P2>>;
  800. /// [alg.req.sortable], concept `sortable`
  801. template<typename _Iter, typename _Rel = ranges::less,
  802. typename _Proj = identity>
  803. concept sortable = permutable<_Iter>
  804. && indirect_strict_weak_order<_Rel, projected<_Iter, _Proj>>;
  805. struct unreachable_sentinel_t
  806. {
  807. template<weakly_incrementable _It>
  808. friend constexpr bool
  809. operator==(unreachable_sentinel_t, const _It&) noexcept
  810. { return false; }
  811. };
  812. inline constexpr unreachable_sentinel_t unreachable_sentinel{};
  813. // This is the namespace for [range.access] CPOs.
  814. namespace ranges::__cust_access
  815. {
  816. using std::__detail::__class_or_enum;
  817. struct _Decay_copy final
  818. {
  819. template<typename _Tp>
  820. constexpr decay_t<_Tp>
  821. operator()(_Tp&& __t) const
  822. noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
  823. { return std::forward<_Tp>(__t); }
  824. } inline constexpr __decay_copy{};
  825. template<typename _Tp>
  826. concept __member_begin = requires(_Tp& __t)
  827. {
  828. { __decay_copy(__t.begin()) } -> input_or_output_iterator;
  829. };
  830. // Poison pills so that unqualified lookup doesn't find std::begin.
  831. void begin(auto&) = delete;
  832. void begin(const auto&) = delete;
  833. template<typename _Tp>
  834. concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
  835. && requires(_Tp& __t)
  836. {
  837. { __decay_copy(begin(__t)) } -> input_or_output_iterator;
  838. };
  839. // Simplified version of std::ranges::begin that only supports lvalues,
  840. // for use by __range_iter_t below.
  841. template<typename _Tp>
  842. requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>
  843. auto
  844. __begin(_Tp& __t)
  845. {
  846. if constexpr (is_array_v<_Tp>)
  847. return __t + 0;
  848. else if constexpr (__member_begin<_Tp&>)
  849. return __t.begin();
  850. else
  851. return begin(__t);
  852. }
  853. } // namespace ranges::__cust_access
  854. namespace __detail
  855. {
  856. // Implementation of std::ranges::iterator_t, without using ranges::begin.
  857. template<typename _Tp>
  858. using __range_iter_t
  859. = decltype(ranges::__cust_access::__begin(std::declval<_Tp&>()));
  860. } // namespace __detail
  861. #endif // C++20 library concepts
  862. _GLIBCXX_END_NAMESPACE_VERSION
  863. } // namespace std
  864. #endif // C++20
  865. #endif // _ITERATOR_CONCEPTS_H