concepts.hpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_ITERATOR_CONCEPTS_HPP
  14. #define RANGES_V3_ITERATOR_CONCEPTS_HPP
  15. #include <iterator>
  16. #include <type_traits>
  17. #include <meta/meta.hpp>
  18. #include <concepts/concepts.hpp>
  19. #include <range/v3/range_fwd.hpp>
  20. #include <range/v3/functional/comparisons.hpp>
  21. #include <range/v3/functional/concepts.hpp>
  22. #include <range/v3/functional/identity.hpp>
  23. #include <range/v3/functional/invoke.hpp>
  24. #include <range/v3/iterator/access.hpp>
  25. #include <range/v3/iterator/traits.hpp>
  26. #ifdef _GLIBCXX_DEBUG
  27. #include <debug/safe_iterator.h>
  28. #endif
  29. #include <range/v3/detail/prologue.hpp>
  30. namespace ranges
  31. {
  32. /// \addtogroup group-iterator-concepts
  33. /// @{
  34. /// \cond
  35. namespace detail
  36. {
  37. template<typename I>
  38. using iter_traits_t = meta::conditional_t<is_std_iterator_traits_specialized_v<I>,
  39. std::iterator_traits<I>, I>;
  40. #if defined(_GLIBCXX_DEBUG)
  41. template(typename I, typename T, typename Seq)(
  42. requires same_as<I, __gnu_debug::_Safe_iterator<T *, Seq>>)
  43. auto iter_concept_(__gnu_debug::_Safe_iterator<T *, Seq>, priority_tag<3>)
  44. -> ranges::contiguous_iterator_tag;
  45. #endif
  46. #if defined(__GLIBCXX__)
  47. template(typename I, typename T, typename Seq)(
  48. requires same_as<I, __gnu_cxx::__normal_iterator<T *, Seq>>)
  49. auto iter_concept_(__gnu_cxx::__normal_iterator<T *, Seq>, priority_tag<3>)
  50. -> ranges::contiguous_iterator_tag;
  51. #endif
  52. #if defined(_LIBCPP_VERSION)
  53. template(typename I, typename T)(
  54. requires same_as<I, std::__wrap_iter<T *>>)
  55. auto iter_concept_(std::__wrap_iter<T *>, priority_tag<3>)
  56. -> ranges::contiguous_iterator_tag;
  57. #endif
  58. #if defined(_MSVC_STL_VERSION) || defined(_IS_WRS)
  59. template(typename I)(
  60. requires same_as<I, class I::_Array_iterator>)
  61. auto iter_concept_(I, priority_tag<3>)
  62. -> ranges::contiguous_iterator_tag;
  63. template(typename I)(
  64. requires same_as<I, class I::_Array_const_iterator>)
  65. auto iter_concept_(I, priority_tag<3>)
  66. -> ranges::contiguous_iterator_tag;
  67. template(typename I)(
  68. requires same_as<I, class I::_Vector_iterator>)
  69. auto iter_concept_(I, priority_tag<3>)
  70. -> ranges::contiguous_iterator_tag;
  71. template(typename I)(
  72. requires same_as<I, class I::_Vector_const_iterator>)
  73. auto iter_concept_(I, priority_tag<3>)
  74. -> ranges::contiguous_iterator_tag;
  75. template(typename I)(
  76. requires same_as<I, class I::_String_iterator>)
  77. auto iter_concept_(I, priority_tag<3>)
  78. -> ranges::contiguous_iterator_tag;
  79. template(typename I)(
  80. requires same_as<I, class I::_String_const_iterator>)
  81. auto iter_concept_(I, priority_tag<3>)
  82. -> ranges::contiguous_iterator_tag;
  83. template(typename I)(
  84. requires same_as<I, class I::_String_view_iterator>)
  85. auto iter_concept_(I, priority_tag<3>)
  86. -> ranges::contiguous_iterator_tag;
  87. #endif
  88. template(typename I, typename T)(
  89. requires same_as<I, T *>)
  90. auto iter_concept_(T *, priority_tag<3>)
  91. -> ranges::contiguous_iterator_tag;
  92. template<typename I>
  93. auto iter_concept_(I, priority_tag<2>) ->
  94. typename iter_traits_t<I>::iterator_concept;
  95. template<typename I>
  96. auto iter_concept_(I, priority_tag<1>) ->
  97. typename iter_traits_t<I>::iterator_category;
  98. template<typename I>
  99. auto iter_concept_(I, priority_tag<0>)
  100. -> enable_if_t<!is_std_iterator_traits_specialized_v<I>,
  101. std::random_access_iterator_tag>;
  102. template<typename I>
  103. using iter_concept_t =
  104. decltype(iter_concept_<I>(std::declval<I>(), priority_tag<3>{}));
  105. using ::concepts::detail::weakly_equality_comparable_with_;
  106. template<typename I>
  107. using readable_types_t =
  108. meta::list<iter_value_t<I>, iter_reference_t<I>, iter_rvalue_reference_t<I>>;
  109. } // namespace detail
  110. /// \endcond
  111. // clang-format off
  112. /// \concept readable_
  113. /// \brief The \c readable_ concept
  114. template(typename I)(
  115. concept (readable_)(I),
  116. // requires (I const i)
  117. // (
  118. // { *i } -> same_as<iter_reference_t<I>>;
  119. // { iter_move(i) } -> same_as<iter_rvalue_reference_t<I>>;
  120. // ) &&
  121. same_as<iter_reference_t<I const>, iter_reference_t<I>> AND
  122. same_as<iter_rvalue_reference_t<I const>, iter_rvalue_reference_t<I>> AND
  123. common_reference_with<iter_reference_t<I> &&, iter_value_t<I> &> AND
  124. common_reference_with<iter_reference_t<I> &&,
  125. iter_rvalue_reference_t<I> &&> AND
  126. common_reference_with<iter_rvalue_reference_t<I> &&, iter_value_t<I> const &>
  127. );
  128. /// \concept indirectly_readable
  129. /// \brief The \c indirectly_readable concept
  130. template<typename I>
  131. CPP_concept indirectly_readable = //
  132. CPP_concept_ref(ranges::readable_, uncvref_t<I>);
  133. template<typename I>
  134. RANGES_DEPRECATED("Please use ranges::indirectly_readable instead")
  135. RANGES_INLINE_VAR constexpr bool readable = //
  136. indirectly_readable<I>;
  137. /// \concept writable_
  138. /// \brief The \c writable_ concept
  139. template<typename O, typename T>
  140. CPP_requires(writable_,
  141. requires(O && o, T && t) //
  142. (
  143. *o = (T &&) t,
  144. *(O &&) o = (T &&) t,
  145. const_cast<iter_reference_t<O> const &&>(*o) = (T &&) t,
  146. const_cast<iter_reference_t<O> const &&>(*(O &&) o) = (T &&) t
  147. ));
  148. /// \concept indirectly_writable
  149. /// \brief The \c indirectly_writable concept
  150. template<typename O, typename T>
  151. CPP_concept indirectly_writable = //
  152. CPP_requires_ref(ranges::writable_, O, T);
  153. template<typename O, typename T>
  154. RANGES_DEPRECATED("Please use ranges::indirectly_writable instead")
  155. RANGES_INLINE_VAR constexpr bool writable = //
  156. indirectly_writable<O, T>;
  157. // clang-format on
  158. /// \cond
  159. namespace detail
  160. {
  161. #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
  162. template<typename D>
  163. inline constexpr bool _is_integer_like_ = std::is_integral<D>::value;
  164. #else
  165. template<typename D, typename = void>
  166. constexpr bool _is_integer_like_ = std::is_integral<D>::value;
  167. #endif
  168. // gcc10 uses for std::ranges::range_difference_t<
  169. // std::ranges::iota_view<size_t, size_t>> == __int128
  170. #if __SIZEOF_INT128__
  171. __extension__ typedef __int128 int128_t;
  172. #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
  173. template<>
  174. inline constexpr bool _is_integer_like_<int128_t> = true;
  175. #else
  176. template<typename Enable>
  177. constexpr bool _is_integer_like_<int128_t, Enable> = true;
  178. #endif
  179. #endif // __SIZEOF_INT128__
  180. // clang-format off
  181. /// \concept integer_like_
  182. /// \brief The \c integer_like_ concept
  183. template<typename D>
  184. CPP_concept integer_like_ = _is_integer_like_<D>;
  185. // TODO additional syntactic and semantic requirements
  186. #ifdef RANGES_WORKAROUND_MSVC_792338
  187. template<typename D, bool Signed = (D(-1) < D(0))>
  188. constexpr bool _is_signed_(D *)
  189. {
  190. return Signed;
  191. }
  192. constexpr bool _is_signed_(void *)
  193. {
  194. return false;
  195. }
  196. /// \concept signed_integer_like_
  197. /// \brief The \c signed_integer_like_ concept
  198. template<typename D>
  199. CPP_concept signed_integer_like_ =
  200. integer_like_<D> && detail::_is_signed_((D*) nullptr);
  201. #else // ^^^ workaround / no workaround vvv
  202. /// \concept signed_integer_like_impl_
  203. /// \brief The \c signed_integer_like_impl_ concept
  204. template(typename D)(
  205. concept (signed_integer_like_impl_)(D),
  206. integer_like_<D> AND
  207. concepts::type<std::integral_constant<bool, (D(-1) < D(0))>> AND
  208. std::integral_constant<bool, (D(-1) < D(0))>::value
  209. );
  210. /// \concept signed_integer_like_
  211. /// \brief The \c signed_integer_like_ concept
  212. template<typename D>
  213. CPP_concept signed_integer_like_ =
  214. integer_like_<D> &&
  215. CPP_concept_ref(detail::signed_integer_like_impl_, D);
  216. #endif // RANGES_WORKAROUND_MSVC_792338
  217. // clang-format on
  218. } // namespace detail
  219. /// \endcond
  220. // clang-format off
  221. /// \concept weakly_incrementable_
  222. /// \brief The \c weakly_incrementable_ concept
  223. template<typename I>
  224. CPP_requires(weakly_incrementable_,
  225. requires(I i) //
  226. (
  227. ++i,
  228. i++,
  229. concepts::requires_<same_as<I&, decltype(++i)>>
  230. ));
  231. /// \concept weakly_incrementable_
  232. /// \brief The \c weakly_incrementable_ concept
  233. template(typename I)(
  234. concept (weakly_incrementable_)(I),
  235. concepts::type<iter_difference_t<I>> AND
  236. detail::signed_integer_like_<iter_difference_t<I>>);
  237. /// \concept weakly_incrementable
  238. /// \brief The \c weakly_incrementable concept
  239. template<typename I>
  240. CPP_concept weakly_incrementable =
  241. copyable<I> &&
  242. CPP_requires_ref(ranges::weakly_incrementable_, I) &&
  243. CPP_concept_ref(ranges::weakly_incrementable_, I);
  244. /// \concept incrementable_
  245. /// \brief The \c incrementable_ concept
  246. template<typename I>
  247. CPP_requires(incrementable_,
  248. requires(I i) //
  249. (
  250. concepts::requires_<same_as<I, decltype(i++)>>
  251. ));
  252. /// \concept incrementable
  253. /// \brief The \c incrementable concept
  254. template<typename I>
  255. CPP_concept incrementable =
  256. regular<I> &&
  257. weakly_incrementable<I> &&
  258. CPP_requires_ref(ranges::incrementable_, I);
  259. /// \concept input_or_output_iterator_
  260. /// \brief The \c input_or_output_iterator_ concept
  261. template(typename I)(
  262. concept (input_or_output_iterator_)(I),
  263. detail::dereferenceable_<I&>
  264. );
  265. /// \concept input_or_output_iterator
  266. /// \brief The \c input_or_output_iterator concept
  267. template<typename I>
  268. CPP_concept input_or_output_iterator =
  269. weakly_incrementable<I> &&
  270. CPP_concept_ref(ranges::input_or_output_iterator_, I);
  271. /// \concept sentinel_for
  272. /// \brief The \c sentinel_for concept
  273. template<typename S, typename I>
  274. CPP_concept sentinel_for =
  275. semiregular<S> &&
  276. input_or_output_iterator<I> &&
  277. detail::weakly_equality_comparable_with_<S, I>;
  278. /// \concept sized_sentinel_for_
  279. /// \brief The \c sized_sentinel_for_ concept
  280. template<typename S, typename I>
  281. CPP_requires(sized_sentinel_for_,
  282. requires(S const & s, I const & i) //
  283. (
  284. s - i,
  285. i - s,
  286. concepts::requires_<same_as<iter_difference_t<I>, decltype(s - i)>>,
  287. concepts::requires_<same_as<iter_difference_t<I>, decltype(i - s)>>
  288. ));
  289. /// \concept sized_sentinel_for_
  290. /// \brief The \c sized_sentinel_for_ concept
  291. template(typename S, typename I)(
  292. concept (sized_sentinel_for_)(S, I),
  293. (!disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>>) AND
  294. sentinel_for<S, I>);
  295. /// \concept sized_sentinel_for
  296. /// \brief The \c sized_sentinel_for concept
  297. template<typename S, typename I>
  298. CPP_concept sized_sentinel_for =
  299. CPP_concept_ref(sized_sentinel_for_, S, I) &&
  300. CPP_requires_ref(ranges::sized_sentinel_for_, S, I);
  301. /// \concept output_iterator_
  302. /// \brief The \c output_iterator_ concept
  303. template<typename Out, typename T>
  304. CPP_requires(output_iterator_,
  305. requires(Out o, T && t) //
  306. (
  307. *o++ = (T &&) t
  308. ));
  309. /// \concept output_iterator
  310. /// \brief The \c output_iterator concept
  311. template<typename Out, typename T>
  312. CPP_concept output_iterator =
  313. input_or_output_iterator<Out> &&
  314. indirectly_writable<Out, T> &&
  315. CPP_requires_ref(ranges::output_iterator_, Out, T);
  316. /// \concept with_category_
  317. /// \brief The \c with_category_ concept
  318. template(typename I, typename Tag)(
  319. concept (with_category_)(I, Tag),
  320. derived_from<detail::iter_concept_t<I>, Tag>
  321. );
  322. /// \concept input_iterator
  323. /// \brief The \c input_iterator concept
  324. template<typename I>
  325. CPP_concept input_iterator =
  326. input_or_output_iterator<I> &&
  327. indirectly_readable<I> &&
  328. CPP_concept_ref(ranges::with_category_, I, std::input_iterator_tag);
  329. /// \concept forward_iterator
  330. /// \brief The \c forward_iterator concept
  331. template<typename I>
  332. CPP_concept forward_iterator =
  333. input_iterator<I> &&
  334. incrementable<I> &&
  335. sentinel_for<I, I> &&
  336. CPP_concept_ref(ranges::with_category_, I, std::forward_iterator_tag);
  337. /// \concept bidirectional_iterator_
  338. /// \brief The \c bidirectional_iterator_ concept
  339. template<typename I>
  340. CPP_requires(bidirectional_iterator_,
  341. requires(I i) //
  342. (
  343. --i,
  344. i--,
  345. concepts::requires_<same_as<I&, decltype(--i)>>,
  346. concepts::requires_<same_as<I, decltype(i--)>>
  347. ));
  348. /// \concept bidirectional_iterator
  349. /// \brief The \c bidirectional_iterator concept
  350. template<typename I>
  351. CPP_concept bidirectional_iterator =
  352. forward_iterator<I> &&
  353. CPP_requires_ref(ranges::bidirectional_iterator_, I) &&
  354. CPP_concept_ref(ranges::with_category_, I, std::bidirectional_iterator_tag);
  355. /// \concept random_access_iterator_
  356. /// \brief The \c random_access_iterator_ concept
  357. template<typename I>
  358. CPP_requires(random_access_iterator_,
  359. requires(I i, iter_difference_t<I> n)
  360. (
  361. i + n,
  362. n + i,
  363. i - n,
  364. i += n,
  365. i -= n,
  366. concepts::requires_<same_as<decltype(i + n), I>>,
  367. concepts::requires_<same_as<decltype(n + i), I>>,
  368. concepts::requires_<same_as<decltype(i - n), I>>,
  369. concepts::requires_<same_as<decltype(i += n), I&>>,
  370. concepts::requires_<same_as<decltype(i -= n), I&>>,
  371. concepts::requires_<same_as<decltype(i[n]), iter_reference_t<I>>>
  372. ));
  373. /// \concept random_access_iterator
  374. /// \brief The \c random_access_iterator concept
  375. template<typename I>
  376. CPP_concept random_access_iterator =
  377. bidirectional_iterator<I> &&
  378. totally_ordered<I> &&
  379. sized_sentinel_for<I, I> &&
  380. CPP_requires_ref(ranges::random_access_iterator_, I) &&
  381. CPP_concept_ref(ranges::with_category_, I, std::random_access_iterator_tag);
  382. /// \concept contiguous_iterator_
  383. /// \brief The \c contiguous_iterator_ concept
  384. template(typename I)(
  385. concept (contiguous_iterator_)(I),
  386. std::is_lvalue_reference<iter_reference_t<I>>::value AND
  387. same_as<iter_value_t<I>, uncvref_t<iter_reference_t<I>>> AND
  388. derived_from<detail::iter_concept_t<I>, ranges::contiguous_iterator_tag>
  389. );
  390. /// \concept contiguous_iterator
  391. /// \brief The \c contiguous_iterator concept
  392. template<typename I>
  393. CPP_concept contiguous_iterator =
  394. random_access_iterator<I> &&
  395. CPP_concept_ref(ranges::contiguous_iterator_, I);
  396. // clang-format on
  397. /////////////////////////////////////////////////////////////////////////////////////
  398. // iterator_tag_of
  399. template<typename Rng>
  400. using iterator_tag_of = //
  401. std::enable_if_t< //
  402. input_iterator<Rng>, //
  403. meta::conditional_t< //
  404. contiguous_iterator<Rng>, //
  405. ranges::contiguous_iterator_tag, //
  406. meta::conditional_t< //
  407. random_access_iterator<Rng>, //
  408. std::random_access_iterator_tag, //
  409. meta::conditional_t< //
  410. bidirectional_iterator<Rng>, //
  411. std::bidirectional_iterator_tag, //
  412. meta::conditional_t< //
  413. forward_iterator<Rng>, //
  414. std::forward_iterator_tag, //
  415. std::input_iterator_tag>>>>>;
  416. /// \cond
  417. namespace detail
  418. {
  419. template<typename, bool>
  420. struct iterator_category_
  421. {};
  422. template<typename I>
  423. struct iterator_category_<I, true>
  424. {
  425. using type = iterator_tag_of<I>;
  426. };
  427. template<typename T, typename U = meta::_t<std::remove_const<T>>>
  428. using iterator_category = iterator_category_<U, (bool)input_iterator<U>>;
  429. } // namespace detail
  430. /// \endcond
  431. /// \cond
  432. // Generally useful to know if an iterator is single-pass or not:
  433. // clang-format off
  434. /// \concept single_pass_iterator_
  435. /// \brief The \c single_pass_iterator_ concept
  436. template<typename I>
  437. CPP_concept single_pass_iterator_ =
  438. input_or_output_iterator<I> && !forward_iterator<I>;
  439. // clang-format on
  440. /// \endcond
  441. //////////////////////////////////////////////////////////////////////////////////////
  442. // indirect_result_t
  443. template<typename Fun, typename... Is>
  444. using indirect_result_t =
  445. detail::enable_if_t<(bool)and_v<(bool)indirectly_readable<Is>...>,
  446. invoke_result_t<Fun, iter_reference_t<Is>...>>;
  447. /// \cond
  448. namespace detail
  449. {
  450. // clang-format off
  451. /// \concept common_reference_with_4_impl_
  452. /// \brief The \c common_reference_with_4_impl_ concept
  453. template(typename T1, typename T2, typename T3, typename T4)(
  454. concept (common_reference_with_4_impl_)(T1, T2, T3, T4),
  455. concepts::type<common_reference_t<T1, T2, T3, T4>> AND
  456. convertible_to<T1, common_reference_t<T1, T2, T3, T4>> AND
  457. convertible_to<T2, common_reference_t<T1, T2, T3, T4>> AND
  458. convertible_to<T3, common_reference_t<T1, T2, T3, T4>> AND
  459. convertible_to<T4, common_reference_t<T1, T2, T3, T4>>
  460. );
  461. /// \concept common_reference_with_4_
  462. /// \brief The \c common_reference_with_4_ concept
  463. template<typename T1, typename T2, typename T3, typename T4>
  464. CPP_concept common_reference_with_4_ =
  465. CPP_concept_ref(detail::common_reference_with_4_impl_, T1, T2, T3, T4);
  466. // axiom: all permutations of T1,T2,T3,T4 have the same
  467. // common reference type.
  468. /// \concept indirectly_unary_invocable_impl_
  469. /// \brief The \c indirectly_unary_invocable_impl_ concept
  470. template(typename F, typename I)(
  471. concept (indirectly_unary_invocable_impl_)(F, I),
  472. invocable<F &, iter_value_t<I> &> AND
  473. invocable<F &, iter_reference_t<I>> AND
  474. invocable<F &, iter_common_reference_t<I>> AND
  475. common_reference_with<
  476. invoke_result_t<F &, iter_value_t<I> &>,
  477. invoke_result_t<F &, iter_reference_t<I>>>
  478. );
  479. /// \concept indirectly_unary_invocable_
  480. /// \brief The \c indirectly_unary_invocable_ concept
  481. template<typename F, typename I>
  482. CPP_concept indirectly_unary_invocable_ =
  483. indirectly_readable<I> &&
  484. CPP_concept_ref(detail::indirectly_unary_invocable_impl_, F, I);
  485. // clang-format on
  486. } // namespace detail
  487. /// \endcond
  488. // clang-format off
  489. /// \concept indirectly_unary_invocable
  490. /// \brief The \c indirectly_unary_invocable concept
  491. template<typename F, typename I>
  492. CPP_concept indirectly_unary_invocable =
  493. detail::indirectly_unary_invocable_<F, I> &&
  494. copy_constructible<F>;
  495. /// \concept indirectly_regular_unary_invocable_
  496. /// \brief The \c indirectly_regular_unary_invocable_ concept
  497. template(typename F, typename I)(
  498. concept (indirectly_regular_unary_invocable_)(F, I),
  499. regular_invocable<F &, iter_value_t<I> &> AND
  500. regular_invocable<F &, iter_reference_t<I>> AND
  501. regular_invocable<F &, iter_common_reference_t<I>> AND
  502. common_reference_with<
  503. invoke_result_t<F &, iter_value_t<I> &>,
  504. invoke_result_t<F &, iter_reference_t<I>>>
  505. );
  506. /// \concept indirectly_regular_unary_invocable
  507. /// \brief The \c indirectly_regular_unary_invocable concept
  508. template<typename F, typename I>
  509. CPP_concept indirectly_regular_unary_invocable =
  510. indirectly_readable<I> &&
  511. copy_constructible<F> &&
  512. CPP_concept_ref(ranges::indirectly_regular_unary_invocable_, F, I);
  513. /// \cond
  514. // Non-standard indirect invocable concepts
  515. /// \concept indirectly_binary_invocable_impl_
  516. /// \brief The \c indirectly_binary_invocable_impl_ concept
  517. template(typename F, typename I1, typename I2)(
  518. concept (indirectly_binary_invocable_impl_)(F, I1, I2),
  519. invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
  520. invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
  521. invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
  522. invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
  523. invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
  524. detail::common_reference_with_4_<
  525. invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
  526. invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
  527. invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
  528. invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
  529. );
  530. /// \concept indirectly_binary_invocable_
  531. /// \brief The \c indirectly_binary_invocable_ concept
  532. template<typename F, typename I1, typename I2>
  533. CPP_concept indirectly_binary_invocable_ =
  534. indirectly_readable<I1> && indirectly_readable<I2> &&
  535. copy_constructible<F> &&
  536. CPP_concept_ref(ranges::indirectly_binary_invocable_impl_, F, I1, I2);
  537. /// \concept indirectly_regular_binary_invocable_impl_
  538. /// \brief The \c indirectly_regular_binary_invocable_impl_ concept
  539. template(typename F, typename I1, typename I2)(
  540. concept (indirectly_regular_binary_invocable_impl_)(F, I1, I2),
  541. regular_invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
  542. regular_invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
  543. regular_invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
  544. regular_invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
  545. regular_invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
  546. detail::common_reference_with_4_<
  547. invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
  548. invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
  549. invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
  550. invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
  551. );
  552. /// \concept indirectly_regular_binary_invocable_
  553. /// \brief The \c indirectly_regular_binary_invocable_ concept
  554. template<typename F, typename I1, typename I2>
  555. CPP_concept indirectly_regular_binary_invocable_ =
  556. indirectly_readable<I1> && indirectly_readable<I2> &&
  557. copy_constructible<F> &&
  558. CPP_concept_ref(ranges::indirectly_regular_binary_invocable_impl_, F, I1, I2);
  559. /// \endcond
  560. /// \concept indirect_unary_predicate_
  561. /// \brief The \c indirect_unary_predicate_ concept
  562. template(typename F, typename I)(
  563. concept (indirect_unary_predicate_)(F, I),
  564. predicate<F &, iter_value_t<I> &> AND
  565. predicate<F &, iter_reference_t<I>> AND
  566. predicate<F &, iter_common_reference_t<I>>
  567. );
  568. /// \concept indirect_unary_predicate
  569. /// \brief The \c indirect_unary_predicate concept
  570. template<typename F, typename I>
  571. CPP_concept indirect_unary_predicate =
  572. indirectly_readable<I> &&
  573. copy_constructible<F> &&
  574. CPP_concept_ref(ranges::indirect_unary_predicate_, F, I);
  575. /// \concept indirect_binary_predicate_impl_
  576. /// \brief The \c indirect_binary_predicate_impl_ concept
  577. template(typename F, typename I1, typename I2)(
  578. concept (indirect_binary_predicate_impl_)(F, I1, I2),
  579. predicate<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
  580. predicate<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
  581. predicate<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
  582. predicate<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
  583. predicate<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
  584. );
  585. /// \concept indirect_binary_predicate_
  586. /// \brief The \c indirect_binary_predicate_ concept
  587. template<typename F, typename I1, typename I2>
  588. CPP_concept indirect_binary_predicate_ =
  589. indirectly_readable<I1> && indirectly_readable<I2> &&
  590. copy_constructible<F> &&
  591. CPP_concept_ref(ranges::indirect_binary_predicate_impl_, F, I1, I2);
  592. /// \concept indirect_relation_
  593. /// \brief The \c indirect_relation_ concept
  594. template(typename F, typename I1, typename I2)(
  595. concept (indirect_relation_)(F, I1, I2),
  596. relation<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
  597. relation<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
  598. relation<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
  599. relation<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
  600. relation<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
  601. );
  602. /// \concept indirect_relation
  603. /// \brief The \c indirect_relation concept
  604. template<typename F, typename I1, typename I2 = I1>
  605. CPP_concept indirect_relation =
  606. indirectly_readable<I1> && indirectly_readable<I2> &&
  607. copy_constructible<F> &&
  608. CPP_concept_ref(ranges::indirect_relation_, F, I1, I2);
  609. /// \concept indirect_strict_weak_order_
  610. /// \brief The \c indirect_strict_weak_order_ concept
  611. template(typename F, typename I1, typename I2)(
  612. concept (indirect_strict_weak_order_)(F, I1, I2),
  613. strict_weak_order<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
  614. strict_weak_order<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
  615. strict_weak_order<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
  616. strict_weak_order<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
  617. strict_weak_order<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
  618. );
  619. /// \concept indirect_strict_weak_order
  620. /// \brief The \c indirect_strict_weak_order concept
  621. template<typename F, typename I1, typename I2 = I1>
  622. CPP_concept indirect_strict_weak_order =
  623. indirectly_readable<I1> && indirectly_readable<I2> &&
  624. copy_constructible<F> &&
  625. CPP_concept_ref(ranges::indirect_strict_weak_order_, F, I1, I2);
  626. // clang-format on
  627. //////////////////////////////////////////////////////////////////////////////////////
  628. // projected struct, for "projecting" a readable with a unary callable
  629. /// \cond
  630. namespace detail
  631. {
  632. RANGES_DIAGNOSTIC_PUSH
  633. RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
  634. template<typename I, typename Proj>
  635. struct projected_
  636. {
  637. struct type
  638. {
  639. using reference = indirect_result_t<Proj &, I>;
  640. using value_type = uncvref_t<reference>;
  641. reference operator*() const;
  642. };
  643. };
  644. RANGES_DIAGNOSTIC_POP
  645. template<typename Proj>
  646. struct select_projected_
  647. {
  648. template<typename I>
  649. using apply =
  650. meta::_t<
  651. detail::enable_if_t<
  652. (bool)indirectly_regular_unary_invocable<Proj, I>,
  653. detail::projected_<I, Proj>>>;
  654. };
  655. template<>
  656. struct select_projected_<identity>
  657. {
  658. template<typename I>
  659. using apply = detail::enable_if_t<(bool)indirectly_readable<I>, I>;
  660. };
  661. } // namespace detail
  662. /// \endcond
  663. template<typename I, typename Proj>
  664. using projected = typename detail::select_projected_<Proj>::template apply<I>;
  665. template<typename I, typename Proj>
  666. struct incrementable_traits<detail::projected_<I, Proj>> : incrementable_traits<I>
  667. {};
  668. // clang-format off
  669. /// \concept indirectly_movable_
  670. /// \brief The \c indirectly_movable_ concept
  671. template(typename I, typename O)(
  672. concept (indirectly_movable_)(I, O),
  673. indirectly_writable<O, iter_rvalue_reference_t<I>>
  674. );
  675. /// \concept indirectly_movable
  676. /// \brief The \c indirectly_movable concept
  677. template<typename I, typename O>
  678. CPP_concept indirectly_movable =
  679. indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_movable_, I, O);
  680. /// \concept indirectly_movable_storable_
  681. /// \brief The \c indirectly_movable_storable_ concept
  682. template(typename I, typename O)(
  683. concept (indirectly_movable_storable_)(I, O),
  684. indirectly_writable<O, iter_value_t<I>> AND
  685. movable<iter_value_t<I>> AND
  686. constructible_from<iter_value_t<I>, iter_rvalue_reference_t<I>> AND
  687. assignable_from<iter_value_t<I> &, iter_rvalue_reference_t<I>>
  688. );
  689. /// \concept indirectly_movable_storable
  690. /// \brief The \c indirectly_movable_storable concept
  691. template<typename I, typename O>
  692. CPP_concept indirectly_movable_storable =
  693. indirectly_movable<I, O> &&
  694. CPP_concept_ref(ranges::indirectly_movable_storable_, I, O);
  695. /// \concept indirectly_copyable_
  696. /// \brief The \c indirectly_copyable_ concept
  697. template(typename I, typename O)(
  698. concept (indirectly_copyable_)(I, O),
  699. indirectly_writable<O, iter_reference_t<I>>
  700. );
  701. /// \concept indirectly_copyable
  702. /// \brief The \c indirectly_copyable concept
  703. template<typename I, typename O>
  704. CPP_concept indirectly_copyable =
  705. indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_copyable_, I, O);
  706. /// \concept indirectly_copyable_storable_
  707. /// \brief The \c indirectly_copyable_storable_ concept
  708. template(typename I, typename O)(
  709. concept (indirectly_copyable_storable_)(I, O),
  710. indirectly_writable<O, iter_value_t<I> const &> AND
  711. copyable<iter_value_t<I>> AND
  712. constructible_from<iter_value_t<I>, iter_reference_t<I>> AND
  713. assignable_from<iter_value_t<I> &, iter_reference_t<I>>
  714. );
  715. /// \concept indirectly_copyable_storable
  716. /// \brief The \c indirectly_copyable_storable concept
  717. template<typename I, typename O>
  718. CPP_concept indirectly_copyable_storable =
  719. indirectly_copyable<I, O> &&
  720. CPP_concept_ref(ranges::indirectly_copyable_storable_, I, O);
  721. /// \concept indirectly_swappable_
  722. /// \brief The \c indirectly_swappable_ concept
  723. template<typename I1, typename I2>
  724. CPP_requires(indirectly_swappable_,
  725. requires(I1 const i1, I2 const i2) //
  726. (
  727. ranges::iter_swap(i1, i2),
  728. ranges::iter_swap(i1, i1),
  729. ranges::iter_swap(i2, i2),
  730. ranges::iter_swap(i2, i1)
  731. ));
  732. /// \concept indirectly_swappable
  733. /// \brief The \c indirectly_swappable concept
  734. template<typename I1, typename I2 = I1>
  735. CPP_concept indirectly_swappable =
  736. indirectly_readable<I1> && //
  737. indirectly_readable<I2> && //
  738. CPP_requires_ref(ranges::indirectly_swappable_, I1, I2);
  739. /// \concept projected_indirect_relation_
  740. /// \brief The \c projected_indirect_relation_ concept
  741. template(typename C, typename I1, typename P1, typename I2, typename P2)(
  742. concept (projected_indirect_relation_)(C, I1, P1, I2, P2),
  743. indirect_relation<C, projected<I1, P1>, projected<I2, P2>>
  744. );
  745. /// \concept indirectly_comparable
  746. /// \brief The \c indirectly_comparable concept
  747. template<typename I1, typename I2, typename C, typename P1 = identity,
  748. typename P2 = identity>
  749. CPP_concept indirectly_comparable =
  750. CPP_concept_ref(ranges::projected_indirect_relation_, C, I1, P1, I2, P2);
  751. //////////////////////////////////////////////////////////////////////////////////////
  752. // Composite concepts for use defining algorithms:
  753. /// \concept permutable
  754. /// \brief The \c permutable concept
  755. template<typename I>
  756. CPP_concept permutable =
  757. forward_iterator<I> &&
  758. indirectly_swappable<I, I> &&
  759. indirectly_movable_storable<I, I>;
  760. /// \concept projected_indirect_strict_weak_order_
  761. /// \brief The \c projected_indirect_strict_weak_order_ concept
  762. template(typename C, typename I1, typename P1, typename I2, typename P2)(
  763. concept (projected_indirect_strict_weak_order_)(C, I1, P1, I2, P2),
  764. indirect_strict_weak_order<C, projected<I1, P1>, projected<I2, P2>>
  765. );
  766. template<typename I1, typename I2, typename Out, typename C = less,
  767. typename P1 = identity, typename P2 = identity>
  768. CPP_concept mergeable =
  769. input_iterator<I1> &&
  770. input_iterator<I2> &&
  771. weakly_incrementable<Out> &&
  772. indirectly_copyable<I1, Out> &&
  773. indirectly_copyable<I2, Out> &&
  774. CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I1, P1, I2, P2);
  775. /// \concept sortable
  776. /// \brief The \c sortable concept
  777. template<typename I, typename C = less, typename P = identity>
  778. CPP_concept sortable =
  779. permutable<I> &&
  780. CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I, P, I, P);
  781. // clang-format on
  782. struct sentinel_tag
  783. {};
  784. struct sized_sentinel_tag : sentinel_tag
  785. {};
  786. template<typename S, typename I>
  787. using sentinel_tag_of = //
  788. std::enable_if_t< //
  789. sentinel_for<S, I>, //
  790. meta::conditional_t< //
  791. sized_sentinel_for<S, I>, //
  792. sized_sentinel_tag, //
  793. sentinel_tag>>;
  794. // Deprecated things:
  795. /// \cond
  796. template<typename I>
  797. using iterator_category RANGES_DEPRECATED(
  798. "iterator_category is deprecated. Use the iterator concepts instead") =
  799. detail::iterator_category<I>;
  800. template<typename I>
  801. using iterator_category_t RANGES_DEPRECATED(
  802. "iterator_category_t is deprecated. Use the iterator concepts instead") =
  803. meta::_t<detail::iterator_category<I>>;
  804. template<typename Fun, typename... Is>
  805. using indirect_invoke_result_t RANGES_DEPRECATED(
  806. "Please switch to indirect_result_t") = indirect_result_t<Fun, Is...>;
  807. template<typename Fun, typename... Is>
  808. struct RANGES_DEPRECATED("Please switch to indirect_result_t") indirect_invoke_result
  809. : meta::defer<indirect_result_t, Fun, Is...>
  810. {};
  811. template<typename Sig>
  812. struct indirect_result_of
  813. {};
  814. template<typename Fun, typename... Is>
  815. struct RANGES_DEPRECATED("Please switch to indirect_result_t")
  816. indirect_result_of<Fun(Is...)> : meta::defer<indirect_result_t, Fun, Is...>
  817. {};
  818. template<typename Sig>
  819. using indirect_result_of_t RANGES_DEPRECATED("Please switch to indirect_result_t") =
  820. meta::_t<indirect_result_of<Sig>>;
  821. /// \endcond
  822. namespace cpp20
  823. {
  824. using ranges::bidirectional_iterator;
  825. using ranges::contiguous_iterator;
  826. using ranges::forward_iterator;
  827. using ranges::incrementable;
  828. using ranges::indirect_relation;
  829. using ranges::indirect_result_t;
  830. using ranges::indirect_strict_weak_order;
  831. using ranges::indirect_unary_predicate;
  832. using ranges::indirectly_comparable;
  833. using ranges::indirectly_copyable;
  834. using ranges::indirectly_copyable_storable;
  835. using ranges::indirectly_movable;
  836. using ranges::indirectly_movable_storable;
  837. using ranges::indirectly_readable;
  838. using ranges::indirectly_regular_unary_invocable;
  839. using ranges::indirectly_swappable;
  840. using ranges::indirectly_unary_invocable;
  841. using ranges::indirectly_writable;
  842. using ranges::input_iterator;
  843. using ranges::input_or_output_iterator;
  844. using ranges::mergeable;
  845. using ranges::output_iterator;
  846. using ranges::permutable;
  847. using ranges::projected;
  848. using ranges::random_access_iterator;
  849. using ranges::sentinel_for;
  850. using ranges::sized_sentinel_for;
  851. using ranges::sortable;
  852. using ranges::weakly_incrementable;
  853. } // namespace cpp20
  854. /// @}
  855. } // namespace ranges
  856. #ifdef _GLIBCXX_DEBUG
  857. // HACKHACK: workaround underconstrained operator- for libstdc++ debug iterator wrapper
  858. // by intentionally creating an ambiguity when the wrapped types don't support the
  859. // necessary operation.
  860. namespace __gnu_debug
  861. {
  862. template(typename I1, typename I2, typename Seq)(
  863. requires (!::ranges::sized_sentinel_for<I1, I2>)) //
  864. void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I2, Seq> const &) =
  865. delete;
  866. template(typename I1, typename Seq)(
  867. requires (!::ranges::sized_sentinel_for<I1, I1>)) //
  868. void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I1, Seq> const &) =
  869. delete;
  870. } // namespace __gnu_debug
  871. #endif
  872. #if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
  873. // HACKHACK: workaround libc++ (https://llvm.org/bugs/show_bug.cgi?id=28421)
  874. // and libstdc++ (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71771)
  875. // underconstrained operator- for reverse_iterator by disabling sized_sentinel_for
  876. // when the base iterators do not model sized_sentinel_for.
  877. namespace ranges
  878. {
  879. template<typename S, typename I>
  880. /*inline*/ constexpr bool
  881. disable_sized_sentinel<std::reverse_iterator<S>, std::reverse_iterator<I>> =
  882. !static_cast<bool>(sized_sentinel_for<I, S>);
  883. } // namespace ranges
  884. #endif // defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
  885. #include <range/v3/detail/epilogue.hpp>
  886. #endif // RANGES_V3_ITERATOR_CONCEPTS_HPP