Chromium Code Reviews| 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..8d2ad1b28b257c25a285b15b2de43741399335c1 |
| --- /dev/null |
| +++ b/base/containers/flat_set_unittest.cc |
| @@ -0,0 +1,1365 @@ |
| +// 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" |
| + |
| +// Following tests are ported and extended tests from libcpp for std::set. |
| +// They can be found here: |
| +// https://github.com/llvm-mirror/libcxx/tree/master/test/std/containers/associative/set |
| +// |
| +// Not ported tests: |
| +// * No tests with PrivateConstructor and std::less<> changed to std::less<T> |
| +// These tests have to do with C++14 std::less<> |
| +// http://en.cppreference.com/w/cpp/utility/functional/less_void |
| +// and add support for templated versions of lookup functions. |
| +// Current implementation of flat containers doesn't support it. |
| +// * No tests with TemplateConstructor. |
| +// Library working group issue: LWG #2059 |
| +// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2059 |
| +// There is an ambiguity between erase with an iterator and erase with a key, |
| +// if key has a templated constructor. We have to fix this. |
| +// * No tests for max_size() |
| +// Has to do with allocator support. |
| +// * No tests with DefaultOnly. |
| +// Standard containers allocate each element in the separate node on the heap |
| +// and then manipulate these nodes. Flat containers store their elements in |
| +// contiguous memory and move them around, type is required to be movable. |
| +// * No tests for N3644. |
| +// This proposal suggests that all default constructed iterators compare |
| +// equal. Currently we use std::vector iterators and they don't implement |
| +// this. |
| +// * No tests with min_allocator. |
| +// Allocators are not widely used in Chromium, and how we are going to |
| +// customize underlying data (if we are going to) is still up to debate. |
| +// * No tests counting allocations. Flat sets have different allocation |
| +// patterns than std::sets and we do not consider them to be a part of the |
| +// interface. |
| + |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/macros.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace { |
| + |
| +class MoveOnly { |
| + public: |
| + MoveOnly(int data = 1) : data_(data) {} |
| + MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; } |
| + MoveOnly& operator=(MoveOnly&& x) { |
| + data_ = x.data_; |
| + x.data_ = 0; |
| + return *this; |
| + } |
| + |
| + friend bool operator==(const MoveOnly& x, const MoveOnly& y) { |
|
Peter Kasting
2016/12/20 02:33:51
Any particular reason to prefer member vs. non-mem
dyaroshev
2016/12/20 21:59:55
1. This type is implicitly convertible from int (t
|
| + return x.data_ == y.data_; |
| + } |
| + |
| + friend bool operator<(const MoveOnly& x, const MoveOnly& y) { |
| + return x.data_ < y.data_; |
| + } |
| + |
| + int data() const { return data_; } |
| + |
| + private: |
| + int data_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MoveOnly); |
| +}; |
| + |
| +template <class It> |
| +class InputIterator { |
| + public: |
| + using iterator_category = std::input_iterator_tag; |
| + using value_type = typename std::iterator_traits<It>::value_type; |
| + using difference_type = typename std::iterator_traits<It>::difference_type; |
| + using pointer = It; |
| + using reference = typename std::iterator_traits<It>::reference; |
| + |
| + InputIterator() : it_() {} |
| + explicit InputIterator(It it) : it_(it) {} |
| + InputIterator(const InputIterator& x) : it_(x.it_) {} |
| + |
| + reference operator*() const { return *it_; } |
| + pointer operator->() const { return it_; } |
| + |
| + InputIterator& operator++() { |
| + ++it_; |
| + return *this; |
| + } |
| + InputIterator operator++(int) { |
| + InputIterator tmp(*this); |
| + ++(*this); |
| + return tmp; |
| + } |
| + |
| + friend bool operator==(const InputIterator& x, const InputIterator& y) { |
| + return x.it_ == y.it_; |
| + } |
| + friend bool operator!=(const InputIterator& x, const InputIterator& y) { |
| + return !(x == y); |
| + } |
| + |
| + private: |
| + It it_; |
| +}; |
| + |
| +template <typename It> |
| +InputIterator<It> MakeInputIterator(It it) { |
| + return InputIterator<It>(it); |
| +} |
| + |
| +class Emplaceable { |
| + public: |
| + Emplaceable() = default; |
| + Emplaceable(int i, double d) : int_(i), double_(d) {} |
| + Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) { |
| + x.int_ = 0; |
| + x.double_ = 0.0; |
| + } |
| + |
| + Emplaceable& operator=(Emplaceable&& x) { |
| + int_ = x.int_; |
| + x.int_ = 0; |
| + double_ = x.double_; |
| + x.double_ = 0.0; |
| + return *this; |
| + } |
| + |
| + friend bool operator==(const Emplaceable& x, const Emplaceable& y) { |
| + return x.int_ == y.int_ && x.double_ == y.double_; |
| + } |
| + |
| + friend bool operator<(const Emplaceable& x, const Emplaceable& y) { |
| + return std::tie(x.int_, x.double_) < std::tie(y.int_, y.double_); |
| + } |
| + |
| + private: |
| + int int_ = 0; |
| + double double_ = 0.0; |
|
Peter Kasting
2016/12/20 02:33:51
Nit: I dunno that I'm as big a fan of these initia
dyaroshev
2016/12/20 21:59:55
Done.
|
| + |
| + DISALLOW_COPY_AND_ASSIGN(Emplaceable); |
| +}; |
| + |
| +class NonDefaultConstructibleCompare { |
| + public: |
| + NonDefaultConstructibleCompare(int) {} |
| + |
| + template <typename T> |
| + bool operator()(const T& lhs, const T& rhs) { |
| + return std::less<T>()(lhs, rhs); |
| + } |
| +}; |
| + |
| +template <typename T> |
| +std::string ToString(const T& val) { |
| + return std::to_string(val); |
| +} |
| + |
| +std::string ToString(const MoveOnly& val) { |
| + return std::to_string(val.data()); |
| +} |
| + |
| +template <typename XRange, typename YRange> |
| +// Requires: |
| +// XRange is ForwardRange |
| +// YRange is ForwardRange |
| +// ValueType<XRange> is EqualityComparable to ValueType<YRange> |
| +bool EqualRange(const XRange& x_range, const YRange& y_range) { |
| + if (std::distance(x_range.begin(), x_range.end()) != |
| + std::distance(y_range.begin(), y_range.end())) |
| + return false; |
| + |
| + return std::equal(x_range.begin(), x_range.end(), y_range.begin()); |
|
Peter Kasting
2016/12/20 02:33:50
Nit: Or just:
return (std::distance(x_range.beg
dyaroshev
2016/12/20 21:59:55
Done.
|
| +} |
| + |
| +template <typename Range> |
| +// Requires: |
| +// Range is InputRange |
| +// ValueType<Range> is ConvertibleToString. |
| +std::string RangeToString(const Range& range) { |
| + std::string res = "["; |
| + for (const auto& val : range) { |
|
Peter Kasting
2016/12/20 02:33:51
Nit: {} unnecessary
dyaroshev
2016/12/20 21:59:55
Done.
|
| + res += ToString(val) + ", "; |
| + } |
| + res += ']'; |
| + return res; |
| +} |
| + |
| +template <typename TestedRange> |
| +// Requires: |
| +// TestedRange is ForwardRange |
| +// ExpectedRange is ForwardRange |
| +// ValueType<TestedRange> is EqualityComparable to int |
| +// ValueType<TestedRange> is ConvertibleToString. |
| +void ExpectRange(const TestedRange& tested_range, |
| + const std::vector<int>& expected_range) { |
| + EXPECT_TRUE(EqualRange(tested_range, expected_range)) |
| + << "Expected: " << RangeToString(expected_range) |
| + << " Actual: " << RangeToString(tested_range); |
|
Peter Kasting
2016/12/20 02:33:51
Nit: Maybe put a comma at the beginning of this se
dyaroshev
2016/12/20 21:59:55
Done.
|
| +} |
| + |
| +} // namespace |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Class. |
| + |
| +// Check that base::flat_set and its iterators can be instantiated with an |
| +// incomplete type. |
| + |
| +TEST(FlatSet, IncompleteType) { |
| + struct A { |
| + using Set = base::flat_set<A>; |
| + int data; |
| + Set m; |
| + Set::iterator it; |
| + Set::const_iterator cit; |
| + |
| + // We do not declare operator< because clang complains that it's unused. |
| + }; |
| + |
| + A a; |
| +} |
| + |
| +TEST(FlatSet, Stability) { |
| + using Pair = std::pair<int, int>; |
| + |
| + struct LessByFirst { |
| + bool operator()(const Pair& x, const Pair& y) { return x.first < y.first; } |
| + }; |
| + |
| + using Set = base::flat_set<Pair, LessByFirst>; |
| + |
| + auto AllSecondAreZero = [](const Set& cont) { |
| + return std::all_of(cont.begin(), cont.end(), |
| + [](const Pair& elem) { return elem.second == 0; }); |
| + }; |
| + |
| + Set cont{{0, 0}, {1, 0}, {0, 1}, {2, 0}, {0, 2}, {1, 1}}; |
| + EXPECT_TRUE(AllSecondAreZero(cont)) << "initializer_list constructor"; |
| + |
| + cont.insert(Pair(0, 1)); |
| + EXPECT_TRUE(AllSecondAreZero(cont)) << "single insert"; |
| + |
| + cont.insert({{3, 0}, {0, 1}, {1, 1}, {3, 1}, {2, 1}, {3, 2}}); |
| + EXPECT_TRUE(AllSecondAreZero(cont)) << "initializer_list insert"; |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Types. |
| + |
| +// key_type |
| +// key_compare |
| +// value_type |
| +// value_compare |
| +// allocator_type |
| +// pointer |
| +// const_pointer |
| +// reference |
| +// const_reference |
| +// size_type |
| +// difference_type |
| +// iterator |
| +// const_iterator |
| +// reverse_iterator |
| +// const_reverse_iterator |
| + |
| +TEST(FlatSet, Types) { |
| + using Set = base::flat_set<int>; |
| + |
| + // These are guarantied to be portable. |
|
Peter Kasting
2016/12/20 02:33:51
Nit: guaranteed
dyaroshev
2016/12/20 21:59:55
Done.
|
| + static_assert((std::is_same<int, Set::key_type>::value), ""); |
| + static_assert((std::is_same<int, Set::value_type>::value), ""); |
| + static_assert((std::is_same<std::less<int>, Set::key_compare>::value), ""); |
| + static_assert((std::is_same<std::less<int>, Set::value_compare>::value), ""); |
| + static_assert((std::is_same<int&, Set::reference>::value), ""); |
| + static_assert((std::is_same<const int&, Set::const_reference>::value), ""); |
| + static_assert((std::is_same<int*, Set::pointer>::value), ""); |
| + static_assert((std::is_same<const int*, Set::const_pointer>::value), ""); |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Lifetime. |
| + |
| +// flat_set() |
| +// flat_set(const Compare& comp, const Allocator& alloc = Allocator()) |
| +// flat_set(const Allocator& alloc) |
| + |
| +TEST(FlatSet, DefaultConstructor) { |
| + { |
| + using Set = base::flat_set<int>; |
|
Peter Kasting
2016/12/20 02:33:50
This alias appears in basically every test. Maybe
dyaroshev
2016/12/20 21:59:55
Moved all common typedefs in anonymous namespace.
|
| + |
| + Set cont; |
| + ExpectRange(cont, {}); |
| + } |
| + |
| + { |
| + using Set = base::flat_set<int, NonDefaultConstructibleCompare>; |
| + |
| + Set cont{NonDefaultConstructibleCompare(0)}; |
|
Peter Kasting
2016/12/20 02:33:51
Do you really need to use {} here? (Maybe it avoi
dyaroshev
2016/12/20 21:59:55
Done.
|
| + ExpectRange(cont, {}); |
| + } |
| +} |
| + |
| +// flat_set(InputIterator first, |
| +// InputIterator last, |
| +// const Compare& comp = Compare(), |
| +// const Allocator& alloc = Allocator()) |
| +// flat_set(InputIterator first, InputIterator last, const Allocator& alloc) |
| + |
| +TEST(FlatSet, RangeConstructor) { |
| + { |
| + using Set = base::flat_set<int>; |
| + |
| + Set::value_type ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
| + |
| + Set cont(MakeInputIterator(std::begin(ar)), |
| + MakeInputIterator(std::end(ar))); |
| + ExpectRange(cont, {1, 2, 3}); |
| + } |
| + { |
| + using Set = base::flat_set<int, NonDefaultConstructibleCompare>; |
| + |
| + Set::value_type ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
| + |
| + Set cont(MakeInputIterator(std::begin(ar)), MakeInputIterator(std::end(ar)), |
| + NonDefaultConstructibleCompare(0)); |
| + ExpectRange(cont, {1, 2, 3}); |
| + } |
| +} |
| + |
| +// flat_set(const flat_set& x) |
| +// flat_set(const flat_set& x, const Allocator& alloc) |
| + |
| +TEST(FlatSet, CopyConstructor) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set original{1, 2, 3, 4}; |
| + Set copied(original); |
| + |
| + ExpectRange(copied, {1, 2, 3, 4}); |
| + ExpectRange(original, {1, 2, 3, 4}); |
| + EXPECT_EQ(original, copied); |
| +} |
| + |
| +// flat_set(flat_set&& x) |
| +// flat_set(flat_set&& x, const Allocator& alloc) |
| + |
| +TEST(FlatSet, MoveConstructor) { |
| + using Set = base::flat_set<MoveOnly>; |
| + |
| + int input_range[] = {1, 2, 3, 4}; |
| + |
| + Set original(std::begin(input_range), std::end(input_range)); |
| + Set moved(std::move(original)); |
| + |
| + ExpectRange(moved, {1, 2, 3, 4}); |
| +} |
| + |
| +// flat_set(std::initializer_list<value_type> il, |
| +// const Compare& comp = Compare(), |
| +// const Allocator& alloc = Allocator()) |
| +// flat_set(std::initializer_list<value_type> il, const Allocator& a) |
| + |
| +TEST(FlatSet, InitializerListConstructor) { |
| + { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 10, 8}; |
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 8, 10}); |
| + } |
| + { |
| + using Set = base::flat_set<int, NonDefaultConstructibleCompare>; |
| + |
| + Set cont({1, 2, 3, 4, 5, 6, 10, 8}, NonDefaultConstructibleCompare(0)); |
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 8, 10}); |
| + } |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Assignments. |
| + |
| +// flat_set& operator=(const flat_set& x) |
| + |
| +TEST(FlatSet, CopyAssignable) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set original{1, 2, 3, 4}; |
| + Set copied; |
| + copied = original; |
| + |
| + ExpectRange(copied, {1, 2, 3, 4}); |
| + ExpectRange(original, {1, 2, 3, 4}); |
| + EXPECT_EQ(original, copied); |
| +} |
| + |
| +// flat_set& operator=(flat_set&& x) |
| + |
| +TEST(FlatSet, MoveAssignable) { |
| + using Set = base::flat_set<MoveOnly>; |
| + |
| + int input_range[] = {1, 2, 3, 4}; |
| + |
| + Set original(std::begin(input_range), std::end(input_range)); |
| + Set moved; |
| + moved = std::move(original); |
| + |
| + ExpectRange(moved, {1, 2, 3, 4}); |
| +} |
| + |
| +// flat_set& operator=(std::initializer_list<value_type> il) |
| + |
| +TEST(FlatSet, InitializerListAssignable) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{0}; |
| + cont = {1, 2, 3, 4, 5, 6, 10, 8}; |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.count(0)); |
|
Peter Kasting
2016/12/20 02:33:51
Nit: I still suggest using "0U" and similar for ca
dyaroshev
2016/12/20 21:59:55
Done.
|
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 8, 10}); |
| +} |
| + |
| +// -------------------------------------------------------------------------- |
| +// Memory management. |
| + |
| +// void reserve(size_type size) |
| + |
| +TEST(FlatSet, Reserve) { |
| + using Set = base::flat_set<int>; |
| + Set cont{1, 2, 3}; |
| + |
| + cont.reserve(5); |
| + EXPECT_LE(static_cast<Set::size_type>(5), cont.capacity()); |
| +} |
| + |
| +// size_type capacity() const |
| + |
| +TEST(FlatSet, Capacity) { |
| + using Set = base::flat_set<int>; |
| + Set cont{1, 2, 3}; |
| + EXPECT_LE(cont.size(), cont.capacity()); |
| + cont.reserve(5); |
| + EXPECT_LE(cont.size(), cont.capacity()); |
| +} |
| + |
| +// void shrink_to_fit() |
| + |
| +TEST(FlatSet, ShrinkToFit) { |
| + using Set = base::flat_set<int>; |
| + Set cont{1, 2, 3}; |
| + |
| + Set::size_type capacity_before = cont.capacity(); |
| + cont.shrink_to_fit(); |
| + EXPECT_GE(capacity_before, cont.capacity()); |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Size management. |
| + |
| +// void clear(); |
| + |
| +TEST(FlatSet, Clear) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 7, 8}; |
| + cont.clear(); |
| + ExpectRange(cont, {}); |
| +} |
| + |
| +// size_type size() const; |
| + |
| +TEST(FlatSet, Size) { |
| + using Set = base::flat_set<int>; |
| + Set cont; |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.size()); |
| + cont.insert(2); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + cont.insert(1); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + cont.insert(3); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + cont.erase(cont.begin()); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + cont.erase(cont.begin()); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + cont.erase(cont.begin()); |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.size()); |
| +} |
| + |
| +// bool empty() const; |
| + |
| +TEST(FlatSet, Empty) { |
| + using Set = base::flat_set<int>; |
| + Set cont; |
| + EXPECT_TRUE(cont.empty()); |
| + cont.insert(1); |
| + EXPECT_FALSE(cont.empty()); |
| + cont.clear(); |
| + EXPECT_TRUE(cont.empty()); |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Iterators. |
| + |
| +// iterator begin(); |
| +// const_iterator begin() const; |
| +// iterator end(); |
| +// const_iterator end() const; |
| +// |
| +// reverse_iterator rbegin(); |
| +// const_reverse_iterator rbegin() const; |
| +// reverse_iterator rend(); |
| +// const_reverse_iterator rend() const; |
| +// |
| +// const_iterator cbegin() const; |
| +// const_iterator cend() const; |
| +// const_reverse_iterator crbegin() const; |
| +// const_reverse_iterator crend() const; |
| + |
| +TEST(FlatSet, Iterators) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 7, 8}; |
| + |
| + auto size = static_cast<Set::difference_type>(cont.size()); |
| + |
| + EXPECT_EQ(size, std::distance(cont.begin(), cont.end())); |
| + EXPECT_EQ(size, std::distance(cont.cbegin(), cont.cend())); |
| + EXPECT_EQ(size, std::distance(cont.rbegin(), cont.rend())); |
| + EXPECT_EQ(size, std::distance(cont.crbegin(), cont.crend())); |
| + |
| + { |
| + Set::iterator it = cont.begin(); |
| + Set::const_iterator c_it = cont.cbegin(); |
| + EXPECT_EQ(it, c_it); |
| + for (int j = 1; it != cont.end(); ++it, ++c_it, ++j) { |
| + EXPECT_EQ(j, *it); |
| + EXPECT_EQ(j, *c_it); |
| + } |
| + } |
| + { |
| + Set::reverse_iterator rit = cont.rbegin(); |
| + Set::const_reverse_iterator c_rit = cont.crbegin(); |
| + EXPECT_EQ(rit, c_rit); |
| + for (int j = static_cast<int>(size); rit != cont.rend(); |
| + ++rit, ++c_rit, --j) { |
| + EXPECT_EQ(j, *rit); |
| + EXPECT_EQ(j, *c_rit); |
| + } |
| + } |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Insert operations. |
| + |
| +// pair<iterator, bool> insert(const value_type& v); |
| + |
| +TEST(FlatSet, InsertCV) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont; |
| + int value = 2; |
|
Peter Kasting
2016/12/20 02:33:51
Does this test not test the same thing if you inli
dyaroshev
2016/12/20 21:59:55
I was trying to make emphasise that it calls inser
Peter Kasting
2016/12/20 22:06:38
Yeah, that's a good point.
|
| + std::pair<Set::iterator, bool> result = cont.insert(value); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result.first); |
| + |
| + value = 1; |
| + result = cont.insert(value); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(1, *result.first); |
| + |
| + value = 3; |
| + result = cont.insert(value); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(std::prev(cont.end()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result.first); |
| + |
| + value = 3; |
| + result = cont.insert(value); |
| + EXPECT_FALSE(result.second); |
| + EXPECT_EQ(std::prev(cont.end()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result.first); |
| +} |
| + |
| +// pair<iterator, bool> insert(value_type&& v); |
| + |
| +TEST(FlatSet, InsertRV) { |
| + using Set = base::flat_set<MoveOnly>; |
| + |
| + Set cont; |
| + std::pair<Set::iterator, bool> result = cont.insert(MoveOnly(2)); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result.first); |
| + |
| + result = cont.insert(MoveOnly(1)); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(1, *result.first); |
| + |
| + result = cont.insert(MoveOnly(3)); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(std::prev(cont.end()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result.first); |
| + |
| + result = cont.insert(MoveOnly(3)); |
| + EXPECT_FALSE(result.second); |
| + EXPECT_EQ(std::prev(cont.end()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), *result.first); |
|
Peter Kasting
2016/12/20 02:33:51
This cast seems incorrect.
dyaroshev
2016/12/20 21:59:55
Done.
|
| +} |
| + |
| +// iterator insert(const_iterator position, const value_type& v); |
| + |
| +TEST(FlatSet, InsertIterCV) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont; |
| + Set::iterator result = cont.insert(cont.cend(), 2); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result); |
| + |
| + result = cont.insert(cont.cend(), 1); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(1, *result); |
| + |
| + result = cont.insert(cont.cend(), 3); |
| + EXPECT_EQ(std::prev(cont.end()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result); |
| + |
| + result = cont.insert(cont.cend(), 3); |
| + EXPECT_EQ(std::prev(cont.end()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result); |
| +} |
| + |
| +// iterator insert(const_iterator position, value_type&& v); |
| + |
| +TEST(FlatSet, InsertIterRV) { |
| + using Set = base::flat_set<MoveOnly>; |
| + |
| + Set cont; |
| + Set::iterator result = cont.insert(cont.cend(), MoveOnly(2)); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result); |
| + |
| + result = cont.insert(cont.cend(), MoveOnly(1)); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(1, *result); |
| + |
| + result = cont.insert(cont.cend(), MoveOnly(3)); |
| + EXPECT_EQ(std::prev(cont.end()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result); |
| + |
| + result = cont.insert(cont.cend(), MoveOnly(3)); |
| + EXPECT_EQ(std::prev(cont.end()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(3), cont.size()); |
| + EXPECT_EQ(3, *result); |
| +} |
| + |
| +// template <class InputIterator> |
| +// void insert(InputIterator first, InputIterator last); |
| + |
| +TEST(FlatSet, InsertRange) { |
| + using Set = base::flat_set<int>; |
| + |
| + int input[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
| + |
| + Set cont; |
| + cont.insert(MakeInputIterator(std::begin(input)), |
| + MakeInputIterator(std::end(input))); |
| + ExpectRange(cont, {1, 2, 3}); |
| +} |
| + |
| +// void insert(initializer_list<value_type> il); |
| + |
| +TEST(FlatSet, InsertInitializerList) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont = {10, 8}; |
| + cont.insert({1, 2, 3, 4, 5, 6}); |
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 8, 10}); |
| +} |
| + |
| +// template <class... Args> |
| +// pair<iterator, bool> emplace(Args&&... args); |
| + |
| +TEST(FlatSet, Emplace) { |
| + { |
| + using Set = base::flat_set<Emplaceable>; |
| + |
| + Set cont; |
| + std::pair<Set::iterator, bool> result = cont.emplace(); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(Emplaceable(), *cont.begin()); |
| + |
| + result = cont.emplace(2, 3.5); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(std::next(cont.begin()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(Emplaceable(2, 3.5), *result.first); |
| + |
| + result = cont.emplace(2, 3.5); |
| + EXPECT_FALSE(result.second); |
| + EXPECT_EQ(std::next(cont.begin()), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(Emplaceable(2, 3.5), *result.first); |
| + } |
| + { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont; |
| + std::pair<Set::iterator, bool> result = cont.emplace(2); |
| + EXPECT_TRUE(result.second); |
| + EXPECT_EQ(cont.begin(), result.first); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result.first); |
| + } |
| +} |
| + |
| +// template <class... Args> |
| +// iterator emplace_hint(const_iterator position, Args&&... args); |
| + |
| +TEST(FlatSet, EmplaceHint) { |
| + { |
| + using Set = base::flat_set<Emplaceable>; |
| + |
| + Set cont; |
| + Set::iterator result = cont.emplace_hint(cont.cend()); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(Emplaceable(), *cont.begin()); |
| + |
| + result = cont.emplace_hint(cont.cend(), 2, 3.5); |
| + EXPECT_EQ(std::next(cont.begin()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(Emplaceable(2, 3.5), *result); |
| + |
| + result = cont.emplace_hint(cont.cbegin(), 2, 3.5); |
| + EXPECT_EQ(std::next(cont.begin()), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(2), cont.size()); |
| + EXPECT_EQ(Emplaceable(2, 3.5), *result); |
| + } |
| + { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont; |
| + Set::iterator result = cont.emplace_hint(cont.cend(), 2); |
| + EXPECT_EQ(cont.begin(), result); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.size()); |
| + EXPECT_EQ(2, *result); |
| + } |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Erase operations. |
| + |
| +// iterator erase(const_iterator position); |
| + |
| +TEST(FlatSet, EraseCIter) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 7, 8}; |
| + |
| + Set::iterator it = cont.erase(std::next(cont.cbegin(), 3)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), it); |
| + ExpectRange(cont, {1, 2, 3, 5, 6, 7, 8}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 0)); |
| + EXPECT_EQ(cont.begin(), it); |
| + ExpectRange(cont, {2, 3, 5, 6, 7, 8}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 5)); |
| + EXPECT_EQ(cont.end(), it); |
| + ExpectRange(cont, {2, 3, 5, 6, 7}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 1)); |
| + EXPECT_EQ(std::next(cont.begin()), it); |
| + ExpectRange(cont, {2, 5, 6, 7}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 2)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), it); |
| + ExpectRange(cont, {2, 5, 7}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 2)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), it); |
| + ExpectRange(cont, {2, 5}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 0)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), it); |
| + ExpectRange(cont, {5}); |
| + |
| + it = cont.erase(cont.cbegin()); |
| + EXPECT_EQ(cont.begin(), it); |
| + EXPECT_EQ(cont.end(), it); |
| +} |
| + |
| +// iterator erase(const_iterator first, const_iterator last); |
| + |
| +TEST(FlatSet, EraseCIterCIter) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 7, 8}; |
| + |
| + Set::iterator it = |
| + cont.erase(std::next(cont.cbegin(), 5), std::next(cont.cbegin(), 5)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), it); |
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 7, 8}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 3), std::next(cont.cbegin(), 4)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), it); |
| + ExpectRange(cont, {1, 2, 3, 5, 6, 7, 8}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 2), std::next(cont.cbegin(), 5)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), it); |
| + ExpectRange(cont, {1, 2, 7, 8}); |
| + |
| + it = cont.erase(std::next(cont.cbegin(), 0), std::next(cont.cbegin(), 2)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), it); |
| + ExpectRange(cont, {7, 8}); |
| + |
| + it = cont.erase(cont.cbegin(), cont.cend()); |
| + EXPECT_EQ(cont.begin(), it); |
| + EXPECT_EQ(cont.end(), it); |
| +} |
| + |
| +// size_type erase(const key_type& k); |
| + |
| +TEST(FlatSet, EraseKey) { |
| + using Set = base::flat_set<int>; |
| + |
| + Set cont{1, 2, 3, 4, 5, 6, 7, 8}; |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.erase(9)); |
| + ExpectRange(cont, {1, 2, 3, 4, 5, 6, 7, 8}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(4)); |
| + ExpectRange(cont, {1, 2, 3, 5, 6, 7, 8}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(1)); |
| + ExpectRange(cont, {2, 3, 5, 6, 7, 8}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(8)); |
| + ExpectRange(cont, {2, 3, 5, 6, 7}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(3)); |
| + ExpectRange(cont, {2, 5, 6, 7}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(6)); |
| + ExpectRange(cont, {2, 5, 7}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(7)); |
| + ExpectRange(cont, {2, 5}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(2)); |
| + ExpectRange(cont, {5}); |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.erase(5)); |
| + ExpectRange(cont, {}); |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Comparators. |
| + |
| +// key_compare key_comp() const |
| + |
| +TEST(FlatSet, KeyComp) { |
| + using Set = base::flat_set<int, std::greater<int>>; |
| + |
| + Set cont{1, 2, 3, 4, 5}; |
| + |
| + EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.key_comp())); |
| + cont.insert({6, 7, 8, 9, 10}); |
| + EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.key_comp())); |
| +} |
| + |
| +// value_compare value_comp() const |
| + |
| +TEST(FlatSet, ValueComp) { |
| + using Set = base::flat_set<int, std::greater<int>>; |
| + |
| + Set cont{1, 2, 3, 4, 5}; |
| + |
| + EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.value_comp())); |
| + cont.insert({6, 7, 8, 9, 10}); |
| + EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.value_comp())); |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// Binary search operations. |
| + |
| +// size_type count(const key_type& k) const; |
| + |
| +TEST(FlatSet, Count) { |
| + { |
| + using Set = base::flat_set<int>; |
| + |
| + const Set cont{5, 6, 7, 8, 9, 10, 11, 12}; |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(5)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(6)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(7)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(8)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(9)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(10)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(11)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(12)); |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.count(4)); |
| + } |
| + { |
| + using Set = base::flat_set<int, std::less<int>>; |
| + |
| + const Set cont{5, 6, 7, 8, 9, 10, 11, 12}; |
| + |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(5)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(6)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(7)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(8)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(9)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(10)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(11)); |
| + EXPECT_EQ(static_cast<Set::size_type>(1), cont.count(12)); |
| + EXPECT_EQ(static_cast<Set::size_type>(0), cont.count(4)); |
| + } |
| +} |
| + |
| +// iterator find(const key_type& k); |
| +// const_iterator find(const key_type& k) const; |
| + |
| +TEST(FlatSet, Find) { |
| + { |
| + using Set = base::flat_set<int>; |
| + { |
| + Set cont{5, 6, 7, 8, 9, 10, 11, 12}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.find(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.find(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.find(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.find(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.find(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.find(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.find(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.find(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.find(4)); |
| + } |
| + { |
| + const Set cont{5, 6, 7, 8, 9, 10, 11, 12}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.find(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.find(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.find(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.find(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.find(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.find(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.find(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.find(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.find(4)); |
| + } |
| + } |
| + { |
| + using Set = base::flat_set<int, std::less<int>>; |
| + |
| + Set cont{5, 6, 7, 8, 9, 10, 11, 12}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.find(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.find(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.find(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.find(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.find(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.find(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.find(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.find(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.find(4)); |
| + } |
| +} |
| + |
| +// pair<iterator,iterator> equal_range(const key_type& k); |
| +// pair<const_iterator,const_iterator> equal_range(const key_type& k) const; |
| + |
| +TEST(FlatSet, EqualRange) { |
| + { |
| + using Set = base::flat_set<int>; |
| + { |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + std::pair<Set::iterator, Set::iterator> result = cont.equal_range(5); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(7); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(9); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(11); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(13); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(15); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(17); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(19); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + result = cont.equal_range(4); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.second); |
| + result = cont.equal_range(6); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(8); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(10); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(12); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(14); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(16); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(18); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(20); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + } |
| + { |
| + const Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + std::pair<Set::const_iterator, Set::const_iterator> result = |
| + cont.equal_range(5); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(7); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(9); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(11); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(13); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(15); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(17); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(19); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + result = cont.equal_range(4); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.second); |
| + result = cont.equal_range(6); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(8); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(10); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(12); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(14); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(16); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(18); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(20); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + } |
| + } |
| + |
| + { |
| + using Set = base::flat_set<int, std::less<int>>; |
| + |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + std::pair<Set::iterator, Set::iterator> result = cont.equal_range(5); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(7); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(9); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(11); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(13); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(15); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(17); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(19); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + result = cont.equal_range(4); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 0), result.second); |
| + result = cont.equal_range(6); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 1), result.second); |
| + result = cont.equal_range(8); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 2), result.second); |
| + result = cont.equal_range(10); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 3), result.second); |
| + result = cont.equal_range(12); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 4), result.second); |
| + result = cont.equal_range(14); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 5), result.second); |
| + result = cont.equal_range(16); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 6), result.second); |
| + result = cont.equal_range(18); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 7), result.second); |
| + result = cont.equal_range(20); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.first); |
| + EXPECT_EQ(std::next(cont.begin(), 8), result.second); |
| + } |
| +} |
| + |
| +// iterator lower_bound(const key_type& k); |
| +// const_iterator lower_bound(const key_type& k) const; |
| + |
| +TEST(FlatSet, LowerBound) { |
| + { |
| + using Set = base::flat_set<int>; |
| + { |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.lower_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.lower_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.lower_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.lower_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.lower_bound(20)); |
| + } |
| + { |
| + const Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.lower_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.lower_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.lower_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.lower_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.lower_bound(20)); |
| + } |
| + } |
| + { |
| + using Set = base::flat_set<int, std::less<int>>; |
| + |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(cont.begin(), cont.lower_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin()), cont.lower_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.lower_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.lower_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.lower_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.lower_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.lower_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.lower_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.lower_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.lower_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.lower_bound(20)); |
| + } |
| +} |
| + |
| +// iterator upper_bound(const key_type& k); |
| +// const_iterator upper_bound(const key_type& k) const; |
| + |
| +TEST(FlatSet, UpperBound) { |
| + { |
| + using Set = base::flat_set<int>; |
| + { |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.upper_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(20)); |
| + } |
| + { |
| + const Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.upper_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(20)); |
| + } |
| + } |
| + { |
| + using Set = base::flat_set<int, std::less<int>>; |
| + |
| + Set cont{5, 7, 9, 11, 13, 15, 17, 19}; |
| + |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(5)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(7)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(9)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(11)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(13)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(15)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(17)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(19)); |
| + EXPECT_EQ(std::next(cont.begin(), 0), cont.upper_bound(4)); |
| + EXPECT_EQ(std::next(cont.begin(), 1), cont.upper_bound(6)); |
| + EXPECT_EQ(std::next(cont.begin(), 2), cont.upper_bound(8)); |
| + EXPECT_EQ(std::next(cont.begin(), 3), cont.upper_bound(10)); |
| + EXPECT_EQ(std::next(cont.begin(), 4), cont.upper_bound(12)); |
| + EXPECT_EQ(std::next(cont.begin(), 5), cont.upper_bound(14)); |
| + EXPECT_EQ(std::next(cont.begin(), 6), cont.upper_bound(16)); |
| + EXPECT_EQ(std::next(cont.begin(), 7), cont.upper_bound(18)); |
| + EXPECT_EQ(std::next(cont.begin(), 8), cont.upper_bound(20)); |
| + } |
| +} |
| + |
| +// ---------------------------------------------------------------------------- |
| +// General operations. |
| + |
| +// void swap(flat_set& x) |
| +// void swap(flat_set& x, flat_set& y) |
| + |
| +TEST(FlatSetOurs, Swap) { |
| + using Set = base::flat_set<int>; |
| + Set x{1, 2, 3}; |
| + Set y{4}; |
| + swap(x, y); |
| + ExpectRange(x, {4}); |
| + ExpectRange(y, {1, 2, 3}); |
| + |
| + y.swap(x); |
| + ExpectRange(x, {1, 2, 3}); |
| + ExpectRange(y, {4}); |
| +} |
| + |
| +// bool operator==(const flat_set& x, const flat_set& y) |
| +// bool operator!=(const flat_set& x, const flat_set& y) |
| +// bool operator<(const flat_set& x, const flat_set& y) |
| +// bool operator>(const flat_set& x, const flat_set& y) |
| +// bool operator<=(const flat_set& x, const flat_set& y) |
| +// bool operator>=(const flat_set& x, const flat_set& y) |
| + |
| +TEST(FlatSet, Comparison) { |
| + // Provided comparator does not participate in comparison. |
| + using Cmp = std::greater<int>; |
| + using Set = base::flat_set<int, Cmp>; |
| + |
| + Set biggest{3}; |
| + Set smallest{1}; |
| + Set middle{1, 2}; |
| + |
| + EXPECT_EQ(biggest, biggest); |
| + EXPECT_NE(biggest, smallest); |
| + EXPECT_LT(smallest, middle); |
| + EXPECT_LE(smallest, middle); |
| + EXPECT_LE(middle, middle); |
| + EXPECT_GT(biggest, middle); |
| + EXPECT_GE(biggest, middle); |
| + EXPECT_GE(biggest, biggest); |
| +} |