| Index: base/containers/flat_set_unittest.cc
|
| diff --git a/base/containers/flat_set_unittest.cc b/base/containers/flat_set_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dbfb73bd7b5fddd70d4710337824d24340cce03c
|
| --- /dev/null
|
| +++ b/base/containers/flat_set_unittest.cc
|
| @@ -0,0 +1,761 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/containers/flat_set.h"
|
| +
|
| +#include <algorithm>
|
| +#include <functional>
|
| +#include <set>
|
| +#include <string>
|
| +#include <utility>
|
| +
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace {
|
| +
|
| +class MoveOnlyInt {
|
| + public:
|
| + MoveOnlyInt() = default;
|
| + explicit MoveOnlyInt(int rhs) : body_(rhs) {}
|
| +
|
| + operator int() const { return body_; }
|
| +
|
| + MoveOnlyInt(const MoveOnlyInt&) = delete;
|
| + MoveOnlyInt(MoveOnlyInt&& rhs) : body_(rhs.body_) { rhs.body_ = 0; }
|
| + MoveOnlyInt& operator=(const MoveOnlyInt&) = delete;
|
| + MoveOnlyInt& operator=(MoveOnlyInt&& rhs) {
|
| + body_ = rhs.body_;
|
| + rhs.body_ = 0;
|
| + return *this;
|
| + }
|
| + ~MoveOnlyInt() = default;
|
| +
|
| + friend bool operator<(const MoveOnlyInt& lhs, const MoveOnlyInt& rhs) {
|
| + return lhs.body_ < rhs.body_;
|
| + }
|
| +
|
| + private:
|
| + int body_ = 0;
|
| +};
|
| +
|
| +struct LessByFirst {
|
| + template <typename FirstPair, typename SecondPair>
|
| + bool operator()(const FirstPair& lhs, const SecondPair& rhs) {
|
| + return std::less<typename FirstPair::first_type>()(lhs.first, rhs.first);
|
| + }
|
| +};
|
| +
|
| +class NonDefaultConstructableCompare {
|
| + public:
|
| + NonDefaultConstructableCompare(int) {}
|
| +
|
| + template <typename T>
|
| + bool operator()(const T& lhs, const T& rhs) {
|
| + return std::less<T>()(lhs, rhs);
|
| + }
|
| +};
|
| +
|
| +NonDefaultConstructableCompare MakeWeiredCmp() {
|
| + return NonDefaultConstructableCompare(0);
|
| +}
|
| +
|
| +template <typename LhsSet, typename RhsSet>
|
| +bool EqualRanges(const LhsSet& lhs, const RhsSet& rhs) {
|
| + if (lhs.size() != rhs.size())
|
| + return false;
|
| + return std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
| +}
|
| +
|
| +template <typename T, typename Cmp>
|
| +void ExpectSetsAreEqual(const base::flat_set<T, Cmp>& fl_set,
|
| + const std::set<T, Cmp>& std_set) {
|
| + if (EqualRanges(fl_set, std_set))
|
| + return;
|
| + std::string error_msg("\nExpected values are: [");
|
| + for (const auto& v : std_set)
|
| + error_msg += std::to_string(v) + ' ';
|
| + error_msg += "]\nActual values are: [";
|
| + for (const auto& v : fl_set)
|
| + error_msg += std::to_string(v) + ' ';
|
| + error_msg += "]";
|
| +
|
| + ASSERT_TRUE(false) << error_msg;
|
| +}
|
| +
|
| +#define TEST_INTEGERS_LIST 5, 3, 5, 1, 1, 9, 0,
|
| +
|
| +constexpr int kIntRange[] = {TEST_INTEGERS_LIST};
|
| +
|
| +const std::initializer_list<int> kInitList = {TEST_INTEGERS_LIST};
|
| +
|
| +#undef TEST_INTEGERS_LIST
|
| +
|
| +} // namespace
|
| +
|
| +namespace base {
|
| +
|
| +using CopySet = flat_set<int>;
|
| +using CopyStdSet = std::set<int>;
|
| +using CopyVec = std::vector<int>;
|
| +using MoveSet = flat_set<MoveOnlyInt>;
|
| +using MoveStdSet = std::set<MoveOnlyInt>;
|
| +using MoveVec = std::vector<MoveOnlyInt>;
|
| +using PairSet = flat_set<std::pair<int, int>, LessByFirst>;
|
| +using PairVec = std::vector<std::pair<int, int>>;
|
| +using WeiredCmpSet = flat_set<int, NonDefaultConstructableCompare>;
|
| +using WeiredCmpStdSet = std::set<int, NonDefaultConstructableCompare>;
|
| +
|
| +TEST(FlatSetOurs, Swap) {
|
| + using M = flat_set<int>;
|
| + M lhs{1, 2, 3};
|
| + M rhs{4};
|
| + swap(lhs, rhs);
|
| + EXPECT_EQ(lhs.size(), static_cast<M::size_type>(1));
|
| + EXPECT_EQ(rhs.size(), static_cast<M::size_type>(3));
|
| + EXPECT_EQ(rhs.count(1), static_cast<M::size_type>(1));
|
| + EXPECT_EQ(rhs.count(2), static_cast<M::size_type>(1));
|
| + EXPECT_EQ(rhs.count(3), static_cast<M::size_type>(1));
|
| + EXPECT_EQ(lhs.count(1), static_cast<M::size_type>(0));
|
| + EXPECT_EQ(lhs.count(4), static_cast<M::size_type>(1));
|
| +
|
| + rhs.swap(lhs); // member function wokrs too;
|
| +}
|
| +
|
| +TEST(FlatSetOurs, Comparison) {
|
| + using M = flat_set<int>;
|
| + M biggest{3};
|
| + M smallest{1};
|
| + M middle{1, 2};
|
| +
|
| + EXPECT_TRUE(biggest == biggest);
|
| + EXPECT_TRUE(biggest != smallest);
|
| + EXPECT_TRUE(smallest < middle);
|
| + EXPECT_TRUE(smallest <= middle);
|
| + EXPECT_TRUE(biggest >= middle);
|
| + EXPECT_TRUE(biggest > middle);
|
| +}
|
| +
|
| +TEST(FlatSetOurs, Constructors) {
|
| + // default constructable
|
| + { CopySet s1; }
|
| + // constructable with Compare()
|
| + {
|
| + CopySet s1{std::less<int>()};
|
| + WeiredCmpSet s3{MakeWeiredCmp()};
|
| + }
|
| + // constructable with Compare() and Allocator()
|
| + { CopySet s1{std::less<int>(), std::allocator<int>()}; }
|
| + // constructable with range
|
| + {
|
| + CopySet s1(std::begin(kIntRange), std::end(kIntRange));
|
| + CopyStdSet std_s1(std::begin(kIntRange), std::end(kIntRange));
|
| + ExpectSetsAreEqual(s1, std_s1);
|
| + }
|
| + // constructable with range and compare
|
| + {
|
| + WeiredCmpSet s1(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| + WeiredCmpStdSet std_s1(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| + ExpectSetsAreEqual(s1, std_s1);
|
| + }
|
| + // constructable with range, compare and allocator
|
| + {
|
| + WeiredCmpSet s1(std::begin(kIntRange), std::end(kIntRange),
|
| + NonDefaultConstructableCompare(0), std::allocator<int>());
|
| + WeiredCmpStdSet std_s1(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| + ExpectSetsAreEqual(s1, std_s1);
|
| + }
|
| + // copy constructable
|
| + {
|
| + WeiredCmpStdSet test_set(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| +
|
| + WeiredCmpSet s1(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| + WeiredCmpSet s2(s1);
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // move constructable
|
| + {
|
| + MoveStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + MoveSet s2(std::move(s1));
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // constructable with an allocator
|
| + { CopySet s1{std::allocator<int>()}; }
|
| + // copy constructable with an allocator
|
| + {
|
| + WeiredCmpStdSet test_set(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| +
|
| + WeiredCmpSet s1(std::begin(kIntRange), std::end(kIntRange),
|
| + MakeWeiredCmp());
|
| +
|
| + WeiredCmpSet s2(s1, std::allocator<int>());
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // move constructable with an allocator
|
| + {
|
| + MoveStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + MoveSet s2(std::move(s1), std::allocator<MoveOnlyInt>());
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // constructable with an initializer list
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1(kInitList);
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| + // constructable with an initializer list and compare
|
| + {
|
| + WeiredCmpStdSet test_set(kInitList, MakeWeiredCmp());
|
| + WeiredCmpSet s1(kInitList, MakeWeiredCmp());
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| + // constructable with an initializer list, compare and an allocator
|
| + {
|
| + WeiredCmpStdSet test_set(kInitList, MakeWeiredCmp());
|
| + WeiredCmpSet s1(kInitList, MakeWeiredCmp(), std::allocator<int>());
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| + // constructable with a range and an allocator
|
| + {
|
| + CopyStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| + CopySet s1(std::begin(kIntRange), std::end(kIntRange),
|
| + std::allocator<int>());
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| + // constructable with an initializer list and an allocator
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1(kInitList, std::allocator<int>());
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, Assigments) {
|
| + using MoveVec = std::vector<MoveOnlyInt>;
|
| +
|
| + // copy assimgnable
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| +
|
| + CopySet s1(kInitList);
|
| + CopySet s2;
|
| + s2 = s1;
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // move assignable
|
| + {
|
| + MoveStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| + MoveSet s2;
|
| +
|
| + s2 = std::move(s1);
|
| + ExpectSetsAreEqual(s2, test_set);
|
| + }
|
| + // assignable to an initializer list
|
| + {
|
| + CopyStdSet test_set;
|
| + test_set = kInitList;
|
| +
|
| + CopySet s1;
|
| + s1 = kInitList;
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, MemoryManagment) {
|
| + constexpr CopySet::size_type kReserveSize = 5;
|
| +
|
| + // get allocator
|
| + {
|
| + CopyVec test;
|
| + CopySet s1;
|
| +
|
| + EXPECT_TRUE(test.get_allocator() == s1.get_allocator());
|
| + }
|
| + // capacity
|
| + {
|
| + CopyVec test;
|
| + CopySet s1;
|
| +
|
| + EXPECT_EQ(s1.capacity(), test.capacity());
|
| + }
|
| + // reserve
|
| + {
|
| + CopySet s1;
|
| +
|
| + s1.reserve(kReserveSize);
|
| + EXPECT_GE(s1.capacity(), kReserveSize);
|
| + }
|
| + // shrink to fit
|
| + {
|
| + CopySet s1;
|
| +
|
| + s1.reserve(kReserveSize);
|
| + s1.insert(kInitList);
|
| + auto capacity_before = s1.capacity();
|
| + s1.shrink_to_fit();
|
| + EXPECT_GE(capacity_before, s1.capacity()); // Shrink to fit is not binding.
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, Iterators) {
|
| + // begin, end
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.begin(), test_set.end()),
|
| + CopyVec(s1.begin(), s1.end()));
|
| + }
|
| + // const begin, end
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + const CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.begin(), test_set.end()),
|
| + CopyVec(s1.begin(), s1.end()));
|
| + }
|
| + // rbegin, rend
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.rbegin(), test_set.rend()),
|
| + CopyVec(s1.rbegin(), s1.rend()));
|
| + }
|
| + // const rbegin, rend
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + const CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.rbegin(), test_set.rend()),
|
| + CopyVec(s1.rbegin(), s1.rend()));
|
| + }
|
| + // cbegin, cend
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + const CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.cbegin(), test_set.cend()),
|
| + CopyVec(s1.cbegin(), s1.cend()));
|
| + }
|
| + // crbegin, crend
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1(kInitList);
|
| +
|
| + EXPECT_EQ(CopyVec(test_set.crbegin(), test_set.crend()),
|
| + CopyVec(s1.crbegin(), s1.crend()));
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, CapasityAccessors) {
|
| + // empty
|
| + {
|
| + CopySet s1;
|
| + EXPECT_TRUE(s1.empty());
|
| + }
|
| + // size
|
| + {
|
| + CopySet s1;
|
| + EXPECT_EQ(s1.size(), static_cast<CopySet::size_type>(0));
|
| + }
|
| + // max size
|
| + {
|
| + CopySet s1;
|
| + EXPECT_EQ(s1.max_size(), CopyVec().max_size());
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, OneValueInsertionsWithoutHints) {
|
| + // insert (const value_type&) in the beginning successful
|
| + {
|
| + CopySet s1{2, 3, 4};
|
| +
|
| + const int val1 = 1;
|
| + auto pos_suc = s1.insert(val1);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 0);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (const value_type&) in the middle successful
|
| + {
|
| + CopySet s1{1, 2, 4};
|
| +
|
| + const int val1 = 3;
|
| + auto pos_suc = s1.insert(val1);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 2);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (const value_type&) in the end successful
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| +
|
| + const int val1 = 4;
|
| + auto pos_suc = s1.insert(val1);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 3);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (const value_type&) not successful
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| +
|
| + const int val1 = 1;
|
| + auto pos_suc = s1.insert(val1);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 0);
|
| + EXPECT_FALSE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3}));
|
| + }
|
| +
|
| + // insert (value_type&&) in the beginning successful
|
| + {
|
| + constexpr int kIntRange[] = {2, 3, 4};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos_suc = s1.insert(MoveOnlyInt(1));
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 0);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (value_type&&) in the middle successful
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 4};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos_suc = s1.insert(MoveOnlyInt(3));
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 2);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (value_type&&) in the end successful
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 3};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos_suc = s1.insert(MoveOnlyInt(4));
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 3);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // insert (value_type&&) not successful
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 3};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos_suc = s1.insert(MoveOnlyInt(1));
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 0);
|
| + EXPECT_FALSE(pos_suc.second);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3}));
|
| + }
|
| +
|
| + // emplace (Args&&...) in the beginning successful
|
| + {
|
| + PairSet s1{{2, 0}, {3, 0}, {4, 0}};
|
| +
|
| + auto pos_suc = s1.emplace(1, 0);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 0);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace (Args&&...) in the middle successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {4, 0}};
|
| +
|
| + auto pos_suc = s1.emplace(3, 0);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 2);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace (Args&&...) in the end successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}};
|
| +
|
| + auto pos_suc = s1.emplace(4, 0);
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 3);
|
| + EXPECT_TRUE(pos_suc.second);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace (Args&&...) is not successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}};
|
| +
|
| + auto pos_suc = s1.emplace(3, 1); // checking that we keep the old one
|
| +
|
| + EXPECT_EQ(pos_suc.first - s1.begin(), 2);
|
| + EXPECT_FALSE(pos_suc.second);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()), PairVec({{1, 0}, {2, 0}, {3, 0}}));
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, InsertingWithAHint) {
|
| + // inserting (position, const &) with correct hint in the beginning is
|
| + // succesfull
|
| + {
|
| + CopySet s1{2, 3, 4};
|
| +
|
| + const int val1 = 1;
|
| + auto pos = s1.insert(s1.begin(), val1);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 0);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, const &) with correct hint in the middle is succesfull
|
| + {
|
| + CopySet s1{1, 2, 4};
|
| +
|
| + const int val1 = 3;
|
| + auto pos = s1.insert(s1.begin() + 2, val1);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 2);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, const &) with correct hint in the end is succesfull
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| +
|
| + const int val1 = 4;
|
| + auto pos = s1.insert(s1.end(), val1);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 3);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, const &) with hint is not succefful
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| +
|
| + const int val1 = 2;
|
| + auto pos = s1.insert(s1.begin(), val1);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 1);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3}));
|
| + }
|
| +
|
| + // inserting (position, &&) with correct hint in the beginning is succefful
|
| + {
|
| + constexpr int kIntRange[] = {2, 3, 4};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos = s1.insert(s1.begin(), MoveOnlyInt(1));
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 0);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, &&) with correct hint in the middle is succefful
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 4};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos = s1.insert(s1.begin() + 2, MoveOnlyInt(3));
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 2);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, &&) with correct hint in the end is succesfull
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 3};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos = s1.insert(s1.end(), MoveOnlyInt(4));
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 3);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // inserting (position, &&) with hint is not succefful
|
| + {
|
| + constexpr int kIntRange[] = {1, 2, 3};
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + auto pos = s1.insert(s1.begin(), MoveOnlyInt(2));
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 1);
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3}));
|
| + }
|
| +
|
| + // emplace_hint (position Args&&...) with correct hint in the beginning
|
| + // successful
|
| + {
|
| + PairSet s1{{2, 0}, {3, 0}, {4, 0}};
|
| +
|
| + auto pos = s1.emplace_hint(s1.begin(), 1, 0);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 0);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace_hint (position Args&&...) with correct hint in the middle
|
| + // successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {4, 0}};
|
| +
|
| + auto pos = s1.emplace_hint(s1.begin() + 2, 3, 0);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 2);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace_hint (position Args&&...) with correct hint in the end successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}};
|
| +
|
| + auto pos = s1.emplace_hint(s1.end(), 4, 0);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 3);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // emplace_hint (position Args&&...) is not successful
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}};
|
| +
|
| + auto pos = s1.emplace_hint(s1.begin(), 2, 0);
|
| +
|
| + EXPECT_EQ(pos - s1.begin(), 1);
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()), PairVec({{1, 0}, {2, 0}, {3, 0}}));
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetOurs, InsertRange) {
|
| + // insert (first, last) simple
|
| + {
|
| + CopyStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| + CopySet s1;
|
| +
|
| + s1.insert(std::begin(kIntRange), std::end(kIntRange));
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| + // insert ({}) simple
|
| + {
|
| + CopyStdSet test_set(kInitList);
|
| + CopySet s1;
|
| +
|
| + s1.insert(kInitList);
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| +
|
| + // insert (first, last) move only
|
| + {
|
| + MoveStdSet test_set(std::begin(kIntRange), std::end(kIntRange));
|
| + MoveSet s1;
|
| +
|
| + MoveVec vec(std::begin(kIntRange), std::end(kIntRange));
|
| +
|
| + s1.insert(std::make_move_iterator(vec.begin()),
|
| + std::make_move_iterator(vec.end()));
|
| +
|
| + ExpectSetsAreEqual(s1, test_set);
|
| + }
|
| +
|
| + // insert (first, last) simple merge
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| + constexpr int kMergingRange[] = {1, 4};
|
| + s1.insert(std::begin(kMergingRange), std::end(kMergingRange));
|
| +
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| + // insert ({}) simple merge
|
| + {
|
| + CopySet s1{1, 2, 3};
|
| + s1.insert({1, 4});
|
| +
|
| + EXPECT_EQ(CopyVec(s1.begin(), s1.end()), CopyVec({1, 2, 3, 4}));
|
| + }
|
| +
|
| + // insert (first, last) stable regarding already inserted
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}, {4, 0}};
|
| + const std::pair<int, int> kMergingRange[] = {
|
| + {1, 1}, {2, 1}, {1, 2}, {3, 1}};
|
| + s1.insert(std::begin(kMergingRange), std::end(kMergingRange));
|
| +
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| + // insert ({}) stable regarding already inserted
|
| + {
|
| + PairSet s1{{1, 0}, {2, 0}, {3, 0}, {4, 0}};
|
| + s1.insert({{1, 1}, {2, 1}, {1, 2}, {3, 1}});
|
| +
|
| + EXPECT_EQ(PairVec(s1.begin(), s1.end()),
|
| + PairVec({{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
|
| + }
|
| +}
|
| +
|
| +} // namespace base
|
|
|