1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_CONTAINERS_FLAT_SET_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_CONTAINERS_FLAT_SET_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <functional> 9*6777b538SAndroid Build Coastguard Worker #include <vector> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_tree.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/template_util.h" 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker namespace base { 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker // flat_set is a container with a std::set-like interface that stores its 18*6777b538SAndroid Build Coastguard Worker // contents in a sorted container, by default a vector. 19*6777b538SAndroid Build Coastguard Worker // 20*6777b538SAndroid Build Coastguard Worker // Its implementation mostly tracks the corresponding standardization proposal 21*6777b538SAndroid Build Coastguard Worker // https://wg21.link/P1222. 22*6777b538SAndroid Build Coastguard Worker // 23*6777b538SAndroid Build Coastguard Worker // Please see //base/containers/README.md for an overview of which container 24*6777b538SAndroid Build Coastguard Worker // to select. 25*6777b538SAndroid Build Coastguard Worker // 26*6777b538SAndroid Build Coastguard Worker // PROS 27*6777b538SAndroid Build Coastguard Worker // 28*6777b538SAndroid Build Coastguard Worker // - Good memory locality. 29*6777b538SAndroid Build Coastguard Worker // - Low overhead, especially for smaller sets. 30*6777b538SAndroid Build Coastguard Worker // - Performance is good for more workloads than you might expect (see 31*6777b538SAndroid Build Coastguard Worker // overview link above). 32*6777b538SAndroid Build Coastguard Worker // - Supports C++14 set interface. 33*6777b538SAndroid Build Coastguard Worker // 34*6777b538SAndroid Build Coastguard Worker // CONS 35*6777b538SAndroid Build Coastguard Worker // 36*6777b538SAndroid Build Coastguard Worker // - Inserts and removals are O(n). 37*6777b538SAndroid Build Coastguard Worker // 38*6777b538SAndroid Build Coastguard Worker // IMPORTANT NOTES 39*6777b538SAndroid Build Coastguard Worker // 40*6777b538SAndroid Build Coastguard Worker // - Iterators are invalidated across mutations. 41*6777b538SAndroid Build Coastguard Worker // - If possible, construct a flat_set in one operation by inserting into 42*6777b538SAndroid Build Coastguard Worker // a container and moving that container into the flat_set constructor. 43*6777b538SAndroid Build Coastguard Worker // - For multiple removals use base::EraseIf() which is O(n) rather than 44*6777b538SAndroid Build Coastguard Worker // O(n * removed_items). 45*6777b538SAndroid Build Coastguard Worker // 46*6777b538SAndroid Build Coastguard Worker // QUICK REFERENCE 47*6777b538SAndroid Build Coastguard Worker // 48*6777b538SAndroid Build Coastguard Worker // Most of the core functionality is inherited from flat_tree. Please see 49*6777b538SAndroid Build Coastguard Worker // flat_tree.h for more details for most of these functions. As a quick 50*6777b538SAndroid Build Coastguard Worker // reference, the functions available are: 51*6777b538SAndroid Build Coastguard Worker // 52*6777b538SAndroid Build Coastguard Worker // Constructors (inputs need not be sorted): 53*6777b538SAndroid Build Coastguard Worker // flat_set(const flat_set&); 54*6777b538SAndroid Build Coastguard Worker // flat_set(flat_set&&); 55*6777b538SAndroid Build Coastguard Worker // flat_set(InputIterator first, InputIterator last, 56*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); 57*6777b538SAndroid Build Coastguard Worker // flat_set(const container_type& items, 58*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); 59*6777b538SAndroid Build Coastguard Worker // flat_set(container_type&& items, 60*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); // Re-use storage. 61*6777b538SAndroid Build Coastguard Worker // flat_set(std::initializer_list<value_type> ilist, 62*6777b538SAndroid Build Coastguard Worker // const Compare& comp = Compare()); 63*6777b538SAndroid Build Coastguard Worker // 64*6777b538SAndroid Build Coastguard Worker // Constructors (inputs need to be sorted): 65*6777b538SAndroid Build Coastguard Worker // flat_set(sorted_unique_t, 66*6777b538SAndroid Build Coastguard Worker // InputIterator first, InputIterator last, 67*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); 68*6777b538SAndroid Build Coastguard Worker // flat_set(sorted_unique_t, 69*6777b538SAndroid Build Coastguard Worker // const container_type& items, 70*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); 71*6777b538SAndroid Build Coastguard Worker // flat_set(sorted_unique_t, 72*6777b538SAndroid Build Coastguard Worker // container_type&& items, 73*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); // Re-use storage. 74*6777b538SAndroid Build Coastguard Worker // flat_set(sorted_unique_t, 75*6777b538SAndroid Build Coastguard Worker // std::initializer_list<value_type> ilist, 76*6777b538SAndroid Build Coastguard Worker // const Compare& comp = Compare()); 77*6777b538SAndroid Build Coastguard Worker // 78*6777b538SAndroid Build Coastguard Worker // Assignment functions: 79*6777b538SAndroid Build Coastguard Worker // flat_set& operator=(const flat_set&); 80*6777b538SAndroid Build Coastguard Worker // flat_set& operator=(flat_set&&); 81*6777b538SAndroid Build Coastguard Worker // flat_set& operator=(initializer_list<Key>); 82*6777b538SAndroid Build Coastguard Worker // 83*6777b538SAndroid Build Coastguard Worker // Memory management functions: 84*6777b538SAndroid Build Coastguard Worker // void reserve(size_t); 85*6777b538SAndroid Build Coastguard Worker // size_t capacity() const; 86*6777b538SAndroid Build Coastguard Worker // void shrink_to_fit(); 87*6777b538SAndroid Build Coastguard Worker // 88*6777b538SAndroid Build Coastguard Worker // Size management functions: 89*6777b538SAndroid Build Coastguard Worker // void clear(); 90*6777b538SAndroid Build Coastguard Worker // size_t size() const; 91*6777b538SAndroid Build Coastguard Worker // size_t max_size() const; 92*6777b538SAndroid Build Coastguard Worker // bool empty() const; 93*6777b538SAndroid Build Coastguard Worker // 94*6777b538SAndroid Build Coastguard Worker // Iterator functions: 95*6777b538SAndroid Build Coastguard Worker // iterator begin(); 96*6777b538SAndroid Build Coastguard Worker // const_iterator begin() const; 97*6777b538SAndroid Build Coastguard Worker // const_iterator cbegin() const; 98*6777b538SAndroid Build Coastguard Worker // iterator end(); 99*6777b538SAndroid Build Coastguard Worker // const_iterator end() const; 100*6777b538SAndroid Build Coastguard Worker // const_iterator cend() const; 101*6777b538SAndroid Build Coastguard Worker // reverse_iterator rbegin(); 102*6777b538SAndroid Build Coastguard Worker // const reverse_iterator rbegin() const; 103*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator crbegin() const; 104*6777b538SAndroid Build Coastguard Worker // reverse_iterator rend(); 105*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator rend() const; 106*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator crend() const; 107*6777b538SAndroid Build Coastguard Worker // 108*6777b538SAndroid Build Coastguard Worker // Insert and accessor functions: 109*6777b538SAndroid Build Coastguard Worker // pair<iterator, bool> insert(const key_type&); 110*6777b538SAndroid Build Coastguard Worker // pair<iterator, bool> insert(key_type&&); 111*6777b538SAndroid Build Coastguard Worker // void insert(InputIterator first, InputIterator last); 112*6777b538SAndroid Build Coastguard Worker // iterator insert(const_iterator hint, const key_type&); 113*6777b538SAndroid Build Coastguard Worker // iterator insert(const_iterator hint, key_type&&); 114*6777b538SAndroid Build Coastguard Worker // pair<iterator, bool> emplace(Args&&...); 115*6777b538SAndroid Build Coastguard Worker // iterator emplace_hint(const_iterator, Args&&...); 116*6777b538SAndroid Build Coastguard Worker // 117*6777b538SAndroid Build Coastguard Worker // Underlying type functions: 118*6777b538SAndroid Build Coastguard Worker // container_type extract() &&; 119*6777b538SAndroid Build Coastguard Worker // void replace(container_type&&); 120*6777b538SAndroid Build Coastguard Worker // 121*6777b538SAndroid Build Coastguard Worker // Erase functions: 122*6777b538SAndroid Build Coastguard Worker // iterator erase(iterator); 123*6777b538SAndroid Build Coastguard Worker // iterator erase(const_iterator); 124*6777b538SAndroid Build Coastguard Worker // iterator erase(const_iterator first, const_iterator& last); 125*6777b538SAndroid Build Coastguard Worker // template <typename K> size_t erase(const K& key); 126*6777b538SAndroid Build Coastguard Worker // 127*6777b538SAndroid Build Coastguard Worker // Comparators (see std::set documentation). 128*6777b538SAndroid Build Coastguard Worker // key_compare key_comp() const; 129*6777b538SAndroid Build Coastguard Worker // value_compare value_comp() const; 130*6777b538SAndroid Build Coastguard Worker // 131*6777b538SAndroid Build Coastguard Worker // Search functions: 132*6777b538SAndroid Build Coastguard Worker // template <typename K> size_t count(const K&) const; 133*6777b538SAndroid Build Coastguard Worker // template <typename K> iterator find(const K&); 134*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator find(const K&) const; 135*6777b538SAndroid Build Coastguard Worker // template <typename K> bool contains(const K&) const; 136*6777b538SAndroid Build Coastguard Worker // template <typename K> pair<iterator, iterator> equal_range(K&); 137*6777b538SAndroid Build Coastguard Worker // template <typename K> iterator lower_bound(const K&); 138*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator lower_bound(const K&) const; 139*6777b538SAndroid Build Coastguard Worker // template <typename K> iterator upper_bound(const K&); 140*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator upper_bound(const K&) const; 141*6777b538SAndroid Build Coastguard Worker // 142*6777b538SAndroid Build Coastguard Worker // General functions: 143*6777b538SAndroid Build Coastguard Worker // void swap(flat_set&); 144*6777b538SAndroid Build Coastguard Worker // 145*6777b538SAndroid Build Coastguard Worker // Non-member operators: 146*6777b538SAndroid Build Coastguard Worker // bool operator==(const flat_set&, const flat_set); 147*6777b538SAndroid Build Coastguard Worker // bool operator!=(const flat_set&, const flat_set); 148*6777b538SAndroid Build Coastguard Worker // bool operator<(const flat_set&, const flat_set); 149*6777b538SAndroid Build Coastguard Worker // bool operator>(const flat_set&, const flat_set); 150*6777b538SAndroid Build Coastguard Worker // bool operator>=(const flat_set&, const flat_set); 151*6777b538SAndroid Build Coastguard Worker // bool operator<=(const flat_set&, const flat_set); 152*6777b538SAndroid Build Coastguard Worker // 153*6777b538SAndroid Build Coastguard Worker template <class Key, 154*6777b538SAndroid Build Coastguard Worker class Compare = std::less<>, 155*6777b538SAndroid Build Coastguard Worker class Container = std::vector<Key>> 156*6777b538SAndroid Build Coastguard Worker using flat_set = typename ::base::internal:: 157*6777b538SAndroid Build Coastguard Worker flat_tree<Key, std::identity, Compare, Container>; 158*6777b538SAndroid Build Coastguard Worker 159*6777b538SAndroid Build Coastguard Worker // Utility function to simplify constructing a flat_set from a fixed list 160*6777b538SAndroid Build Coastguard Worker // of keys. The keys are obtained by applying the projection |proj| to the 161*6777b538SAndroid Build Coastguard Worker // |unprojected_elements|. The set's keys are sorted by |comp|. 162*6777b538SAndroid Build Coastguard Worker // 163*6777b538SAndroid Build Coastguard Worker // Example usage (creates a set {16, 9, 4, 1}): 164*6777b538SAndroid Build Coastguard Worker // auto set = base::MakeFlatSet<int>( 165*6777b538SAndroid Build Coastguard Worker // std::vector<int>{1, 2, 3, 4}, [](int i, int j) { return i > j; }, 166*6777b538SAndroid Build Coastguard Worker // [](int i) { return i * i; }); 167*6777b538SAndroid Build Coastguard Worker template <class Key, 168*6777b538SAndroid Build Coastguard Worker class Compare = std::less<>, 169*6777b538SAndroid Build Coastguard Worker class Container = std::vector<Key>, 170*6777b538SAndroid Build Coastguard Worker class InputContainer, 171*6777b538SAndroid Build Coastguard Worker class Projection = std::identity> 172*6777b538SAndroid Build Coastguard Worker constexpr flat_set<Key, Compare, Container> MakeFlatSet( 173*6777b538SAndroid Build Coastguard Worker const InputContainer& unprojected_elements, 174*6777b538SAndroid Build Coastguard Worker const Compare& comp = Compare(), 175*6777b538SAndroid Build Coastguard Worker const Projection& proj = Projection()) { 176*6777b538SAndroid Build Coastguard Worker Container elements; 177*6777b538SAndroid Build Coastguard Worker internal::ReserveIfSupported(elements, unprojected_elements); 178*6777b538SAndroid Build Coastguard Worker base::ranges::transform(unprojected_elements, std::back_inserter(elements), 179*6777b538SAndroid Build Coastguard Worker proj); 180*6777b538SAndroid Build Coastguard Worker return flat_set<Key, Compare, Container>(std::move(elements), comp); 181*6777b538SAndroid Build Coastguard Worker } 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker } // namespace base 184*6777b538SAndroid Build Coastguard Worker 185*6777b538SAndroid Build Coastguard Worker #endif // BASE_CONTAINERS_FLAT_SET_H_ 186