aboutsummaryrefslogtreecommitdiff
path: root/absl/container/btree_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/btree_test.cc')
-rw-r--r--absl/container/btree_test.cc712
1 files changed, 81 insertions, 631 deletions
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index d27cf271..9edf38f9 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -15,7 +15,6 @@
#include "absl/container/btree_test.h"
#include <cstdint>
-#include <limits>
#include <map>
#include <memory>
#include <stdexcept>
@@ -53,9 +52,7 @@ using ::absl::test_internal::MovableOnlyInstance;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
-using ::testing::IsNull;
using ::testing::Pair;
-using ::testing::SizeIs;
template <typename T, typename U>
void CheckPairEquals(const T &x, const U &y) {
@@ -92,8 +89,8 @@ class base_checker {
public:
base_checker() : const_tree_(tree_) {}
- base_checker(const base_checker &other)
- : tree_(other.tree_), const_tree_(tree_), checker_(other.checker_) {}
+ base_checker(const base_checker &x)
+ : tree_(x.tree_), const_tree_(tree_), checker_(x.checker_) {}
template <typename InputIterator>
base_checker(InputIterator b, InputIterator e)
: tree_(b, e), const_tree_(tree_), checker_(b, e) {}
@@ -127,11 +124,11 @@ class base_checker {
}
return tree_iter;
}
- void value_check(const value_type &v) {
+ void value_check(const value_type &x) {
typename KeyOfValue<typename TreeType::key_type,
typename TreeType::value_type>::type key_of_value;
- const key_type &key = key_of_value(v);
- CheckPairEquals(*find(key), v);
+ const key_type &key = key_of_value(x);
+ CheckPairEquals(*find(key), x);
lower_bound(key);
upper_bound(key);
equal_range(key);
@@ -190,9 +187,9 @@ class base_checker {
return res;
}
- base_checker &operator=(const base_checker &other) {
- tree_ = other.tree_;
- checker_ = other.checker_;
+ base_checker &operator=(const base_checker &x) {
+ tree_ = x.tree_;
+ checker_ = x.checker_;
return *this;
}
@@ -253,9 +250,9 @@ class base_checker {
tree_.clear();
checker_.clear();
}
- void swap(base_checker &other) {
- tree_.swap(other.tree_);
- checker_.swap(other.checker_);
+ void swap(base_checker &x) {
+ tree_.swap(x.tree_);
+ checker_.swap(x.checker_);
}
void verify() const {
@@ -326,28 +323,28 @@ class unique_checker : public base_checker<TreeType, CheckerType> {
public:
unique_checker() : super_type() {}
- unique_checker(const unique_checker &other) : super_type(other) {}
+ unique_checker(const unique_checker &x) : super_type(x) {}
template <class InputIterator>
unique_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
unique_checker &operator=(const unique_checker &) = default;
// Insertion routines.
- std::pair<iterator, bool> insert(const value_type &v) {
+ std::pair<iterator, bool> insert(const value_type &x) {
int size = this->tree_.size();
std::pair<typename CheckerType::iterator, bool> checker_res =
- this->checker_.insert(v);
- std::pair<iterator, bool> tree_res = this->tree_.insert(v);
+ this->checker_.insert(x);
+ std::pair<iterator, bool> tree_res = this->tree_.insert(x);
CheckPairEquals(*tree_res.first, *checker_res.first);
EXPECT_EQ(tree_res.second, checker_res.second);
EXPECT_EQ(this->tree_.size(), this->checker_.size());
EXPECT_EQ(this->tree_.size(), size + tree_res.second);
return tree_res;
}
- iterator insert(iterator position, const value_type &v) {
+ iterator insert(iterator position, const value_type &x) {
int size = this->tree_.size();
std::pair<typename CheckerType::iterator, bool> checker_res =
- this->checker_.insert(v);
- iterator tree_res = this->tree_.insert(position, v);
+ this->checker_.insert(x);
+ iterator tree_res = this->tree_.insert(position, x);
CheckPairEquals(*tree_res, *checker_res.first);
EXPECT_EQ(this->tree_.size(), this->checker_.size());
EXPECT_EQ(this->tree_.size(), size + checker_res.second);
@@ -374,25 +371,25 @@ class multi_checker : public base_checker<TreeType, CheckerType> {
public:
multi_checker() : super_type() {}
- multi_checker(const multi_checker &other) : super_type(other) {}
+ multi_checker(const multi_checker &x) : super_type(x) {}
template <class InputIterator>
multi_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
multi_checker &operator=(const multi_checker &) = default;
// Insertion routines.
- iterator insert(const value_type &v) {
+ iterator insert(const value_type &x) {
int size = this->tree_.size();
- auto checker_res = this->checker_.insert(v);
- iterator tree_res = this->tree_.insert(v);
+ auto checker_res = this->checker_.insert(x);
+ iterator tree_res = this->tree_.insert(x);
CheckPairEquals(*tree_res, *checker_res);
EXPECT_EQ(this->tree_.size(), this->checker_.size());
EXPECT_EQ(this->tree_.size(), size + 1);
return tree_res;
}
- iterator insert(iterator position, const value_type &v) {
+ iterator insert(iterator position, const value_type &x) {
int size = this->tree_.size();
- auto checker_res = this->checker_.insert(v);
- iterator tree_res = this->tree_.insert(position, v);
+ auto checker_res = this->checker_.insert(x);
+ iterator tree_res = this->tree_.insert(position, x);
CheckPairEquals(*tree_res, *checker_res);
EXPECT_EQ(this->tree_.size(), this->checker_.size());
EXPECT_EQ(this->tree_.size(), size + 1);
@@ -595,7 +592,7 @@ void BtreeTest() {
using V = typename remove_pair_const<typename T::value_type>::type;
const std::vector<V> random_values = GenerateValuesWithSeed<V>(
absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
- GTEST_FLAG_GET(random_seed));
+ testing::GTEST_FLAG(random_seed));
unique_checker<T, C> container;
@@ -619,7 +616,7 @@ void BtreeMultiTest() {
using V = typename remove_pair_const<typename T::value_type>::type;
const std::vector<V> random_values = GenerateValuesWithSeed<V>(
absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
- GTEST_FLAG_GET(random_seed));
+ testing::GTEST_FLAG(random_seed));
multi_checker<T, C> container;
@@ -815,12 +812,10 @@ void MapTest() {
TEST(Btree, set_int32) { SetTest<int32_t>(); }
TEST(Btree, set_int64) { SetTest<int64_t>(); }
TEST(Btree, set_string) { SetTest<std::string>(); }
-TEST(Btree, set_cord) { SetTest<absl::Cord>(); }
TEST(Btree, set_pair) { SetTest<std::pair<int, int>>(); }
TEST(Btree, map_int32) { MapTest<int32_t>(); }
TEST(Btree, map_int64) { MapTest<int64_t>(); }
TEST(Btree, map_string) { MapTest<std::string>(); }
-TEST(Btree, map_cord) { MapTest<absl::Cord>(); }
TEST(Btree, map_pair) { MapTest<std::pair<int, int>>(); }
template <typename K, int N = 256>
@@ -852,12 +847,10 @@ void MultiMapTest() {
TEST(Btree, multiset_int32) { MultiSetTest<int32_t>(); }
TEST(Btree, multiset_int64) { MultiSetTest<int64_t>(); }
TEST(Btree, multiset_string) { MultiSetTest<std::string>(); }
-TEST(Btree, multiset_cord) { MultiSetTest<absl::Cord>(); }
TEST(Btree, multiset_pair) { MultiSetTest<std::pair<int, int>>(); }
TEST(Btree, multimap_int32) { MultiMapTest<int32_t>(); }
TEST(Btree, multimap_int64) { MultiMapTest<int64_t>(); }
TEST(Btree, multimap_string) { MultiMapTest<std::string>(); }
-TEST(Btree, multimap_cord) { MultiMapTest<absl::Cord>(); }
TEST(Btree, multimap_pair) { MultiMapTest<std::pair<int, int>>(); }
struct CompareIntToString {
@@ -1183,103 +1176,6 @@ TEST(Btree, RangeCtorSanity) {
EXPECT_EQ(1, tmap.size());
}
-} // namespace
-
-class BtreeNodePeer {
- public:
- // Yields the size of a leaf node with a specific number of values.
- template <typename ValueType>
- constexpr static size_t GetTargetNodeSize(size_t target_values_per_node) {
- return btree_node<
- set_params<ValueType, std::less<ValueType>, std::allocator<ValueType>,
- /*TargetNodeSize=*/256, // This parameter isn't used here.
- /*Multi=*/false>>::SizeWithNSlots(target_values_per_node);
- }
-
- // Yields the number of slots in a (non-root) leaf node for this btree.
- template <typename Btree>
- constexpr static size_t GetNumSlotsPerNode() {
- return btree_node<typename Btree::params_type>::kNodeSlots;
- }
-
- template <typename Btree>
- constexpr static size_t GetMaxFieldType() {
- return std::numeric_limits<
- typename btree_node<typename Btree::params_type>::field_type>::max();
- }
-
- template <typename Btree>
- constexpr static bool UsesLinearNodeSearch() {
- return btree_node<typename Btree::params_type>::use_linear_search::value;
- }
-};
-
-namespace {
-
-class BtreeMapTest : public ::testing::Test {
- public:
- struct Key {};
- struct Cmp {
- template <typename T>
- bool operator()(T, T) const {
- return false;
- }
- };
-
- struct KeyLin {
- using absl_btree_prefer_linear_node_search = std::true_type;
- };
- struct CmpLin : Cmp {
- using absl_btree_prefer_linear_node_search = std::true_type;
- };
-
- struct KeyBin {
- using absl_btree_prefer_linear_node_search = std::false_type;
- };
- struct CmpBin : Cmp {
- using absl_btree_prefer_linear_node_search = std::false_type;
- };
-
- template <typename K, typename C>
- static bool IsLinear() {
- return BtreeNodePeer::UsesLinearNodeSearch<absl::btree_map<K, int, C>>();
- }
-};
-
-TEST_F(BtreeMapTest, TestLinearSearchPreferredForKeyLinearViaAlias) {
- // Test requesting linear search by directly exporting an alias.
- EXPECT_FALSE((IsLinear<Key, Cmp>()));
- EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
- EXPECT_TRUE((IsLinear<Key, CmpLin>()));
- EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
-}
-
-TEST_F(BtreeMapTest, LinearChoiceTree) {
- // Cmp has precedence, and is forcing binary
- EXPECT_FALSE((IsLinear<Key, CmpBin>()));
- EXPECT_FALSE((IsLinear<KeyLin, CmpBin>()));
- EXPECT_FALSE((IsLinear<KeyBin, CmpBin>()));
- EXPECT_FALSE((IsLinear<int, CmpBin>()));
- EXPECT_FALSE((IsLinear<std::string, CmpBin>()));
- // Cmp has precedence, and is forcing linear
- EXPECT_TRUE((IsLinear<Key, CmpLin>()));
- EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
- EXPECT_TRUE((IsLinear<KeyBin, CmpLin>()));
- EXPECT_TRUE((IsLinear<int, CmpLin>()));
- EXPECT_TRUE((IsLinear<std::string, CmpLin>()));
- // Cmp has no preference, Key determines linear vs binary.
- EXPECT_FALSE((IsLinear<Key, Cmp>()));
- EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
- EXPECT_FALSE((IsLinear<KeyBin, Cmp>()));
- // arithmetic key w/ std::less or std::greater: linear
- EXPECT_TRUE((IsLinear<int, std::less<int>>()));
- EXPECT_TRUE((IsLinear<double, std::greater<double>>()));
- // arithmetic key w/ custom compare: binary
- EXPECT_FALSE((IsLinear<int, Cmp>()));
- // non-arithmetic key: binary
- EXPECT_FALSE((IsLinear<std::string, std::less<std::string>>()));
-}
-
TEST(Btree, BtreeMapCanHoldMoveOnlyTypes) {
absl::btree_map<std::string, std::unique_ptr<std::string>> m;
@@ -1372,8 +1268,6 @@ TEST(Btree, KeyCompareToAdapter) {
AssertKeyCompareToAdapted<std::less<absl::string_view>, absl::string_view>();
AssertKeyCompareToAdapted<std::greater<absl::string_view>,
absl::string_view>();
- AssertKeyCompareToAdapted<std::less<absl::Cord>, absl::Cord>();
- AssertKeyCompareToAdapted<std::greater<absl::Cord>, absl::Cord>();
AssertKeyCompareToNotAdapted<std::less<int>, int>();
AssertKeyCompareToNotAdapted<std::greater<int>, int>();
}
@@ -1425,6 +1319,28 @@ TEST(Btree, RValueInsert) {
EXPECT_EQ(tracker.swaps(), 0);
}
+} // namespace
+
+class BtreeNodePeer {
+ public:
+ // Yields the size of a leaf node with a specific number of values.
+ template <typename ValueType>
+ constexpr static size_t GetTargetNodeSize(size_t target_values_per_node) {
+ return btree_node<
+ set_params<ValueType, std::less<ValueType>, std::allocator<ValueType>,
+ /*TargetNodeSize=*/256, // This parameter isn't used here.
+ /*Multi=*/false>>::SizeWithNValues(target_values_per_node);
+ }
+
+ // Yields the number of values in a (non-root) leaf node for this set.
+ template <typename Set>
+ constexpr static size_t GetNumValuesPerNode() {
+ return btree_node<typename Set::params_type>::kNodeValues;
+ }
+};
+
+namespace {
+
// A btree set with a specific number of values per node.
template <typename Key, int TargetValuesPerNode, typename Cmp = std::less<Key>>
class SizedBtreeSet
@@ -1458,7 +1374,7 @@ void ExpectOperationCounts(const int expected_moves,
TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
InstanceTracker tracker;
// Note: this is minimum number of values per node.
- SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4> set4;
+ SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/3> set3;
// Note: this is the default number of values per node for a set of int32s
// (with 64-bit pointers).
SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61> set61;
@@ -1469,28 +1385,28 @@ TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
std::vector<int> values =
GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set3)>(), 3);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set61)>(), 61);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set100)>(), 100);
if (sizeof(void *) == 8) {
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
- BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>());
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<absl::btree_set<int32_t>>(),
+ BtreeNodePeer::GetNumValuesPerNode<decltype(set61)>());
}
// Test key insertion/deletion in random order.
- ExpectOperationCounts(56540, 134212, values, &tracker, &set4);
+ ExpectOperationCounts(45281, 132551, values, &tracker, &set3);
ExpectOperationCounts(386718, 129807, values, &tracker, &set61);
ExpectOperationCounts(586761, 130310, values, &tracker, &set100);
// Test key insertion/deletion in sorted order.
std::sort(values.begin(), values.end());
- ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
+ ExpectOperationCounts(26638, 92134, values, &tracker, &set3);
ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
// Test key insertion/deletion in reverse sorted order.
std::reverse(values.begin(), values.end());
- ExpectOperationCounts(54949, 127531, values, &tracker, &set4);
+ ExpectOperationCounts(49951, 119325, values, &tracker, &set3);
ExpectOperationCounts(338813, 118266, values, &tracker, &set61);
ExpectOperationCounts(534529, 125279, values, &tracker, &set100);
}
@@ -1507,9 +1423,9 @@ struct MovableOnlyInstanceThreeWayCompare {
TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
InstanceTracker tracker;
// Note: this is minimum number of values per node.
- SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4,
+ SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/3,
MovableOnlyInstanceThreeWayCompare>
- set4;
+ set3;
// Note: this is the default number of values per node for a set of int32s
// (with 64-bit pointers).
SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61,
@@ -1524,28 +1440,28 @@ TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
std::vector<int> values =
GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set3)>(), 3);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set61)>(), 61);
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<decltype(set100)>(), 100);
if (sizeof(void *) == 8) {
- EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
- BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>());
+ EXPECT_EQ(BtreeNodePeer::GetNumValuesPerNode<absl::btree_set<int32_t>>(),
+ BtreeNodePeer::GetNumValuesPerNode<decltype(set61)>());
}
// Test key insertion/deletion in random order.
- ExpectOperationCounts(56540, 124221, values, &tracker, &set4);
+ ExpectOperationCounts(45281, 122560, values, &tracker, &set3);
ExpectOperationCounts(386718, 119816, values, &tracker, &set61);
ExpectOperationCounts(586761, 120319, values, &tracker, &set100);
// Test key insertion/deletion in sorted order.
std::sort(values.begin(), values.end());
- ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
+ ExpectOperationCounts(26638, 92134, values, &tracker, &set3);
ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
// Test key insertion/deletion in reverse sorted order.
std::reverse(values.begin(), values.end());
- ExpectOperationCounts(54949, 117532, values, &tracker, &set4);
+ ExpectOperationCounts(49951, 109326, values, &tracker, &set3);
ExpectOperationCounts(338813, 108267, values, &tracker, &set61);
ExpectOperationCounts(534529, 115280, values, &tracker, &set100);
}
@@ -1621,7 +1537,7 @@ TEST(Btree, MapAt) {
#ifdef ABSL_HAVE_EXCEPTIONS
EXPECT_THROW(map.at(3), std::out_of_range);
#else
- EXPECT_DEATH_IF_SUPPORTED(map.at(3), "absl::btree_map::at");
+ EXPECT_DEATH(map.at(3), "absl::btree_map::at");
#endif
}
@@ -1708,25 +1624,10 @@ TEST(Btree, StrSplitCompatible) {
EXPECT_EQ(split_set, expected_set);
}
-TEST(Btree, KeyComp) {
- absl::btree_set<int> s;
- EXPECT_TRUE(s.key_comp()(1, 2));
- EXPECT_FALSE(s.key_comp()(2, 2));
- EXPECT_FALSE(s.key_comp()(2, 1));
-
- absl::btree_map<int, int> m1;
- EXPECT_TRUE(m1.key_comp()(1, 2));
- EXPECT_FALSE(m1.key_comp()(2, 2));
- EXPECT_FALSE(m1.key_comp()(2, 1));
-
- // Even though we internally adapt the comparator of `m2` to be three-way and
- // heterogeneous, the comparator we expose through key_comp() is the original
- // unadapted comparator.
- absl::btree_map<std::string, int> m2;
- EXPECT_TRUE(m2.key_comp()("a", "b"));
- EXPECT_FALSE(m2.key_comp()("b", "b"));
- EXPECT_FALSE(m2.key_comp()("b", "a"));
-}
+// We can't use EXPECT_EQ/etc. to compare absl::weak_ordering because they
+// convert literal 0 to int and absl::weak_ordering can only be compared with
+// literal 0. Defining this function allows for avoiding ClangTidy warnings.
+bool Identity(const bool b) { return b; }
TEST(Btree, ValueComp) {
absl::btree_set<int> s;
@@ -1739,13 +1640,13 @@ TEST(Btree, ValueComp) {
EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(2, 0)));
EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(1, 0)));
- // Even though we internally adapt the comparator of `m2` to be three-way and
- // heterogeneous, the comparator we expose through value_comp() is based on
- // the original unadapted comparator.
absl::btree_map<std::string, int> m2;
- EXPECT_TRUE(m2.value_comp()(std::make_pair("a", 0), std::make_pair("b", 0)));
- EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("b", 0)));
- EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)));
+ EXPECT_TRUE(Identity(
+ m2.value_comp()(std::make_pair("a", 0), std::make_pair("b", 0)) < 0));
+ EXPECT_TRUE(Identity(
+ m2.value_comp()(std::make_pair("b", 0), std::make_pair("b", 0)) == 0));
+ EXPECT_TRUE(Identity(
+ m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)) > 0));
}
TEST(Btree, DefaultConstruction) {
@@ -2053,30 +1954,6 @@ TEST(Btree, ExtractAndInsertNodeHandleMultiMap) {
EXPECT_EQ(res, ++other.begin());
}
-TEST(Btree, ExtractMultiMapEquivalentKeys) {
- // Note: using string keys means a three-way comparator.
- absl::btree_multimap<std::string, int> map;
- for (int i = 0; i < 100; ++i) {
- for (int j = 0; j < 100; ++j) {
- map.insert({absl::StrCat(i), j});
- }
- }
-
- for (int i = 0; i < 100; ++i) {
- const std::string key = absl::StrCat(i);
- auto node_handle = map.extract(key);
- EXPECT_EQ(node_handle.key(), key);
- EXPECT_EQ(node_handle.mapped(), 0) << i;
- }
-
- for (int i = 0; i < 100; ++i) {
- const std::string key = absl::StrCat(i);
- auto node_handle = map.extract(key);
- EXPECT_EQ(node_handle.key(), key);
- EXPECT_EQ(node_handle.mapped(), 1) << i;
- }
-}
-
// For multisets, insert with hint also affects correctness because we need to
// insert immediately before the hint if possible.
struct InsertMultiHintData {
@@ -2218,31 +2095,6 @@ TEST(Btree, MergeIntoMultiMapsWithDifferentComparators) {
Pair(4, 1), Pair(4, 4), Pair(5, 5)));
}
-TEST(Btree, MergeIntoSetMovableOnly) {
- absl::btree_set<MovableOnlyInstance> src;
- src.insert(MovableOnlyInstance(1));
- absl::btree_multiset<MovableOnlyInstance> dst1;
- dst1.insert(MovableOnlyInstance(2));
- absl::btree_set<MovableOnlyInstance> dst2;
-
- // Test merge into multiset.
- dst1.merge(src);
-
- EXPECT_TRUE(src.empty());
- // ElementsAre/ElementsAreArray don't work with move-only types.
- ASSERT_THAT(dst1, SizeIs(2));
- EXPECT_EQ(*dst1.begin(), MovableOnlyInstance(1));
- EXPECT_EQ(*std::next(dst1.begin()), MovableOnlyInstance(2));
-
- // Test merge into set.
- dst2.merge(dst1);
-
- EXPECT_TRUE(dst1.empty());
- ASSERT_THAT(dst2, SizeIs(2));
- EXPECT_EQ(*dst2.begin(), MovableOnlyInstance(1));
- EXPECT_EQ(*std::next(dst2.begin()), MovableOnlyInstance(2));
-}
-
struct KeyCompareToWeakOrdering {
template <typename T>
absl::weak_ordering operator()(const T &a, const T &b) const {
@@ -2274,11 +2126,11 @@ TEST(Btree, UserProvidedKeyCompareToComparators) {
TEST(Btree, TryEmplaceBasicTest) {
absl::btree_map<int, std::string> m;
- // Should construct a string from the literal.
+ // Should construct a std::string from the literal.
m.try_emplace(1, "one");
EXPECT_EQ(1, m.size());
- // Try other string constructors and const lvalue key.
+ // Try other std::string constructors and const lvalue key.
const int key(42);
m.try_emplace(key, 3, 'a');
m.try_emplace(2, std::string("two"));
@@ -2546,408 +2398,6 @@ TEST(Btree, BitfieldArgument) {
m[n];
}
-TEST(Btree, SetRangeConstructorAndInsertSupportExplicitConversionComparable) {
- const absl::string_view names[] = {"n1", "n2"};
-
- absl::btree_set<std::string> name_set1{std::begin(names), std::end(names)};
- EXPECT_THAT(name_set1, ElementsAreArray(names));
-
- absl::btree_set<std::string> name_set2;
- name_set2.insert(std::begin(names), std::end(names));
- EXPECT_THAT(name_set2, ElementsAreArray(names));
-}
-
-// A type that is explicitly convertible from int and counts constructor calls.
-struct ConstructorCounted {
- explicit ConstructorCounted(int i) : i(i) { ++constructor_calls; }
- bool operator==(int other) const { return i == other; }
-
- int i;
- static int constructor_calls;
-};
-int ConstructorCounted::constructor_calls = 0;
-
-struct ConstructorCountedCompare {
- bool operator()(int a, const ConstructorCounted &b) const { return a < b.i; }
- bool operator()(const ConstructorCounted &a, int b) const { return a.i < b; }
- bool operator()(const ConstructorCounted &a,
- const ConstructorCounted &b) const {
- return a.i < b.i;
- }
- using is_transparent = void;
-};
-
-TEST(Btree,
- SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
- const int i[] = {0, 1, 1};
- ConstructorCounted::constructor_calls = 0;
-
- absl::btree_set<ConstructorCounted, ConstructorCountedCompare> set{
- std::begin(i), std::end(i)};
- EXPECT_THAT(set, ElementsAre(0, 1));
- EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
-
- set.insert(std::begin(i), std::end(i));
- EXPECT_THAT(set, ElementsAre(0, 1));
- EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
-}
-
-TEST(Btree,
- SetRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
- const int i[] = {0, 1};
-
- absl::btree_set<std::vector<void *>> s1{std::begin(i), std::end(i)};
- EXPECT_THAT(s1, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
-
- absl::btree_set<std::vector<void *>> s2;
- s2.insert(std::begin(i), std::end(i));
- EXPECT_THAT(s2, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
-}
-
-// libstdc++ included with GCC 4.9 has a bug in the std::pair constructors that
-// prevents explicit conversions between pair types.
-// We only run this test for the libstdc++ from GCC 7 or newer because we can't
-// reliably check the libstdc++ version prior to that release.
-#if !defined(__GLIBCXX__) || \
- (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7)
-TEST(Btree, MapRangeConstructorAndInsertSupportExplicitConversionComparable) {
- const std::pair<absl::string_view, int> names[] = {{"n1", 1}, {"n2", 2}};
-
- absl::btree_map<std::string, int> name_map1{std::begin(names),
- std::end(names)};
- EXPECT_THAT(name_map1, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
-
- absl::btree_map<std::string, int> name_map2;
- name_map2.insert(std::begin(names), std::end(names));
- EXPECT_THAT(name_map2, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
-}
-
-TEST(Btree,
- MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
- const std::pair<int, int> i[] = {{0, 1}, {1, 2}, {1, 3}};
- ConstructorCounted::constructor_calls = 0;
-
- absl::btree_map<ConstructorCounted, int, ConstructorCountedCompare> map{
- std::begin(i), std::end(i)};
- EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
- EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
-
- map.insert(std::begin(i), std::end(i));
- EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
- EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
-}
-
-TEST(Btree,
- MapRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
- const std::pair<int, int> i[] = {{0, 1}, {1, 2}};
-
- absl::btree_map<std::vector<void *>, int> m1{std::begin(i), std::end(i)};
- EXPECT_THAT(m1,
- ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
-
- absl::btree_map<std::vector<void *>, int> m2;
- m2.insert(std::begin(i), std::end(i));
- EXPECT_THAT(m2,
- ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
-}
-
-TEST(Btree, HeterogeneousTryEmplace) {
- absl::btree_map<std::string, int> m;
- std::string s = "key";
- absl::string_view sv = s;
- m.try_emplace(sv, 1);
- EXPECT_EQ(m[s], 1);
-
- m.try_emplace(m.end(), sv, 2);
- EXPECT_EQ(m[s], 1);
-}
-
-TEST(Btree, HeterogeneousOperatorMapped) {
- absl::btree_map<std::string, int> m;
- std::string s = "key";
- absl::string_view sv = s;
- m[sv] = 1;
- EXPECT_EQ(m[s], 1);
-
- m[sv] = 2;
- EXPECT_EQ(m[s], 2);
-}
-
-TEST(Btree, HeterogeneousInsertOrAssign) {
- absl::btree_map<std::string, int> m;
- std::string s = "key";
- absl::string_view sv = s;
- m.insert_or_assign(sv, 1);
- EXPECT_EQ(m[s], 1);
-
- m.insert_or_assign(m.end(), sv, 2);
- EXPECT_EQ(m[s], 2);
-}
-#endif
-
-// This test requires std::launder for mutable key access in node handles.
-#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
-TEST(Btree, NodeHandleMutableKeyAccess) {
- {
- absl::btree_map<std::string, std::string> map;
-
- map["key1"] = "mapped";
-
- auto nh = map.extract(map.begin());
- nh.key().resize(3);
- map.insert(std::move(nh));
-
- EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
- }
- // Also for multimap.
- {
- absl::btree_multimap<std::string, std::string> map;
-
- map.emplace("key1", "mapped");
-
- auto nh = map.extract(map.begin());
- nh.key().resize(3);
- map.insert(std::move(nh));
-
- EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
- }
-}
-#endif
-
-struct MultiKey {
- int i1;
- int i2;
-};
-
-bool operator==(const MultiKey a, const MultiKey b) {
- return a.i1 == b.i1 && a.i2 == b.i2;
-}
-
-// A heterogeneous comparator that has different equivalence classes for
-// different lookup types.
-struct MultiKeyComp {
- using is_transparent = void;
- bool operator()(const MultiKey a, const MultiKey b) const {
- if (a.i1 != b.i1) return a.i1 < b.i1;
- return a.i2 < b.i2;
- }
- bool operator()(const int a, const MultiKey b) const { return a < b.i1; }
- bool operator()(const MultiKey a, const int b) const { return a.i1 < b; }
-};
-
-// A heterogeneous, three-way comparator that has different equivalence classes
-// for different lookup types.
-struct MultiKeyThreeWayComp {
- using is_transparent = void;
- absl::weak_ordering operator()(const MultiKey a, const MultiKey b) const {
- if (a.i1 < b.i1) return absl::weak_ordering::less;
- if (a.i1 > b.i1) return absl::weak_ordering::greater;
- if (a.i2 < b.i2) return absl::weak_ordering::less;
- if (a.i2 > b.i2) return absl::weak_ordering::greater;
- return absl::weak_ordering::equivalent;
- }
- absl::weak_ordering operator()(const int a, const MultiKey b) const {
- if (a < b.i1) return absl::weak_ordering::less;
- if (a > b.i1) return absl::weak_ordering::greater;
- return absl::weak_ordering::equivalent;
- }
- absl::weak_ordering operator()(const MultiKey a, const int b) const {
- if (a.i1 < b) return absl::weak_ordering::less;
- if (a.i1 > b) return absl::weak_ordering::greater;
- return absl::weak_ordering::equivalent;
- }
-};
-
-template <typename Compare>
-class BtreeMultiKeyTest : public ::testing::Test {};
-using MultiKeyComps = ::testing::Types<MultiKeyComp, MultiKeyThreeWayComp>;
-TYPED_TEST_SUITE(BtreeMultiKeyTest, MultiKeyComps);
-
-TYPED_TEST(BtreeMultiKeyTest, EqualRange) {
- absl::btree_set<MultiKey, TypeParam> set;
- for (int i = 0; i < 100; ++i) {
- for (int j = 0; j < 100; ++j) {
- set.insert({i, j});
- }
- }
-
- for (int i = 0; i < 100; ++i) {
- auto equal_range = set.equal_range(i);
- EXPECT_EQ(equal_range.first->i1, i);
- EXPECT_EQ(equal_range.first->i2, 0) << i;
- EXPECT_EQ(std::distance(equal_range.first, equal_range.second), 100) << i;
- }
-}
-
-TYPED_TEST(BtreeMultiKeyTest, Extract) {
- absl::btree_set<MultiKey, TypeParam> set;
- for (int i = 0; i < 100; ++i) {
- for (int j = 0; j < 100; ++j) {
- set.insert({i, j});
- }
- }
-
- for (int i = 0; i < 100; ++i) {
- auto node_handle = set.extract(i);
- EXPECT_EQ(node_handle.value().i1, i);
- EXPECT_EQ(node_handle.value().i2, 0) << i;
- }
-
- for (int i = 0; i < 100; ++i) {
- auto node_handle = set.extract(i);
- EXPECT_EQ(node_handle.value().i1, i);
- EXPECT_EQ(node_handle.value().i2, 1) << i;
- }
-}
-
-TYPED_TEST(BtreeMultiKeyTest, Erase) {
- absl::btree_set<MultiKey, TypeParam> set = {
- {1, 1}, {2, 1}, {2, 2}, {3, 1}};
- EXPECT_EQ(set.erase(2), 2);
- EXPECT_THAT(set, ElementsAre(MultiKey{1, 1}, MultiKey{3, 1}));
-}
-
-TYPED_TEST(BtreeMultiKeyTest, Count) {
- const absl::btree_set<MultiKey, TypeParam> set = {
- {1, 1}, {2, 1}, {2, 2}, {3, 1}};
- EXPECT_EQ(set.count(2), 2);
-}
-
-TEST(Btree, AllocConstructor) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used = 0;
- Alloc alloc(&bytes_used);
- Set set(alloc);
-
- set.insert({1, 2, 3});
-
- EXPECT_THAT(set, ElementsAre(1, 2, 3));
- EXPECT_GT(bytes_used, set.size() * sizeof(int));
-}
-
-TEST(Btree, AllocInitializerListConstructor) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used = 0;
- Alloc alloc(&bytes_used);
- Set set({1, 2, 3}, alloc);
-
- EXPECT_THAT(set, ElementsAre(1, 2, 3));
- EXPECT_GT(bytes_used, set.size() * sizeof(int));
-}
-
-TEST(Btree, AllocRangeConstructor) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used = 0;
- Alloc alloc(&bytes_used);
- std::vector<int> v = {1, 2, 3};
- Set set(v.begin(), v.end(), alloc);
-
- EXPECT_THAT(set, ElementsAre(1, 2, 3));
- EXPECT_GT(bytes_used, set.size() * sizeof(int));
-}
-
-TEST(Btree, AllocCopyConstructor) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used1 = 0;
- Alloc alloc1(&bytes_used1);
- Set set1(alloc1);
-
- set1.insert({1, 2, 3});
-
- int64_t bytes_used2 = 0;
- Alloc alloc2(&bytes_used2);
- Set set2(set1, alloc2);
-
- EXPECT_THAT(set1, ElementsAre(1, 2, 3));
- EXPECT_THAT(set2, ElementsAre(1, 2, 3));
- EXPECT_GT(bytes_used1, set1.size() * sizeof(int));
- EXPECT_EQ(bytes_used1, bytes_used2);
-}
-
-TEST(Btree, AllocMoveConstructor_SameAlloc) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used = 0;
- Alloc alloc(&bytes_used);
- Set set1(alloc);
-
- set1.insert({1, 2, 3});
-
- const int64_t original_bytes_used = bytes_used;
- EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
-
- Set set2(std::move(set1), alloc);
-
- EXPECT_THAT(set2, ElementsAre(1, 2, 3));
- EXPECT_EQ(bytes_used, original_bytes_used);
-}
-
-TEST(Btree, AllocMoveConstructor_DifferentAlloc) {
- using Alloc = CountingAllocator<int>;
- using Set = absl::btree_set<int, std::less<int>, Alloc>;
- int64_t bytes_used1 = 0;
- Alloc alloc1(&bytes_used1);
- Set set1(alloc1);
-
- set1.insert({1, 2, 3});
-
- const int64_t original_bytes_used = bytes_used1;
- EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
-
- int64_t bytes_used2 = 0;
- Alloc alloc2(&bytes_used2);
- Set set2(std::move(set1), alloc2);
-
- EXPECT_THAT(set2, ElementsAre(1, 2, 3));
- // We didn't free these bytes allocated by `set1` yet.
- EXPECT_EQ(bytes_used1, original_bytes_used);
- EXPECT_EQ(bytes_used2, original_bytes_used);
-}
-
-bool IntCmp(const int a, const int b) { return a < b; }
-
-TEST(Btree, SupportsFunctionPtrComparator) {
- absl::btree_set<int, decltype(IntCmp) *> set(IntCmp);
- set.insert({1, 2, 3});
- EXPECT_THAT(set, ElementsAre(1, 2, 3));
- EXPECT_TRUE(set.key_comp()(1, 2));
- EXPECT_TRUE(set.value_comp()(1, 2));
-
- absl::btree_map<int, int, decltype(IntCmp) *> map(&IntCmp);
- map[1] = 1;
- EXPECT_THAT(map, ElementsAre(Pair(1, 1)));
- EXPECT_TRUE(map.key_comp()(1, 2));
- EXPECT_TRUE(map.value_comp()(std::make_pair(1, 1), std::make_pair(2, 2)));
-}
-
-template <typename Compare>
-struct TransparentPassThroughComp {
- using is_transparent = void;
-
- // This will fail compilation if we attempt a comparison that Compare does not
- // support, and the failure will happen inside the function implementation so
- // it can't be avoided by using SFINAE on this comparator.
- template <typename T, typename U>
- bool operator()(const T &lhs, const U &rhs) const {
- return Compare()(lhs, rhs);
- }
-};
-
-TEST(Btree,
- SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators) {
- absl::btree_set<MultiKey, TransparentPassThroughComp<MultiKeyComp>> set;
- set.insert(MultiKey{1, 2});
- EXPECT_TRUE(set.contains(1));
-}
-
-TEST(Btree, ConstructImplicitlyWithUnadaptedComparator) {
- absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
-}
-
} // namespace
} // namespace container_internal
ABSL_NAMESPACE_END