// Copyright 2017 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "absl/algorithm/algorithm.h" #include #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" namespace { TEST(EqualTest, DefaultComparisonRandomAccess) { std::vector v1{1, 2, 3}; std::vector v2 = v1; std::vector v3 = {1, 2}; std::vector v4 = {1, 2, 4}; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); } TEST(EqualTest, DefaultComparison) { std::list lst1{1, 2, 3}; std::list lst2 = lst1; std::list lst3{1, 2}; std::list lst4{1, 2, 4}; EXPECT_TRUE(absl::equal(lst1.begin(), lst1.end(), lst2.begin(), lst2.end())); EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst3.begin(), lst3.end())); EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst4.begin(), lst4.end())); } TEST(EqualTest, EmptyRange) { std::vector v1{1, 2, 3}; std::vector empty1; std::vector empty2; EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), empty1.begin(), empty1.end())); EXPECT_FALSE(absl::equal(empty1.begin(), empty1.end(), v1.begin(), v1.end())); EXPECT_TRUE( absl::equal(empty1.begin(), empty1.end(), empty2.begin(), empty2.end())); } TEST(EqualTest, MixedIterTypes) { std::vector v1{1, 2, 3}; std::list lst1{v1.begin(), v1.end()}; std::list lst2{1, 2, 4}; std::list lst3{1, 2}; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), lst1.begin(), lst1.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst2.begin(), lst2.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst3.begin(), lst3.end())); } TEST(EqualTest, MixedValueTypes) { std::vector v1{1, 2, 3}; std::vector v2{1, 2, 3}; std::vector v3{1, 2}; std::vector v4{1, 2, 4}; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); } TEST(EqualTest, WeirdIterators) { std::vector v1{true, false}; std::vector v2 = v1; std::vector v3{true}; std::vector v4{true, true, true}; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); } TEST(EqualTest, CustomComparison) { int n[] = {1, 2, 3, 4}; std::vector v1{&n[0], &n[1], &n[2]}; std::vector v2 = v1; std::vector v3{&n[0], &n[1], &n[3]}; std::vector v4{&n[0], &n[1]}; auto eq = [](int* a, int* b) { return *a == *b; }; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), eq)); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), eq)); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end(), eq)); } TEST(EqualTest, MoveOnlyPredicate) { std::vector v1{1, 2, 3}; std::vector v2{4, 5, 6}; // move-only equality predicate struct Eq { Eq() = default; Eq(Eq &&) = default; Eq(const Eq &) = delete; Eq &operator=(const Eq &) = delete; bool operator()(const int a, const int b) const { return a == b; } }; EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v1.begin(), v1.end(), Eq())); EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), Eq())); } struct CountingTrivialPred { int* count; bool operator()(int, int) const { ++*count; return true; } }; TEST(EqualTest, RandomAccessComplexity) { std::vector v1{1, 1, 3}; std::vector v2 = v1; std::vector v3{1, 2}; do { int count = 0; absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), CountingTrivialPred{&count}); EXPECT_LE(count, 3); } while (std::next_permutation(v2.begin(), v2.end())); int count = 0; absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), CountingTrivialPred{&count}); EXPECT_EQ(count, 0); } class LinearSearchTest : public testing::Test { protected: LinearSearchTest() : container_{1, 2, 3} {} static bool Is3(int n) { return n == 3; } static bool Is4(int n) { return n == 4; } std::vector container_; }; TEST_F(LinearSearchTest, linear_search) { EXPECT_TRUE(absl::linear_search(container_.begin(), container_.end(), 3)); EXPECT_FALSE(absl::linear_search(container_.begin(), container_.end(), 4)); } TEST_F(LinearSearchTest, linear_searchConst) { const std::vector *const const_container = &container_; EXPECT_TRUE( absl::linear_search(const_container->begin(), const_container->end(), 3)); EXPECT_FALSE( absl::linear_search(const_container->begin(), const_container->end(), 4)); } TEST(RotateTest, Rotate) { std::vector v{0, 1, 2, 3, 4}; EXPECT_EQ(*absl::rotate(v.begin(), v.begin() + 2, v.end()), 0); EXPECT_THAT(v, testing::ElementsAreArray({2, 3, 4, 0, 1})); std::list l{0, 1, 2, 3, 4}; EXPECT_EQ(*absl::rotate(l.begin(), std::next(l.begin(), 3), l.end()), 0); EXPECT_THAT(l, testing::ElementsAreArray({3, 4, 0, 1, 2})); } } // namespace