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..5e49f4bb37a933eb567797b578cdd8c94d915105 |
--- /dev/null |
+++ b/base/containers/flat_set_unittest.cc |
@@ -0,0 +1,1764 @@ |
+// 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 modified and extended tests from libcpp for std::set. |
Peter Kasting
2016/12/16 08:09:08
You say "extended" here, but below you document on
dyaroshev
2016/12/18 22:27:23
Changed the description a bit. I think removed tes
|
+// They can be found here: |
+// https://github.com/llvm-mirror/libcxx/tree/master/test/std/containers/associative/set |
+// |
+// Removed 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 |
Peter Kasting
2016/12/16 08:09:08
Nit: No comma
dyaroshev
2016/12/18 22:27:24
Done.
|
+// patterns than std::sets and we do not consider them to be a part of the |
+// interface. |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+class MoveOnly { |
+ MoveOnly(const MoveOnly&); |
Peter Kasting
2016/12/16 08:09:07
Nit: As much as possible, declare private section
dyaroshev
2016/12/18 22:27:24
Done.
|
+ MoveOnly& operator=(const MoveOnly&); |
Peter Kasting
2016/12/16 08:09:07
Nit: Use DISALLOW_COPY_AND_ASSIGN to remove these.
dyaroshev
2016/12/18 22:27:24
Done.
|
+ |
+ int data_; |
+ |
+ public: |
+ MoveOnly(int data = 1) : data_(data) {} |
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; } |
Peter Kasting
2016/12/16 08:09:07
Nit: |rhs| may be a more idiomatic name than |x|.
dyaroshev
2016/12/18 22:27:23
Replied in other comment
|
+ MoveOnly& operator=(MoveOnly&& x) { |
+ data_ = x.data_; |
+ x.data_ = 0; |
Peter Kasting
2016/12/16 08:09:08
Why set x.data_ at all? So behavior failures will
dyaroshev
2016/12/18 22:27:23
We check that we don't leave moved out elements.
|
+ return *this; |
+ } |
+ |
+ int get() const { return data_; } |
Peter Kasting
2016/12/16 08:09:07
Nit: Accessors should be named like the underlying
dyaroshev
2016/12/18 22:27:23
Done.
|
+ |
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; } |
+ bool operator<(const MoveOnly& x) const { return data_ < x.data_; } |
+}; |
+ |
+template <class It, class ItTraits = It> |
+class input_iterator { |
+ typedef std::iterator_traits<ItTraits> Traits; |
+ It it_; |
+ |
+ template <class U, class T> |
+ friend class input_iterator; |
+ |
+ public: |
+ typedef std::input_iterator_tag iterator_category; |
+ typedef typename Traits::value_type value_type; |
+ typedef typename Traits::difference_type difference_type; |
+ typedef It pointer; |
+ typedef typename Traits::reference reference; |
+ |
+ It base() const { return it_; } |
+ |
+ input_iterator() : it_() {} |
+ explicit input_iterator(It it) : it_(it) {} |
+ template <class U, class T> |
+ input_iterator(const input_iterator<U, T>& u) : it_(u.it_) {} |
+ |
+ reference operator*() const { return *it_; } |
+ pointer operator->() const { return it_; } |
+ |
+ input_iterator& operator++() { |
+ ++it_; |
+ return *this; |
+ } |
+ input_iterator operator++(int) { |
+ input_iterator tmp(*this); |
+ ++(*this); |
+ return tmp; |
+ } |
+ |
+ friend bool operator==(const input_iterator& x, const input_iterator& y) { |
+ return x.it_ == y.it_; |
+ } |
+ friend bool operator!=(const input_iterator& x, const input_iterator& y) { |
+ return !(x == y); |
+ } |
+ |
+ template <class T> |
+ void operator,(T const&) = delete; |
Peter Kasting
2016/12/16 08:09:08
Why?
dyaroshev
2016/12/18 22:27:23
Copied from libc++. I think this is to avoid some
|
+}; |
+ |
+template <class T, class TV, class U, class UV> |
+inline bool operator==(const input_iterator<T, TV>& x, |
+ const input_iterator<U, UV>& y) { |
+ return x.base() == y.base(); |
+} |
+ |
+template <class T, class TV, class U, class UV> |
+inline bool operator!=(const input_iterator<T, TV>& x, |
+ const input_iterator<U, UV>& y) { |
+ return !(x == y); |
+} |
+ |
+class Emplaceable { |
+ Emplaceable(const Emplaceable&); |
+ Emplaceable& operator=(const Emplaceable&); |
+ |
+ int int_; |
+ double double_; |
+ |
+ public: |
+ Emplaceable() : int_(0), double_(0) {} |
+ Emplaceable(int i, double d) : int_(i), double_(d) {} |
+ Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) { |
+ x.int_ = 0; |
+ x.double_ = 0; |
+ } |
+ Emplaceable& operator=(Emplaceable&& x) { |
+ int_ = x.int_; |
+ x.int_ = 0; |
+ double_ = x.double_; |
+ x.double_ = 0; |
+ return *this; |
+ } |
+ |
+ bool operator==(const Emplaceable& x) const { |
+ return int_ == x.int_ && double_ == x.double_; |
+ } |
+ bool operator<(const Emplaceable& x) const { |
+ return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_); |
+ } |
+ |
+ int get() const { return int_; } |
+}; |
+ |
+class NonDefaultConstructibleCompare { |
+ public: |
+ NonDefaultConstructibleCompare(int) {} |
+ |
+ template <typename T> |
+ bool operator()(const T& lhs, const T& rhs) { |
+ return std::less<T>()(lhs, rhs); |
+ } |
+}; |
+ |
+} // namespace |
+ |
+// ---------------------------------------------------------------------------- |
+// Class: |
+ |
+// Check that base::flat_set and it's iterators can be instantiated with an |
Peter Kasting
2016/12/16 08:09:07
Nit: its
dyaroshev
2016/12/18 22:27:24
Done.
|
+// incomplete type. |
+ |
+TEST(FlatSet, IncompleteType) { |
+ struct A { |
+ typedef base::flat_set<A> Set; |
+ int data; |
+ Set m; |
+ Set::iterator it; |
+ Set::const_iterator cit; |
+ }; |
+ |
+ // libcpp tests define operator< for A, but clang is complaining that it's |
+ // unused |
Peter Kasting
2016/12/16 08:09:08
Nit: Not a complete sentence, too vague to be usef
dyaroshev
2016/12/18 22:27:23
It's just strange to declare a set of type without
|
+ |
+ A a; |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Types: |
+ |
+// class flat_set |
Peter Kasting
2016/12/16 08:09:08
Nit: No need to "// class flat_set" above all thes
dyaroshev
2016/12/18 22:27:23
Done.
|
+ |
+// // types: |
+// typedef Key key_type; |
+// typedef key_type value_type; |
+// typedef Compare key_compare; |
+// typedef key_compare value_compare; |
+// typedef Allocator allocator_type; |
+// typedef typename allocator_type::reference reference; |
+// typedef typename allocator_type::const_reference const_reference; |
+// typedef typename allocator_type::pointer pointer; |
+// typedef typename allocator_type::const_pointer const_pointer; |
+// typedef typename allocator_type::size_type size_type; |
+// typedef typename allocator_type::difference_type difference_type; |
+ |
+TEST(FlatSet, Types) { |
+ { |
Peter Kasting
2016/12/16 08:09:07
Nit: Avoid these {} blocks in tests except where y
dyaroshev
2016/12/18 22:27:24
Done.
|
+ typedef base::flat_set<int> C; |
Peter Kasting
2016/12/16 08:09:08
Nit: "using" type aliases seem slightly more reada
dyaroshev
2016/12/18 22:27:23
Done.
|
+ static_assert((std::is_same<C::key_type, int>::value), ""); |
+ static_assert((std::is_same<C::value_type, int>::value), ""); |
+ static_assert((std::is_same<C::key_compare, std::less<int>>::value), ""); |
+ static_assert((std::is_same<C::value_compare, std::less<int>>::value), ""); |
+ static_assert((std::is_same<C::allocator_type, std::allocator<int>>::value), |
+ ""); |
+ static_assert((std::is_same<C::reference, int&>::value), ""); |
dyaroshev
2016/12/15 16:10:59
Tests for reference/pointer etc are libc++ specifi
dyaroshev
2016/12/18 22:27:24
Done.
|
+ static_assert((std::is_same<C::const_reference, const int&>::value), ""); |
+ static_assert((std::is_same<C::pointer, int*>::value), ""); |
+ static_assert((std::is_same<C::const_pointer, const int*>::value), ""); |
+ static_assert((std::is_same<C::size_type, std::size_t>::value), ""); |
Peter Kasting
2016/12/16 08:09:07
Nit: For better or worse, Chromium code does not q
dyaroshev
2016/12/18 22:27:24
Done.
|
+ static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), |
+ ""); |
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Lifetime. |
+ |
+// class flat_set |
+ |
+// flat_set() |
+// flat_set(const Compare& comp, const Allocator& alloc = Allocator()) |
+// flat_set(const Allocator& alloc) |
+ |
+TEST(FlatSet, DefaultConstructor) { |
+ { |
+ typedef base::flat_set<int> M; |
+ |
+ M m; |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
Peter Kasting
2016/12/16 08:09:07
Nit: Say 0U instead of casting to size_type. (The
dyaroshev
2016/12/18 22:27:24
Done.
|
+ } |
+ |
+ { |
+ typedef base::flat_set<int, NonDefaultConstructibleCompare> M; |
+ |
+ M m{NonDefaultConstructibleCompare(0)}; |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// 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) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
+ |
+ M m(input_iterator<const V*>(ar), |
+ input_iterator<const V*>(ar + sizeof(ar) / sizeof(ar[0]))); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*m.begin(), 1); |
+ EXPECT_EQ(*next(m.begin()), 2); |
Peter Kasting
2016/12/16 08:09:08
Nit: Shouldn't this be std::next()? (many places)
dyaroshev
2016/12/18 22:27:24
Worked because of ADL lookup. Copied from libc++ t
|
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ } |
+ { |
+ typedef base::flat_set<int, NonDefaultConstructibleCompare> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
+ |
+ M m(input_iterator<const V*>(ar), |
+ input_iterator<const V*>(ar + sizeof(ar) / sizeof(ar[0])), |
+ NonDefaultConstructibleCompare(0)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*m.begin(), 1); |
+ EXPECT_EQ(*next(m.begin()), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// flat_set(const flat_set& x) |
+// flat_set(const flat_set& x, const Allocator& alloc) |
+ |
+TEST(FlatSet, CopyConstructor) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 2, 3, 4}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ M m2(m); |
+ |
+ EXPECT_EQ(m2.count(1), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(2), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(3), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(4), static_cast<M::size_type>(1)); |
Peter Kasting
2016/12/16 08:09:08
Nit: Here and a lot of places below it seems like
dyaroshev
2016/12/18 22:27:23
Done.
|
+ } |
+} |
+ |
+// class flat_set |
+ |
+// flat_set(flat_set&& x) |
+// flat_set(flat_set&& x, const Allocator& alloc) |
+ |
+TEST(FlatSet, MoveConstructor) { |
+ { |
+ typedef base::flat_set<MoveOnly> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 2, 3, 4}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ M m2(std::move(m)); |
+ |
+ EXPECT_EQ(m2.count(1), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(2), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(3), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(4), static_cast<M::size_type>(1)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// 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) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::value_type V; |
Peter Kasting
2016/12/16 08:09:07
Nit: Just use int directly, and don't bother with
dyaroshev
2016/12/18 22:27:24
Done.
|
+ |
+ M m{1, 2, 3, 4, 5, 6, 10, 8}; |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(distance(m.begin(), m.end()), |
Peter Kasting
2016/12/16 08:09:08
Nit: Shouldn't this be std::distance? (3 places)
dyaroshev
2016/12/18 22:27:24
Done.
|
+ static_cast<M::difference_type>(m.size())); |
Peter Kasting
2016/12/16 08:09:07
Nit: Use ptrdiff_t directly (many places)
dyaroshev
2016/12/18 22:27:24
I don't think that the standard guaranties this. A
Peter Kasting
2016/12/18 22:47:43
The standard doesn't, but your static_assertions a
|
+ M::const_iterator i = m.cbegin(); |
+ EXPECT_EQ(*i, V(1)); |
+ EXPECT_EQ(*++i, V(2)); |
+ EXPECT_EQ(*++i, V(3)); |
+ EXPECT_EQ(*++i, V(4)); |
+ EXPECT_EQ(*++i, V(5)); |
+ EXPECT_EQ(*++i, V(6)); |
+ EXPECT_EQ(*++i, V(8)); |
+ EXPECT_EQ(*++i, V(10)); |
+ } |
+ { |
+ typedef base::flat_set<int, NonDefaultConstructibleCompare> M; |
+ typedef M::value_type V; |
+ |
+ M m({1, 2, 3, 4, 5, 6, 10, 8}, NonDefaultConstructibleCompare(0)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(distance(m.begin(), m.end()), |
+ static_cast<M::difference_type>(m.size())); |
+ M::const_iterator i = m.cbegin(); |
+ EXPECT_EQ(*i, V(1)); |
+ EXPECT_EQ(*++i, V(2)); |
+ EXPECT_EQ(*++i, V(3)); |
+ EXPECT_EQ(*++i, V(4)); |
+ EXPECT_EQ(*++i, V(5)); |
+ EXPECT_EQ(*++i, V(6)); |
+ EXPECT_EQ(*++i, V(8)); |
+ EXPECT_EQ(*++i, V(10)); |
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Assignments. |
+ |
+// class flat_set |
+ |
+// flat_set& operator=(const flat_set& x) |
+ |
+TEST(FlatSet, CopyAssignable) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 2, 3, 4}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
Peter Kasting
2016/12/16 08:09:08
Nit: use arraysize(). (Multiple places)
dyaroshev
2016/12/18 22:27:23
Changed to using initiailizer lists and begin/end
|
+ M m2; |
+ m2 = m; |
+ |
+ EXPECT_EQ(m2.count(1), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(2), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(3), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(4), static_cast<M::size_type>(1)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// flat_set& operator=(flat_set&& x) |
+ |
+TEST(FlatSet, MoveAssignable) { |
+ { |
+ typedef base::flat_set<MoveOnly> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 2, 3, 4}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ M m2; |
+ m2 = std::move(m); |
+ |
+ EXPECT_EQ(m2.count(1), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(2), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(3), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(m2.count(4), static_cast<M::size_type>(1)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// flat_set& operator=(std::initializer_list<value_type> il) |
+ |
+TEST(FlatSet, InitializerListAssignable) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::value_type V; |
+ |
+ M m{0}; |
+ m = {1, 2, 3, 4, 5, 6, 10, 8}; |
+ |
+ EXPECT_EQ(m.count(0), static_cast<M::size_type>(0)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(distance(m.begin(), m.end()), |
+ static_cast<M::difference_type>(m.size())); |
+ M::const_iterator i = m.cbegin(); |
+ EXPECT_EQ(*i, V(1)); |
+ EXPECT_EQ(*++i, V(2)); |
+ EXPECT_EQ(*++i, V(3)); |
+ EXPECT_EQ(*++i, V(4)); |
+ EXPECT_EQ(*++i, V(5)); |
+ EXPECT_EQ(*++i, V(6)); |
+ EXPECT_EQ(*++i, V(8)); |
+ EXPECT_EQ(*++i, V(10)); |
+ } |
+} |
+ |
+// -------------------------------------------------------------------------- |
+// Memory management. |
+ |
+// class flat_set |
+ |
+// void reserve(size_type size) |
+ |
+TEST(FlatSet, Reserve) { |
+ { |
+ typedef base::flat_set<int> M; |
+ M m{1, 2, 3}; |
+ |
+ m.reserve(5); |
+ EXPECT_GE(m.capacity(), static_cast<M::size_type>(5)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// size_type capacity() const |
+ |
+TEST(FlatSet, Capacity) { |
+ { |
+ typedef base::flat_set<int> M; |
+ M m{1, 2, 3}; |
+ EXPECT_GE(m.capacity(), m.size()); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// void shrink_to_fit() |
+ |
+TEST(FlatSet, ShrinkToFit) { |
+ { |
+ typedef base::flat_set<int> M; |
+ M m{1, 2, 3}; |
+ |
+ M::size_type capacity_before = m.capacity(); |
+ m.shrink_to_fit(); |
+ EXPECT_GE(capacity_before, m.capacity()); |
Peter Kasting
2016/12/16 08:09:08
Maybe a stronger test would be to reserve() more s
dyaroshev
2016/12/18 22:27:23
I've checked against the spec: shrink_to_fit can d
Peter Kasting
2016/12/18 22:47:43
Wow. That seems unfortunate.
I would add an expl
|
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Size management. |
+ |
+// class flat_set |
+ |
+// void clear(); |
+ |
+TEST(FlatSet, Clear) { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 2, 3, 4, 5, 6, 7, 8}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ m.clear(); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+} |
+ |
+// class flat_set |
+ |
+// size_type size() const; |
+ |
+TEST(FlatSet, Size) { |
+ { |
+ typedef base::flat_set<int> M; |
+ M m; |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ m.insert(M::value_type(2)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ m.insert(M::value_type(1)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ m.insert(M::value_type(3)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ m.erase(m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ m.erase(m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ m.erase(m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// bool empty() const; |
+ |
+TEST(FlatSet, Empty) { |
+ typedef base::flat_set<int> M; |
+ M m; |
+ EXPECT_TRUE(m.empty()); |
+ m.insert(M::value_type(1)); |
+ EXPECT_FALSE(m.empty()); |
+ m.clear(); |
+ EXPECT_TRUE(m.empty()); |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Iterators. |
+ |
+// class flat_set |
+ |
+// 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) { |
+ { |
+ typedef int V; |
+ |
+ V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, |
+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8}; |
+ |
+ base::flat_set<int> m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(std::distance(m.begin(), m.end()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ EXPECT_EQ(std::distance(m.rbegin(), m.rend()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ base::flat_set<int>::iterator i; |
+ i = m.begin(); |
+ base::flat_set<int>::const_iterator k = i; |
+ EXPECT_EQ(i, k); |
+ for (int j = 1; static_cast<std::size_t>(j) <= m.size(); ++j, ++i) |
Peter Kasting
2016/12/16 08:09:08
Nit: What about:
for (int j = 1; i != m.end();
dyaroshev
2016/12/18 22:27:23
Done.
|
+ EXPECT_EQ(*i, j); |
+ } |
+ { |
+ typedef int V; |
+ |
+ V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, |
+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8}; |
+ |
+ const base::flat_set<int> m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(std::distance(m.begin(), m.end()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ EXPECT_EQ(std::distance(m.cbegin(), m.cend()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ EXPECT_EQ(std::distance(m.rbegin(), m.rend()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ EXPECT_EQ(std::distance(m.crbegin(), m.crend()), |
+ static_cast<base::flat_set<int>::difference_type>(m.size())); |
+ base::flat_set<int>::const_iterator i; |
+ i = m.begin(); |
+ for (int j = 1; static_cast<std::size_t>(j) <= m.size(); ++j, ++i) |
+ EXPECT_EQ(*i, j); |
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Insert/Erase operations. |
+ |
+// class flat_set |
+ |
+// pair<iterator, bool> insert(const value_type& v); |
+ |
+TEST(FlatSet, InsertCV) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::value_type V; |
+ typedef std::pair<M::iterator, bool> R; |
+ |
+ M m; |
+ V v(2); |
+ R r = m.insert(v); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r.first, 2); |
+ |
+ v = 1; |
+ r = m.insert(v); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r.first, 1); |
+ |
+ v = 3; |
+ r = m.insert(v); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r.first, 3); |
+ |
+ v = 3; |
+ r = m.insert(v); |
+ EXPECT_FALSE(r.second); |
+ EXPECT_EQ(r.first, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r.first, 3); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// pair<iterator, bool> insert(value_type&& v); |
+ |
+TEST(FlatSet, InsertRV) { |
+ { |
+ typedef base::flat_set<MoveOnly> M; |
+ typedef std::pair<M::iterator, bool> R; |
+ M m; |
+ R r = m.insert(M::value_type(2)); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r.first, 2); |
+ |
+ r = m.insert(M::value_type(1)); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r.first, 1); |
+ |
+ r = m.insert(M::value_type(3)); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r.first, 3); |
+ |
+ r = m.insert(M::value_type(3)); |
+ EXPECT_FALSE(r.second); |
+ EXPECT_EQ(r.first, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r.first, static_cast<M::size_type>(3)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator insert(const_iterator position, const value_type& v); |
+ |
+TEST(FlatSet, InsertIterCV) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::iterator R; |
+ M m; |
+ R r = m.insert(m.cend(), M::value_type(2)); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r, 2); |
+ |
+ r = m.insert(m.cend(), M::value_type(1)); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r, 1); |
+ |
+ r = m.insert(m.cend(), M::value_type(3)); |
+ EXPECT_EQ(r, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r, 3); |
+ |
+ r = m.insert(m.cend(), M::value_type(3)); |
+ EXPECT_EQ(r, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r, 3); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator insert(const_iterator position, value_type&& v); |
+ |
+TEST(FlatSet, InsertIterRV) { |
+ { |
+ typedef base::flat_set<MoveOnly> M; |
+ typedef M::iterator R; |
+ M m; |
+ R r = m.insert(m.cend(), M::value_type(2)); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r, 2); |
+ |
+ r = m.insert(m.cend(), M::value_type(1)); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r, 1); |
+ |
+ r = m.insert(m.cend(), M::value_type(3)); |
+ EXPECT_EQ(r, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r, 3); |
+ |
+ r = m.insert(m.cend(), M::value_type(3)); |
+ EXPECT_EQ(r, prev(m.end())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*r, 3); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// template <class InputIterator> |
+// void insert(InputIterator first, InputIterator last); |
+ |
+TEST(FlatSet, InsertRange) { |
dyaroshev
2016/12/15 16:10:59
Add tests for stability.
dyaroshev
2016/12/18 22:27:23
Done.
|
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ |
+ V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; |
+ |
+ M m; |
+ m.insert(input_iterator<const V*>(ar), |
+ input_iterator<const V*>(ar + sizeof(ar) / sizeof(ar[0]))); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(*m.begin(), 1); |
+ EXPECT_EQ(*next(m.begin()), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// void insert(initializer_list<value_type> il); |
+ |
+TEST(FlatSet, InsertInitializerList) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::value_type V; |
+ M m = {10, 8}; |
+ m.insert({1, 2, 3, 4, 5, 6}); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(distance(m.begin(), m.end()), |
+ static_cast<M::difference_type>(m.size())); |
+ M::const_iterator i = m.cbegin(); |
+ EXPECT_EQ(*i, V(1)); |
+ EXPECT_EQ(*++i, V(2)); |
+ EXPECT_EQ(*++i, V(3)); |
+ EXPECT_EQ(*++i, V(4)); |
+ EXPECT_EQ(*++i, V(5)); |
+ EXPECT_EQ(*++i, V(6)); |
+ EXPECT_EQ(*++i, V(8)); |
+ EXPECT_EQ(*++i, V(10)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// template <class... Args> |
+// pair<iterator, bool> emplace(Args&&... args); |
+ |
+TEST(FlatSet, Emplace) { |
+ { |
+ typedef base::flat_set<Emplaceable> M; |
+ typedef std::pair<M::iterator, bool> R; |
+ M m; |
+ R r = m.emplace(); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*m.begin(), Emplaceable()); |
+ r = m.emplace(2, 3.5); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, next(m.begin())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r.first, Emplaceable(2, 3.5)); |
+ r = m.emplace(2, 3.5); |
+ EXPECT_TRUE(!r.second); |
Peter Kasting
2016/12/16 08:09:08
Nit: EXPECT_FALSE(r.second)
dyaroshev
2016/12/18 22:27:24
Done.
|
+ EXPECT_EQ(r.first, next(m.begin())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r.first, Emplaceable(2, 3.5)); |
+ } |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef std::pair<M::iterator, bool> R; |
+ M m; |
+ R r = m.emplace(M::value_type(2)); |
+ EXPECT_TRUE(r.second); |
+ EXPECT_EQ(r.first, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r.first, 2); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// template <class... Args> |
+// iterator emplace_hint(const_iterator position, Args&&... args); |
+ |
+TEST(FlatSet, EmplaceHint) { |
+ { |
+ typedef base::flat_set<Emplaceable> M; |
+ typedef M::iterator R; |
+ M m; |
+ R r = m.emplace_hint(m.cend()); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*m.begin(), Emplaceable()); |
+ r = m.emplace_hint(m.cend(), 2, 3.5); |
+ EXPECT_EQ(r, next(m.begin())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r, Emplaceable(2, 3.5)); |
+ r = m.emplace_hint(m.cbegin(), 2, 3.5); |
+ EXPECT_EQ(r, next(m.begin())); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(*r, Emplaceable(2, 3.5)); |
+ } |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef M::iterator R; |
+ M m; |
+ R r = m.emplace_hint(m.cend(), M::value_type(2)); |
+ EXPECT_EQ(r, m.begin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*r, 2); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator erase(const_iterator position); |
+ |
+TEST(FlatSet, EraseCIter) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ typedef M::iterator I; |
+ |
+ V ar[] = {1, 2, 3, 4, 5, 6, 7, 8}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ I i = m.erase(next(m.cbegin(), 3)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(7)); |
+ EXPECT_EQ(i, next(m.begin(), 3)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ EXPECT_EQ(*next(m.begin(), 3), 5); |
+ EXPECT_EQ(*next(m.begin(), 4), 6); |
+ EXPECT_EQ(*next(m.begin(), 5), 7); |
+ EXPECT_EQ(*next(m.begin(), 6), 8); |
+ |
+ i = m.erase(next(m.cbegin(), 0)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(6)); |
+ EXPECT_EQ(i, m.begin()); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 3); |
+ EXPECT_EQ(*next(m.begin(), 2), 5); |
+ EXPECT_EQ(*next(m.begin(), 3), 6); |
+ EXPECT_EQ(*next(m.begin(), 4), 7); |
+ EXPECT_EQ(*next(m.begin(), 5), 8); |
+ |
+ i = m.erase(next(m.cbegin(), 5)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(5)); |
+ EXPECT_EQ(i, m.end()); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 3); |
+ EXPECT_EQ(*next(m.begin(), 2), 5); |
+ EXPECT_EQ(*next(m.begin(), 3), 6); |
+ EXPECT_EQ(*next(m.begin(), 4), 7); |
+ |
+ i = m.erase(next(m.cbegin(), 1)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(4)); |
+ EXPECT_EQ(i, next(m.begin())); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ EXPECT_EQ(*next(m.begin(), 2), 6); |
+ EXPECT_EQ(*next(m.begin(), 3), 7); |
+ |
+ i = m.erase(next(m.cbegin(), 2)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(i, next(m.begin(), 2)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ EXPECT_EQ(*next(m.begin(), 2), 7); |
+ |
+ i = m.erase(next(m.cbegin(), 2)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(i, next(m.begin(), 2)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ |
+ i = m.erase(next(m.cbegin(), 0)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(i, next(m.begin(), 0)); |
+ EXPECT_EQ(*next(m.begin(), 0), 5); |
+ |
+ i = m.erase(m.cbegin()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ EXPECT_EQ(i, m.begin()); |
+ EXPECT_EQ(i, m.end()); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator erase(const_iterator first, const_iterator last); |
+ |
+TEST(FlatSet, EraseCIterCIter) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ typedef M::iterator I; |
+ |
+ V ar[] = {1, 2, 3, 4, 5, 6, 7, 8}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ I i = m.erase(next(m.cbegin(), 5), next(m.cbegin(), 5)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(i, next(m.begin(), 5)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ EXPECT_EQ(*next(m.begin(), 3), 4); |
+ EXPECT_EQ(*next(m.begin(), 4), 5); |
+ EXPECT_EQ(*next(m.begin(), 5), 6); |
+ EXPECT_EQ(*next(m.begin(), 6), 7); |
+ EXPECT_EQ(*next(m.begin(), 7), 8); |
+ |
+ i = m.erase(next(m.cbegin(), 3), next(m.cbegin(), 4)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(7)); |
+ EXPECT_EQ(i, next(m.begin(), 3)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ EXPECT_EQ(*next(m.begin(), 3), 5); |
+ EXPECT_EQ(*next(m.begin(), 4), 6); |
+ EXPECT_EQ(*next(m.begin(), 5), 7); |
+ EXPECT_EQ(*next(m.begin(), 6), 8); |
+ |
+ i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 5)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(4)); |
+ EXPECT_EQ(i, next(m.begin(), 2)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 7); |
+ EXPECT_EQ(*next(m.begin(), 3), 8); |
+ |
+ i = m.erase(next(m.cbegin(), 0), next(m.cbegin(), 2)); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(i, next(m.begin(), 0)); |
+ EXPECT_EQ(*next(m.begin(), 0), 7); |
+ EXPECT_EQ(*next(m.begin(), 1), 8); |
+ |
+ i = m.erase(m.cbegin(), m.cend()); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ EXPECT_EQ(i, m.end()); |
+ } |
+} |
+ |
+// class set |
+ |
+// size_type erase(const key_type& k); |
+ |
+TEST(FlatSet, EraseKey) { |
+ { |
+ typedef base::flat_set<int> M; |
+ typedef int V; |
+ typedef M::size_type I; |
+ |
+ V ar[] = {1, 2, 3, 4, 5, 6, 7, 8}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ I i = m.erase(9); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(8)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(0)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ EXPECT_EQ(*next(m.begin(), 3), 4); |
+ EXPECT_EQ(*next(m.begin(), 4), 5); |
+ EXPECT_EQ(*next(m.begin(), 5), 6); |
+ EXPECT_EQ(*next(m.begin(), 6), 7); |
+ EXPECT_EQ(*next(m.begin(), 7), 8); |
+ |
+ i = m.erase(4); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(7)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 1); |
+ EXPECT_EQ(*next(m.begin(), 1), 2); |
+ EXPECT_EQ(*next(m.begin(), 2), 3); |
+ EXPECT_EQ(*next(m.begin(), 3), 5); |
+ EXPECT_EQ(*next(m.begin(), 4), 6); |
+ EXPECT_EQ(*next(m.begin(), 5), 7); |
+ EXPECT_EQ(*next(m.begin(), 6), 8); |
+ |
+ i = m.erase(1); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(6)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 3); |
+ EXPECT_EQ(*next(m.begin(), 2), 5); |
+ EXPECT_EQ(*next(m.begin(), 3), 6); |
+ EXPECT_EQ(*next(m.begin(), 4), 7); |
+ EXPECT_EQ(*next(m.begin(), 5), 8); |
+ |
+ i = m.erase(8); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(5)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 3); |
+ EXPECT_EQ(*next(m.begin(), 2), 5); |
+ EXPECT_EQ(*next(m.begin(), 3), 6); |
+ EXPECT_EQ(*next(m.begin(), 4), 7); |
+ |
+ i = m.erase(3); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(4)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ EXPECT_EQ(*next(m.begin(), 2), 6); |
+ EXPECT_EQ(*next(m.begin(), 3), 7); |
+ |
+ i = m.erase(6); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(3)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ EXPECT_EQ(*next(m.begin(), 2), 7); |
+ |
+ i = m.erase(7); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(2)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 2); |
+ EXPECT_EQ(*next(m.begin(), 1), 5); |
+ |
+ i = m.erase(2); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(1)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ EXPECT_EQ(*next(m.begin(), 0), 5); |
+ |
+ i = m.erase(5); |
+ EXPECT_EQ(m.size(), static_cast<M::size_type>(0)); |
+ EXPECT_EQ(i, static_cast<M::size_type>(1)); |
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Comparators. |
dyaroshev
2016/12/15 16:10:59
Add test that flat_set is sorted with provided com
dyaroshev
2016/12/18 22:27:24
Done.
|
+ |
+// ---------------------------------------------------------------------------- |
+// Binary search operations. |
+ |
+// class flat_set |
+ |
+// size_type count(const key_type& k) const; |
+ |
+TEST(FlatSet, Count) { |
+ { |
+ typedef int V; |
+ typedef base::flat_set<int> M; |
+ typedef M::size_type R; |
+ |
+ V ar[] = {5, 6, 7, 8, 9, 10, 11, 12}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.count(5); |
Peter Kasting
2016/12/16 08:09:07
Nit: Avoid unneeded temps, e.g.
EXPECT_EQ(1U, m
dyaroshev
2016/12/18 22:27:25
Done, where seemed appropriate.
|
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(6); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(7); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(8); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(9); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(10); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(11); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(12); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(4); |
+ EXPECT_EQ(r, static_cast<M::size_type>(0)); |
+ } |
+ { |
+ typedef int V; |
+ typedef base::flat_set<int, std::less<V>> M; |
+ typedef M::size_type R; |
+ |
+ V ar[] = {5, 6, 7, 8, 9, 10, 11, 12}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.count(5); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(6); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(7); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(8); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(9); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(10); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(11); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(12); |
+ EXPECT_EQ(r, static_cast<M::size_type>(1)); |
+ r = m.count(4); |
+ EXPECT_EQ(r, static_cast<M::size_type>(0)); |
+ } |
+} |
+ |
+// class set |
+ |
+// iterator find(const key_type& k); |
+// const_iterator find(const key_type& k) const; |
+ |
+TEST(FlatSet, Find) { |
+ { |
+ typedef int V; |
+ typedef base::flat_set<V> M; |
+ { |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 6, 7, 8, 9, 10, 11, 12}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.find(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.find(6); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.find(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.find(8); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.find(9); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.find(10); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.find(11); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.find(12); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.find(4); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ { |
+ typedef M::const_iterator R; |
+ |
+ V ar[] = {5, 6, 7, 8, 9, 10, 11, 12}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.find(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.find(6); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.find(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.find(8); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.find(9); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.find(10); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.find(11); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.find(12); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.find(4); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ } |
+ { |
+ typedef int V; |
+ typedef base::flat_set<V, std::less<V>> M; |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 6, 7, 8, 9, 10, 11, 12}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.find(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.find(6); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.find(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.find(8); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.find(9); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.find(10); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.find(11); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.find(12); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.find(4); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// pair<iterator,iterator> equal_range(const key_type& k); |
+// pair<const_iterator,const_iterator> equal_range(const key_type& k) const; |
+ |
+TEST(FlatSet, EqualRange) { |
+ { |
+ typedef int V; |
+ typedef base::flat_set<int> M; |
+ { |
+ typedef std::pair<M::iterator, M::iterator> R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.equal_range(5); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(7); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(9); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(11); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(13); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(15); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(17); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(19); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ r = m.equal_range(4); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 0)); |
+ r = m.equal_range(6); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(8); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(10); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(12); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(14); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(16); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(18); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(20); |
+ EXPECT_EQ(r.first, next(m.begin(), 8)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ } |
+ { |
+ typedef std::pair<M::const_iterator, M::const_iterator> R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.equal_range(5); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(7); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(9); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(11); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(13); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(15); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(17); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(19); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ r = m.equal_range(4); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 0)); |
+ r = m.equal_range(6); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(8); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(10); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(12); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(14); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(16); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(18); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(20); |
+ EXPECT_EQ(r.first, next(m.begin(), 8)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ } |
+ } |
+ |
+ { |
+ typedef int V; |
+ typedef base::flat_set<V, std::less<V>> M; |
+ { |
+ typedef std::pair<M::iterator, M::iterator> R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.equal_range(5); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(7); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(9); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(11); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(13); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(15); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(17); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(19); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ r = m.equal_range(4); |
+ EXPECT_EQ(r.first, next(m.begin(), 0)); |
+ EXPECT_EQ(r.second, next(m.begin(), 0)); |
+ r = m.equal_range(6); |
+ EXPECT_EQ(r.first, next(m.begin(), 1)); |
+ EXPECT_EQ(r.second, next(m.begin(), 1)); |
+ r = m.equal_range(8); |
+ EXPECT_EQ(r.first, next(m.begin(), 2)); |
+ EXPECT_EQ(r.second, next(m.begin(), 2)); |
+ r = m.equal_range(10); |
+ EXPECT_EQ(r.first, next(m.begin(), 3)); |
+ EXPECT_EQ(r.second, next(m.begin(), 3)); |
+ r = m.equal_range(12); |
+ EXPECT_EQ(r.first, next(m.begin(), 4)); |
+ EXPECT_EQ(r.second, next(m.begin(), 4)); |
+ r = m.equal_range(14); |
+ EXPECT_EQ(r.first, next(m.begin(), 5)); |
+ EXPECT_EQ(r.second, next(m.begin(), 5)); |
+ r = m.equal_range(16); |
+ EXPECT_EQ(r.first, next(m.begin(), 6)); |
+ EXPECT_EQ(r.second, next(m.begin(), 6)); |
+ r = m.equal_range(18); |
+ EXPECT_EQ(r.first, next(m.begin(), 7)); |
+ EXPECT_EQ(r.second, next(m.begin(), 7)); |
+ r = m.equal_range(20); |
+ EXPECT_EQ(r.first, next(m.begin(), 8)); |
+ EXPECT_EQ(r.second, next(m.begin(), 8)); |
+ } |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator lower_bound(const key_type& k); |
+// const_iterator lower_bound(const key_type& k) const; |
+ |
+TEST(FlatSet, LowerBound) { |
+ { |
+ typedef int V; |
+ typedef base::flat_set<int> M; |
+ { |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.lower_bound(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.lower_bound(7); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.lower_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.lower_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.lower_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ { |
+ typedef M::const_iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.lower_bound(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.lower_bound(7); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.lower_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.lower_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.lower_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ } |
+ { |
+ typedef int V; |
+ typedef base::flat_set<V, std::less<V>> M; |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.lower_bound(5); |
+ EXPECT_EQ(r, m.begin()); |
+ r = m.lower_bound(7); |
+ EXPECT_EQ(r, next(m.begin())); |
+ r = m.lower_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.lower_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.lower_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.lower_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.lower_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.lower_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.lower_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.lower_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.lower_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+} |
+ |
+// class flat_set |
+ |
+// iterator upper_bound(const key_type& k); |
+// const_iterator upper_bound(const key_type& k) const; |
+ |
+TEST(FlatSet, UpperBound) { |
+ { |
+ typedef int V; |
+ typedef base::flat_set<int> M; |
+ { |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.upper_bound(5); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ r = m.upper_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.upper_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ { |
+ typedef M::const_iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ const M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.upper_bound(5); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ r = m.upper_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.upper_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+ } |
+ { |
+ typedef int V; |
+ typedef base::flat_set<V, std::less<V>> M; |
+ typedef M::iterator R; |
+ |
+ V ar[] = {5, 7, 9, 11, 13, 15, 17, 19}; |
+ |
+ M m(ar, ar + sizeof(ar) / sizeof(ar[0])); |
+ R r = m.upper_bound(5); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(7); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(9); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(11); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(13); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(15); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(17); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(19); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ r = m.upper_bound(4); |
+ EXPECT_EQ(r, next(m.begin(), 0)); |
+ r = m.upper_bound(6); |
+ EXPECT_EQ(r, next(m.begin(), 1)); |
+ r = m.upper_bound(8); |
+ EXPECT_EQ(r, next(m.begin(), 2)); |
+ r = m.upper_bound(10); |
+ EXPECT_EQ(r, next(m.begin(), 3)); |
+ r = m.upper_bound(12); |
+ EXPECT_EQ(r, next(m.begin(), 4)); |
+ r = m.upper_bound(14); |
+ EXPECT_EQ(r, next(m.begin(), 5)); |
+ r = m.upper_bound(16); |
+ EXPECT_EQ(r, next(m.begin(), 6)); |
+ r = m.upper_bound(18); |
+ EXPECT_EQ(r, next(m.begin(), 7)); |
+ r = m.upper_bound(20); |
+ EXPECT_EQ(r, next(m.begin(), 8)); |
+ } |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Regular type operations |
+ |
+// class flat_set |
+ |
+// void swap(flat_set& x) |
+// void swap(flat_set& x, flat_set& y) |
+ |
+TEST(FlatSetOurs, Swap) { |
+ using M = base::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 works too; |
+} |
+ |
+// class flat_set |
+ |
+// 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) { |
+ using M = base::flat_set<int>; |
+ M biggest{3}; |
+ M smallest{1}; |
+ M 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); |
+} |