container.h 78 KB

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