xref: /aosp_15_r20/external/cronet/base/containers/fixed_flat_set.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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