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