| Index: base/containers/flat_set_libcpp_unittest.cc
|
| diff --git a/base/containers/flat_set_libcpp_unittest.cc b/base/containers/flat_set_libcpp_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..766dd9d06f2824382830d4993c80694ae434e1b9
|
| --- /dev/null
|
| +++ b/base/containers/flat_set_libcpp_unittest.cc
|
| @@ -0,0 +1,1686 @@
|
| +// 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 tests from libc++ for std::set.
|
| +// 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 implentation 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 manipualte these nodes. Flat containers store their elements in
|
| +// contigious memory and move them around, type is required to be movable.
|
| +// * No tests for N3644.
|
| +// This proposal suggests that all defaul 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
|
| +// castomise 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 "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace base {
|
| +
|
| +namespace {
|
| +
|
| +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 MoveOnly {
|
| + MoveOnly(const MoveOnly&);
|
| + MoveOnly& operator=(const MoveOnly&);
|
| +
|
| + int data_;
|
| +
|
| + 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;
|
| + }
|
| +
|
| + int get() const { return data_; }
|
| +
|
| + 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;
|
| +};
|
| +
|
| +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);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// class flat_set
|
| +
|
| +// void clear();
|
| +
|
| +TEST(FlatSet, Clear) {
|
| + typedef base::flat_set<int> M;
|
| + typedef int V;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 1,
|
| + 2,
|
| + 3,
|
| + 4,
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(m.size() == 8);
|
| + m.clear();
|
| + ASSERT_TRUE(m.size() == 0);
|
| +}
|
| +
|
| +// 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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8,
|
| + 9,
|
| + 10,
|
| + 11,
|
| + 12
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.count(5);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(6);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(7);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(8);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(9);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(10);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(11);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(12);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(4);
|
| + ASSERT_TRUE(r == 0);
|
| + }
|
| + {
|
| + typedef int V;
|
| + typedef base::flat_set<int, std::less<V>> M;
|
| + typedef M::size_type R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8,
|
| + 9,
|
| + 10,
|
| + 11,
|
| + 12
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.count(5);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(6);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(7);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(8);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(9);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(10);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(11);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(12);
|
| + ASSERT_TRUE(r == 1);
|
| + r = m.count(4);
|
| + ASSERT_TRUE(r == 0);
|
| + }
|
| +}
|
| +
|
| +// 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();
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*m.begin() == Emplaceable());
|
| + r = m.emplace(2, 3.5);
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == next(m.begin()));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r.first == Emplaceable(2, 3.5));
|
| + r = m.emplace(2, 3.5);
|
| + ASSERT_TRUE(!r.second);
|
| + ASSERT_TRUE(r.first == next(m.begin()));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*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));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*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());
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*m.begin() == Emplaceable());
|
| + r = m.emplace_hint(m.cend(), 2, 3.5);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r == Emplaceable(2, 3.5));
|
| + r = m.emplace_hint(m.cbegin(), 2, 3.5);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*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));
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*r == 2);
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// bool empty() const;
|
| +
|
| +TEST(FlatSet, Empty) {
|
| + typedef base::flat_set<int> M;
|
| + M m;
|
| + ASSERT_TRUE(m.empty());
|
| + m.insert(M::value_type(1));
|
| + ASSERT_TRUE(!m.empty());
|
| + m.clear();
|
| + ASSERT_TRUE(m.empty());
|
| +}
|
| +
|
| +// 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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.equal_range(5);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(7);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(9);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(11);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(13);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(15);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(17);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(19);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 8));
|
| + r = m.equal_range(4);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 0));
|
| + r = m.equal_range(6);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(8);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(10);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(12);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(14);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(16);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(18);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(20);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 8));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 8));
|
| + }
|
| + {
|
| + typedef std::pair<M::const_iterator, M::const_iterator> R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.equal_range(5);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(7);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(9);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(11);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(13);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(15);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(17);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(19);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 8));
|
| + r = m.equal_range(4);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 0));
|
| + r = m.equal_range(6);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(8);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(10);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(12);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(14);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(16);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(18);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(20);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 8));
|
| + ASSERT_TRUE(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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.equal_range(5);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(7);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(9);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(11);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(13);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(15);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(17);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(19);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 8));
|
| + r = m.equal_range(4);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 0));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 0));
|
| + r = m.equal_range(6);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 1));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 1));
|
| + r = m.equal_range(8);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 2));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 2));
|
| + r = m.equal_range(10);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 3));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 3));
|
| + r = m.equal_range(12);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 4));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 4));
|
| + r = m.equal_range(14);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 5));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 5));
|
| + r = m.equal_range(16);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 6));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 6));
|
| + r = m.equal_range(18);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 7));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 7));
|
| + r = m.equal_range(20);
|
| + ASSERT_TRUE(r.first == next(m.begin(), 8));
|
| + ASSERT_TRUE(r.second == next(m.begin(), 8));
|
| + }
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// iterator erase(const_iterator position);
|
| +
|
| +TEST(FlatSet, EraseCIter) {
|
| + {
|
| + typedef base::flat_set<int> M;
|
| + typedef int V;
|
| + typedef M::iterator I;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 1,
|
| + 2,
|
| + 3,
|
| + 4,
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(m.size() == 8);
|
| + I i = m.erase(next(m.cbegin(), 3));
|
| + ASSERT_TRUE(m.size() == 7);
|
| + ASSERT_TRUE(i == next(m.begin(), 3));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 6) == 8);
|
| +
|
| + i = m.erase(next(m.cbegin(), 0));
|
| + ASSERT_TRUE(m.size() == 6);
|
| + ASSERT_TRUE(i == m.begin());
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 8);
|
| +
|
| + i = m.erase(next(m.cbegin(), 5));
|
| + ASSERT_TRUE(m.size() == 5);
|
| + ASSERT_TRUE(i == m.end());
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 7);
|
| +
|
| + i = m.erase(next(m.cbegin(), 1));
|
| + ASSERT_TRUE(m.size() == 4);
|
| + ASSERT_TRUE(i == next(m.begin()));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 7);
|
| +
|
| + i = m.erase(next(m.cbegin(), 2));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(i == next(m.begin(), 2));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 7);
|
| +
|
| + i = m.erase(next(m.cbegin(), 2));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(i == next(m.begin(), 2));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| +
|
| + i = m.erase(next(m.cbegin(), 0));
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(i == next(m.begin(), 0));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 5);
|
| +
|
| + i = m.erase(m.cbegin());
|
| + ASSERT_TRUE(m.size() == 0);
|
| + ASSERT_TRUE(i == m.begin());
|
| + ASSERT_TRUE(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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 1,
|
| + 2,
|
| + 3,
|
| + 4,
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(m.size() == 8);
|
| + I i = m.erase(next(m.cbegin(), 5), next(m.cbegin(), 5));
|
| + ASSERT_TRUE(m.size() == 8);
|
| + ASSERT_TRUE(i == next(m.begin(), 5));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 4);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 6) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 7) == 8);
|
| +
|
| + i = m.erase(next(m.cbegin(), 3), next(m.cbegin(), 4));
|
| + ASSERT_TRUE(m.size() == 7);
|
| + ASSERT_TRUE(i == next(m.begin(), 3));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 6) == 8);
|
| +
|
| + i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 5));
|
| + ASSERT_TRUE(m.size() == 4);
|
| + ASSERT_TRUE(i == next(m.begin(), 2));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 8);
|
| +
|
| + i = m.erase(next(m.cbegin(), 0), next(m.cbegin(), 2));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(i == next(m.begin(), 0));
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 8);
|
| +
|
| + i = m.erase(m.cbegin(), m.cend());
|
| + ASSERT_TRUE(m.size() == 0);
|
| + ASSERT_TRUE(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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 1,
|
| + 2,
|
| + 3,
|
| + 4,
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(m.size() == 8);
|
| + I i = m.erase(9);
|
| + ASSERT_TRUE(m.size() == 8);
|
| + ASSERT_TRUE(i == 0);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 4);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 6) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 7) == 8);
|
| +
|
| + i = m.erase(4);
|
| + ASSERT_TRUE(m.size() == 7);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 6) == 8);
|
| +
|
| + i = m.erase(1);
|
| + ASSERT_TRUE(m.size() == 6);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 7);
|
| + ASSERT_TRUE(*next(m.begin(), 5) == 8);
|
| +
|
| + i = m.erase(8);
|
| + ASSERT_TRUE(m.size() == 5);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 3);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 4) == 7);
|
| +
|
| + i = m.erase(3);
|
| + ASSERT_TRUE(m.size() == 4);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 6);
|
| + ASSERT_TRUE(*next(m.begin(), 3) == 7);
|
| +
|
| + i = m.erase(6);
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 7);
|
| +
|
| + i = m.erase(7);
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 1) == 5);
|
| +
|
| + i = m.erase(2);
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(i == 1);
|
| + ASSERT_TRUE(*next(m.begin(), 0) == 5);
|
| +
|
| + i = m.erase(5);
|
| + ASSERT_TRUE(m.size() == 0);
|
| + ASSERT_TRUE(i == 1);
|
| + }
|
| +}
|
| +
|
| +// 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;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8,
|
| + 9,
|
| + 10,
|
| + 11,
|
| + 12
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.find(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.find(6);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.find(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.find(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.find(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.find(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.find(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.find(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.find(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + {
|
| + typedef M::const_iterator R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8,
|
| + 9,
|
| + 10,
|
| + 11,
|
| + 12
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.find(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.find(6);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.find(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.find(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.find(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.find(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.find(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.find(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.find(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + }
|
| + {
|
| + typedef int V;
|
| + typedef base::flat_set<V, std::less<V>> M;
|
| + typedef M::iterator R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 6,
|
| + 7,
|
| + 8,
|
| + 9,
|
| + 10,
|
| + 11,
|
| + 12
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.find(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.find(6);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.find(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.find(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.find(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.find(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.find(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.find(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.find(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| +}
|
| +
|
| +// Check that base::flat_set and it's iterators can be instantiated with an
|
| +// incomplete type.
|
| +
|
| +TEST(FlatSet, IncompleteType) {
|
| + struct A {
|
| + typedef base::flat_set<A> Set;
|
| + int data;
|
| + Set m;
|
| + Set::iterator it;
|
| + Set::const_iterator cit;
|
| + };
|
| +
|
| + // libc++ tests define operator< for A, but clang is complaining that it's
|
| + // unsued
|
| +
|
| + A a;
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// pair<iterator, bool> insert(const value_type& v);
|
| +
|
| +TEST(FlatSet, InsertCV) {
|
| + {
|
| + typedef base::flat_set<int> M;
|
| + typedef std::pair<M::iterator, bool> R;
|
| + M m;
|
| + R r = m.insert(M::value_type(2));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*r.first == 2);
|
| +
|
| + r = m.insert(M::value_type(1));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r.first == 1);
|
| +
|
| + r = m.insert(M::value_type(3));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r.first == 3);
|
| +
|
| + r = m.insert(M::value_type(3));
|
| + ASSERT_TRUE(!r.second);
|
| + ASSERT_TRUE(r.first == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r.first == 3);
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// void insert(initializer_list<value_type> il);
|
| +
|
| +TEST(FlatSet, InitializerList) {
|
| + {
|
| + typedef base::flat_set<int> C;
|
| + typedef C::value_type V;
|
| + C m = {10, 8};
|
| + m.insert({1, 2, 3, 4, 5, 6});
|
| + ASSERT_TRUE(m.size() == 8);
|
| + ASSERT_TRUE(distance(m.begin(), m.end()) ==
|
| + static_cast<C::difference_type>(m.size()));
|
| + C::const_iterator i = m.cbegin();
|
| + ASSERT_TRUE(*i == V(1));
|
| + ASSERT_TRUE(*++i == V(2));
|
| + ASSERT_TRUE(*++i == V(3));
|
| + ASSERT_TRUE(*++i == V(4));
|
| + ASSERT_TRUE(*++i == V(5));
|
| + ASSERT_TRUE(*++i == V(6));
|
| + ASSERT_TRUE(*++i == V(8));
|
| + ASSERT_TRUE(*++i == V(10));
|
| + }
|
| +}
|
| +
|
| +// 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));
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*r == 2);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(1));
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r == 1);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(3));
|
| + ASSERT_TRUE(r == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r == 3);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(3));
|
| + ASSERT_TRUE(r == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r == 3);
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// template <class InputIterator>
|
| +// void insert(InputIterator first, InputIterator last);
|
| +
|
| +TEST(FlatSet, InsertIterIter) {
|
| + {
|
| + typedef std::set<int> M;
|
| + typedef int V;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 1,
|
| + 1,
|
| + 1,
|
| + 2,
|
| + 2,
|
| + 2,
|
| + 3,
|
| + 3,
|
| + 3
|
| + };
|
| + // clang-format on
|
| +
|
| + M m;
|
| + m.insert(input_iterator<const V*>(ar),
|
| + input_iterator<const V*>(ar + sizeof(ar) / sizeof(ar[0])));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*m.begin() == 1);
|
| + ASSERT_TRUE(*next(m.begin()) == 2);
|
| + ASSERT_TRUE(*next(m.begin(), 2) == 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));
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*r == 2);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(1));
|
| + ASSERT_TRUE(r == m.begin());
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r == 1);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(3));
|
| + ASSERT_TRUE(r == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r == 3);
|
| +
|
| + r = m.insert(m.cend(), M::value_type(3));
|
| + ASSERT_TRUE(r == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r == 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));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + ASSERT_TRUE(*r.first == 2);
|
| +
|
| + r = m.insert(M::value_type(1));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == m.begin());
|
| + ASSERT_TRUE(m.size() == 2);
|
| + ASSERT_TRUE(*r.first == 1);
|
| +
|
| + r = m.insert(M::value_type(3));
|
| + ASSERT_TRUE(r.second);
|
| + ASSERT_TRUE(r.first == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r.first == 3);
|
| +
|
| + r = m.insert(M::value_type(3));
|
| + ASSERT_TRUE(!r.second);
|
| + ASSERT_TRUE(r.first == prev(m.end()));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + ASSERT_TRUE(*r.first == 3);
|
| + }
|
| +}
|
| +
|
| +// 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;
|
| + // clang-format off
|
| + 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
|
| + };
|
| + // clang-format on
|
| +
|
| + base::flat_set<int> m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(std::distance(m.begin(), m.end()) ==
|
| + static_cast<base::flat_set<int>::difference_type>(m.size()));
|
| + ASSERT_TRUE(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;
|
| + ASSERT_TRUE(i == k);
|
| + for (int j = 1; static_cast<std::size_t>(j) <= m.size(); ++j, ++i)
|
| + ASSERT_TRUE(*i == j);
|
| + }
|
| + {
|
| + typedef int V;
|
| + // clang-format off
|
| + 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
|
| + };
|
| + // clang-format on
|
| +
|
| + const base::flat_set<int> m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + ASSERT_TRUE(std::distance(m.begin(), m.end()) ==
|
| + static_cast<base::flat_set<int>::difference_type>(m.size()));
|
| + ASSERT_TRUE(std::distance(m.cbegin(), m.cend()) ==
|
| + static_cast<base::flat_set<int>::difference_type>(m.size()));
|
| + ASSERT_TRUE(std::distance(m.rbegin(), m.rend()) ==
|
| + static_cast<base::flat_set<int>::difference_type>(m.size()));
|
| + ASSERT_TRUE(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)
|
| + ASSERT_TRUE(*i == j);
|
| + }
|
| +}
|
| +
|
| +// 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;
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.lower_bound(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.lower_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.lower_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.lower_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.lower_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + {
|
| + typedef M::const_iterator R;
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.lower_bound(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.lower_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.lower_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.lower_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.lower_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + }
|
| + {
|
| + typedef int V;
|
| + typedef base::flat_set<V, std::less<V>> M;
|
| + typedef M::iterator R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.lower_bound(5);
|
| + ASSERT_TRUE(r == m.begin());
|
| + r = m.lower_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin()));
|
| + r = m.lower_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.lower_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.lower_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.lower_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.lower_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.lower_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.lower_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.lower_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.lower_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// size_type size() const;
|
| +
|
| +TEST(FlatSet, Size) {
|
| + {
|
| + typedef base::flat_set<int> M;
|
| + M m;
|
| + ASSERT_TRUE(m.size() == 0);
|
| + m.insert(M::value_type(2));
|
| + ASSERT_TRUE(m.size() == 1);
|
| + m.insert(M::value_type(1));
|
| + ASSERT_TRUE(m.size() == 2);
|
| + m.insert(M::value_type(3));
|
| + ASSERT_TRUE(m.size() == 3);
|
| + m.erase(m.begin());
|
| + ASSERT_TRUE(m.size() == 2);
|
| + m.erase(m.begin());
|
| + ASSERT_TRUE(m.size() == 1);
|
| + m.erase(m.begin());
|
| + ASSERT_TRUE(m.size() == 0);
|
| + }
|
| +}
|
| +
|
| +// class flat_set
|
| +
|
| +// // 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) {
|
| + {
|
| + typedef base::flat_set<int> C;
|
| + 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), "");
|
| + 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), "");
|
| + static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value),
|
| + "");
|
| + }
|
| +}
|
| +
|
| +// 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;
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.upper_bound(5);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + r = m.upper_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.upper_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + {
|
| + typedef M::const_iterator R;
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + const M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.upper_bound(5);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + r = m.upper_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.upper_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| + }
|
| + {
|
| + typedef int V;
|
| + typedef base::flat_set<V, std::less<V>> M;
|
| + typedef M::iterator R;
|
| +
|
| + // clang-format off
|
| + V ar[] =
|
| + {
|
| + 5,
|
| + 7,
|
| + 9,
|
| + 11,
|
| + 13,
|
| + 15,
|
| + 17,
|
| + 19
|
| + };
|
| + // clang-format on
|
| +
|
| + M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
|
| + R r = m.upper_bound(5);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(7);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(9);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(11);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(13);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(15);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(17);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(19);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + r = m.upper_bound(4);
|
| + ASSERT_TRUE(r == next(m.begin(), 0));
|
| + r = m.upper_bound(6);
|
| + ASSERT_TRUE(r == next(m.begin(), 1));
|
| + r = m.upper_bound(8);
|
| + ASSERT_TRUE(r == next(m.begin(), 2));
|
| + r = m.upper_bound(10);
|
| + ASSERT_TRUE(r == next(m.begin(), 3));
|
| + r = m.upper_bound(12);
|
| + ASSERT_TRUE(r == next(m.begin(), 4));
|
| + r = m.upper_bound(14);
|
| + ASSERT_TRUE(r == next(m.begin(), 5));
|
| + r = m.upper_bound(16);
|
| + ASSERT_TRUE(r == next(m.begin(), 6));
|
| + r = m.upper_bound(18);
|
| + ASSERT_TRUE(r == next(m.begin(), 7));
|
| + r = m.upper_bound(20);
|
| + ASSERT_TRUE(r == next(m.begin(), 8));
|
| + }
|
| +}
|
| +
|
| +} // namespace base
|
|
|