iterator_concepts.h 30 KB

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