bitset.h
Go to the documentation of this file.
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_CORE_LIB_GPRPP_BITSET_H
16 #define GRPC_CORE_LIB_GPRPP_BITSET_H
17 
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 #include <type_traits>
24 
26 
27 #if __cplusplus > 201103l
28 #define GRPC_BITSET_CONSTEXPR_MUTATOR constexpr
29 #else
30 #define GRPC_BITSET_CONSTEXPR_MUTATOR
31 #endif
32 
33 namespace grpc_core {
34 
35 // Given a bit count as an integer, vend as member type `Type` a type with
36 // exactly that number of bits. Undefined if that bit count is not available.
37 template <size_t kBits>
38 struct UintSelector;
39 
40 template <>
41 struct UintSelector<8> {
42  typedef uint8_t Type;
43 };
44 template <>
45 struct UintSelector<16> {
46  typedef uint16_t Type;
47 };
48 template <>
49 struct UintSelector<32> {
50  typedef uint32_t Type;
51 };
52 template <>
53 struct UintSelector<64> {
54  typedef uint64_t Type;
55 };
56 
57 // An unsigned integer of some number of bits.
58 template <size_t kBits>
60 
61 // Given the total number of bits that need to be stored, choose the size of
62 // 'unit' for a BitSet... We'll use an array of units to store the total set.
63 // For small bit counts we are selective in the type to try and balance byte
64 // size and performance
65 // - the details will likely be tweaked into the future.
66 // Once we get over 96 bits, we just use uint64_t for everything.
67 constexpr size_t ChooseUnitBitsForBitSet(size_t total_bits) {
68  return total_bits <= 8 ? 8
69  : total_bits <= 16 ? 16
70  : total_bits <= 24 ? 8
71  : total_bits <= 32 ? 32
72  : total_bits <= 48 ? 16
73  : total_bits <= 64 ? 64
74  : total_bits <= 96 ? 32
75  : 64;
76 }
77 
78 // A BitSet that's configurable.
79 // Contains storage for kTotalBits, stored as an array of integers of size
80 // kUnitBits. e.g. to store 72 bits in 8 bit chunks, we'd say BitSet<72, 8>.
81 // Since most users shouldn't care about the size of unit used, we default
82 // kUnitBits to whatever is selected by ChooseUnitBitsForBitSet
83 template <size_t kTotalBits,
84  size_t kUnitBits = ChooseUnitBitsForBitSet(kTotalBits)>
85 class BitSet {
86  static constexpr size_t kUnits = (kTotalBits + kUnitBits - 1) / kUnitBits;
87 
88  public:
89  // Initialize to all bits false
90  constexpr BitSet() : units_{} {}
91 
92  // Set bit i to true
94  units_[unit_for(i)] |= mask_for(i);
95  }
96 
97  // Set bit i to is_set
99  if (is_set) {
100  set(i);
101  } else {
102  clear(i);
103  }
104  }
105 
106  // Set bit i to false
108  units_[unit_for(i)] &= ~mask_for(i);
109  }
110 
111  // Return true if bit i is set
112  constexpr bool is_set(int i) const {
113  return (units_[unit_for(i)] & mask_for(i)) != 0;
114  }
115 
116  // Return true if all bits are set
117  bool all() const {
118  if (kTotalBits % kUnitBits == 0) {
119  // kTotalBits is a multiple of kUnitBits ==> we can just check for all
120  // ones in each unit.
121  for (size_t i = 0; i < kUnits; i++) {
122  if (units_[i] != all_ones()) return false;
123  }
124  return true;
125  } else {
126  // kTotalBits is not a multiple of kUnitBits ==> we need special handling
127  // for checking partial filling of the last unit (since not all of its
128  // bits are used!)
129  for (size_t i = 0; i < kUnits - 1; i++) {
130  if (units_[i] != all_ones()) return false;
131  }
132  return units_[kUnits - 1] == n_ones(kTotalBits % kUnitBits);
133  }
134  }
135 
136  // Return true if *no* bits are set.
137  bool none() const {
138  for (size_t i = 0; i < kUnits; i++) {
139  if (units_[i] != 0) return false;
140  }
141  return true;
142  }
143 
144  // Return a count of how many bits are set.
145  uint32_t count() const {
146  uint32_t count = 0;
147  for (size_t i = 0; i < kUnits; i++) {
148  count += BitCount(units_[i]);
149  }
150  return count;
151  }
152 
153  bool operator==(const BitSet& other) const {
154  for (size_t i = 0; i < kUnits; i++) {
155  if (units_[i] != other.units_[i]) return false;
156  }
157  return true;
158  }
159 
160  template <typename Int>
162  (sizeof(Int) * 8 >= kTotalBits),
163  Int>::type
164  ToInt() const {
165  Int result = 0;
166  for (size_t i = 0; i < kTotalBits; i++) {
167  if (is_set(i)) result |= (Int(1) << i);
168  }
169  return result;
170  }
171 
172  private:
173  // Given a bit index, return which unit it's stored in.
174  static constexpr size_t unit_for(size_t bit) { return bit / kUnitBits; }
175 
176  // Given a bit index, return a mask to access that bit within it's unit.
177  static constexpr Uint<kUnitBits> mask_for(size_t bit) {
178  return Uint<kUnitBits>{1} << (bit % kUnitBits);
179  }
180 
181  // Return a value that is all ones
182  static constexpr Uint<kUnitBits> all_ones() {
183  return Uint<kUnitBits>(~Uint<kUnitBits>(0));
184  }
185 
186  // Return a value with n bottom bits ones
187  static constexpr Uint<kUnitBits> n_ones(size_t n) {
188  return n == kUnitBits ? all_ones() : (Uint<kUnitBits>(1) << n) - 1;
189  }
190 
191  // The set of units - kUnitBits sized integers that store kUnitBits bits!
193 };
194 
195 // Zero-size specialization of BitSet.
196 // Useful for generic programming.
197 // Make a compile time error out of get/set type accesses, and hard-codes
198 // queries that do make sense.
199 template <>
200 class BitSet<0> {
201  public:
202  constexpr BitSet() {}
203 
204  bool all() const { return true; }
205  bool none() const { return true; }
206  uint32_t count() const { return 0; }
207 };
208 
209 } // namespace grpc_core
210 
211 #endif // GRPC_CORE_LIB_GPRPP_BITSET_H
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
grpc_core::UintSelector< 32 >::Type
uint32_t Type
Definition: bitset.h:50
grpc_core::BitSet::set
GRPC_BITSET_CONSTEXPR_MUTATOR void set(int i)
Definition: bitset.h:93
grpc_core::UintSelector
Definition: bitset.h:38
grpc_core::UintSelector< 64 >::Type
uint64_t Type
Definition: bitset.h:54
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
grpc_core::BitSet::set
GRPC_BITSET_CONSTEXPR_MUTATOR void set(int i, bool is_set)
Definition: bitset.h:98
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::BitSet::mask_for
static constexpr Uint< kUnitBits > mask_for(size_t bit)
Definition: bitset.h:177
useful.h
grpc_core::BitSet< 0 >::none
bool none() const
Definition: bitset.h:205
grpc_core::BitSet::clear
GRPC_BITSET_CONSTEXPR_MUTATOR void clear(int i)
Definition: bitset.h:107
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
grpc_core::Uint
typename UintSelector< kBits >::Type Uint
Definition: bitset.h:59
grpc_core::BitSet::is_set
constexpr bool is_set(int i) const
Definition: bitset.h:112
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
grpc_core::BitSet::count
uint32_t count() const
Definition: bitset.h:145
grpc_core::BitSet< 0 >::all
bool all() const
Definition: bitset.h:204
grpc_core::BitSet< 0 >::count
uint32_t count() const
Definition: bitset.h:206
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
grpc_core::BitSet::operator==
bool operator==(const BitSet &other) const
Definition: bitset.h:153
grpc_core::BitSet::n_ones
static constexpr Uint< kUnitBits > n_ones(size_t n)
Definition: bitset.h:187
Json::Int
int Int
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:228
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
stdint.h
grpc_core::ChooseUnitBitsForBitSet
constexpr size_t ChooseUnitBitsForBitSet(size_t total_bits)
Definition: bitset.h:67
grpc_core::BitSet< 0 >::BitSet
constexpr BitSet()
Definition: bitset.h:202
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_core::BitSet
Definition: bitset.h:85
grpc_core::BitSet::all
bool all() const
Definition: bitset.h:117
grpc_core::BitSet::ToInt
std::enable_if< std::is_unsigned< Int >::value &&(sizeof(Int) *8 >=kTotalBits), Int >::type ToInt() const
Definition: bitset.h:164
grpc_core::BitSet::unit_for
static constexpr size_t unit_for(size_t bit)
Definition: bitset.h:174
grpc_core::BitSet::kUnits
static constexpr size_t kUnits
Definition: bitset.h:86
grpc_core::BitCount
constexpr uint32_t BitCount(uint32_t i)
Definition: useful.h:72
grpc_core::BitSet::none
bool none() const
Definition: bitset.h:137
grpc_core::UintSelector< 16 >::Type
uint16_t Type
Definition: bitset.h:46
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
GRPC_BITSET_CONSTEXPR_MUTATOR
#define GRPC_BITSET_CONSTEXPR_MUTATOR
Definition: bitset.h:30
grpc_core::BitSet::BitSet
constexpr BitSet()
Definition: bitset.h:90
grpc_core::UintSelector< 8 >::Type
uint8_t Type
Definition: bitset.h:42
grpc_core::BitSet::units_
Uint< kUnitBits > units_[kUnits]
Definition: bitset.h:192
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_core::BitSet::all_ones
static constexpr Uint< kUnitBits > all_ones()
Definition: bitset.h:182
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:39