File indexing completed on 2025-01-18 09:27:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifndef ABSL_ALGORITHM_CONTAINER_H_
0041 #define ABSL_ALGORITHM_CONTAINER_H_
0042
0043 #include <algorithm>
0044 #include <cassert>
0045 #include <iterator>
0046 #include <numeric>
0047 #include <random>
0048 #include <type_traits>
0049 #include <unordered_map>
0050 #include <unordered_set>
0051 #include <utility>
0052 #include <vector>
0053
0054 #include "absl/algorithm/algorithm.h"
0055 #include "absl/base/config.h"
0056 #include "absl/base/macros.h"
0057 #include "absl/base/nullability.h"
0058 #include "absl/meta/type_traits.h"
0059
0060 namespace absl {
0061 ABSL_NAMESPACE_BEGIN
0062 namespace container_algorithm_internal {
0063
0064
0065
0066
0067 using std::begin;
0068 using std::end;
0069
0070
0071
0072
0073 template <typename C>
0074 using ContainerIter = decltype(begin(std::declval<C&>()));
0075
0076
0077
0078 template <typename C1, typename C2>
0079 using ContainerIterPairType =
0080 decltype(std::make_pair(ContainerIter<C1>(), ContainerIter<C2>()));
0081
0082 template <typename C>
0083 using ContainerDifferenceType = decltype(std::distance(
0084 std::declval<ContainerIter<C>>(), std::declval<ContainerIter<C>>()));
0085
0086 template <typename C>
0087 using ContainerPointerType =
0088 typename std::iterator_traits<ContainerIter<C>>::pointer;
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 template <typename C>
0102 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) {
0103 return begin(c);
0104 }
0105
0106 template <typename C>
0107 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) {
0108 return end(c);
0109 }
0110
0111 template <typename T>
0112 struct IsUnorderedContainer : std::false_type {};
0113
0114 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0115 struct IsUnorderedContainer<
0116 std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type {};
0117
0118 template <class Key, class Hash, class KeyEqual, class Allocator>
0119 struct IsUnorderedContainer<std::unordered_set<Key, Hash, KeyEqual, Allocator>>
0120 : std::true_type {};
0121
0122 }
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 template <typename C, typename EqualityComparable>
0135 bool c_linear_search(const C& c, EqualityComparable&& value) {
0136 return linear_search(container_algorithm_internal::c_begin(c),
0137 container_algorithm_internal::c_end(c),
0138 std::forward<EqualityComparable>(value));
0139 }
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 template <typename C>
0150 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
0151 container_algorithm_internal::ContainerDifferenceType<const C>
0152 c_distance(const C& c) {
0153 return std::distance(container_algorithm_internal::c_begin(c),
0154 container_algorithm_internal::c_end(c));
0155 }
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 template <typename C, typename Pred>
0166 bool c_all_of(const C& c, Pred&& pred) {
0167 return std::all_of(container_algorithm_internal::c_begin(c),
0168 container_algorithm_internal::c_end(c),
0169 std::forward<Pred>(pred));
0170 }
0171
0172
0173
0174
0175
0176 template <typename C, typename Pred>
0177 bool c_any_of(const C& c, Pred&& pred) {
0178 return std::any_of(container_algorithm_internal::c_begin(c),
0179 container_algorithm_internal::c_end(c),
0180 std::forward<Pred>(pred));
0181 }
0182
0183
0184
0185
0186
0187 template <typename C, typename Pred>
0188 bool c_none_of(const C& c, Pred&& pred) {
0189 return std::none_of(container_algorithm_internal::c_begin(c),
0190 container_algorithm_internal::c_end(c),
0191 std::forward<Pred>(pred));
0192 }
0193
0194
0195
0196
0197
0198 template <typename C, typename Function>
0199 decay_t<Function> c_for_each(C&& c, Function&& f) {
0200 return std::for_each(container_algorithm_internal::c_begin(c),
0201 container_algorithm_internal::c_end(c),
0202 std::forward<Function>(f));
0203 }
0204
0205
0206
0207
0208
0209 template <typename C, typename T>
0210 container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value) {
0211 return std::find(container_algorithm_internal::c_begin(c),
0212 container_algorithm_internal::c_end(c),
0213 std::forward<T>(value));
0214 }
0215
0216
0217
0218
0219
0220 template <typename Sequence, typename T>
0221 bool c_contains(const Sequence& sequence, T&& value) {
0222 return absl::c_find(sequence, std::forward<T>(value)) !=
0223 container_algorithm_internal::c_end(sequence);
0224 }
0225
0226
0227
0228
0229
0230 template <typename C, typename Pred>
0231 container_algorithm_internal::ContainerIter<C> c_find_if(C& c, Pred&& pred) {
0232 return std::find_if(container_algorithm_internal::c_begin(c),
0233 container_algorithm_internal::c_end(c),
0234 std::forward<Pred>(pred));
0235 }
0236
0237
0238
0239
0240
0241 template <typename C, typename Pred>
0242 container_algorithm_internal::ContainerIter<C> c_find_if_not(C& c,
0243 Pred&& pred) {
0244 return std::find_if_not(container_algorithm_internal::c_begin(c),
0245 container_algorithm_internal::c_end(c),
0246 std::forward<Pred>(pred));
0247 }
0248
0249
0250
0251
0252
0253 template <typename Sequence1, typename Sequence2>
0254 container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
0255 Sequence1& sequence, Sequence2& subsequence) {
0256 return std::find_end(container_algorithm_internal::c_begin(sequence),
0257 container_algorithm_internal::c_end(sequence),
0258 container_algorithm_internal::c_begin(subsequence),
0259 container_algorithm_internal::c_end(subsequence));
0260 }
0261
0262
0263
0264 template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
0265 container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
0266 Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) {
0267 return std::find_end(container_algorithm_internal::c_begin(sequence),
0268 container_algorithm_internal::c_end(sequence),
0269 container_algorithm_internal::c_begin(subsequence),
0270 container_algorithm_internal::c_end(subsequence),
0271 std::forward<BinaryPredicate>(pred));
0272 }
0273
0274
0275
0276
0277
0278
0279 template <typename C1, typename C2>
0280 container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container,
0281 C2& options) {
0282 return std::find_first_of(container_algorithm_internal::c_begin(container),
0283 container_algorithm_internal::c_end(container),
0284 container_algorithm_internal::c_begin(options),
0285 container_algorithm_internal::c_end(options));
0286 }
0287
0288
0289
0290 template <typename C1, typename C2, typename BinaryPredicate>
0291 container_algorithm_internal::ContainerIter<C1> c_find_first_of(
0292 C1& container, C2& options, BinaryPredicate&& pred) {
0293 return std::find_first_of(container_algorithm_internal::c_begin(container),
0294 container_algorithm_internal::c_end(container),
0295 container_algorithm_internal::c_begin(options),
0296 container_algorithm_internal::c_end(options),
0297 std::forward<BinaryPredicate>(pred));
0298 }
0299
0300
0301
0302
0303
0304 template <typename Sequence>
0305 container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
0306 Sequence& sequence) {
0307 return std::adjacent_find(container_algorithm_internal::c_begin(sequence),
0308 container_algorithm_internal::c_end(sequence));
0309 }
0310
0311
0312
0313 template <typename Sequence, typename BinaryPredicate>
0314 container_algorithm_internal::ContainerIter<Sequence> c_adjacent_find(
0315 Sequence& sequence, BinaryPredicate&& pred) {
0316 return std::adjacent_find(container_algorithm_internal::c_begin(sequence),
0317 container_algorithm_internal::c_end(sequence),
0318 std::forward<BinaryPredicate>(pred));
0319 }
0320
0321
0322
0323
0324
0325 template <typename C, typename T>
0326 container_algorithm_internal::ContainerDifferenceType<const C> c_count(
0327 const C& c, T&& value) {
0328 return std::count(container_algorithm_internal::c_begin(c),
0329 container_algorithm_internal::c_end(c),
0330 std::forward<T>(value));
0331 }
0332
0333
0334
0335
0336
0337 template <typename C, typename Pred>
0338 container_algorithm_internal::ContainerDifferenceType<const C> c_count_if(
0339 const C& c, Pred&& pred) {
0340 return std::count_if(container_algorithm_internal::c_begin(c),
0341 container_algorithm_internal::c_end(c),
0342 std::forward<Pred>(pred));
0343 }
0344
0345
0346
0347
0348
0349
0350 template <typename C1, typename C2>
0351 container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1,
0352 C2& c2) {
0353 return std::mismatch(container_algorithm_internal::c_begin(c1),
0354 container_algorithm_internal::c_end(c1),
0355 container_algorithm_internal::c_begin(c2),
0356 container_algorithm_internal::c_end(c2));
0357 }
0358
0359
0360
0361
0362 template <typename C1, typename C2, typename BinaryPredicate>
0363 container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(
0364 C1& c1, C2& c2, BinaryPredicate pred) {
0365 return std::mismatch(container_algorithm_internal::c_begin(c1),
0366 container_algorithm_internal::c_end(c1),
0367 container_algorithm_internal::c_begin(c2),
0368 container_algorithm_internal::c_end(c2), pred);
0369 }
0370
0371
0372
0373
0374
0375 template <typename C1, typename C2>
0376 bool c_equal(const C1& c1, const C2& c2) {
0377 return std::equal(container_algorithm_internal::c_begin(c1),
0378 container_algorithm_internal::c_end(c1),
0379 container_algorithm_internal::c_begin(c2),
0380 container_algorithm_internal::c_end(c2));
0381 }
0382
0383
0384
0385 template <typename C1, typename C2, typename BinaryPredicate>
0386 bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
0387 return std::equal(container_algorithm_internal::c_begin(c1),
0388 container_algorithm_internal::c_end(c1),
0389 container_algorithm_internal::c_begin(c2),
0390 container_algorithm_internal::c_end(c2),
0391 std::forward<BinaryPredicate>(pred));
0392 }
0393
0394
0395
0396
0397
0398 template <typename C1, typename C2>
0399 bool c_is_permutation(const C1& c1, const C2& c2) {
0400 return std::is_permutation(container_algorithm_internal::c_begin(c1),
0401 container_algorithm_internal::c_end(c1),
0402 container_algorithm_internal::c_begin(c2),
0403 container_algorithm_internal::c_end(c2));
0404 }
0405
0406
0407
0408 template <typename C1, typename C2, typename BinaryPredicate>
0409 bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) {
0410 return std::is_permutation(container_algorithm_internal::c_begin(c1),
0411 container_algorithm_internal::c_end(c1),
0412 container_algorithm_internal::c_begin(c2),
0413 container_algorithm_internal::c_end(c2),
0414 std::forward<BinaryPredicate>(pred));
0415 }
0416
0417
0418
0419
0420
0421 template <typename Sequence1, typename Sequence2>
0422 container_algorithm_internal::ContainerIter<Sequence1> c_search(
0423 Sequence1& sequence, Sequence2& subsequence) {
0424 return std::search(container_algorithm_internal::c_begin(sequence),
0425 container_algorithm_internal::c_end(sequence),
0426 container_algorithm_internal::c_begin(subsequence),
0427 container_algorithm_internal::c_end(subsequence));
0428 }
0429
0430
0431
0432 template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
0433 container_algorithm_internal::ContainerIter<Sequence1> c_search(
0434 Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) {
0435 return std::search(container_algorithm_internal::c_begin(sequence),
0436 container_algorithm_internal::c_end(sequence),
0437 container_algorithm_internal::c_begin(subsequence),
0438 container_algorithm_internal::c_end(subsequence),
0439 std::forward<BinaryPredicate>(pred));
0440 }
0441
0442
0443
0444
0445
0446 template <typename Sequence1, typename Sequence2>
0447 bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence) {
0448 return absl::c_search(sequence, subsequence) !=
0449 container_algorithm_internal::c_end(sequence);
0450 }
0451
0452
0453
0454 template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
0455 bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence,
0456 BinaryPredicate&& pred) {
0457 return absl::c_search(sequence, subsequence,
0458 std::forward<BinaryPredicate>(pred)) !=
0459 container_algorithm_internal::c_end(sequence);
0460 }
0461
0462
0463
0464
0465
0466 template <typename Sequence, typename Size, typename T>
0467 container_algorithm_internal::ContainerIter<Sequence> c_search_n(
0468 Sequence& sequence, Size count, T&& value) {
0469 return std::search_n(container_algorithm_internal::c_begin(sequence),
0470 container_algorithm_internal::c_end(sequence), count,
0471 std::forward<T>(value));
0472 }
0473
0474
0475
0476 template <typename Sequence, typename Size, typename T,
0477 typename BinaryPredicate>
0478 container_algorithm_internal::ContainerIter<Sequence> c_search_n(
0479 Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred) {
0480 return std::search_n(container_algorithm_internal::c_begin(sequence),
0481 container_algorithm_internal::c_end(sequence), count,
0482 std::forward<T>(value),
0483 std::forward<BinaryPredicate>(pred));
0484 }
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 template <typename InputSequence, typename OutputIterator>
0495 OutputIterator c_copy(const InputSequence& input, OutputIterator output) {
0496 return std::copy(container_algorithm_internal::c_begin(input),
0497 container_algorithm_internal::c_end(input), output);
0498 }
0499
0500
0501
0502
0503
0504 template <typename C, typename Size, typename OutputIterator>
0505 OutputIterator c_copy_n(const C& input, Size n, OutputIterator output) {
0506 return std::copy_n(container_algorithm_internal::c_begin(input), n, output);
0507 }
0508
0509
0510
0511
0512
0513 template <typename InputSequence, typename OutputIterator, typename Pred>
0514 OutputIterator c_copy_if(const InputSequence& input, OutputIterator output,
0515 Pred&& pred) {
0516 return std::copy_if(container_algorithm_internal::c_begin(input),
0517 container_algorithm_internal::c_end(input), output,
0518 std::forward<Pred>(pred));
0519 }
0520
0521
0522
0523
0524
0525 template <typename C, typename BidirectionalIterator>
0526 BidirectionalIterator c_copy_backward(const C& src,
0527 BidirectionalIterator dest) {
0528 return std::copy_backward(container_algorithm_internal::c_begin(src),
0529 container_algorithm_internal::c_end(src), dest);
0530 }
0531
0532
0533
0534
0535
0536 template <typename C, typename OutputIterator>
0537 OutputIterator c_move(C&& src, OutputIterator dest) {
0538 return std::move(container_algorithm_internal::c_begin(src),
0539 container_algorithm_internal::c_end(src), dest);
0540 }
0541
0542
0543
0544
0545
0546 template <typename C, typename BidirectionalIterator>
0547 BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest) {
0548 return std::move_backward(container_algorithm_internal::c_begin(src),
0549 container_algorithm_internal::c_end(src), dest);
0550 }
0551
0552
0553
0554
0555
0556
0557 template <typename C1, typename C2>
0558 container_algorithm_internal::ContainerIter<C2> c_swap_ranges(C1& c1, C2& c2) {
0559 auto first1 = container_algorithm_internal::c_begin(c1);
0560 auto last1 = container_algorithm_internal::c_end(c1);
0561 auto first2 = container_algorithm_internal::c_begin(c2);
0562 auto last2 = container_algorithm_internal::c_end(c2);
0563
0564 using std::swap;
0565 for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) {
0566 swap(*first1, *first2);
0567 }
0568 return first2;
0569 }
0570
0571
0572
0573
0574
0575
0576
0577 template <typename InputSequence, typename OutputIterator, typename UnaryOp>
0578 OutputIterator c_transform(const InputSequence& input, OutputIterator output,
0579 UnaryOp&& unary_op) {
0580 return std::transform(container_algorithm_internal::c_begin(input),
0581 container_algorithm_internal::c_end(input), output,
0582 std::forward<UnaryOp>(unary_op));
0583 }
0584
0585
0586
0587
0588 template <typename InputSequence1, typename InputSequence2,
0589 typename OutputIterator, typename BinaryOp>
0590 OutputIterator c_transform(const InputSequence1& input1,
0591 const InputSequence2& input2, OutputIterator output,
0592 BinaryOp&& binary_op) {
0593 auto first1 = container_algorithm_internal::c_begin(input1);
0594 auto last1 = container_algorithm_internal::c_end(input1);
0595 auto first2 = container_algorithm_internal::c_begin(input2);
0596 auto last2 = container_algorithm_internal::c_end(input2);
0597 for (; first1 != last1 && first2 != last2;
0598 ++first1, (void)++first2, ++output) {
0599 *output = binary_op(*first1, *first2);
0600 }
0601
0602 return output;
0603 }
0604
0605
0606
0607
0608
0609
0610 template <typename Sequence, typename T>
0611 void c_replace(Sequence& sequence, const T& old_value, const T& new_value) {
0612 std::replace(container_algorithm_internal::c_begin(sequence),
0613 container_algorithm_internal::c_end(sequence), old_value,
0614 new_value);
0615 }
0616
0617
0618
0619
0620
0621
0622 template <typename C, typename Pred, typename T>
0623 void c_replace_if(C& c, Pred&& pred, T&& new_value) {
0624 std::replace_if(container_algorithm_internal::c_begin(c),
0625 container_algorithm_internal::c_end(c),
0626 std::forward<Pred>(pred), std::forward<T>(new_value));
0627 }
0628
0629
0630
0631
0632
0633
0634 template <typename C, typename OutputIterator, typename T>
0635 OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value,
0636 T&& new_value) {
0637 return std::replace_copy(container_algorithm_internal::c_begin(c),
0638 container_algorithm_internal::c_end(c), result,
0639 std::forward<T>(old_value),
0640 std::forward<T>(new_value));
0641 }
0642
0643
0644
0645
0646
0647
0648 template <typename C, typename OutputIterator, typename Pred, typename T>
0649 OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred,
0650 const T& new_value) {
0651 return std::replace_copy_if(container_algorithm_internal::c_begin(c),
0652 container_algorithm_internal::c_end(c), result,
0653 std::forward<Pred>(pred), new_value);
0654 }
0655
0656
0657
0658
0659
0660 template <typename C, typename T>
0661 void c_fill(C& c, const T& value) {
0662 std::fill(container_algorithm_internal::c_begin(c),
0663 container_algorithm_internal::c_end(c), value);
0664 }
0665
0666
0667
0668
0669
0670 template <typename C, typename Size, typename T>
0671 void c_fill_n(C& c, Size n, const T& value) {
0672 std::fill_n(container_algorithm_internal::c_begin(c), n, value);
0673 }
0674
0675
0676
0677
0678
0679 template <typename C, typename Generator>
0680 void c_generate(C& c, Generator&& gen) {
0681 std::generate(container_algorithm_internal::c_begin(c),
0682 container_algorithm_internal::c_end(c),
0683 std::forward<Generator>(gen));
0684 }
0685
0686
0687
0688
0689
0690
0691 template <typename C, typename Size, typename Generator>
0692 container_algorithm_internal::ContainerIter<C> c_generate_n(C& c, Size n,
0693 Generator&& gen) {
0694 return std::generate_n(container_algorithm_internal::c_begin(c), n,
0695 std::forward<Generator>(gen));
0696 }
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708 template <typename C, typename OutputIterator, typename T>
0709 OutputIterator c_remove_copy(const C& c, OutputIterator result,
0710 const T& value) {
0711 return std::remove_copy(container_algorithm_internal::c_begin(c),
0712 container_algorithm_internal::c_end(c), result,
0713 value);
0714 }
0715
0716
0717
0718
0719
0720
0721 template <typename C, typename OutputIterator, typename Pred>
0722 OutputIterator c_remove_copy_if(const C& c, OutputIterator result,
0723 Pred&& pred) {
0724 return std::remove_copy_if(container_algorithm_internal::c_begin(c),
0725 container_algorithm_internal::c_end(c), result,
0726 std::forward<Pred>(pred));
0727 }
0728
0729
0730
0731
0732
0733
0734 template <typename C, typename OutputIterator>
0735 OutputIterator c_unique_copy(const C& c, OutputIterator result) {
0736 return std::unique_copy(container_algorithm_internal::c_begin(c),
0737 container_algorithm_internal::c_end(c), result);
0738 }
0739
0740
0741
0742 template <typename C, typename OutputIterator, typename BinaryPredicate>
0743 OutputIterator c_unique_copy(const C& c, OutputIterator result,
0744 BinaryPredicate&& pred) {
0745 return std::unique_copy(container_algorithm_internal::c_begin(c),
0746 container_algorithm_internal::c_end(c), result,
0747 std::forward<BinaryPredicate>(pred));
0748 }
0749
0750
0751
0752
0753
0754 template <typename Sequence>
0755 void c_reverse(Sequence& sequence) {
0756 std::reverse(container_algorithm_internal::c_begin(sequence),
0757 container_algorithm_internal::c_end(sequence));
0758 }
0759
0760
0761
0762
0763
0764 template <typename C, typename OutputIterator>
0765 OutputIterator c_reverse_copy(const C& sequence, OutputIterator result) {
0766 return std::reverse_copy(container_algorithm_internal::c_begin(sequence),
0767 container_algorithm_internal::c_end(sequence),
0768 result);
0769 }
0770
0771
0772
0773
0774
0775
0776 template <typename C,
0777 typename Iterator = container_algorithm_internal::ContainerIter<C>>
0778 Iterator c_rotate(C& sequence, Iterator middle) {
0779 return absl::rotate(container_algorithm_internal::c_begin(sequence), middle,
0780 container_algorithm_internal::c_end(sequence));
0781 }
0782
0783
0784
0785
0786
0787
0788 template <typename C, typename OutputIterator>
0789 OutputIterator c_rotate_copy(
0790 const C& sequence,
0791 container_algorithm_internal::ContainerIter<const C> middle,
0792 OutputIterator result) {
0793 return std::rotate_copy(container_algorithm_internal::c_begin(sequence),
0794 middle, container_algorithm_internal::c_end(sequence),
0795 result);
0796 }
0797
0798
0799
0800
0801
0802
0803 template <typename RandomAccessContainer, typename UniformRandomBitGenerator>
0804 void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen) {
0805 std::shuffle(container_algorithm_internal::c_begin(c),
0806 container_algorithm_internal::c_end(c),
0807 std::forward<UniformRandomBitGenerator>(gen));
0808 }
0809
0810
0811
0812
0813
0814
0815 template <typename C, typename OutputIterator, typename Distance,
0816 typename UniformRandomBitGenerator>
0817 OutputIterator c_sample(const C& c, OutputIterator result, Distance n,
0818 UniformRandomBitGenerator&& gen) {
0819 #if defined(__cpp_lib_sample) && __cpp_lib_sample >= 201603L
0820 return std::sample(container_algorithm_internal::c_begin(c),
0821 container_algorithm_internal::c_end(c), result, n,
0822 std::forward<UniformRandomBitGenerator>(gen));
0823 #else
0824
0825 auto first = container_algorithm_internal::c_begin(c);
0826 Distance unsampled_elements = c_distance(c);
0827 n = (std::min)(n, unsampled_elements);
0828 for (; n != 0; ++first) {
0829 Distance r =
0830 std::uniform_int_distribution<Distance>(0, --unsampled_elements)(gen);
0831 if (r < n) {
0832 *result++ = *first;
0833 --n;
0834 }
0835 }
0836 return result;
0837 #endif
0838 }
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849 template <typename C, typename Pred>
0850 bool c_is_partitioned(const C& c, Pred&& pred) {
0851 return std::is_partitioned(container_algorithm_internal::c_begin(c),
0852 container_algorithm_internal::c_end(c),
0853 std::forward<Pred>(pred));
0854 }
0855
0856
0857
0858
0859
0860
0861
0862 template <typename C, typename Pred>
0863 container_algorithm_internal::ContainerIter<C> c_partition(C& c, Pred&& pred) {
0864 return std::partition(container_algorithm_internal::c_begin(c),
0865 container_algorithm_internal::c_end(c),
0866 std::forward<Pred>(pred));
0867 }
0868
0869
0870
0871
0872
0873
0874
0875
0876 template <typename C, typename Pred>
0877 container_algorithm_internal::ContainerIter<C> c_stable_partition(C& c,
0878 Pred&& pred) {
0879 return std::stable_partition(container_algorithm_internal::c_begin(c),
0880 container_algorithm_internal::c_end(c),
0881 std::forward<Pred>(pred));
0882 }
0883
0884
0885
0886
0887
0888
0889
0890 template <typename C, typename OutputIterator1, typename OutputIterator2,
0891 typename Pred>
0892 std::pair<OutputIterator1, OutputIterator2> c_partition_copy(
0893 const C& c, OutputIterator1 out_true, OutputIterator2 out_false,
0894 Pred&& pred) {
0895 return std::partition_copy(container_algorithm_internal::c_begin(c),
0896 container_algorithm_internal::c_end(c), out_true,
0897 out_false, std::forward<Pred>(pred));
0898 }
0899
0900
0901
0902
0903
0904
0905 template <typename C, typename Pred>
0906 container_algorithm_internal::ContainerIter<C> c_partition_point(C& c,
0907 Pred&& pred) {
0908 return std::partition_point(container_algorithm_internal::c_begin(c),
0909 container_algorithm_internal::c_end(c),
0910 std::forward<Pred>(pred));
0911 }
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921 template <typename C>
0922 void c_sort(C& c) {
0923 std::sort(container_algorithm_internal::c_begin(c),
0924 container_algorithm_internal::c_end(c));
0925 }
0926
0927
0928
0929 template <typename C, typename LessThan>
0930 void c_sort(C& c, LessThan&& comp) {
0931 std::sort(container_algorithm_internal::c_begin(c),
0932 container_algorithm_internal::c_end(c),
0933 std::forward<LessThan>(comp));
0934 }
0935
0936
0937
0938
0939
0940
0941 template <typename C>
0942 void c_stable_sort(C& c) {
0943 std::stable_sort(container_algorithm_internal::c_begin(c),
0944 container_algorithm_internal::c_end(c));
0945 }
0946
0947
0948
0949 template <typename C, typename LessThan>
0950 void c_stable_sort(C& c, LessThan&& comp) {
0951 std::stable_sort(container_algorithm_internal::c_begin(c),
0952 container_algorithm_internal::c_end(c),
0953 std::forward<LessThan>(comp));
0954 }
0955
0956
0957
0958
0959
0960 template <typename C>
0961 bool c_is_sorted(const C& c) {
0962 return std::is_sorted(container_algorithm_internal::c_begin(c),
0963 container_algorithm_internal::c_end(c));
0964 }
0965
0966
0967
0968 template <typename C, typename LessThan>
0969 bool c_is_sorted(const C& c, LessThan&& comp) {
0970 return std::is_sorted(container_algorithm_internal::c_begin(c),
0971 container_algorithm_internal::c_end(c),
0972 std::forward<LessThan>(comp));
0973 }
0974
0975
0976
0977
0978
0979
0980 template <typename RandomAccessContainer>
0981 void c_partial_sort(
0982 RandomAccessContainer& sequence,
0983 container_algorithm_internal::ContainerIter<RandomAccessContainer> middle) {
0984 std::partial_sort(container_algorithm_internal::c_begin(sequence), middle,
0985 container_algorithm_internal::c_end(sequence));
0986 }
0987
0988
0989
0990 template <typename RandomAccessContainer, typename LessThan>
0991 void c_partial_sort(
0992 RandomAccessContainer& sequence,
0993 container_algorithm_internal::ContainerIter<RandomAccessContainer> middle,
0994 LessThan&& comp) {
0995 std::partial_sort(container_algorithm_internal::c_begin(sequence), middle,
0996 container_algorithm_internal::c_end(sequence),
0997 std::forward<LessThan>(comp));
0998 }
0999
1000
1001
1002
1003
1004
1005
1006
1007 template <typename C, typename RandomAccessContainer>
1008 container_algorithm_internal::ContainerIter<RandomAccessContainer>
1009 c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) {
1010 return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence),
1011 container_algorithm_internal::c_end(sequence),
1012 container_algorithm_internal::c_begin(result),
1013 container_algorithm_internal::c_end(result));
1014 }
1015
1016
1017
1018 template <typename C, typename RandomAccessContainer, typename LessThan>
1019 container_algorithm_internal::ContainerIter<RandomAccessContainer>
1020 c_partial_sort_copy(const C& sequence, RandomAccessContainer& result,
1021 LessThan&& comp) {
1022 return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence),
1023 container_algorithm_internal::c_end(sequence),
1024 container_algorithm_internal::c_begin(result),
1025 container_algorithm_internal::c_end(result),
1026 std::forward<LessThan>(comp));
1027 }
1028
1029
1030
1031
1032
1033
1034 template <typename C>
1035 container_algorithm_internal::ContainerIter<C> c_is_sorted_until(C& c) {
1036 return std::is_sorted_until(container_algorithm_internal::c_begin(c),
1037 container_algorithm_internal::c_end(c));
1038 }
1039
1040
1041
1042 template <typename C, typename LessThan>
1043 container_algorithm_internal::ContainerIter<C> c_is_sorted_until(
1044 C& c, LessThan&& comp) {
1045 return std::is_sorted_until(container_algorithm_internal::c_begin(c),
1046 container_algorithm_internal::c_end(c),
1047 std::forward<LessThan>(comp));
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057 template <typename RandomAccessContainer>
1058 void c_nth_element(
1059 RandomAccessContainer& sequence,
1060 container_algorithm_internal::ContainerIter<RandomAccessContainer> nth) {
1061 std::nth_element(container_algorithm_internal::c_begin(sequence), nth,
1062 container_algorithm_internal::c_end(sequence));
1063 }
1064
1065
1066
1067 template <typename RandomAccessContainer, typename LessThan>
1068 void c_nth_element(
1069 RandomAccessContainer& sequence,
1070 container_algorithm_internal::ContainerIter<RandomAccessContainer> nth,
1071 LessThan&& comp) {
1072 std::nth_element(container_algorithm_internal::c_begin(sequence), nth,
1073 container_algorithm_internal::c_end(sequence),
1074 std::forward<LessThan>(comp));
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 template <typename Sequence, typename T>
1087 container_algorithm_internal::ContainerIter<Sequence> c_lower_bound(
1088 Sequence& sequence, const T& value) {
1089 return std::lower_bound(container_algorithm_internal::c_begin(sequence),
1090 container_algorithm_internal::c_end(sequence), value);
1091 }
1092
1093
1094
1095 template <typename Sequence, typename T, typename LessThan>
1096 container_algorithm_internal::ContainerIter<Sequence> c_lower_bound(
1097 Sequence& sequence, const T& value, LessThan&& comp) {
1098 return std::lower_bound(container_algorithm_internal::c_begin(sequence),
1099 container_algorithm_internal::c_end(sequence), value,
1100 std::forward<LessThan>(comp));
1101 }
1102
1103
1104
1105
1106
1107
1108 template <typename Sequence, typename T>
1109 container_algorithm_internal::ContainerIter<Sequence> c_upper_bound(
1110 Sequence& sequence, const T& value) {
1111 return std::upper_bound(container_algorithm_internal::c_begin(sequence),
1112 container_algorithm_internal::c_end(sequence), value);
1113 }
1114
1115
1116
1117 template <typename Sequence, typename T, typename LessThan>
1118 container_algorithm_internal::ContainerIter<Sequence> c_upper_bound(
1119 Sequence& sequence, const T& value, LessThan&& comp) {
1120 return std::upper_bound(container_algorithm_internal::c_begin(sequence),
1121 container_algorithm_internal::c_end(sequence), value,
1122 std::forward<LessThan>(comp));
1123 }
1124
1125
1126
1127
1128
1129
1130 template <typename Sequence, typename T>
1131 container_algorithm_internal::ContainerIterPairType<Sequence, Sequence>
1132 c_equal_range(Sequence& sequence, const T& value) {
1133 return std::equal_range(container_algorithm_internal::c_begin(sequence),
1134 container_algorithm_internal::c_end(sequence), value);
1135 }
1136
1137
1138
1139 template <typename Sequence, typename T, typename LessThan>
1140 container_algorithm_internal::ContainerIterPairType<Sequence, Sequence>
1141 c_equal_range(Sequence& sequence, const T& value, LessThan&& comp) {
1142 return std::equal_range(container_algorithm_internal::c_begin(sequence),
1143 container_algorithm_internal::c_end(sequence), value,
1144 std::forward<LessThan>(comp));
1145 }
1146
1147
1148
1149
1150
1151
1152 template <typename Sequence, typename T>
1153 bool c_binary_search(const Sequence& sequence, const T& value) {
1154 return std::binary_search(container_algorithm_internal::c_begin(sequence),
1155 container_algorithm_internal::c_end(sequence),
1156 value);
1157 }
1158
1159
1160
1161 template <typename Sequence, typename T, typename LessThan>
1162 bool c_binary_search(const Sequence& sequence, const T& value,
1163 LessThan&& comp) {
1164 return std::binary_search(container_algorithm_internal::c_begin(sequence),
1165 container_algorithm_internal::c_end(sequence),
1166 value, std::forward<LessThan>(comp));
1167 }
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177 template <typename C1, typename C2, typename OutputIterator>
1178 OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) {
1179 return std::merge(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), result);
1183 }
1184
1185
1186
1187 template <typename C1, typename C2, typename OutputIterator, typename LessThan>
1188 OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result,
1189 LessThan&& comp) {
1190 return std::merge(container_algorithm_internal::c_begin(c1),
1191 container_algorithm_internal::c_end(c1),
1192 container_algorithm_internal::c_begin(c2),
1193 container_algorithm_internal::c_end(c2), result,
1194 std::forward<LessThan>(comp));
1195 }
1196
1197
1198
1199
1200
1201 template <typename C>
1202 void c_inplace_merge(C& c,
1203 container_algorithm_internal::ContainerIter<C> middle) {
1204 std::inplace_merge(container_algorithm_internal::c_begin(c), middle,
1205 container_algorithm_internal::c_end(c));
1206 }
1207
1208
1209
1210 template <typename C, typename LessThan>
1211 void c_inplace_merge(C& c,
1212 container_algorithm_internal::ContainerIter<C> middle,
1213 LessThan&& comp) {
1214 std::inplace_merge(container_algorithm_internal::c_begin(c), middle,
1215 container_algorithm_internal::c_end(c),
1216 std::forward<LessThan>(comp));
1217 }
1218
1219
1220
1221
1222
1223
1224 template <typename C1, typename C2>
1225 bool c_includes(const C1& c1, const C2& c2) {
1226 return std::includes(container_algorithm_internal::c_begin(c1),
1227 container_algorithm_internal::c_end(c1),
1228 container_algorithm_internal::c_begin(c2),
1229 container_algorithm_internal::c_end(c2));
1230 }
1231
1232
1233
1234 template <typename C1, typename C2, typename LessThan>
1235 bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) {
1236 return std::includes(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),
1240 std::forward<LessThan>(comp));
1241 }
1242
1243
1244
1245
1246
1247
1248 template <typename C1, typename C2, typename OutputIterator,
1249 typename = typename std::enable_if<
1250 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1251 void>::type,
1252 typename = typename std::enable_if<
1253 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1254 void>::type>
1255 OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) {
1256 return std::set_union(container_algorithm_internal::c_begin(c1),
1257 container_algorithm_internal::c_end(c1),
1258 container_algorithm_internal::c_begin(c2),
1259 container_algorithm_internal::c_end(c2), output);
1260 }
1261
1262
1263
1264 template <typename C1, typename C2, typename OutputIterator, typename LessThan,
1265 typename = typename std::enable_if<
1266 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1267 void>::type,
1268 typename = typename std::enable_if<
1269 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1270 void>::type>
1271 OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output,
1272 LessThan&& comp) {
1273 return std::set_union(container_algorithm_internal::c_begin(c1),
1274 container_algorithm_internal::c_end(c1),
1275 container_algorithm_internal::c_begin(c2),
1276 container_algorithm_internal::c_end(c2), output,
1277 std::forward<LessThan>(comp));
1278 }
1279
1280
1281
1282
1283
1284 template <typename C1, typename C2, typename OutputIterator,
1285 typename = typename std::enable_if<
1286 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1287 void>::type,
1288 typename = typename std::enable_if<
1289 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1290 void>::type>
1291 OutputIterator c_set_intersection(const C1& c1, const C2& c2,
1292 OutputIterator output) {
1293
1294
1295
1296 assert(absl::c_is_sorted(c1));
1297 assert(absl::c_is_sorted(c2));
1298 return std::set_intersection(container_algorithm_internal::c_begin(c1),
1299 container_algorithm_internal::c_end(c1),
1300 container_algorithm_internal::c_begin(c2),
1301 container_algorithm_internal::c_end(c2), output);
1302 }
1303
1304
1305
1306 template <typename C1, typename C2, typename OutputIterator, typename LessThan,
1307 typename = typename std::enable_if<
1308 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1309 void>::type,
1310 typename = typename std::enable_if<
1311 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1312 void>::type>
1313 OutputIterator c_set_intersection(const C1& c1, const C2& c2,
1314 OutputIterator output, LessThan&& comp) {
1315
1316
1317
1318 assert(absl::c_is_sorted(c1, comp));
1319 assert(absl::c_is_sorted(c2, comp));
1320 return std::set_intersection(container_algorithm_internal::c_begin(c1),
1321 container_algorithm_internal::c_end(c1),
1322 container_algorithm_internal::c_begin(c2),
1323 container_algorithm_internal::c_end(c2), output,
1324 std::forward<LessThan>(comp));
1325 }
1326
1327
1328
1329
1330
1331
1332 template <typename C1, typename C2, typename OutputIterator,
1333 typename = typename std::enable_if<
1334 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1335 void>::type,
1336 typename = typename std::enable_if<
1337 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1338 void>::type>
1339 OutputIterator c_set_difference(const C1& c1, const C2& c2,
1340 OutputIterator output) {
1341 return std::set_difference(container_algorithm_internal::c_begin(c1),
1342 container_algorithm_internal::c_end(c1),
1343 container_algorithm_internal::c_begin(c2),
1344 container_algorithm_internal::c_end(c2), output);
1345 }
1346
1347
1348
1349 template <typename C1, typename C2, typename OutputIterator, typename LessThan,
1350 typename = typename std::enable_if<
1351 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1352 void>::type,
1353 typename = typename std::enable_if<
1354 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1355 void>::type>
1356 OutputIterator c_set_difference(const C1& c1, const C2& c2,
1357 OutputIterator output, LessThan&& comp) {
1358 return std::set_difference(container_algorithm_internal::c_begin(c1),
1359 container_algorithm_internal::c_end(c1),
1360 container_algorithm_internal::c_begin(c2),
1361 container_algorithm_internal::c_end(c2), output,
1362 std::forward<LessThan>(comp));
1363 }
1364
1365
1366
1367
1368
1369
1370 template <typename C1, typename C2, typename OutputIterator,
1371 typename = typename std::enable_if<
1372 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1373 void>::type,
1374 typename = typename std::enable_if<
1375 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1376 void>::type>
1377 OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2,
1378 OutputIterator output) {
1379 return std::set_symmetric_difference(
1380 container_algorithm_internal::c_begin(c1),
1381 container_algorithm_internal::c_end(c1),
1382 container_algorithm_internal::c_begin(c2),
1383 container_algorithm_internal::c_end(c2), output);
1384 }
1385
1386
1387
1388 template <typename C1, typename C2, typename OutputIterator, typename LessThan,
1389 typename = typename std::enable_if<
1390 !container_algorithm_internal::IsUnorderedContainer<C1>::value,
1391 void>::type,
1392 typename = typename std::enable_if<
1393 !container_algorithm_internal::IsUnorderedContainer<C2>::value,
1394 void>::type>
1395 OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2,
1396 OutputIterator output,
1397 LessThan&& comp) {
1398 return std::set_symmetric_difference(
1399 container_algorithm_internal::c_begin(c1),
1400 container_algorithm_internal::c_end(c1),
1401 container_algorithm_internal::c_begin(c2),
1402 container_algorithm_internal::c_end(c2), output,
1403 std::forward<LessThan>(comp));
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 template <typename RandomAccessContainer>
1415 void c_push_heap(RandomAccessContainer& sequence) {
1416 std::push_heap(container_algorithm_internal::c_begin(sequence),
1417 container_algorithm_internal::c_end(sequence));
1418 }
1419
1420
1421
1422 template <typename RandomAccessContainer, typename LessThan>
1423 void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) {
1424 std::push_heap(container_algorithm_internal::c_begin(sequence),
1425 container_algorithm_internal::c_end(sequence),
1426 std::forward<LessThan>(comp));
1427 }
1428
1429
1430
1431
1432
1433 template <typename RandomAccessContainer>
1434 void c_pop_heap(RandomAccessContainer& sequence) {
1435 std::pop_heap(container_algorithm_internal::c_begin(sequence),
1436 container_algorithm_internal::c_end(sequence));
1437 }
1438
1439
1440
1441 template <typename RandomAccessContainer, typename LessThan>
1442 void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) {
1443 std::pop_heap(container_algorithm_internal::c_begin(sequence),
1444 container_algorithm_internal::c_end(sequence),
1445 std::forward<LessThan>(comp));
1446 }
1447
1448
1449
1450
1451
1452 template <typename RandomAccessContainer>
1453 void c_make_heap(RandomAccessContainer& sequence) {
1454 std::make_heap(container_algorithm_internal::c_begin(sequence),
1455 container_algorithm_internal::c_end(sequence));
1456 }
1457
1458
1459
1460 template <typename RandomAccessContainer, typename LessThan>
1461 void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) {
1462 std::make_heap(container_algorithm_internal::c_begin(sequence),
1463 container_algorithm_internal::c_end(sequence),
1464 std::forward<LessThan>(comp));
1465 }
1466
1467
1468
1469
1470
1471 template <typename RandomAccessContainer>
1472 void c_sort_heap(RandomAccessContainer& sequence) {
1473 std::sort_heap(container_algorithm_internal::c_begin(sequence),
1474 container_algorithm_internal::c_end(sequence));
1475 }
1476
1477
1478
1479 template <typename RandomAccessContainer, typename LessThan>
1480 void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) {
1481 std::sort_heap(container_algorithm_internal::c_begin(sequence),
1482 container_algorithm_internal::c_end(sequence),
1483 std::forward<LessThan>(comp));
1484 }
1485
1486
1487
1488
1489
1490 template <typename RandomAccessContainer>
1491 bool c_is_heap(const RandomAccessContainer& sequence) {
1492 return std::is_heap(container_algorithm_internal::c_begin(sequence),
1493 container_algorithm_internal::c_end(sequence));
1494 }
1495
1496
1497
1498 template <typename RandomAccessContainer, typename LessThan>
1499 bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) {
1500 return std::is_heap(container_algorithm_internal::c_begin(sequence),
1501 container_algorithm_internal::c_end(sequence),
1502 std::forward<LessThan>(comp));
1503 }
1504
1505
1506
1507
1508
1509 template <typename RandomAccessContainer>
1510 container_algorithm_internal::ContainerIter<RandomAccessContainer>
1511 c_is_heap_until(RandomAccessContainer& sequence) {
1512 return std::is_heap_until(container_algorithm_internal::c_begin(sequence),
1513 container_algorithm_internal::c_end(sequence));
1514 }
1515
1516
1517
1518 template <typename RandomAccessContainer, typename LessThan>
1519 container_algorithm_internal::ContainerIter<RandomAccessContainer>
1520 c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) {
1521 return std::is_heap_until(container_algorithm_internal::c_begin(sequence),
1522 container_algorithm_internal::c_end(sequence),
1523 std::forward<LessThan>(comp));
1524 }
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535 template <typename Sequence>
1536 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1537 container_algorithm_internal::ContainerIter<Sequence>
1538 c_min_element(Sequence& sequence) {
1539 return std::min_element(container_algorithm_internal::c_begin(sequence),
1540 container_algorithm_internal::c_end(sequence));
1541 }
1542
1543
1544
1545 template <typename Sequence, typename LessThan>
1546 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1547 container_algorithm_internal::ContainerIter<Sequence>
1548 c_min_element(Sequence& sequence, LessThan&& comp) {
1549 return std::min_element(container_algorithm_internal::c_begin(sequence),
1550 container_algorithm_internal::c_end(sequence),
1551 std::forward<LessThan>(comp));
1552 }
1553
1554
1555
1556
1557
1558
1559 template <typename Sequence>
1560 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1561 container_algorithm_internal::ContainerIter<Sequence>
1562 c_max_element(Sequence& sequence) {
1563 return std::max_element(container_algorithm_internal::c_begin(sequence),
1564 container_algorithm_internal::c_end(sequence));
1565 }
1566
1567
1568
1569 template <typename Sequence, typename LessThan>
1570 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1571 container_algorithm_internal::ContainerIter<Sequence>
1572 c_max_element(Sequence& sequence, LessThan&& comp) {
1573 return std::max_element(container_algorithm_internal::c_begin(sequence),
1574 container_algorithm_internal::c_end(sequence),
1575 std::forward<LessThan>(comp));
1576 }
1577
1578
1579
1580
1581
1582
1583
1584 template <typename C>
1585 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1586 container_algorithm_internal::ContainerIterPairType<C, C>
1587 c_minmax_element(C& c) {
1588 return std::minmax_element(container_algorithm_internal::c_begin(c),
1589 container_algorithm_internal::c_end(c));
1590 }
1591
1592
1593
1594 template <typename C, typename LessThan>
1595 ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
1596 container_algorithm_internal::ContainerIterPairType<C, C>
1597 c_minmax_element(C& c, LessThan&& comp) {
1598 return std::minmax_element(container_algorithm_internal::c_begin(c),
1599 container_algorithm_internal::c_end(c),
1600 std::forward<LessThan>(comp));
1601 }
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614 template <typename Sequence1, typename Sequence2>
1615 bool c_lexicographical_compare(const Sequence1& sequence1,
1616 const Sequence2& sequence2) {
1617 return std::lexicographical_compare(
1618 container_algorithm_internal::c_begin(sequence1),
1619 container_algorithm_internal::c_end(sequence1),
1620 container_algorithm_internal::c_begin(sequence2),
1621 container_algorithm_internal::c_end(sequence2));
1622 }
1623
1624
1625
1626 template <typename Sequence1, typename Sequence2, typename LessThan>
1627 bool c_lexicographical_compare(const Sequence1& sequence1,
1628 const Sequence2& sequence2, LessThan&& comp) {
1629 return std::lexicographical_compare(
1630 container_algorithm_internal::c_begin(sequence1),
1631 container_algorithm_internal::c_end(sequence1),
1632 container_algorithm_internal::c_begin(sequence2),
1633 container_algorithm_internal::c_end(sequence2),
1634 std::forward<LessThan>(comp));
1635 }
1636
1637
1638
1639
1640
1641
1642 template <typename C>
1643 bool c_next_permutation(C& c) {
1644 return std::next_permutation(container_algorithm_internal::c_begin(c),
1645 container_algorithm_internal::c_end(c));
1646 }
1647
1648
1649
1650 template <typename C, typename LessThan>
1651 bool c_next_permutation(C& c, LessThan&& comp) {
1652 return std::next_permutation(container_algorithm_internal::c_begin(c),
1653 container_algorithm_internal::c_end(c),
1654 std::forward<LessThan>(comp));
1655 }
1656
1657
1658
1659
1660
1661
1662 template <typename C>
1663 bool c_prev_permutation(C& c) {
1664 return std::prev_permutation(container_algorithm_internal::c_begin(c),
1665 container_algorithm_internal::c_end(c));
1666 }
1667
1668
1669
1670 template <typename C, typename LessThan>
1671 bool c_prev_permutation(C& c, LessThan&& comp) {
1672 return std::prev_permutation(container_algorithm_internal::c_begin(c),
1673 container_algorithm_internal::c_end(c),
1674 std::forward<LessThan>(comp));
1675 }
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686 template <typename Sequence, typename T>
1687 void c_iota(Sequence& sequence, const T& value) {
1688 std::iota(container_algorithm_internal::c_begin(sequence),
1689 container_algorithm_internal::c_end(sequence), value);
1690 }
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701 template <typename Sequence, typename T>
1702 decay_t<T> c_accumulate(const Sequence& sequence, T&& init) {
1703 return std::accumulate(container_algorithm_internal::c_begin(sequence),
1704 container_algorithm_internal::c_end(sequence),
1705 std::forward<T>(init));
1706 }
1707
1708
1709
1710 template <typename Sequence, typename T, typename BinaryOp>
1711 decay_t<T> c_accumulate(const Sequence& sequence, T&& init,
1712 BinaryOp&& binary_op) {
1713 return std::accumulate(container_algorithm_internal::c_begin(sequence),
1714 container_algorithm_internal::c_end(sequence),
1715 std::forward<T>(init),
1716 std::forward<BinaryOp>(binary_op));
1717 }
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727 template <typename Sequence1, typename Sequence2, typename T>
1728 decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2,
1729 T&& sum) {
1730 return std::inner_product(container_algorithm_internal::c_begin(factors1),
1731 container_algorithm_internal::c_end(factors1),
1732 container_algorithm_internal::c_begin(factors2),
1733 std::forward<T>(sum));
1734 }
1735
1736
1737
1738
1739 template <typename Sequence1, typename Sequence2, typename T,
1740 typename BinaryOp1, typename BinaryOp2>
1741 decay_t<T> c_inner_product(const Sequence1& factors1, const Sequence2& factors2,
1742 T&& sum, BinaryOp1&& op1, BinaryOp2&& op2) {
1743 return std::inner_product(container_algorithm_internal::c_begin(factors1),
1744 container_algorithm_internal::c_end(factors1),
1745 container_algorithm_internal::c_begin(factors2),
1746 std::forward<T>(sum), std::forward<BinaryOp1>(op1),
1747 std::forward<BinaryOp2>(op2));
1748 }
1749
1750
1751
1752
1753
1754
1755 template <typename InputSequence, typename OutputIt>
1756 OutputIt c_adjacent_difference(const InputSequence& input,
1757 OutputIt output_first) {
1758 return std::adjacent_difference(container_algorithm_internal::c_begin(input),
1759 container_algorithm_internal::c_end(input),
1760 output_first);
1761 }
1762
1763
1764
1765 template <typename InputSequence, typename OutputIt, typename BinaryOp>
1766 OutputIt c_adjacent_difference(const InputSequence& input,
1767 OutputIt output_first, BinaryOp&& op) {
1768 return std::adjacent_difference(container_algorithm_internal::c_begin(input),
1769 container_algorithm_internal::c_end(input),
1770 output_first, std::forward<BinaryOp>(op));
1771 }
1772
1773
1774
1775
1776
1777
1778
1779 template <typename InputSequence, typename OutputIt>
1780 OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first) {
1781 return std::partial_sum(container_algorithm_internal::c_begin(input),
1782 container_algorithm_internal::c_end(input),
1783 output_first);
1784 }
1785
1786
1787
1788 template <typename InputSequence, typename OutputIt, typename BinaryOp>
1789 OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first,
1790 BinaryOp&& op) {
1791 return std::partial_sum(container_algorithm_internal::c_begin(input),
1792 container_algorithm_internal::c_end(input),
1793 output_first, std::forward<BinaryOp>(op));
1794 }
1795
1796 ABSL_NAMESPACE_END
1797 }
1798
1799 #endif