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