1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 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_FIXED_FLAT_SET_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_CONTAINERS_FIXED_FLAT_SET_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <algorithm> 9*6777b538SAndroid Build Coastguard Worker #include <array> 10*6777b538SAndroid Build Coastguard Worker #include <functional> 11*6777b538SAndroid Build Coastguard Worker #include <type_traits> 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_set.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_tree.h" 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker namespace base { 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker // fixed_flat_set is a immutable container with a std::set-like interface that 20*6777b538SAndroid Build Coastguard Worker // stores its contents in a sorted std::array. 21*6777b538SAndroid Build Coastguard Worker // 22*6777b538SAndroid Build Coastguard Worker // It is a special case of base::flat_set, and mostly useful as a look-up table. 23*6777b538SAndroid Build Coastguard Worker // 24*6777b538SAndroid Build Coastguard Worker // Please see //base/containers/README.md for an overview of which container 25*6777b538SAndroid Build Coastguard Worker // to select. 26*6777b538SAndroid Build Coastguard Worker // 27*6777b538SAndroid Build Coastguard Worker // QUICK REFERENCE 28*6777b538SAndroid Build Coastguard Worker // 29*6777b538SAndroid Build Coastguard Worker // Most of the core functionality is inherited from flat_tree. Please see 30*6777b538SAndroid Build Coastguard Worker // flat_tree.h for more details for most of these functions. As a quick 31*6777b538SAndroid Build Coastguard Worker // reference, the functions available are: 32*6777b538SAndroid Build Coastguard Worker // 33*6777b538SAndroid Build Coastguard Worker // Constructors (inputs need to be sorted): 34*6777b538SAndroid Build Coastguard Worker // fixed_flat_set(const fixed_flat_set&); 35*6777b538SAndroid Build Coastguard Worker // fixed_flat_set(sorted_unique_t, 36*6777b538SAndroid Build Coastguard Worker // const container_type& items, 37*6777b538SAndroid Build Coastguard Worker // const Compare& compare = Compare()); 38*6777b538SAndroid Build Coastguard Worker // 39*6777b538SAndroid Build Coastguard Worker // Size management functions: 40*6777b538SAndroid Build Coastguard Worker // size_t size() const; 41*6777b538SAndroid Build Coastguard Worker // size_t max_size() const; 42*6777b538SAndroid Build Coastguard Worker // bool empty() const; 43*6777b538SAndroid Build Coastguard Worker // 44*6777b538SAndroid Build Coastguard Worker // Iterator functions: 45*6777b538SAndroid Build Coastguard Worker // const_iterator begin() const; 46*6777b538SAndroid Build Coastguard Worker // const_iterator cbegin() const; 47*6777b538SAndroid Build Coastguard Worker // const_iterator end() const; 48*6777b538SAndroid Build Coastguard Worker // const_iterator cend() const; 49*6777b538SAndroid Build Coastguard Worker // const reverse_iterator rbegin() const; 50*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator crbegin() const; 51*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator rend() const; 52*6777b538SAndroid Build Coastguard Worker // const_reverse_iterator crend() const; 53*6777b538SAndroid Build Coastguard Worker // 54*6777b538SAndroid Build Coastguard Worker // Comparators (see std::set documentation). 55*6777b538SAndroid Build Coastguard Worker // key_compare key_comp() const; 56*6777b538SAndroid Build Coastguard Worker // value_compare value_comp() const; 57*6777b538SAndroid Build Coastguard Worker // 58*6777b538SAndroid Build Coastguard Worker // Search functions: 59*6777b538SAndroid Build Coastguard Worker // template <typename K> size_t count(const K&) const; 60*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator find(const K&) const; 61*6777b538SAndroid Build Coastguard Worker // template <typename K> bool contains(const K&) const; 62*6777b538SAndroid Build Coastguard Worker // template <typename K> 63*6777b538SAndroid Build Coastguard Worker // pair<const_iterator, const_iterator> equal_range(K&) const; 64*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator lower_bound(const K&) const; 65*6777b538SAndroid Build Coastguard Worker // template <typename K> const_iterator upper_bound(const K&) const; 66*6777b538SAndroid Build Coastguard Worker // 67*6777b538SAndroid Build Coastguard Worker // Non-member operators: 68*6777b538SAndroid Build Coastguard Worker // bool operator==(const fixed_flat_set&, const fixed_flat_set&); 69*6777b538SAndroid Build Coastguard Worker // bool operator!=(const fixed_flat_set&, const fixed_flat_set&); 70*6777b538SAndroid Build Coastguard Worker // bool operator<(const fixed_flat_set&, const fixed_flat_set&); 71*6777b538SAndroid Build Coastguard Worker // bool operator>(const fixed_flat_set&, const fixed_flat_set&); 72*6777b538SAndroid Build Coastguard Worker // bool operator>=(const fixed_flat_set&, const fixed_flat_set&); 73*6777b538SAndroid Build Coastguard Worker // bool operator<=(const fixed_flat_set&, const fixed_flat_set&); 74*6777b538SAndroid Build Coastguard Worker // 75*6777b538SAndroid Build Coastguard Worker template <class Key, size_t N, class Compare = std::less<>> 76*6777b538SAndroid Build Coastguard Worker using fixed_flat_set = base::flat_set<Key, Compare, std::array<const Key, N>>; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // Utility function to simplify constructing a fixed_flat_set from a fixed list 79*6777b538SAndroid Build Coastguard Worker // of keys and values. Requires that the passed in `data` contains unique keys 80*6777b538SAndroid Build Coastguard Worker // and be sorted by key. See `MakeFixedFlatSet` for a variant that sorts the 81*6777b538SAndroid Build Coastguard Worker // input automatically. 82*6777b538SAndroid Build Coastguard Worker // 83*6777b538SAndroid Build Coastguard Worker // Example usage: 84*6777b538SAndroid Build Coastguard Worker // constexpr auto kSet = base::MakeFixedFlatSet<std::string_view>( 85*6777b538SAndroid Build Coastguard Worker // base::sorted_unique, {"bar", "baz", "foo", "qux"}); 86*6777b538SAndroid Build Coastguard Worker template <class Key, size_t N, class Compare = std::less<>> 87*6777b538SAndroid Build Coastguard Worker consteval fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( 88*6777b538SAndroid Build Coastguard Worker sorted_unique_t, 89*6777b538SAndroid Build Coastguard Worker std::common_type_t<Key> (&&data)[N], 90*6777b538SAndroid Build Coastguard Worker const Compare& comp = Compare()) { 91*6777b538SAndroid Build Coastguard Worker CHECK(internal::is_sorted_and_unique(data, comp)); 92*6777b538SAndroid Build Coastguard Worker // Specify the value_type explicitly to ensure that the returned array has 93*6777b538SAndroid Build Coastguard Worker // immutable keys. 94*6777b538SAndroid Build Coastguard Worker return fixed_flat_set<Key, N, Compare>( 95*6777b538SAndroid Build Coastguard Worker sorted_unique, internal::ToArray<const Key>(data), comp); 96*6777b538SAndroid Build Coastguard Worker } 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker // Utility function to simplify constructing a fixed_flat_set from a fixed list 99*6777b538SAndroid Build Coastguard Worker // of keys. Requires that the passed in `data` contains unique keys. 100*6777b538SAndroid Build Coastguard Worker // 101*6777b538SAndroid Build Coastguard Worker // Large inputs will run into compiler limits, e.g. "constexpr evaluation hit 102*6777b538SAndroid Build Coastguard Worker // maximum step limit". In that case, use `MakeFixedFlatSet(sorted_unique)`. 103*6777b538SAndroid Build Coastguard Worker // 104*6777b538SAndroid Build Coastguard Worker // Example usage: 105*6777b538SAndroid Build Coastguard Worker // constexpr auto kIntSet = base::MakeFixedFlatSet<int>({1, 2, 3, 4}); 106*6777b538SAndroid Build Coastguard Worker // 107*6777b538SAndroid Build Coastguard Worker // Data needs not to be sorted: 108*6777b538SAndroid Build Coastguard Worker // constexpr auto kStringSet = base::MakeFixedFlatSet<std::string_view>( 109*6777b538SAndroid Build Coastguard Worker // {"foo", "bar", "baz", "qux"}); 110*6777b538SAndroid Build Coastguard Worker // 111*6777b538SAndroid Build Coastguard Worker // Note: Wrapping `Key` in `std::common_type_t` below requires callers to 112*6777b538SAndroid Build Coastguard Worker // explicitly specify `Key`, which is desired here. 113*6777b538SAndroid Build Coastguard Worker template <class Key, size_t N, class Compare = std::less<>> 114*6777b538SAndroid Build Coastguard Worker consteval fixed_flat_set<Key, N, Compare> MakeFixedFlatSet( 115*6777b538SAndroid Build Coastguard Worker std::common_type_t<Key> (&&data)[N], 116*6777b538SAndroid Build Coastguard Worker const Compare& comp = Compare()) { 117*6777b538SAndroid Build Coastguard Worker std::sort(data, data + N, comp); 118*6777b538SAndroid Build Coastguard Worker return MakeFixedFlatSet<Key>(sorted_unique, std::move(data), comp); 119*6777b538SAndroid Build Coastguard Worker } 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Worker } // namespace base 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker #endif // BASE_CONTAINERS_FIXED_FLAT_SET_H_ 124