summaryrefslogtreecommitdiff
path: root/absl/algorithm/algorithm.h
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2023-10-20 12:49:11 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-10-20 12:49:46 -0700
commitb5fb0582b5bb46d622271a7db61e28ff19ae928c (patch)
treeb58fdda8cebaa72c1d85d5009b9bab764672174b /absl/algorithm/algorithm.h
parent133360ca449bb2a44899e71f253856dca8443bdb (diff)
Use STL algorithms available since C++14 to implement absl::equal and
absl::rotate. Prior to C++14 these were either polyfills or fixes for bugs in standard libraries. PiperOrigin-RevId: 575295101 Change-Id: Ie01e77fedadc879c73203d71babd40c87a419af3
Diffstat (limited to 'absl/algorithm/algorithm.h')
-rw-r--r--absl/algorithm/algorithm.h111
1 files changed, 8 insertions, 103 deletions
diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h
index e9b47338..59aeed7d 100644
--- a/absl/algorithm/algorithm.h
+++ b/absl/algorithm/algorithm.h
@@ -31,92 +31,17 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace algorithm_internal {
-
-// Performs comparisons with operator==, similar to C++14's `std::equal_to<>`.
-struct EqualTo {
- template <typename T, typename U>
- bool operator()(const T& a, const U& b) const {
- return a == b;
- }
-};
-
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred pred, std::input_iterator_tag,
- std::input_iterator_tag) {
- while (true) {
- if (first1 == last1) return first2 == last2;
- if (first2 == last2) return false;
- if (!pred(*first1, *first2)) return false;
- ++first1;
- ++first2;
- }
-}
-
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred&& pred, std::random_access_iterator_tag,
- std::random_access_iterator_tag) {
- return (last1 - first1 == last2 - first2) &&
- std::equal(first1, last1, first2, std::forward<Pred>(pred));
-}
-
-// When we are using our own internal predicate that just applies operator==, we
-// forward to the non-predicate form of std::equal. This enables an optimization
-// in libstdc++ that can result in std::memcmp being used for integer types.
-template <typename InputIter1, typename InputIter2>
-bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, algorithm_internal::EqualTo /* unused */,
- std::random_access_iterator_tag,
- std::random_access_iterator_tag) {
- return (last1 - first1 == last2 - first2) &&
- std::equal(first1, last1, first2);
-}
-
-template <typename It>
-It RotateImpl(It first, It middle, It last, std::true_type) {
- return std::rotate(first, middle, last);
-}
-
-template <typename It>
-It RotateImpl(It first, It middle, It last, std::false_type) {
- std::rotate(first, middle, last);
- return std::next(first, std::distance(middle, last));
-}
-
-} // namespace algorithm_internal
-
// equal()
+// rotate()
//
-// Compares the equality of two ranges specified by pairs of iterators, using
-// the given predicate, returning true iff for each corresponding iterator i1
-// and i2 in the first and second range respectively, pred(*i1, *i2) == true
-//
-// This comparison takes at most min(`last1` - `first1`, `last2` - `first2`)
-// invocations of the predicate. Additionally, if InputIter1 and InputIter2 are
-// both random-access iterators, and `last1` - `first1` != `last2` - `first2`,
-// then the predicate is never invoked and the function returns false.
+// Historical note: Abseil once provided implementations of these algorithms
+// prior to their adoption in C++14. New code should prefer to use the std
+// variants.
//
-// This is a C++11-compatible implementation of C++14 `std::equal`. See
-// https://en.cppreference.com/w/cpp/algorithm/equal for more information.
-template <typename InputIter1, typename InputIter2, typename Pred>
-bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2, Pred&& pred) {
- return algorithm_internal::EqualImpl(
- first1, last1, first2, last2, std::forward<Pred>(pred),
- typename std::iterator_traits<InputIter1>::iterator_category{},
- typename std::iterator_traits<InputIter2>::iterator_category{});
-}
-
-// Overload of equal() that performs comparison of two ranges specified by pairs
-// of iterators using operator==.
-template <typename InputIter1, typename InputIter2>
-bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2,
- InputIter2 last2) {
- return absl::equal(first1, last1, first2, last2,
- algorithm_internal::EqualTo{});
-}
+// See the documentation for the STL <algorithm> header for more information:
+// https://en.cppreference.com/w/cpp/header/algorithm
+using std::equal;
+using std::rotate;
// linear_search()
//
@@ -133,26 +58,6 @@ bool linear_search(InputIterator first, InputIterator last,
return std::find(first, last, value) != last;
}
-// rotate()
-//
-// Performs a left rotation on a range of elements (`first`, `last`) such that
-// `middle` is now the first element. `rotate()` returns an iterator pointing to
-// the first element before rotation. This function is exactly the same as
-// `std::rotate`, but fixes a bug in gcc
-// <= 4.9 where `std::rotate` returns `void` instead of an iterator.
-//
-// The complexity of this algorithm is the same as that of `std::rotate`, but if
-// `ForwardIterator` is not a random-access iterator, then `absl::rotate`
-// performs an additional pass over the range to construct the return value.
-template <typename ForwardIterator>
-ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
- ForwardIterator last) {
- return algorithm_internal::RotateImpl(
- first, middle, last,
- std::is_same<decltype(std::rotate(first, middle, last)),
- ForwardIterator>());
-}
-
ABSL_NAMESPACE_END
} // namespace absl