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