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