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