algorithm.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_UTIL_RANGES_ALGORITHM_H_
  5. #define BASE_UTIL_RANGES_ALGORITHM_H_
  6. #include <algorithm>
  7. #include <utility>
  8. #include "base/util/ranges/functional.h"
  9. #include "base/util/ranges/iterator.h"
  10. namespace util {
  11. namespace ranges {
  12. namespace internal {
  13. // Returns a transformed version of the unary predicate `pred` applying `proj`
  14. // to its argument before invoking `pred` on it.
  15. // Ensures that the return type of `invoke(pred, ...)` is convertible to bool.
  16. template <typename Pred, typename Proj>
  17. constexpr auto ProjectedUnaryPredicate(Pred& pred, Proj& proj) noexcept {
  18. return [&pred, &proj](auto&& arg) -> bool {
  19. return invoke(pred, invoke(proj, std::forward<decltype(arg)>(arg)));
  20. };
  21. }
  22. // Returns a transformed version of the binary predicate `pred` applying `proj1`
  23. // and `proj2` to its arguments before invoking `pred` on them.
  24. // Ensures that the return type of `invoke(pred, ...)` is convertible to bool.
  25. template <typename Pred, typename Proj1, typename Proj2>
  26. constexpr auto ProjectedBinaryPredicate(Pred& pred,
  27. Proj1& proj1,
  28. Proj2& proj2) noexcept {
  29. return [&pred, &proj1, &proj2](auto&& lhs, auto&& rhs) -> bool {
  30. return invoke(pred, invoke(proj1, std::forward<decltype(lhs)>(lhs)),
  31. invoke(proj2, std::forward<decltype(rhs)>(rhs)));
  32. };
  33. }
  34. } // namespace internal
  35. // [alg.nonmodifying] Non-modifying sequence operations
  36. // Reference: https://wg21.link/alg.nonmodifying
  37. // [alg.all.of] All of
  38. // Reference: https://wg21.link/alg.all.of
  39. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  40. //
  41. // Returns: `false` if `E(i)` is `false` for some iterator `i` in the range
  42. // `[first, last)`, and `true` otherwise.
  43. //
  44. // Complexity: At most `last - first` applications of the predicate and any
  45. // projection.
  46. //
  47. // Reference: https://wg21.link/alg.all.of#:~:text=ranges::all_of(I
  48. template <typename InputIterator, typename Pred, typename Proj = identity>
  49. constexpr bool all_of(InputIterator first,
  50. InputIterator last,
  51. Pred pred,
  52. Proj proj = {}) {
  53. return std::all_of(first, last,
  54. internal::ProjectedUnaryPredicate(pred, proj));
  55. }
  56. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  57. //
  58. // Returns: `false` if `E(i)` is `false` for some iterator `i` in `range`, and
  59. // `true` otherwise.
  60. //
  61. // Complexity: At most `size(range)` applications of the predicate and any
  62. // projection.
  63. //
  64. // Reference: https://wg21.link/alg.all.of#:~:text=ranges::all_of(R
  65. template <typename Range, typename Pred, typename Proj = identity>
  66. constexpr bool all_of(Range&& range, Pred pred, Proj proj = {}) {
  67. return ranges::all_of(ranges::begin(range), ranges::end(range),
  68. std::move(pred), std::move(proj));
  69. }
  70. // [alg.any.of] Any of
  71. // Reference: https://wg21.link/alg.any.of
  72. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  73. //
  74. // Returns: `true` if `E(i)` is `true` for some iterator `i` in the range
  75. // `[first, last)`, and `false` otherwise.
  76. //
  77. // Complexity: At most `last - first` applications of the predicate and any
  78. // projection.
  79. //
  80. // Reference: https://wg21.link/alg.any.of#:~:text=ranges::any_of(I
  81. template <typename InputIterator, typename Pred, typename Proj = identity>
  82. constexpr bool any_of(InputIterator first,
  83. InputIterator last,
  84. Pred pred,
  85. Proj proj = {}) {
  86. return std::any_of(first, last,
  87. internal::ProjectedUnaryPredicate(pred, proj));
  88. }
  89. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  90. //
  91. // Returns: `true` if `E(i)` is `true` for some iterator `i` in `range`, and
  92. // `false` otherwise.
  93. //
  94. // Complexity: At most `size(range)` applications of the predicate and any
  95. // projection.
  96. //
  97. // Reference: https://wg21.link/alg.any.of#:~:text=ranges::any_of(R
  98. template <typename Range, typename Pred, typename Proj = identity>
  99. constexpr bool any_of(Range&& range, Pred pred, Proj proj = {}) {
  100. return ranges::any_of(ranges::begin(range), ranges::end(range),
  101. std::move(pred), std::move(proj));
  102. }
  103. // [alg.none.of] None of
  104. // Reference: https://wg21.link/alg.none.of
  105. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  106. //
  107. // Returns: `false` if `E(i)` is `true` for some iterator `i` in the range
  108. // `[first, last)`, and `true` otherwise.
  109. //
  110. // Complexity: At most `last - first` applications of the predicate and any
  111. // projection.
  112. //
  113. // Reference: https://wg21.link/alg.none.of#:~:text=ranges::none_of(I
  114. template <typename InputIterator, typename Pred, typename Proj = identity>
  115. constexpr bool none_of(InputIterator first,
  116. InputIterator last,
  117. Pred pred,
  118. Proj proj = {}) {
  119. return std::none_of(first, last,
  120. internal::ProjectedUnaryPredicate(pred, proj));
  121. }
  122. // Let `E(i)` be `invoke(pred, invoke(proj, *i))`.
  123. //
  124. // Returns: `false` if `E(i)` is `true` for some iterator `i` in `range`, and
  125. // `true` otherwise.
  126. //
  127. // Complexity: At most `size(range)` applications of the predicate and any
  128. // projection.
  129. //
  130. // Reference: https://wg21.link/alg.none.of#:~:text=ranges::none_of(R
  131. template <typename Range, typename Pred, typename Proj = identity>
  132. constexpr bool none_of(Range&& range, Pred pred, Proj proj = {}) {
  133. return ranges::none_of(ranges::begin(range), ranges::end(range),
  134. std::move(pred), std::move(proj));
  135. }
  136. // [alg.foreach] For each
  137. // Reference: https://wg21.link/alg.foreach
  138. // Effects: Calls `invoke(f, invoke(proj, *i))` for every iterator `i` in the
  139. // range `[first, last)`, starting from `first` and proceeding to `last - 1`.
  140. //
  141. // Returns: `f`
  142. // Note: std::ranges::for_each(I first,...) returns a for_each_result, rather
  143. // than an invocable. For simplicitly we match std::for_each's return type
  144. // instead.
  145. //
  146. // Complexity: Applies `f` and `proj` exactly `last - first` times.
  147. //
  148. // Remarks: If `f` returns a result, the result is ignored.
  149. //
  150. // Reference: https://wg21.link/alg.foreach#:~:text=ranges::for_each(I
  151. template <typename InputIterator, typename Fun, typename Proj = identity>
  152. constexpr auto for_each(InputIterator first,
  153. InputIterator last,
  154. Fun f,
  155. Proj proj = {}) {
  156. std::for_each(first, last, [&f, &proj](auto&& arg) {
  157. return invoke(f, invoke(proj, std::forward<decltype(arg)>(arg)));
  158. });
  159. return f;
  160. }
  161. // Effects: Calls `invoke(f, invoke(proj, *i))` for every iterator `i` in the
  162. // range `range`, starting from `begin(range)` and proceeding to `end(range) -
  163. // 1`.
  164. //
  165. // Returns: `f`
  166. // Note: std::ranges::for_each(R&& r,...) returns a for_each_result, rather
  167. // than an invocable. For simplicitly we match std::for_each's return type
  168. // instead.
  169. //
  170. // Complexity: Applies `f` and `proj` exactly `size(range)` times.
  171. //
  172. // Remarks: If `f` returns a result, the result is ignored.
  173. //
  174. // Reference: https://wg21.link/alg.foreach#:~:text=ranges::for_each(R
  175. template <typename Range, typename Fun, typename Proj = identity>
  176. constexpr auto for_each(Range&& range, Fun f, Proj proj = {}) {
  177. return ranges::for_each(ranges::begin(range), ranges::end(range),
  178. std::move(f), std::move(proj));
  179. }
  180. // [alg.find] Find
  181. // Reference: https://wg21.link/alg.find
  182. // Let `E(i)` be `bool(invoke(proj, *i) == value)`.
  183. //
  184. // Returns: The first iterator `i` in the range `[first, last)` for which `E(i)`
  185. // is `true`. Returns `last` if no such iterator is found.
  186. //
  187. // Complexity: At most `last - first` applications of the corresponding
  188. // predicate and any projection.
  189. //
  190. // Reference: https://wg21.link/alg.find#:~:text=ranges::find(I
  191. template <typename InputIterator, typename T, typename Proj = identity>
  192. constexpr auto find(InputIterator first,
  193. InputIterator last,
  194. const T& value,
  195. Proj proj = {}) {
  196. // Note: In order to be able to apply `proj` to each element in [first, last)
  197. // we are dispatching to std::find_if instead of std::find.
  198. return std::find_if(first, last, [&proj, &value](auto&& lhs) {
  199. return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
  200. });
  201. }
  202. // Let `E(i)` be `bool(invoke(proj, *i) == value)`.
  203. //
  204. // Returns: The first iterator `i` in `range` for which `E(i)` is `true`.
  205. // Returns `end(range)` if no such iterator is found.
  206. //
  207. // Complexity: At most `size(range)` applications of the corresponding predicate
  208. // and any projection.
  209. //
  210. // Reference: https://wg21.link/alg.find#:~:text=ranges::find(R
  211. template <typename Range, typename T, typename Proj = identity>
  212. constexpr auto find(Range&& range, const T& value, Proj proj = {}) {
  213. return ranges::find(ranges::begin(range), ranges::end(range), value,
  214. std::move(proj));
  215. }
  216. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`.
  217. //
  218. // Returns: The first iterator `i` in the range `[first, last)` for which `E(i)`
  219. // is `true`. Returns `last` if no such iterator is found.
  220. //
  221. // Complexity: At most `last - first` applications of the corresponding
  222. // predicate and any projection.
  223. //
  224. // Reference: https://wg21.link/alg.find#:~:text=ranges::find_if(I
  225. template <typename InputIterator, typename Pred, typename Proj = identity>
  226. constexpr auto find_if(InputIterator first,
  227. InputIterator last,
  228. Pred pred,
  229. Proj proj = {}) {
  230. return std::find_if(first, last,
  231. internal::ProjectedUnaryPredicate(pred, proj));
  232. }
  233. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`.
  234. //
  235. // Returns: The first iterator `i` in `range` for which `E(i)` is `true`.
  236. // Returns `end(range)` if no such iterator is found.
  237. //
  238. // Complexity: At most `size(range)` applications of the corresponding predicate
  239. // and any projection.
  240. //
  241. // Reference: https://wg21.link/alg.find#:~:text=ranges::find_if(R
  242. template <typename Range, typename Pred, typename Proj = identity>
  243. constexpr auto find_if(Range&& range, Pred pred, Proj proj = {}) {
  244. return ranges::find_if(ranges::begin(range), ranges::end(range),
  245. std::move(pred), std::move(proj));
  246. }
  247. // Let `E(i)` be `bool(!invoke(pred, invoke(proj, *i)))`.
  248. //
  249. // Returns: The first iterator `i` in the range `[first, last)` for which `E(i)`
  250. // is `true`. Returns `last` if no such iterator is found.
  251. //
  252. // Complexity: At most `last - first` applications of the corresponding
  253. // predicate and any projection.
  254. //
  255. // Reference: https://wg21.link/alg.find#:~:text=ranges::find_if_not(I
  256. template <typename InputIterator, typename Pred, typename Proj = identity>
  257. constexpr auto find_if_not(InputIterator first,
  258. InputIterator last,
  259. Pred pred,
  260. Proj proj = {}) {
  261. return std::find_if_not(first, last,
  262. internal::ProjectedUnaryPredicate(pred, proj));
  263. }
  264. // Let `E(i)` be `bool(!invoke(pred, invoke(proj, *i)))`.
  265. //
  266. // Returns: The first iterator `i` in `range` for which `E(i)` is `true`.
  267. // Returns `end(range)` if no such iterator is found.
  268. //
  269. // Complexity: At most `size(range)` applications of the corresponding predicate
  270. // and any projection.
  271. //
  272. // Reference: https://wg21.link/alg.find#:~:text=ranges::find_if_not(R
  273. template <typename Range, typename Pred, typename Proj = identity>
  274. constexpr auto find_if_not(Range&& range, Pred pred, Proj proj = {}) {
  275. return ranges::find_if_not(ranges::begin(range), ranges::end(range),
  276. std::move(pred), std::move(proj));
  277. }
  278. // [alg.find.end] Find end
  279. // Reference: https://wg21.link/alg.find.end
  280. // Let:
  281. // - `E(i,n)` be `invoke(pred, invoke(proj1, *(i + n)),
  282. // invoke(proj2, *(first2 + n)))`
  283. //
  284. // - `i` be `last1` if `[first2, last2)` is empty, or if
  285. // `(last2 - first2) > (last1 - first1)` is `true`, or if there is no iterator
  286. // in the range `[first1, last1 - (last2 - first2))` such that for every
  287. // non-negative integer `n < (last2 - first2)`, `E(i,n)` is `true`. Otherwise
  288. // `i` is the last such iterator in `[first1, last1 - (last2 - first2))`.
  289. //
  290. // Returns: `i`
  291. // Note: std::ranges::find_end(I1 first1,...) returns a range, rather than an
  292. // iterator. For simplicitly we match std::find_end's return type instead.
  293. //
  294. // Complexity:
  295. // At most `(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)`
  296. // applications of the corresponding predicate and any projections.
  297. //
  298. // Reference: https://wg21.link/alg.find.end#:~:text=ranges::find_end(I1
  299. template <typename ForwardIterator1,
  300. typename ForwardIterator2,
  301. typename Pred = ranges::equal_to,
  302. typename Proj1 = identity,
  303. typename Proj2 = identity>
  304. constexpr auto find_end(ForwardIterator1 first1,
  305. ForwardIterator1 last1,
  306. ForwardIterator2 first2,
  307. ForwardIterator2 last2,
  308. Pred pred = {},
  309. Proj1 proj1 = {},
  310. Proj2 proj2 = {}) {
  311. return std::find_end(first1, last1, first2, last2,
  312. internal::ProjectedBinaryPredicate(pred, proj1, proj2));
  313. }
  314. // Let:
  315. // - `E(i,n)` be `invoke(pred, invoke(proj1, *(i + n)),
  316. // invoke(proj2, *(first2 + n)))`
  317. //
  318. // - `i` be `end(range1)` if `range2` is empty, or if
  319. // `size(range2) > size(range1)` is `true`, or if there is no iterator in the
  320. // range `[begin(range1), end(range1) - size(range2))` such that for every
  321. // non-negative integer `n < size(range2)`, `E(i,n)` is `true`. Otherwise `i`
  322. // is the last such iterator in `[begin(range1), end(range1) - size(range2))`.
  323. //
  324. // Returns: `i`
  325. // Note: std::ranges::find_end(R1&& r1,...) returns a range, rather than an
  326. // iterator. For simplicitly we match std::find_end's return type instead.
  327. //
  328. // Complexity: At most `size(range2) * (size(range1) - size(range2) + 1)`
  329. // applications of the corresponding predicate and any projections.
  330. //
  331. // Reference: https://wg21.link/alg.find.end#:~:text=ranges::find_end(R1
  332. template <typename Range1,
  333. typename Range2,
  334. typename Pred = ranges::equal_to,
  335. typename Proj1 = identity,
  336. typename Proj2 = identity>
  337. constexpr auto find_end(Range1&& range1,
  338. Range2&& range2,
  339. Pred pred = {},
  340. Proj1 proj1 = {},
  341. Proj2 proj2 = {}) {
  342. return ranges::find_end(ranges::begin(range1), ranges::end(range1),
  343. ranges::begin(range2), ranges::end(range2),
  344. std::move(pred), std::move(proj1), std::move(proj2));
  345. }
  346. // [alg.find.first.of] Find first
  347. // Reference: https://wg21.link/alg.find.first.of
  348. // Let `E(i,j)` be `bool(invoke(pred, invoke(proj1, *i), invoke(proj2, *j)))`.
  349. //
  350. // Effects: Finds an element that matches one of a set of values.
  351. //
  352. // Returns: The first iterator `i` in the range `[first1, last1)` such that for
  353. // some iterator `j` in the range `[first2, last2)` `E(i,j)` holds. Returns
  354. // `last1` if `[first2, last2)` is empty or if no such iterator is found.
  355. //
  356. // Complexity: At most `(last1 - first1) * (last2 - first2)` applications of the
  357. // corresponding predicate and any projections.
  358. //
  359. // Reference:
  360. // https://wg21.link/alg.find.first.of#:~:text=ranges::find_first_of(I1
  361. template <typename ForwardIterator1,
  362. typename ForwardIterator2,
  363. typename Pred = ranges::equal_to,
  364. typename Proj1 = identity,
  365. typename Proj2 = identity>
  366. constexpr auto find_first_of(ForwardIterator1 first1,
  367. ForwardIterator1 last1,
  368. ForwardIterator2 first2,
  369. ForwardIterator2 last2,
  370. Pred pred = {},
  371. Proj1 proj1 = {},
  372. Proj2 proj2 = {}) {
  373. return std::find_first_of(
  374. first1, last1, first2, last2,
  375. internal::ProjectedBinaryPredicate(pred, proj1, proj2));
  376. }
  377. // Let `E(i,j)` be `bool(invoke(pred, invoke(proj1, *i), invoke(proj2, *j)))`.
  378. //
  379. // Effects: Finds an element that matches one of a set of values.
  380. //
  381. // Returns: The first iterator `i` in `range1` such that for some iterator `j`
  382. // in `range2` `E(i,j)` holds. Returns `end(range1)` if `range2` is empty or if
  383. // no such iterator is found.
  384. //
  385. // Complexity: At most `size(range1) * size(range2)` applications of the
  386. // corresponding predicate and any projections.
  387. //
  388. // Reference:
  389. // https://wg21.link/alg.find.first.of#:~:text=ranges::find_first_of(R1
  390. template <typename Range1,
  391. typename Range2,
  392. typename Pred = ranges::equal_to,
  393. typename Proj1 = identity,
  394. typename Proj2 = identity>
  395. constexpr auto find_first_of(Range1&& range1,
  396. Range2&& range2,
  397. Pred pred = {},
  398. Proj1 proj1 = {},
  399. Proj2 proj2 = {}) {
  400. return ranges::find_first_of(
  401. ranges::begin(range1), ranges::end(range1), ranges::begin(range2),
  402. ranges::end(range2), std::move(pred), std::move(proj1), std::move(proj2));
  403. }
  404. // [alg.adjacent.find] Adjacent find
  405. // Reference: https://wg21.link/alg.adjacent.find
  406. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))))`.
  407. //
  408. // Returns: The first iterator `i` such that both `i` and `i + 1` are in the
  409. // range `[first, last)` for which `E(i)` holds. Returns `last` if no such
  410. // iterator is found.
  411. //
  412. // Complexity: Exactly `min((i - first) + 1, (last - first) - 1)` applications
  413. // of the corresponding predicate, where `i` is `adjacent_find`'s return value.
  414. //
  415. // Reference:
  416. // https://wg21.link/alg.adjacent.find#:~:text=ranges::adjacent_find(I
  417. template <typename ForwardIterator,
  418. typename Pred = ranges::equal_to,
  419. typename Proj = identity>
  420. constexpr auto adjacent_find(ForwardIterator first,
  421. ForwardIterator last,
  422. Pred pred = {},
  423. Proj proj = {}) {
  424. return std::adjacent_find(
  425. first, last, internal::ProjectedBinaryPredicate(pred, proj, proj));
  426. }
  427. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))))`.
  428. //
  429. // Returns: The first iterator `i` such that both `i` and `i + 1` are in the
  430. // range `range` for which `E(i)` holds. Returns `end(range)` if no such
  431. // iterator is found.
  432. //
  433. // Complexity: Exactly `min((i - begin(range)) + 1, size(range) - 1)`
  434. // applications of the corresponding predicate, where `i` is `adjacent_find`'s
  435. // return value.
  436. //
  437. // Reference:
  438. // https://wg21.link/alg.adjacent.find#:~:text=ranges::adjacent_find(R
  439. template <typename Range,
  440. typename Pred = ranges::equal_to,
  441. typename Proj = identity>
  442. constexpr auto adjacent_find(Range&& range, Pred pred = {}, Proj proj = {}) {
  443. return ranges::adjacent_find(ranges::begin(range), ranges::end(range),
  444. std::move(pred), std::move(proj));
  445. }
  446. // [alg.count] Count
  447. // Reference: https://wg21.link/alg.count
  448. // Let `E(i)` be `invoke(proj, *i) == value`.
  449. //
  450. // Effects: Returns the number of iterators `i` in the range `[first, last)` for
  451. // which `E(i)` holds.
  452. //
  453. // Complexity: Exactly `last - first` applications of the corresponding
  454. // predicate and any projection.
  455. //
  456. // Reference: https://wg21.link/alg.count#:~:text=ranges::count(I
  457. template <typename InputIterator, typename T, typename Proj = identity>
  458. constexpr auto count(InputIterator first,
  459. InputIterator last,
  460. const T& value,
  461. Proj proj = {}) {
  462. // Note: In order to be able to apply `proj` to each element in [first, last)
  463. // we are dispatching to std::count_if instead of std::count.
  464. return std::count_if(first, last, [&proj, &value](auto&& lhs) {
  465. return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
  466. });
  467. }
  468. // Let `E(i)` be `invoke(proj, *i) == value`.
  469. //
  470. // Effects: Returns the number of iterators `i` in `range` for which `E(i)`
  471. // holds.
  472. //
  473. // Complexity: Exactly `size(range)` applications of the corresponding predicate
  474. // and any projection.
  475. //
  476. // Reference: https://wg21.link/alg.count#:~:text=ranges::count(R
  477. template <typename Range, typename T, typename Proj = identity>
  478. constexpr auto count(Range&& range, const T& value, Proj proj = {}) {
  479. return ranges::count(ranges::begin(range), ranges::end(range), value,
  480. std::move(proj));
  481. }
  482. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`.
  483. //
  484. // Effects: Returns the number of iterators `i` in the range `[first, last)` for
  485. // which `E(i)` holds.
  486. //
  487. // Complexity: Exactly `last - first` applications of the corresponding
  488. // predicate and any projection.
  489. //
  490. // Reference: https://wg21.link/alg.count#:~:text=ranges::count_if(I
  491. template <typename InputIterator, typename Pred, typename Proj = identity>
  492. constexpr auto count_if(InputIterator first,
  493. InputIterator last,
  494. Pred pred,
  495. Proj proj = {}) {
  496. return std::count_if(first, last,
  497. internal::ProjectedUnaryPredicate(pred, proj));
  498. }
  499. // Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`.
  500. //
  501. // Effects: Returns the number of iterators `i` in `range` for which `E(i)`
  502. // holds.
  503. //
  504. // Complexity: Exactly `size(range)` applications of the corresponding predicate
  505. // and any projection.
  506. //
  507. // Reference: https://wg21.link/alg.count#:~:text=ranges::count_if(R
  508. template <typename Range, typename Pred, typename Proj = identity>
  509. constexpr auto count_if(Range&& range, Pred pred, Proj proj = {}) {
  510. return ranges::count_if(ranges::begin(range), ranges::end(range),
  511. std::move(pred), std::move(proj));
  512. }
  513. // [mismatch] Mismatch
  514. // Reference: https://wg21.link/mismatch
  515. // Let `E(n)` be `!invoke(pred, invoke(proj1, *(first1 + n)),
  516. // invoke(proj2, *(first2 + n)))`.
  517. //
  518. // Let `N` be `min(last1 - first1, last2 - first2)`.
  519. //
  520. // Returns: `{ first1 + n, first2 + n }`, where `n` is the smallest integer in
  521. // `[0, N)` such that `E(n)` holds, or `N` if no such integer exists.
  522. //
  523. // Complexity: At most `N` applications of the corresponding predicate and any
  524. // projections.
  525. //
  526. // Reference: https://wg21.link/mismatch#:~:text=ranges::mismatch(I1
  527. template <typename ForwardIterator1,
  528. typename ForwardIterator2,
  529. typename Pred = ranges::equal_to,
  530. typename Proj1 = identity,
  531. typename Proj2 = identity>
  532. constexpr auto mismatch(ForwardIterator1 first1,
  533. ForwardIterator1 last1,
  534. ForwardIterator2 first2,
  535. ForwardIterator2 last2,
  536. Pred pred = {},
  537. Proj1 proj1 = {},
  538. Proj2 proj2 = {}) {
  539. return std::mismatch(first1, last1, first2, last2,
  540. internal::ProjectedBinaryPredicate(pred, proj1, proj2));
  541. }
  542. // Let `E(n)` be `!invoke(pred, invoke(proj1, *(begin(range1) + n)),
  543. // invoke(proj2, *(begin(range2) + n)))`.
  544. //
  545. // Let `N` be `min(size(range1), size(range2))`.
  546. //
  547. // Returns: `{ begin(range1) + n, begin(range2) + n }`, where `n` is the
  548. // smallest integer in `[0, N)` such that `E(n)` holds, or `N` if no such
  549. // integer exists.
  550. //
  551. // Complexity: At most `N` applications of the corresponding predicate and any
  552. // projections.
  553. //
  554. // Reference: https://wg21.link/mismatch#:~:text=ranges::mismatch(R1
  555. template <typename Range1,
  556. typename Range2,
  557. typename Pred = ranges::equal_to,
  558. typename Proj1 = identity,
  559. typename Proj2 = identity>
  560. constexpr auto mismatch(Range1&& range1,
  561. Range2&& range2,
  562. Pred pred = {},
  563. Proj1 proj1 = {},
  564. Proj2 proj2 = {}) {
  565. return ranges::mismatch(ranges::begin(range1), ranges::end(range1),
  566. ranges::begin(range2), ranges::end(range2),
  567. std::move(pred), std::move(proj1), std::move(proj2));
  568. }
  569. // [alg.equal] Equal
  570. // Reference: https://wg21.link/alg.equal
  571. // Let `E(i)` be
  572. // `invoke(pred, invoke(proj1, *i), invoke(proj2, *(first2 + (i - first1))))`.
  573. //
  574. // Returns: If `last1 - first1 != last2 - first2`, return `false.` Otherwise
  575. // return `true` if `E(i)` holds for every iterator `i` in the range `[first1,
  576. // last1)`. Otherwise, returns `false`.
  577. //
  578. // Complexity: If the types of `first1`, `last1`, `first2`, and `last2` meet the
  579. // `RandomAccessIterator` requirements and `last1 - first1 != last2 - first2`,
  580. // then no applications of the corresponding predicate and each projection;
  581. // otherwise, at most `min(last1 - first1, last2 - first2)` applications of the
  582. // corresponding predicate and any projections.
  583. //
  584. // Reference: https://wg21.link/alg.equal#:~:text=ranges::equal(I1
  585. template <typename ForwardIterator1,
  586. typename ForwardIterator2,
  587. typename Pred = ranges::equal_to,
  588. typename Proj1 = identity,
  589. typename Proj2 = identity>
  590. constexpr bool equal(ForwardIterator1 first1,
  591. ForwardIterator1 last1,
  592. ForwardIterator2 first2,
  593. ForwardIterator2 last2,
  594. Pred pred = {},
  595. Proj1 proj1 = {},
  596. Proj2 proj2 = {}) {
  597. return std::equal(first1, last1, first2, last2,
  598. internal::ProjectedBinaryPredicate(pred, proj1, proj2));
  599. }
  600. // Let `E(i)` be
  601. // `invoke(pred, invoke(proj1, *i),
  602. // invoke(proj2, *(begin(range2) + (i - begin(range1)))))`.
  603. //
  604. // Returns: If `size(range1) != size(range2)`, return `false.` Otherwise return
  605. // `true` if `E(i)` holds for every iterator `i` in `range1`. Otherwise, returns
  606. // `false`.
  607. //
  608. // Complexity: If the types of `begin(range1)`, `end(range1)`, `begin(range2)`,
  609. // and `end(range2)` meet the `RandomAccessIterator` requirements and
  610. // `size(range1) != size(range2)`, then no applications of the corresponding
  611. // predicate and each projection;
  612. // otherwise, at most `min(size(range1), size(range2))` applications of the
  613. // corresponding predicate and any projections.
  614. //
  615. // Reference: https://wg21.link/alg.equal#:~:text=ranges::equal(R1
  616. template <typename Range1,
  617. typename Range2,
  618. typename Pred = ranges::equal_to,
  619. typename Proj1 = identity,
  620. typename Proj2 = identity>
  621. constexpr bool equal(Range1&& range1,
  622. Range2&& range2,
  623. Pred pred = {},
  624. Proj1 proj1 = {},
  625. Proj2 proj2 = {}) {
  626. return ranges::equal(ranges::begin(range1), ranges::end(range1),
  627. ranges::begin(range2), ranges::end(range2),
  628. std::move(pred), std::move(proj1), std::move(proj2));
  629. }
  630. // [alg.is.permutation] Is permutation
  631. // Reference: https://wg21.link/alg.is.permutation
  632. // Returns: If `last1 - first1 != last2 - first2`, return `false`. Otherwise
  633. // return `true` if there exists a permutation of the elements in the range
  634. // `[first2, last2)`, bounded by `[pfirst, plast)`, such that
  635. // `ranges::equal(first1, last1, pfirst, plast, pred, proj, proj)` returns
  636. // `true`; otherwise, returns `false`.
  637. //
  638. // Complexity: No applications of the corresponding predicate if
  639. // ForwardIterator1 and ForwardIterator2 meet the requirements of random access
  640. // iterators and `last1 - first1 != last2 - first2`. Otherwise, exactly
  641. // `last1 - first1` applications of the corresponding predicate and projections
  642. // if `ranges::equal(first1, last1, first2, last2, pred, proj, proj)` would
  643. // return true;
  644. // otherwise, at worst `O(N^2)`, where `N` has the value `last1 - first1`.
  645. //
  646. // Note: While std::ranges::is_permutation supports different projections for
  647. // the first and second range, this is currently not supported due to
  648. // dispatching to std::is_permutation, which demands that `pred` is an
  649. // equivalence relation.
  650. // TODO(https://crbug.com/1071094): Consider supporing different projections in
  651. // the future.
  652. //
  653. // Reference:
  654. // https://wg21.link/alg.is.permutation#:~:text=ranges::is_permutation(I1
  655. template <typename ForwardIterator1,
  656. typename ForwardIterator2,
  657. typename Pred = ranges::equal_to,
  658. typename Proj = identity>
  659. constexpr bool is_permutation(ForwardIterator1 first1,
  660. ForwardIterator1 last1,
  661. ForwardIterator2 first2,
  662. ForwardIterator2 last2,
  663. Pred pred = {},
  664. Proj proj = {}) {
  665. return std::is_permutation(
  666. first1, last1, first2, last2,
  667. internal::ProjectedBinaryPredicate(pred, proj, proj));
  668. }
  669. // Returns: If `size(range1) != size(range2)`, return `false`. Otherwise return
  670. // `true` if there exists a permutation of the elements in `range2`, bounded by
  671. // `[pbegin, pend)`, such that
  672. // `ranges::equal(range1, [pbegin, pend), pred, proj, proj)` returns `true`;
  673. // otherwise, returns `false`.
  674. //
  675. // Complexity: No applications of the corresponding predicate if Range1 and
  676. // Range2 meet the requirements of random access ranges and
  677. // `size(range1) != size(range2)`. Otherwise, exactly `size(range1)`
  678. // applications of the corresponding predicate and projections if
  679. // `ranges::equal(range1, range2, pred, proj, proj)` would return true;
  680. // otherwise, at worst `O(N^2)`, where `N` has the value `size(range1)`.
  681. //
  682. // Note: While std::ranges::is_permutation supports different projections for
  683. // the first and second range, this is currently not supported due to
  684. // dispatching to std::is_permutation, which demands that `pred` is an
  685. // equivalence relation.
  686. // TODO(https://crbug.com/1071094): Consider supporing different projections in
  687. // the future.
  688. //
  689. // Reference:
  690. // https://wg21.link/alg.is.permutation#:~:text=ranges::is_permutation(R1
  691. template <typename Range1,
  692. typename Range2,
  693. typename Pred = ranges::equal_to,
  694. typename Proj = identity>
  695. constexpr bool is_permutation(Range1&& range1,
  696. Range2&& range2,
  697. Pred pred = {},
  698. Proj proj = {}) {
  699. return ranges::is_permutation(ranges::begin(range1), ranges::end(range1),
  700. ranges::begin(range2), ranges::end(range2),
  701. std::move(pred), std::move(proj));
  702. }
  703. // [alg.search] Search
  704. // Reference: https://wg21.link/alg.search
  705. // Returns: `i`, where `i` is the first iterator in the range
  706. // `[first1, last1 - (last2 - first2))` such that for every non-negative integer
  707. // `n` less than `last2 - first2` the condition
  708. // `bool(invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n))))`
  709. // is `true`.
  710. // Returns `last1` if no such iterator exists.
  711. // Note: std::ranges::search(I1 first1,...) returns a range, rather than an
  712. // iterator. For simplicitly we match std::search's return type instead.
  713. //
  714. // Complexity: At most `(last1 - first1) * (last2 - first2)` applications of the
  715. // corresponding predicate and projections.
  716. //
  717. // Reference: https://wg21.link/alg.search#:~:text=ranges::search(I1
  718. template <typename ForwardIterator1,
  719. typename ForwardIterator2,
  720. typename Pred = ranges::equal_to,
  721. typename Proj1 = identity,
  722. typename Proj2 = identity>
  723. constexpr auto search(ForwardIterator1 first1,
  724. ForwardIterator1 last1,
  725. ForwardIterator2 first2,
  726. ForwardIterator2 last2,
  727. Pred pred = {},
  728. Proj1 proj1 = {},
  729. Proj2 proj2 = {}) {
  730. return std::search(first1, last1, first2, last2,
  731. internal::ProjectedBinaryPredicate(pred, proj1, proj2));
  732. }
  733. // Returns: `i`, where `i` is the first iterator in the range
  734. // `[begin(range1), end(range1) - size(range2))` such that for every
  735. // non-negative integer `n` less than `size(range2)` the condition
  736. // `bool(invoke(pred, invoke(proj1, *(i + n)),
  737. // invoke(proj2, *(begin(range2) + n))))` is `true`.
  738. // Returns `end(range1)` if no such iterator exists.
  739. // Note: std::ranges::search(R1&& r1,...) returns a range, rather than an
  740. // iterator. For simplicitly we match std::search's return type instead.
  741. //
  742. // Complexity: At most `size(range1) * size(range2)` applications of the
  743. // corresponding predicate and projections.
  744. //
  745. // Reference: https://wg21.link/alg.search#:~:text=ranges::search(R1
  746. template <typename Range1,
  747. typename Range2,
  748. typename Pred = ranges::equal_to,
  749. typename Proj1 = identity,
  750. typename Proj2 = identity>
  751. constexpr auto search(Range1&& range1,
  752. Range2&& range2,
  753. Pred pred = {},
  754. Proj1 proj1 = {},
  755. Proj2 proj2 = {}) {
  756. return ranges::search(ranges::begin(range1), ranges::end(range1),
  757. ranges::begin(range2), ranges::end(range2),
  758. std::move(pred), std::move(proj1), std::move(proj2));
  759. }
  760. // Mandates: The type `Size` is convertible to an integral type.
  761. //
  762. // Returns: `i` where `i` is the first iterator in the range
  763. // `[first, last - count)` such that for every non-negative integer `n` less
  764. // than `count`, the following condition holds:
  765. // `invoke(pred, invoke(proj, *(i + n)), value)`.
  766. // Returns `last` if no such iterator is found.
  767. // Note: std::ranges::search_n(I1 first1,...) returns a range, rather than an
  768. // iterator. For simplicitly we match std::search_n's return type instead.
  769. //
  770. // Complexity: At most `last - first` applications of the corresponding
  771. // predicate and projection.
  772. //
  773. // Reference: https://wg21.link/alg.search#:~:text=ranges::search_n(I
  774. template <typename ForwardIterator,
  775. typename Size,
  776. typename T,
  777. typename Pred = ranges::equal_to,
  778. typename Proj = identity>
  779. constexpr auto search_n(ForwardIterator first,
  780. ForwardIterator last,
  781. Size count,
  782. const T& value,
  783. Pred pred = {},
  784. Proj proj = {}) {
  785. // The second arg is guaranteed to be `value`, so we'll simply apply the
  786. // identity projection.
  787. identity value_proj;
  788. return std::search_n(
  789. first, last, count, value,
  790. internal::ProjectedBinaryPredicate(pred, proj, value_proj));
  791. }
  792. // Mandates: The type `Size` is convertible to an integral type.
  793. //
  794. // Returns: `i` where `i` is the first iterator in the range
  795. // `[begin(range), end(range) - count)` such that for every non-negative integer
  796. // `n` less than `count`, the following condition holds:
  797. // `invoke(pred, invoke(proj, *(i + n)), value)`.
  798. // Returns `end(arnge)` if no such iterator is found.
  799. // Note: std::ranges::search_n(R1&& r1,...) returns a range, rather than an
  800. // iterator. For simplicitly we match std::search_n's return type instead.
  801. //
  802. // Complexity: At most `size(range)` applications of the corresponding predicate
  803. // and projection.
  804. //
  805. // Reference: https://wg21.link/alg.search#:~:text=ranges::search_n(R
  806. template <typename Range,
  807. typename Size,
  808. typename T,
  809. typename Pred = ranges::equal_to,
  810. typename Proj = identity>
  811. constexpr auto search_n(Range&& range,
  812. Size count,
  813. const T& value,
  814. Pred pred = {},
  815. Proj proj = {}) {
  816. return ranges::search_n(ranges::begin(range), ranges::end(range), count,
  817. value, std::move(pred), std::move(proj));
  818. }
  819. } // namespace ranges
  820. } // namespace util
  821. #endif // BASE_UTIL_RANGES_ALGORITHM_H_