You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

container.h 77 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // -----------------------------------------------------------------------------
  16. // File: container.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This header file provides Container-based versions of algorithmic functions
  20. // within the C++ standard library. The following standard library sets of
  21. // functions are covered within this file:
  22. //
  23. // * Algorithmic <iterator> functions
  24. // * Algorithmic <numeric> functions
  25. // * <algorithm> functions
  26. //
  27. // The standard library functions operate on iterator ranges; the functions
  28. // within this API operate on containers, though many return iterator ranges.
  29. //
  30. // All functions within this API are named with a `c_` prefix. Calls such as
  31. // `absl::c_xx(container, ...) are equivalent to std:: functions such as
  32. // `std::xx(std::begin(cont), std::end(cont), ...)`. Functions that act on
  33. // iterators but not conceptually on iterator ranges (e.g. `std::iter_swap`)
  34. // have no equivalent here.
  35. //
  36. // For template parameter and variable naming, `C` indicates the container type
  37. // to which the function is applied, `Pred` indicates the predicate object type
  38. // to be used by the function and `T` indicates the applicable element type.
  39. #ifndef ABSL_ALGORITHM_CONTAINER_H_
  40. #define ABSL_ALGORITHM_CONTAINER_H_
  41. #include <algorithm>
  42. #include <cassert>
  43. #include <iterator>
  44. #include <numeric>
  45. #include <type_traits>
  46. #include <unordered_map>
  47. #include <unordered_set>
  48. #include <utility>
  49. #include <vector>
  50. #include "absl/algorithm/algorithm.h"
  51. #include "absl/base/macros.h"
  52. #include "absl/meta/type_traits.h"
  53. namespace absl
  54. {
  55. ABSL_NAMESPACE_BEGIN
  56. namespace container_algorithm_internal
  57. {
  58. // NOTE: it is important to defer to ADL lookup for building with C++ modules,
  59. // especially for headers like <valarray> which are not visible from this file
  60. // but specialize std::begin and std::end.
  61. using std::begin;
  62. using std::end;
  63. // The type of the iterator given by begin(c) (possibly std::begin(c)).
  64. // ContainerIter<const vector<T>> gives vector<T>::const_iterator,
  65. // while ContainerIter<vector<T>> gives vector<T>::iterator.
  66. template<typename C>
  67. using ContainerIter = decltype(begin(std::declval<C&>()));
  68. // An MSVC bug involving template parameter substitution requires us to use
  69. // decltype() here instead of just std::pair.
  70. template<typename C1, typename C2>
  71. using ContainerIterPairType =
  72. decltype(std::make_pair(ContainerIter<C1>(), ContainerIter<C2>()));
  73. template<typename C>
  74. using ContainerDifferenceType =
  75. decltype(std::distance(std::declval<ContainerIter<C>>(), std::declval<ContainerIter<C>>()));
  76. template<typename C>
  77. using ContainerPointerType =
  78. typename std::iterator_traits<ContainerIter<C>>::pointer;
  79. // container_algorithm_internal::c_begin and
  80. // container_algorithm_internal::c_end are abbreviations for proper ADL
  81. // lookup of std::begin and std::end, i.e.
  82. // using std::begin;
  83. // using std::end;
  84. // std::foo(begin(c), end(c));
  85. // becomes
  86. // std::foo(container_algorithm_internal::begin(c),
  87. // container_algorithm_internal::end(c));
  88. // These are meant for internal use only.
  89. template<typename C>
  90. ContainerIter<C> c_begin(C& c)
  91. {
  92. return begin(c);
  93. }
  94. template<typename C>
  95. ContainerIter<C> c_end(C& c)
  96. {
  97. return end(c);
  98. }
  99. template<typename T>
  100. struct IsUnorderedContainer : std::false_type
  101. {
  102. };
  103. template<class Key, class T, class Hash, class KeyEqual, class Allocator>
  104. struct IsUnorderedContainer<
  105. std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
  106. {
  107. };
  108. template<class Key, class Hash, class KeyEqual, class Allocator>
  109. struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>> : std::true_type
  110. {
  111. };
  112. // container_algorithm_internal::c_size. It is meant for internal use only.
  113. template<class C>
  114. auto c_size(C& c) -> decltype(c.size())
  115. {
  116. return c.size();
  117. }
  118. template<class T, std::size_t N>
  119. constexpr std::size_t c_size(T (&)[N])
  120. {
  121. return N;
  122. }
  123. } // namespace container_algorithm_internal
  124. // PUBLIC API
  125. //------------------------------------------------------------------------------
  126. // Abseil algorithm.h functions
  127. //------------------------------------------------------------------------------
  128. // c_linear_search()
  129. //
  130. // Container-based version of absl::linear_search() for performing a linear
  131. // search within a container.
  132. template<typename C, typename EqualityComparable>
  133. bool c_linear_search(const C& c, EqualityComparable&& value)
  134. {
  135. return linear_search(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<EqualityComparable>(value));
  136. }
  137. //------------------------------------------------------------------------------
  138. // <iterator> algorithms
  139. //------------------------------------------------------------------------------
  140. // c_distance()
  141. //
  142. // Container-based version of the <iterator> `std::distance()` function to
  143. // return the number of elements within a container.
  144. template<typename C>
  145. container_algorithm_internal::ContainerDifferenceType<const C> c_distance(
  146. const C& c
  147. )
  148. {
  149. return std::distance(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  150. }
  151. //------------------------------------------------------------------------------
  152. // <algorithm> Non-modifying sequence operations
  153. //------------------------------------------------------------------------------
  154. // c_all_of()
  155. //
  156. // Container-based version of the <algorithm> `std::all_of()` function to
  157. // test if all elements within a container satisfy a condition.
  158. template<typename C, typename Pred>
  159. bool c_all_of(const C& c, Pred&& pred)
  160. {
  161. return std::all_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  162. }
  163. // c_any_of()
  164. //
  165. // Container-based version of the <algorithm> `std::any_of()` function to
  166. // test if any element in a container fulfills a condition.
  167. template<typename C, typename Pred>
  168. bool c_any_of(const C& c, Pred&& pred)
  169. {
  170. return std::any_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  171. }
  172. // c_none_of()
  173. //
  174. // Container-based version of the <algorithm> `std::none_of()` function to
  175. // test if no elements in a container fulfill a condition.
  176. template<typename C, typename Pred>
  177. bool c_none_of(const C& c, Pred&& pred)
  178. {
  179. return std::none_of(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  180. }
  181. // c_for_each()
  182. //
  183. // Container-based version of the <algorithm> `std::for_each()` function to
  184. // apply a function to a container's elements.
  185. template<typename C, typename Function>
  186. decay_t<Function> c_for_each(C&& c, Function&& f)
  187. {
  188. return std::for_each(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Function>(f));
  189. }
  190. // c_find()
  191. //
  192. // Container-based version of the <algorithm> `std::find()` function to find
  193. // the first element containing the passed value within a container value.
  194. template<typename C, typename T>
  195. container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value)
  196. {
  197. return std::find(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<T>(value));
  198. }
  199. // c_find_if()
  200. //
  201. // Container-based version of the <algorithm> `std::find_if()` function to find
  202. // the first element in a container matching the given condition.
  203. template<typename C, typename Pred>
  204. container_algorithm_internal::ContainerIter<C> c_find_if(C& c, Pred&& pred)
  205. {
  206. return std::find_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  207. }
  208. // c_find_if_not()
  209. //
  210. // Container-based version of the <algorithm> `std::find_if_not()` function to
  211. // find the first element in a container not matching the given condition.
  212. template<typename C, typename Pred>
  213. container_algorithm_internal::ContainerIter<C> c_find_if_not(C& c, Pred&& pred)
  214. {
  215. return std::find_if_not(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  216. }
  217. // c_find_end()
  218. //
  219. // Container-based version of the <algorithm> `std::find_end()` function to
  220. // find the last subsequence within a container.
  221. template<typename Sequence1, typename Sequence2>
  222. container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
  223. Sequence1& sequence, Sequence2& subsequence
  224. )
  225. {
  226. return std::find_end(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence));
  227. }
  228. // Overload of c_find_end() for using a predicate evaluation other than `==` as
  229. // the function's test condition.
  230. template<typename Sequence1, typename Sequence2, typename BinaryPredicate>
  231. container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
  232. Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred
  233. )
  234. {
  235. return std::find_end(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence), std::forward<BinaryPredicate>(pred));
  236. }
  237. // c_find_first_of()
  238. //
  239. // Container-based version of the <algorithm> `std::find_first_of()` function to
  240. // find the first element within the container that is also within the options
  241. // container.
  242. template<typename C1, typename C2>
  243. container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container, C2& options)
  244. {
  245. return std::find_first_of(container_algorithm_internal::c_begin(container), container_algorithm_internal::c_end(container), container_algorithm_internal::c_begin(options), container_algorithm_internal::c_end(options));
  246. }
  247. // Overload of c_find_first_of() for using a predicate evaluation other than
  248. // `==` as the function's test condition.
  249. template<typename C1, typename C2, typename BinaryPredicate>
  250. container_algorithm_internal::ContainerIter<C1> c_find_first_of(
  251. C1& container, C2& options, BinaryPredicate&& pred
  252. )
  253. {
  254. return std::find_first_of(container_algorithm_internal::c_begin(container), container_algorithm_internal::c_end(container), container_algorithm_internal::c_begin(options), container_algorithm_internal::c_end(options), std::forward<BinaryPredicate>(pred));
  255. }
  256. // c_adjacent_find()
  257. //
  258. // Container-based version of the <algorithm> `std::adjacent_find()` function to
  259. // find equal adjacent elements within a container.
  260. template<typename Sequence>
  261. container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
  262. Sequence& sequence
  263. )
  264. {
  265. return std::adjacent_find(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  266. }
  267. // Overload of c_adjacent_find() for using a predicate evaluation other than
  268. // `==` as the function's test condition.
  269. template<typename Sequence, typename BinaryPredicate>
  270. container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
  271. Sequence& sequence, BinaryPredicate&& pred
  272. )
  273. {
  274. return std::adjacent_find(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<BinaryPredicate>(pred));
  275. }
  276. // c_count()
  277. //
  278. // Container-based version of the <algorithm> `std::count()` function to count
  279. // values that match within a container.
  280. template<typename C, typename T>
  281. container_algorithm_internal::ContainerDifferenceType<const C> c_count(
  282. const C& c, T&& value
  283. )
  284. {
  285. return std::count(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<T>(value));
  286. }
  287. // c_count_if()
  288. //
  289. // Container-based version of the <algorithm> `std::count_if()` function to
  290. // count values matching a condition within a container.
  291. template<typename C, typename Pred>
  292. container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
  293. const C& c, Pred&& pred
  294. )
  295. {
  296. return std::count_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  297. }
  298. // c_mismatch()
  299. //
  300. // Container-based version of the <algorithm> `std::mismatch()` function to
  301. // return the first element where two ordered containers differ. Applies `==` to
  302. // the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
  303. template<typename C1, typename C2>
  304. container_algorithm_internal::ContainerIterPairType<C1, C2>
  305. c_mismatch(C1& c1, C2& c2)
  306. {
  307. auto first1 = container_algorithm_internal::c_begin(c1);
  308. auto last1 = container_algorithm_internal::c_end(c1);
  309. auto first2 = container_algorithm_internal::c_begin(c2);
  310. auto last2 = container_algorithm_internal::c_end(c2);
  311. for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
  312. {
  313. // Negates equality because Cpp17EqualityComparable doesn't require clients
  314. // to overload both `operator==` and `operator!=`.
  315. if (!(*first1 == *first2))
  316. {
  317. break;
  318. }
  319. }
  320. return std::make_pair(first1, first2);
  321. }
  322. // Overload of c_mismatch() for using a predicate evaluation other than `==` as
  323. // the function's test condition. Applies `pred`to the first N elements of `c1`
  324. // and `c2`, where N = min(size(c1), size(c2)).
  325. template<typename C1, typename C2, typename BinaryPredicate>
  326. container_algorithm_internal::ContainerIterPairType<C1, C2>
  327. c_mismatch(C1& c1, C2& c2, BinaryPredicate pred)
  328. {
  329. auto first1 = container_algorithm_internal::c_begin(c1);
  330. auto last1 = container_algorithm_internal::c_end(c1);
  331. auto first2 = container_algorithm_internal::c_begin(c2);
  332. auto last2 = container_algorithm_internal::c_end(c2);
  333. for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
  334. {
  335. if (!pred(*first1, *first2))
  336. {
  337. break;
  338. }
  339. }
  340. return std::make_pair(first1, first2);
  341. }
  342. // c_equal()
  343. //
  344. // Container-based version of the <algorithm> `std::equal()` function to
  345. // test whether two containers are equal.
  346. //
  347. // NOTE: the semantics of c_equal() are slightly different than those of
  348. // equal(): while the latter iterates over the second container only up to the
  349. // size of the first container, c_equal() also checks whether the container
  350. // sizes are equal. This better matches expectations about c_equal() based on
  351. // its signature.
  352. //
  353. // Example:
  354. // vector v1 = <1, 2, 3>;
  355. // vector v2 = <1, 2, 3, 4>;
  356. // equal(std::begin(v1), std::end(v1), std::begin(v2)) returns true
  357. // c_equal(v1, v2) returns false
  358. template<typename C1, typename C2>
  359. bool c_equal(const C1& c1, const C2& c2)
  360. {
  361. return ((container_algorithm_internal::c_size(c1) == container_algorithm_internal::c_size(c2)) && std::equal(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2)));
  362. }
  363. // Overload of c_equal() for using a predicate evaluation other than `==` as
  364. // the function's test condition.
  365. template<typename C1, typename C2, typename BinaryPredicate>
  366. bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred)
  367. {
  368. return ((container_algorithm_internal::c_size(c1) == container_algorithm_internal::c_size(c2)) && std::equal(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), std::forward<BinaryPredicate>(pred)));
  369. }
  370. // c_is_permutation()
  371. //
  372. // Container-based version of the <algorithm> `std::is_permutation()` function
  373. // to test whether a container is a permutation of another.
  374. template<typename C1, typename C2>
  375. bool c_is_permutation(const C1& c1, const C2& c2)
  376. {
  377. using std::begin;
  378. using std::end;
  379. return c1.size() == c2.size() &&
  380. std::is_permutation(begin(c1), end(c1), begin(c2));
  381. }
  382. // Overload of c_is_permutation() for using a predicate evaluation other than
  383. // `==` as the function's test condition.
  384. template<typename C1, typename C2, typename BinaryPredicate>
  385. bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred)
  386. {
  387. using std::begin;
  388. using std::end;
  389. return c1.size() == c2.size() &&
  390. std::is_permutation(begin(c1), end(c1), begin(c2), std::forward<BinaryPredicate>(pred));
  391. }
  392. // c_search()
  393. //
  394. // Container-based version of the <algorithm> `std::search()` function to search
  395. // a container for a subsequence.
  396. template<typename Sequence1, typename Sequence2>
  397. container_algorithm_internal::ContainerIter<Sequence1> c_search(
  398. Sequence1& sequence, Sequence2& subsequence
  399. )
  400. {
  401. return std::search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence));
  402. }
  403. // Overload of c_search() for using a predicate evaluation other than
  404. // `==` as the function's test condition.
  405. template<typename Sequence1, typename Sequence2, typename BinaryPredicate>
  406. container_algorithm_internal::ContainerIter<Sequence1> c_search(
  407. Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred
  408. )
  409. {
  410. return std::search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(subsequence), container_algorithm_internal::c_end(subsequence), std::forward<BinaryPredicate>(pred));
  411. }
  412. // c_search_n()
  413. //
  414. // Container-based version of the <algorithm> `std::search_n()` function to
  415. // search a container for the first sequence of N elements.
  416. template<typename Sequence, typename Size, typename T>
  417. container_algorithm_internal::ContainerIter<Sequence> c_search_n(
  418. Sequence& sequence, Size count, T&& value
  419. )
  420. {
  421. return std::search_n(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), count, std::forward<T>(value));
  422. }
  423. // Overload of c_search_n() for using a predicate evaluation other than
  424. // `==` as the function's test condition.
  425. template<typename Sequence, typename Size, typename T, typename BinaryPredicate>
  426. container_algorithm_internal::ContainerIter<Sequence> c_search_n(
  427. Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred
  428. )
  429. {
  430. return std::search_n(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), count, std::forward<T>(value), std::forward<BinaryPredicate>(pred));
  431. }
  432. //------------------------------------------------------------------------------
  433. // <algorithm> Modifying sequence operations
  434. //------------------------------------------------------------------------------
  435. // c_copy()
  436. //
  437. // Container-based version of the <algorithm> `std::copy()` function to copy a
  438. // container's elements into an iterator.
  439. template<typename InputSequence, typename OutputIterator>
  440. OutputIterator c_copy(const InputSequence& input, OutputIterator output)
  441. {
  442. return std::copy(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output);
  443. }
  444. // c_copy_n()
  445. //
  446. // Container-based version of the <algorithm> `std::copy_n()` function to copy a
  447. // container's first N elements into an iterator.
  448. template<typename C, typename Size, typename OutputIterator>
  449. OutputIterator c_copy_n(const C& input, Size n, OutputIterator output)
  450. {
  451. return std::copy_n(container_algorithm_internal::c_begin(input), n, output);
  452. }
  453. // c_copy_if()
  454. //
  455. // Container-based version of the <algorithm> `std::copy_if()` function to copy
  456. // a container's elements satisfying some condition into an iterator.
  457. template<typename InputSequence, typename OutputIterator, typename Pred>
  458. OutputIterator c_copy_if(const InputSequence& input, OutputIterator output, Pred&& pred)
  459. {
  460. return std::copy_if(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output, std::forward<Pred>(pred));
  461. }
  462. // c_copy_backward()
  463. //
  464. // Container-based version of the <algorithm> `std::copy_backward()` function to
  465. // copy a container's elements in reverse order into an iterator.
  466. template<typename C, typename BidirectionalIterator>
  467. BidirectionalIterator c_copy_backward(const C& src, BidirectionalIterator dest)
  468. {
  469. return std::copy_backward(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
  470. }
  471. // c_move()
  472. //
  473. // Container-based version of the <algorithm> `std::move()` function to move
  474. // a container's elements into an iterator.
  475. template<typename C, typename OutputIterator>
  476. OutputIterator c_move(C&& src, OutputIterator dest)
  477. {
  478. return std::move(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
  479. }
  480. // c_move_backward()
  481. //
  482. // Container-based version of the <algorithm> `std::move_backward()` function to
  483. // move a container's elements into an iterator in reverse order.
  484. template<typename C, typename BidirectionalIterator>
  485. BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest)
  486. {
  487. return std::move_backward(container_algorithm_internal::c_begin(src), container_algorithm_internal::c_end(src), dest);
  488. }
  489. // c_swap_ranges()
  490. //
  491. // Container-based version of the <algorithm> `std::swap_ranges()` function to
  492. // swap a container's elements with another container's elements. Swaps the
  493. // first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)).
  494. template<typename C1, typename C2>
  495. container_algorithm_internal::ContainerIter<C2> c_swap_ranges(C1& c1, C2& c2)
  496. {
  497. auto first1 = container_algorithm_internal::c_begin(c1);
  498. auto last1 = container_algorithm_internal::c_end(c1);
  499. auto first2 = container_algorithm_internal::c_begin(c2);
  500. auto last2 = container_algorithm_internal::c_end(c2);
  501. using std::swap;
  502. for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
  503. {
  504. swap(*first1, *first2);
  505. }
  506. return first2;
  507. }
  508. // c_transform()
  509. //
  510. // Container-based version of the <algorithm> `std::transform()` function to
  511. // transform a container's elements using the unary operation, storing the
  512. // result in an iterator pointing to the last transformed element in the output
  513. // range.
  514. template<typename InputSequence, typename OutputIterator, typename UnaryOp>
  515. OutputIterator c_transform(const InputSequence& input, OutputIterator output, UnaryOp&& unary_op)
  516. {
  517. return std::transform(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output, std::forward<UnaryOp>(unary_op));
  518. }
  519. // Overload of c_transform() for performing a transformation using a binary
  520. // predicate. Applies `binary_op` to the first N elements of `c1` and `c2`,
  521. // where N = min(size(c1), size(c2)).
  522. template<typename InputSequence1, typename InputSequence2, typename OutputIterator, typename BinaryOp>
  523. OutputIterator c_transform(const InputSequence1& input1, const InputSequence2& input2, OutputIterator output, BinaryOp&& binary_op)
  524. {
  525. auto first1 = container_algorithm_internal::c_begin(input1);
  526. auto last1 = container_algorithm_internal::c_end(input1);
  527. auto first2 = container_algorithm_internal::c_begin(input2);
  528. auto last2 = container_algorithm_internal::c_end(input2);
  529. for (; first1 != last1 && first2 != last2;
  530. ++first1, (void)++first2, ++output)
  531. {
  532. *output = binary_op(*first1, *first2);
  533. }
  534. return output;
  535. }
  536. // c_replace()
  537. //
  538. // Container-based version of the <algorithm> `std::replace()` function to
  539. // replace a container's elements of some value with a new value. The container
  540. // is modified in place.
  541. template<typename Sequence, typename T>
  542. void c_replace(Sequence& sequence, const T& old_value, const T& new_value)
  543. {
  544. std::replace(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), old_value, new_value);
  545. }
  546. // c_replace_if()
  547. //
  548. // Container-based version of the <algorithm> `std::replace_if()` function to
  549. // replace a container's elements of some value with a new value based on some
  550. // condition. The container is modified in place.
  551. template<typename C, typename Pred, typename T>
  552. void c_replace_if(C& c, Pred&& pred, T&& new_value)
  553. {
  554. std::replace_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred), std::forward<T>(new_value));
  555. }
  556. // c_replace_copy()
  557. //
  558. // Container-based version of the <algorithm> `std::replace_copy()` function to
  559. // replace a container's elements of some value with a new value and return the
  560. // results within an iterator.
  561. template<typename C, typename OutputIterator, typename T>
  562. OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value, T&& new_value)
  563. {
  564. return std::replace_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward<T>(old_value), std::forward<T>(new_value));
  565. }
  566. // c_replace_copy_if()
  567. //
  568. // Container-based version of the <algorithm> `std::replace_copy_if()` function
  569. // to replace a container's elements of some value with a new value based on
  570. // some condition, and return the results within an iterator.
  571. template<typename C, typename OutputIterator, typename Pred, typename T>
  572. OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred, T&& new_value)
  573. {
  574. return std::replace_copy_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward<Pred>(pred), std::forward<T>(new_value));
  575. }
  576. // c_fill()
  577. //
  578. // Container-based version of the <algorithm> `std::fill()` function to fill a
  579. // container with some value.
  580. template<typename C, typename T>
  581. void c_fill(C& c, T&& value)
  582. {
  583. std::fill(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<T>(value));
  584. }
  585. // c_fill_n()
  586. //
  587. // Container-based version of the <algorithm> `std::fill_n()` function to fill
  588. // the first N elements in a container with some value.
  589. template<typename C, typename Size, typename T>
  590. void c_fill_n(C& c, Size n, T&& value)
  591. {
  592. std::fill_n(container_algorithm_internal::c_begin(c), n, std::forward<T>(value));
  593. }
  594. // c_generate()
  595. //
  596. // Container-based version of the <algorithm> `std::generate()` function to
  597. // assign a container's elements to the values provided by the given generator.
  598. template<typename C, typename Generator>
  599. void c_generate(C& c, Generator&& gen)
  600. {
  601. std::generate(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Generator>(gen));
  602. }
  603. // c_generate_n()
  604. //
  605. // Container-based version of the <algorithm> `std::generate_n()` function to
  606. // assign a container's first N elements to the values provided by the given
  607. // generator.
  608. template<typename C, typename Size, typename Generator>
  609. container_algorithm_internal::ContainerIter<C> c_generate_n(C& c, Size n, Generator&& gen)
  610. {
  611. return std::generate_n(container_algorithm_internal::c_begin(c), n, std::forward<Generator>(gen));
  612. }
  613. // Note: `c_xx()` <algorithm> container versions for `remove()`, `remove_if()`,
  614. // and `unique()` are omitted, because it's not clear whether or not such
  615. // functions should call erase on their supplied sequences afterwards. Either
  616. // behavior would be surprising for a different set of users.
  617. // c_remove_copy()
  618. //
  619. // Container-based version of the <algorithm> `std::remove_copy()` function to
  620. // copy a container's elements while removing any elements matching the given
  621. // `value`.
  622. template<typename C, typename OutputIterator, typename T>
  623. OutputIterator c_remove_copy(const C& c, OutputIterator result, T&& value)
  624. {
  625. return std::remove_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward<T>(value));
  626. }
  627. // c_remove_copy_if()
  628. //
  629. // Container-based version of the <algorithm> `std::remove_copy_if()` function
  630. // to copy a container's elements while removing any elements matching the given
  631. // condition.
  632. template<typename C, typename OutputIterator, typename Pred>
  633. OutputIterator c_remove_copy_if(const C& c, OutputIterator result, Pred&& pred)
  634. {
  635. return std::remove_copy_if(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward<Pred>(pred));
  636. }
  637. // c_unique_copy()
  638. //
  639. // Container-based version of the <algorithm> `std::unique_copy()` function to
  640. // copy a container's elements while removing any elements containing duplicate
  641. // values.
  642. template<typename C, typename OutputIterator>
  643. OutputIterator c_unique_copy(const C& c, OutputIterator result)
  644. {
  645. return std::unique_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result);
  646. }
  647. // Overload of c_unique_copy() for using a predicate evaluation other than
  648. // `==` for comparing uniqueness of the element values.
  649. template<typename C, typename OutputIterator, typename BinaryPredicate>
  650. OutputIterator c_unique_copy(const C& c, OutputIterator result, BinaryPredicate&& pred)
  651. {
  652. return std::unique_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), result, std::forward<BinaryPredicate>(pred));
  653. }
  654. // c_reverse()
  655. //
  656. // Container-based version of the <algorithm> `std::reverse()` function to
  657. // reverse a container's elements.
  658. template<typename Sequence>
  659. void c_reverse(Sequence& sequence)
  660. {
  661. std::reverse(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  662. }
  663. // c_reverse_copy()
  664. //
  665. // Container-based version of the <algorithm> `std::reverse()` function to
  666. // reverse a container's elements and write them to an iterator range.
  667. template<typename C, typename OutputIterator>
  668. OutputIterator c_reverse_copy(const C& sequence, OutputIterator result)
  669. {
  670. return std::reverse_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), result);
  671. }
  672. // c_rotate()
  673. //
  674. // Container-based version of the <algorithm> `std::rotate()` function to
  675. // shift a container's elements leftward such that the `middle` element becomes
  676. // the first element in the container.
  677. template<typename C, typename Iterator = container_algorithm_internal::ContainerIter<C>>
  678. Iterator c_rotate(C& sequence, Iterator middle)
  679. {
  680. return absl::rotate(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence));
  681. }
  682. // c_rotate_copy()
  683. //
  684. // Container-based version of the <algorithm> `std::rotate_copy()` function to
  685. // shift a container's elements leftward such that the `middle` element becomes
  686. // the first element in a new iterator range.
  687. template<typename C, typename OutputIterator>
  688. OutputIterator c_rotate_copy(
  689. const C& sequence,
  690. container_algorithm_internal::ContainerIter<const C> middle,
  691. OutputIterator result
  692. )
  693. {
  694. return std::rotate_copy(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence), result);
  695. }
  696. // c_shuffle()
  697. //
  698. // Container-based version of the <algorithm> `std::shuffle()` function to
  699. // randomly shuffle elements within the container using a `gen()` uniform random
  700. // number generator.
  701. template<typename RandomAccessContainer, typename UniformRandomBitGenerator>
  702. void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen)
  703. {
  704. std::shuffle(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<UniformRandomBitGenerator>(gen));
  705. }
  706. //------------------------------------------------------------------------------
  707. // <algorithm> Partition functions
  708. //------------------------------------------------------------------------------
  709. // c_is_partitioned()
  710. //
  711. // Container-based version of the <algorithm> `std::is_partitioned()` function
  712. // to test whether all elements in the container for which `pred` returns `true`
  713. // precede those for which `pred` is `false`.
  714. template<typename C, typename Pred>
  715. bool c_is_partitioned(const C& c, Pred&& pred)
  716. {
  717. return std::is_partitioned(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  718. }
  719. // c_partition()
  720. //
  721. // Container-based version of the <algorithm> `std::partition()` function
  722. // to rearrange all elements in a container in such a way that all elements for
  723. // which `pred` returns `true` precede all those for which it returns `false`,
  724. // returning an iterator to the first element of the second group.
  725. template<typename C, typename Pred>
  726. container_algorithm_internal::ContainerIter<C> c_partition(C& c, Pred&& pred)
  727. {
  728. return std::partition(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  729. }
  730. // c_stable_partition()
  731. //
  732. // Container-based version of the <algorithm> `std::stable_partition()` function
  733. // to rearrange all elements in a container in such a way that all elements for
  734. // which `pred` returns `true` precede all those for which it returns `false`,
  735. // preserving the relative ordering between the two groups. The function returns
  736. // an iterator to the first element of the second group.
  737. template<typename C, typename Pred>
  738. container_algorithm_internal::ContainerIter<C> c_stable_partition(C& c, Pred&& pred)
  739. {
  740. return std::stable_partition(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  741. }
  742. // c_partition_copy()
  743. //
  744. // Container-based version of the <algorithm> `std::partition_copy()` function
  745. // to partition a container's elements and return them into two iterators: one
  746. // for which `pred` returns `true`, and one for which `pred` returns `false.`
  747. template<typename C, typename OutputIterator1, typename OutputIterator2, typename Pred>
  748. std::pair<OutputIterator1, OutputIterator2> c_partition_copy(
  749. const C& c, OutputIterator1 out_true, OutputIterator2 out_false, Pred&& pred
  750. )
  751. {
  752. return std::partition_copy(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), out_true, out_false, std::forward<Pred>(pred));
  753. }
  754. // c_partition_point()
  755. //
  756. // Container-based version of the <algorithm> `std::partition_point()` function
  757. // to return the first element of an already partitioned container for which
  758. // the given `pred` is not `true`.
  759. template<typename C, typename Pred>
  760. container_algorithm_internal::ContainerIter<C> c_partition_point(C& c, Pred&& pred)
  761. {
  762. return std::partition_point(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<Pred>(pred));
  763. }
  764. //------------------------------------------------------------------------------
  765. // <algorithm> Sorting functions
  766. //------------------------------------------------------------------------------
  767. // c_sort()
  768. //
  769. // Container-based version of the <algorithm> `std::sort()` function
  770. // to sort elements in ascending order of their values.
  771. template<typename C>
  772. void c_sort(C& c)
  773. {
  774. std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  775. }
  776. // Overload of c_sort() for performing a `comp` comparison other than the
  777. // default `operator<`.
  778. template<typename C, typename LessThan>
  779. void c_sort(C& c, LessThan&& comp)
  780. {
  781. std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  782. }
  783. // c_stable_sort()
  784. //
  785. // Container-based version of the <algorithm> `std::stable_sort()` function
  786. // to sort elements in ascending order of their values, preserving the order
  787. // of equivalents.
  788. template<typename C>
  789. void c_stable_sort(C& c)
  790. {
  791. std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  792. }
  793. // Overload of c_stable_sort() for performing a `comp` comparison other than the
  794. // default `operator<`.
  795. template<typename C, typename LessThan>
  796. void c_stable_sort(C& c, LessThan&& comp)
  797. {
  798. std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  799. }
  800. // c_is_sorted()
  801. //
  802. // Container-based version of the <algorithm> `std::is_sorted()` function
  803. // to evaluate whether the given container is sorted in ascending order.
  804. template<typename C>
  805. bool c_is_sorted(const C& c)
  806. {
  807. return std::is_sorted(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  808. }
  809. // c_is_sorted() overload for performing a `comp` comparison other than the
  810. // default `operator<`.
  811. template<typename C, typename LessThan>
  812. bool c_is_sorted(const C& c, LessThan&& comp)
  813. {
  814. return std::is_sorted(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  815. }
  816. // c_partial_sort()
  817. //
  818. // Container-based version of the <algorithm> `std::partial_sort()` function
  819. // to rearrange elements within a container such that elements before `middle`
  820. // are sorted in ascending order.
  821. template<typename RandomAccessContainer>
  822. void c_partial_sort(
  823. RandomAccessContainer& sequence,
  824. container_algorithm_internal::ContainerIter<RandomAccessContainer> middle
  825. )
  826. {
  827. std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence));
  828. }
  829. // Overload of c_partial_sort() for performing a `comp` comparison other than
  830. // the default `operator<`.
  831. template<typename RandomAccessContainer, typename LessThan>
  832. void c_partial_sort(
  833. RandomAccessContainer& sequence,
  834. container_algorithm_internal::ContainerIter<RandomAccessContainer> middle,
  835. LessThan&& comp
  836. )
  837. {
  838. std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  839. }
  840. // c_partial_sort_copy()
  841. //
  842. // Container-based version of the <algorithm> `std::partial_sort_copy()`
  843. // function to sort the elements in the given range `result` within the larger
  844. // `sequence` in ascending order (and using `result` as the output parameter).
  845. // At most min(result.last - result.first, sequence.last - sequence.first)
  846. // elements from the sequence will be stored in the result.
  847. template<typename C, typename RandomAccessContainer>
  848. container_algorithm_internal::ContainerIter<RandomAccessContainer>
  849. c_partial_sort_copy(const C& sequence, RandomAccessContainer& result)
  850. {
  851. return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(result), container_algorithm_internal::c_end(result));
  852. }
  853. // Overload of c_partial_sort_copy() for performing a `comp` comparison other
  854. // than the default `operator<`.
  855. template<typename C, typename RandomAccessContainer, typename LessThan>
  856. container_algorithm_internal::ContainerIter<RandomAccessContainer>
  857. c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, LessThan&& comp)
  858. {
  859. return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), container_algorithm_internal::c_begin(result), container_algorithm_internal::c_end(result), std::forward<LessThan>(comp));
  860. }
  861. // c_is_sorted_until()
  862. //
  863. // Container-based version of the <algorithm> `std::is_sorted_until()` function
  864. // to return the first element within a container that is not sorted in
  865. // ascending order as an iterator.
  866. template<typename C>
  867. container_algorithm_internal::ContainerIter<C> c_is_sorted_until(C& c)
  868. {
  869. return std::is_sorted_until(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  870. }
  871. // Overload of c_is_sorted_until() for performing a `comp` comparison other than
  872. // the default `operator<`.
  873. template<typename C, typename LessThan>
  874. container_algorithm_internal::ContainerIter<C> c_is_sorted_until(
  875. C& c, LessThan&& comp
  876. )
  877. {
  878. return std::is_sorted_until(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  879. }
  880. // c_nth_element()
  881. //
  882. // Container-based version of the <algorithm> `std::nth_element()` function
  883. // to rearrange the elements within a container such that the `nth` element
  884. // would be in that position in an ordered sequence; other elements may be in
  885. // any order, except that all preceding `nth` will be less than that element,
  886. // and all following `nth` will be greater than that element.
  887. template<typename RandomAccessContainer>
  888. void c_nth_element(
  889. RandomAccessContainer& sequence,
  890. container_algorithm_internal::ContainerIter<RandomAccessContainer> nth
  891. )
  892. {
  893. std::nth_element(container_algorithm_internal::c_begin(sequence), nth, container_algorithm_internal::c_end(sequence));
  894. }
  895. // Overload of c_nth_element() for performing a `comp` comparison other than
  896. // the default `operator<`.
  897. template<typename RandomAccessContainer, typename LessThan>
  898. void c_nth_element(
  899. RandomAccessContainer& sequence,
  900. container_algorithm_internal::ContainerIter<RandomAccessContainer> nth,
  901. LessThan&& comp
  902. )
  903. {
  904. std::nth_element(container_algorithm_internal::c_begin(sequence), nth, container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  905. }
  906. //------------------------------------------------------------------------------
  907. // <algorithm> Binary Search
  908. //------------------------------------------------------------------------------
  909. // c_lower_bound()
  910. //
  911. // Container-based version of the <algorithm> `std::lower_bound()` function
  912. // to return an iterator pointing to the first element in a sorted container
  913. // which does not compare less than `value`.
  914. template<typename Sequence, typename T>
  915. container_algorithm_internal::ContainerIter<Sequence> c_lower_bound(
  916. Sequence& sequence, T&& value
  917. )
  918. {
  919. return std::lower_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value));
  920. }
  921. // Overload of c_lower_bound() for performing a `comp` comparison other than
  922. // the default `operator<`.
  923. template<typename Sequence, typename T, typename LessThan>
  924. container_algorithm_internal::ContainerIter<Sequence> c_lower_bound(
  925. Sequence& sequence, T&& value, LessThan&& comp
  926. )
  927. {
  928. return std::lower_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), std::forward<LessThan>(comp));
  929. }
  930. // c_upper_bound()
  931. //
  932. // Container-based version of the <algorithm> `std::upper_bound()` function
  933. // to return an iterator pointing to the first element in a sorted container
  934. // which is greater than `value`.
  935. template<typename Sequence, typename T>
  936. container_algorithm_internal::ContainerIter<Sequence> c_upper_bound(
  937. Sequence& sequence, T&& value
  938. )
  939. {
  940. return std::upper_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value));
  941. }
  942. // Overload of c_upper_bound() for performing a `comp` comparison other than
  943. // the default `operator<`.
  944. template<typename Sequence, typename T, typename LessThan>
  945. container_algorithm_internal::ContainerIter<Sequence> c_upper_bound(
  946. Sequence& sequence, T&& value, LessThan&& comp
  947. )
  948. {
  949. return std::upper_bound(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), std::forward<LessThan>(comp));
  950. }
  951. // c_equal_range()
  952. //
  953. // Container-based version of the <algorithm> `std::equal_range()` function
  954. // to return an iterator pair pointing to the first and last elements in a
  955. // sorted container which compare equal to `value`.
  956. template<typename Sequence, typename T>
  957. container_algorithm_internal::ContainerIterPairType<Sequence, Sequence>
  958. c_equal_range(Sequence& sequence, T&& value)
  959. {
  960. return std::equal_range(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value));
  961. }
  962. // Overload of c_equal_range() for performing a `comp` comparison other than
  963. // the default `operator<`.
  964. template<typename Sequence, typename T, typename LessThan>
  965. container_algorithm_internal::ContainerIterPairType<Sequence, Sequence>
  966. c_equal_range(Sequence& sequence, T&& value, LessThan&& comp)
  967. {
  968. return std::equal_range(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), std::forward<LessThan>(comp));
  969. }
  970. // c_binary_search()
  971. //
  972. // Container-based version of the <algorithm> `std::binary_search()` function
  973. // to test if any element in the sorted container contains a value equivalent to
  974. // 'value'.
  975. template<typename Sequence, typename T>
  976. bool c_binary_search(Sequence&& sequence, T&& value)
  977. {
  978. return std::binary_search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value));
  979. }
  980. // Overload of c_binary_search() for performing a `comp` comparison other than
  981. // the default `operator<`.
  982. template<typename Sequence, typename T, typename LessThan>
  983. bool c_binary_search(Sequence&& sequence, T&& value, LessThan&& comp)
  984. {
  985. return std::binary_search(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value), std::forward<LessThan>(comp));
  986. }
  987. //------------------------------------------------------------------------------
  988. // <algorithm> Merge functions
  989. //------------------------------------------------------------------------------
  990. // c_merge()
  991. //
  992. // Container-based version of the <algorithm> `std::merge()` function
  993. // to merge two sorted containers into a single sorted iterator.
  994. template<typename C1, typename C2, typename OutputIterator>
  995. OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result)
  996. {
  997. return std::merge(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), result);
  998. }
  999. // Overload of c_merge() for performing a `comp` comparison other than
  1000. // the default `operator<`.
  1001. template<typename C1, typename C2, typename OutputIterator, typename LessThan>
  1002. OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, LessThan&& comp)
  1003. {
  1004. return std::merge(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), result, std::forward<LessThan>(comp));
  1005. }
  1006. // c_inplace_merge()
  1007. //
  1008. // Container-based version of the <algorithm> `std::inplace_merge()` function
  1009. // to merge a supplied iterator `middle` into a container.
  1010. template<typename C>
  1011. void c_inplace_merge(C& c, container_algorithm_internal::ContainerIter<C> middle)
  1012. {
  1013. std::inplace_merge(container_algorithm_internal::c_begin(c), middle, container_algorithm_internal::c_end(c));
  1014. }
  1015. // Overload of c_inplace_merge() for performing a merge using a `comp` other
  1016. // than `operator<`.
  1017. template<typename C, typename LessThan>
  1018. void c_inplace_merge(C& c, container_algorithm_internal::ContainerIter<C> middle, LessThan&& comp)
  1019. {
  1020. std::inplace_merge(container_algorithm_internal::c_begin(c), middle, container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  1021. }
  1022. // c_includes()
  1023. //
  1024. // Container-based version of the <algorithm> `std::includes()` function
  1025. // to test whether a sorted container `c1` entirely contains another sorted
  1026. // container `c2`.
  1027. template<typename C1, typename C2>
  1028. bool c_includes(const C1& c1, const C2& c2)
  1029. {
  1030. return std::includes(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2));
  1031. }
  1032. // Overload of c_includes() for performing a merge using a `comp` other than
  1033. // `operator<`.
  1034. template<typename C1, typename C2, typename LessThan>
  1035. bool c_includes(const C1& c1, const C2& c2, LessThan&& comp)
  1036. {
  1037. return std::includes(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), std::forward<LessThan>(comp));
  1038. }
  1039. // c_set_union()
  1040. //
  1041. // Container-based version of the <algorithm> `std::set_union()` function
  1042. // to return an iterator containing the union of two containers; duplicate
  1043. // values are not copied into the output.
  1044. template<typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1045. OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output)
  1046. {
  1047. return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output);
  1048. }
  1049. // Overload of c_set_union() for performing a merge using a `comp` other than
  1050. // `operator<`.
  1051. template<typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1052. OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, LessThan&& comp)
  1053. {
  1054. return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, std::forward<LessThan>(comp));
  1055. }
  1056. // c_set_intersection()
  1057. //
  1058. // Container-based version of the <algorithm> `std::set_intersection()` function
  1059. // to return an iterator containing the intersection of two sorted containers.
  1060. template<typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1061. OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output)
  1062. {
  1063. // In debug builds, ensure that both containers are sorted with respect to the
  1064. // default comparator. std::set_intersection requires the containers be sorted
  1065. // using operator<.
  1066. assert(absl::c_is_sorted(c1));
  1067. assert(absl::c_is_sorted(c2));
  1068. return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output);
  1069. }
  1070. // Overload of c_set_intersection() for performing a merge using a `comp` other
  1071. // than `operator<`.
  1072. template<typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1073. OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output, LessThan&& comp)
  1074. {
  1075. // In debug builds, ensure that both containers are sorted with respect to the
  1076. // default comparator. std::set_intersection requires the containers be sorted
  1077. // using the same comparator.
  1078. assert(absl::c_is_sorted(c1, comp));
  1079. assert(absl::c_is_sorted(c2, comp));
  1080. return std::set_intersection(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, std::forward<LessThan>(comp));
  1081. }
  1082. // c_set_difference()
  1083. //
  1084. // Container-based version of the <algorithm> `std::set_difference()` function
  1085. // to return an iterator containing elements present in the first container but
  1086. // not in the second.
  1087. template<typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1088. OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output)
  1089. {
  1090. return std::set_difference(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output);
  1091. }
  1092. // Overload of c_set_difference() for performing a merge using a `comp` other
  1093. // than `operator<`.
  1094. template<typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1095. OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output, LessThan&& comp)
  1096. {
  1097. return std::set_difference(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), container_algorithm_internal::c_begin(c2), container_algorithm_internal::c_end(c2), output, std::forward<LessThan>(comp));
  1098. }
  1099. // c_set_symmetric_difference()
  1100. //
  1101. // Container-based version of the <algorithm> `std::set_symmetric_difference()`
  1102. // function to return an iterator containing elements present in either one
  1103. // container or the other, but not both.
  1104. template<typename C1, typename C2, typename OutputIterator, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1105. OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output)
  1106. {
  1107. return std::set_symmetric_difference(
  1108. container_algorithm_internal::c_begin(c1),
  1109. container_algorithm_internal::c_end(c1),
  1110. container_algorithm_internal::c_begin(c2),
  1111. container_algorithm_internal::c_end(c2),
  1112. output
  1113. );
  1114. }
  1115. // Overload of c_set_symmetric_difference() for performing a merge using a
  1116. // `comp` other than `operator<`.
  1117. template<typename C1, typename C2, typename OutputIterator, typename LessThan, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C1>::value, void>::type, typename = typename std::enable_if<!container_algorithm_internal::IsUnorderedContainer<C2>::value, void>::type>
  1118. OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output, LessThan&& comp)
  1119. {
  1120. return std::set_symmetric_difference(
  1121. container_algorithm_internal::c_begin(c1),
  1122. container_algorithm_internal::c_end(c1),
  1123. container_algorithm_internal::c_begin(c2),
  1124. container_algorithm_internal::c_end(c2),
  1125. output,
  1126. std::forward<LessThan>(comp)
  1127. );
  1128. }
  1129. //------------------------------------------------------------------------------
  1130. // <algorithm> Heap functions
  1131. //------------------------------------------------------------------------------
  1132. // c_push_heap()
  1133. //
  1134. // Container-based version of the <algorithm> `std::push_heap()` function
  1135. // to push a value onto a container heap.
  1136. template<typename RandomAccessContainer>
  1137. void c_push_heap(RandomAccessContainer& sequence)
  1138. {
  1139. std::push_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1140. }
  1141. // Overload of c_push_heap() for performing a push operation on a heap using a
  1142. // `comp` other than `operator<`.
  1143. template<typename RandomAccessContainer, typename LessThan>
  1144. void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp)
  1145. {
  1146. std::push_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1147. }
  1148. // c_pop_heap()
  1149. //
  1150. // Container-based version of the <algorithm> `std::pop_heap()` function
  1151. // to pop a value from a heap container.
  1152. template<typename RandomAccessContainer>
  1153. void c_pop_heap(RandomAccessContainer& sequence)
  1154. {
  1155. std::pop_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1156. }
  1157. // Overload of c_pop_heap() for performing a pop operation on a heap using a
  1158. // `comp` other than `operator<`.
  1159. template<typename RandomAccessContainer, typename LessThan>
  1160. void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp)
  1161. {
  1162. std::pop_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1163. }
  1164. // c_make_heap()
  1165. //
  1166. // Container-based version of the <algorithm> `std::make_heap()` function
  1167. // to make a container a heap.
  1168. template<typename RandomAccessContainer>
  1169. void c_make_heap(RandomAccessContainer& sequence)
  1170. {
  1171. std::make_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1172. }
  1173. // Overload of c_make_heap() for performing heap comparisons using a
  1174. // `comp` other than `operator<`
  1175. template<typename RandomAccessContainer, typename LessThan>
  1176. void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp)
  1177. {
  1178. std::make_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1179. }
  1180. // c_sort_heap()
  1181. //
  1182. // Container-based version of the <algorithm> `std::sort_heap()` function
  1183. // to sort a heap into ascending order (after which it is no longer a heap).
  1184. template<typename RandomAccessContainer>
  1185. void c_sort_heap(RandomAccessContainer& sequence)
  1186. {
  1187. std::sort_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1188. }
  1189. // Overload of c_sort_heap() for performing heap comparisons using a
  1190. // `comp` other than `operator<`
  1191. template<typename RandomAccessContainer, typename LessThan>
  1192. void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp)
  1193. {
  1194. std::sort_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1195. }
  1196. // c_is_heap()
  1197. //
  1198. // Container-based version of the <algorithm> `std::is_heap()` function
  1199. // to check whether the given container is a heap.
  1200. template<typename RandomAccessContainer>
  1201. bool c_is_heap(const RandomAccessContainer& sequence)
  1202. {
  1203. return std::is_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1204. }
  1205. // Overload of c_is_heap() for performing heap comparisons using a
  1206. // `comp` other than `operator<`
  1207. template<typename RandomAccessContainer, typename LessThan>
  1208. bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp)
  1209. {
  1210. return std::is_heap(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1211. }
  1212. // c_is_heap_until()
  1213. //
  1214. // Container-based version of the <algorithm> `std::is_heap_until()` function
  1215. // to find the first element in a given container which is not in heap order.
  1216. template<typename RandomAccessContainer>
  1217. container_algorithm_internal::ContainerIter<RandomAccessContainer>
  1218. c_is_heap_until(RandomAccessContainer& sequence)
  1219. {
  1220. return std::is_heap_until(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1221. }
  1222. // Overload of c_is_heap_until() for performing heap comparisons using a
  1223. // `comp` other than `operator<`
  1224. template<typename RandomAccessContainer, typename LessThan>
  1225. container_algorithm_internal::ContainerIter<RandomAccessContainer>
  1226. c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp)
  1227. {
  1228. return std::is_heap_until(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1229. }
  1230. //------------------------------------------------------------------------------
  1231. // <algorithm> Min/max
  1232. //------------------------------------------------------------------------------
  1233. // c_min_element()
  1234. //
  1235. // Container-based version of the <algorithm> `std::min_element()` function
  1236. // to return an iterator pointing to the element with the smallest value, using
  1237. // `operator<` to make the comparisons.
  1238. template<typename Sequence>
  1239. container_algorithm_internal::ContainerIter<Sequence> c_min_element(
  1240. Sequence& sequence
  1241. )
  1242. {
  1243. return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1244. }
  1245. // Overload of c_min_element() for performing a `comp` comparison other than
  1246. // `operator<`.
  1247. template<typename Sequence, typename LessThan>
  1248. container_algorithm_internal::ContainerIter<Sequence> c_min_element(
  1249. Sequence& sequence, LessThan&& comp
  1250. )
  1251. {
  1252. return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1253. }
  1254. // c_max_element()
  1255. //
  1256. // Container-based version of the <algorithm> `std::max_element()` function
  1257. // to return an iterator pointing to the element with the largest value, using
  1258. // `operator<` to make the comparisons.
  1259. template<typename Sequence>
  1260. container_algorithm_internal::ContainerIter<Sequence> c_max_element(
  1261. Sequence& sequence
  1262. )
  1263. {
  1264. return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence));
  1265. }
  1266. // Overload of c_max_element() for performing a `comp` comparison other than
  1267. // `operator<`.
  1268. template<typename Sequence, typename LessThan>
  1269. container_algorithm_internal::ContainerIter<Sequence> c_max_element(
  1270. Sequence& sequence, LessThan&& comp
  1271. )
  1272. {
  1273. return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp));
  1274. }
  1275. // c_minmax_element()
  1276. //
  1277. // Container-based version of the <algorithm> `std::minmax_element()` function
  1278. // to return a pair of iterators pointing to the elements containing the
  1279. // smallest and largest values, respectively, using `operator<` to make the
  1280. // comparisons.
  1281. template<typename C>
  1282. container_algorithm_internal::ContainerIterPairType<C, C>
  1283. c_minmax_element(C& c)
  1284. {
  1285. return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  1286. }
  1287. // Overload of c_minmax_element() for performing `comp` comparisons other than
  1288. // `operator<`.
  1289. template<typename C, typename LessThan>
  1290. container_algorithm_internal::ContainerIterPairType<C, C>
  1291. c_minmax_element(C& c, LessThan&& comp)
  1292. {
  1293. return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  1294. }
  1295. //------------------------------------------------------------------------------
  1296. // <algorithm> Lexicographical Comparisons
  1297. //------------------------------------------------------------------------------
  1298. // c_lexicographical_compare()
  1299. //
  1300. // Container-based version of the <algorithm> `std::lexicographical_compare()`
  1301. // function to lexicographically compare (e.g. sort words alphabetically) two
  1302. // container sequences. The comparison is performed using `operator<`. Note
  1303. // that capital letters ("A-Z") have ASCII values less than lowercase letters
  1304. // ("a-z").
  1305. template<typename Sequence1, typename Sequence2>
  1306. bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2)
  1307. {
  1308. return std::lexicographical_compare(
  1309. container_algorithm_internal::c_begin(sequence1),
  1310. container_algorithm_internal::c_end(sequence1),
  1311. container_algorithm_internal::c_begin(sequence2),
  1312. container_algorithm_internal::c_end(sequence2)
  1313. );
  1314. }
  1315. // Overload of c_lexicographical_compare() for performing a lexicographical
  1316. // comparison using a `comp` operator instead of `operator<`.
  1317. template<typename Sequence1, typename Sequence2, typename LessThan>
  1318. bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2, LessThan&& comp)
  1319. {
  1320. return std::lexicographical_compare(
  1321. container_algorithm_internal::c_begin(sequence1),
  1322. container_algorithm_internal::c_end(sequence1),
  1323. container_algorithm_internal::c_begin(sequence2),
  1324. container_algorithm_internal::c_end(sequence2),
  1325. std::forward<LessThan>(comp)
  1326. );
  1327. }
  1328. // c_next_permutation()
  1329. //
  1330. // Container-based version of the <algorithm> `std::next_permutation()` function
  1331. // to rearrange a container's elements into the next lexicographically greater
  1332. // permutation.
  1333. template<typename C>
  1334. bool c_next_permutation(C& c)
  1335. {
  1336. return std::next_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  1337. }
  1338. // Overload of c_next_permutation() for performing a lexicographical
  1339. // comparison using a `comp` operator instead of `operator<`.
  1340. template<typename C, typename LessThan>
  1341. bool c_next_permutation(C& c, LessThan&& comp)
  1342. {
  1343. return std::next_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  1344. }
  1345. // c_prev_permutation()
  1346. //
  1347. // Container-based version of the <algorithm> `std::prev_permutation()` function
  1348. // to rearrange a container's elements into the next lexicographically lesser
  1349. // permutation.
  1350. template<typename C>
  1351. bool c_prev_permutation(C& c)
  1352. {
  1353. return std::prev_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c));
  1354. }
  1355. // Overload of c_prev_permutation() for performing a lexicographical
  1356. // comparison using a `comp` operator instead of `operator<`.
  1357. template<typename C, typename LessThan>
  1358. bool c_prev_permutation(C& c, LessThan&& comp)
  1359. {
  1360. return std::prev_permutation(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
  1361. }
  1362. //------------------------------------------------------------------------------
  1363. // <numeric> algorithms
  1364. //------------------------------------------------------------------------------
  1365. // c_iota()
  1366. //
  1367. // Container-based version of the <algorithm> `std::iota()` function
  1368. // to compute successive values of `value`, as if incremented with `++value`
  1369. // after each element is written. and write them to the container.
  1370. template<typename Sequence, typename T>
  1371. void c_iota(Sequence& sequence, T&& value)
  1372. {
  1373. std::iota(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(value));
  1374. }
  1375. // c_accumulate()
  1376. //
  1377. // Container-based version of the <algorithm> `std::accumulate()` function
  1378. // to accumulate the element values of a container to `init` and return that
  1379. // accumulation by value.
  1380. //
  1381. // Note: Due to a language technicality this function has return type
  1382. // absl::decay_t<T>. As a user of this function you can casually read
  1383. // this as "returns T by value" and assume it does the right thing.
  1384. template<typename Sequence, typename T>
  1385. decay_t<T> c_accumulate(const Sequence& sequence, T&& init)
  1386. {
  1387. return std::accumulate(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(init));
  1388. }
  1389. // Overload of c_accumulate() for using a binary operations other than
  1390. // addition for computing the accumulation.
  1391. template<typename Sequence, typename T, typename BinaryOp>
  1392. decay_t<T> c_accumulate(const Sequence& sequence, T&& init, BinaryOp&& binary_op)
  1393. {
  1394. return std::accumulate(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<T>(init), std::forward<BinaryOp>(binary_op));
  1395. }
  1396. // c_inner_product()
  1397. //
  1398. // Container-based version of the <algorithm> `std::inner_product()` function
  1399. // to compute the cumulative inner product of container element pairs.
  1400. //
  1401. // Note: Due to a language technicality this function has return type
  1402. // absl::decay_t<T>. As a user of this function you can casually read
  1403. // this as "returns T by value" and assume it does the right thing.
  1404. template<typename Sequence1, typename Sequence2, typename T>
  1405. decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2, T&& sum)
  1406. {
  1407. return std::inner_product(container_algorithm_internal::c_begin(factors1), container_algorithm_internal::c_end(factors1), container_algorithm_internal::c_begin(factors2), std::forward<T>(sum));
  1408. }
  1409. // Overload of c_inner_product() for using binary operations other than
  1410. // `operator+` (for computing the accumulation) and `operator*` (for computing
  1411. // the product between the two container's element pair).
  1412. template<typename Sequence1, typename Sequence2, typename T, typename BinaryOp1, typename BinaryOp2>
  1413. decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2, T&& sum, BinaryOp1&& op1, BinaryOp2&& op2)
  1414. {
  1415. return std::inner_product(container_algorithm_internal::c_begin(factors1), container_algorithm_internal::c_end(factors1), container_algorithm_internal::c_begin(factors2), std::forward<T>(sum), std::forward<BinaryOp1>(op1), std::forward<BinaryOp2>(op2));
  1416. }
  1417. // c_adjacent_difference()
  1418. //
  1419. // Container-based version of the <algorithm> `std::adjacent_difference()`
  1420. // function to compute the difference between each element and the one preceding
  1421. // it and write it to an iterator.
  1422. template<typename InputSequence, typename OutputIt>
  1423. OutputIt c_adjacent_difference(const InputSequence& input, OutputIt output_first)
  1424. {
  1425. return std::adjacent_difference(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output_first);
  1426. }
  1427. // Overload of c_adjacent_difference() for using a binary operation other than
  1428. // subtraction to compute the adjacent difference.
  1429. template<typename InputSequence, typename OutputIt, typename BinaryOp>
  1430. OutputIt c_adjacent_difference(const InputSequence& input, OutputIt output_first, BinaryOp&& op)
  1431. {
  1432. return std::adjacent_difference(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output_first, std::forward<BinaryOp>(op));
  1433. }
  1434. // c_partial_sum()
  1435. //
  1436. // Container-based version of the <algorithm> `std::partial_sum()` function
  1437. // to compute the partial sum of the elements in a sequence and write them
  1438. // to an iterator. The partial sum is the sum of all element values so far in
  1439. // the sequence.
  1440. template<typename InputSequence, typename OutputIt>
  1441. OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first)
  1442. {
  1443. return std::partial_sum(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output_first);
  1444. }
  1445. // Overload of c_partial_sum() for using a binary operation other than addition
  1446. // to compute the "partial sum".
  1447. template<typename InputSequence, typename OutputIt, typename BinaryOp>
  1448. OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, BinaryOp&& op)
  1449. {
  1450. return std::partial_sum(container_algorithm_internal::c_begin(input), container_algorithm_internal::c_end(input), output_first, std::forward<BinaryOp>(op));
  1451. }
  1452. ABSL_NAMESPACE_END
  1453. } // namespace absl
  1454. #endif // ABSL_ALGORITHM_CONTAINER_H_