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