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