xref: /aosp_15_r20/external/cronet/base/bits.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 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 // This file defines some bit utilities.
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #ifndef BASE_BITS_H_
8*6777b538SAndroid Build Coastguard Worker #define BASE_BITS_H_
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
11*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include <bit>
14*6777b538SAndroid Build Coastguard Worker #include <concepts>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace base::bits {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker // Bit functions in <bit> are restricted to a specific set of types of unsigned
21*6777b538SAndroid Build Coastguard Worker // integer; restrict functions in this file that are related to those in that
22*6777b538SAndroid Build Coastguard Worker // header to match for consistency.
23*6777b538SAndroid Build Coastguard Worker template <typename T>
24*6777b538SAndroid Build Coastguard Worker concept UnsignedInteger =
25*6777b538SAndroid Build Coastguard Worker     std::unsigned_integral<T> && !std::same_as<T, bool> &&
26*6777b538SAndroid Build Coastguard Worker     !std::same_as<T, char> && !std::same_as<T, char8_t> &&
27*6777b538SAndroid Build Coastguard Worker     !std::same_as<T, char16_t> && !std::same_as<T, char32_t> &&
28*6777b538SAndroid Build Coastguard Worker     !std::same_as<T, wchar_t>;
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker // We want to migrate all users of these functions to use the unsigned type
31*6777b538SAndroid Build Coastguard Worker // versions of the functions, but until they are all moved over, create a
32*6777b538SAndroid Build Coastguard Worker // concept that captures all the types that must be supported for compatibility
33*6777b538SAndroid Build Coastguard Worker // but that we want to remove.
34*6777b538SAndroid Build Coastguard Worker //
35*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1414634): Switch uses to supported functions and
36*6777b538SAndroid Build Coastguard Worker // remove.
37*6777b538SAndroid Build Coastguard Worker template <typename T>
38*6777b538SAndroid Build Coastguard Worker concept SignedIntegerDeprecatedDoNotUse =
39*6777b538SAndroid Build Coastguard Worker     std::integral<T> && !UnsignedInteger<T>;
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker // Returns true iff |value| is a power of 2. DEPRECATED; use
42*6777b538SAndroid Build Coastguard Worker // std::has_single_bit() instead.
43*6777b538SAndroid Build Coastguard Worker //
44*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1414634): Switch uses and remove.
45*6777b538SAndroid Build Coastguard Worker template <typename T>
46*6777b538SAndroid Build Coastguard Worker   requires SignedIntegerDeprecatedDoNotUse<T>
IsPowerOfTwoDeprecatedDoNotUse(T value)47*6777b538SAndroid Build Coastguard Worker constexpr bool IsPowerOfTwoDeprecatedDoNotUse(T value) {
48*6777b538SAndroid Build Coastguard Worker   // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
49*6777b538SAndroid Build Coastguard Worker   //
50*6777b538SAndroid Build Coastguard Worker   // Only positive integers with a single bit set are powers of two. If only one
51*6777b538SAndroid Build Coastguard Worker   // bit is set in x (e.g. 0b00000100000000) then |x-1| will have that bit set
52*6777b538SAndroid Build Coastguard Worker   // to zero and all bits to its right set to 1 (e.g. 0b00000011111111). Hence
53*6777b538SAndroid Build Coastguard Worker   // |x & (x-1)| is 0 iff x is a power of two.
54*6777b538SAndroid Build Coastguard Worker   return value > 0 && (value & (value - 1)) == 0;
55*6777b538SAndroid Build Coastguard Worker }
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker // Round down |size| to a multiple of alignment, which must be a power of two.
58*6777b538SAndroid Build Coastguard Worker template <typename T>
59*6777b538SAndroid Build Coastguard Worker   requires UnsignedInteger<T>
AlignDown(T size,T alignment)60*6777b538SAndroid Build Coastguard Worker inline constexpr T AlignDown(T size, T alignment) {
61*6777b538SAndroid Build Coastguard Worker   DCHECK(std::has_single_bit(alignment));
62*6777b538SAndroid Build Coastguard Worker   return size & ~(alignment - 1);
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker // Round down |size| to a multiple of alignment, which must be a power of two.
66*6777b538SAndroid Build Coastguard Worker // DEPRECATED; use the UnsignedInteger version.
67*6777b538SAndroid Build Coastguard Worker //
68*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1414634): Switch uses and remove.
69*6777b538SAndroid Build Coastguard Worker template <typename T>
70*6777b538SAndroid Build Coastguard Worker   requires SignedIntegerDeprecatedDoNotUse<T>
AlignDownDeprecatedDoNotUse(T size,T alignment)71*6777b538SAndroid Build Coastguard Worker inline constexpr T AlignDownDeprecatedDoNotUse(T size, T alignment) {
72*6777b538SAndroid Build Coastguard Worker   DCHECK(IsPowerOfTwoDeprecatedDoNotUse(alignment));
73*6777b538SAndroid Build Coastguard Worker   return size & ~(alignment - 1);
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker // Move |ptr| back to the previous multiple of alignment, which must be a power
77*6777b538SAndroid Build Coastguard Worker // of two. Defined for types where sizeof(T) is one byte.
78*6777b538SAndroid Build Coastguard Worker template <typename T>
79*6777b538SAndroid Build Coastguard Worker   requires(sizeof(T) == 1)
AlignDown(T * ptr,uintptr_t alignment)80*6777b538SAndroid Build Coastguard Worker inline T* AlignDown(T* ptr, uintptr_t alignment) {
81*6777b538SAndroid Build Coastguard Worker   return reinterpret_cast<T*>(
82*6777b538SAndroid Build Coastguard Worker       AlignDown(reinterpret_cast<uintptr_t>(ptr), alignment));
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker // Round up |size| to a multiple of alignment, which must be a power of two.
86*6777b538SAndroid Build Coastguard Worker template <typename T>
87*6777b538SAndroid Build Coastguard Worker   requires UnsignedInteger<T>
AlignUp(T size,T alignment)88*6777b538SAndroid Build Coastguard Worker inline constexpr T AlignUp(T size, T alignment) {
89*6777b538SAndroid Build Coastguard Worker   DCHECK(std::has_single_bit(alignment));
90*6777b538SAndroid Build Coastguard Worker   return (size + alignment - 1) & ~(alignment - 1);
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker // Round up |size| to a multiple of alignment, which must be a power of two.
94*6777b538SAndroid Build Coastguard Worker // DEPRECATED; use the UnsignedInteger version.
95*6777b538SAndroid Build Coastguard Worker //
96*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1414634): Switch uses and remove.
97*6777b538SAndroid Build Coastguard Worker template <typename T>
98*6777b538SAndroid Build Coastguard Worker   requires SignedIntegerDeprecatedDoNotUse<T>
AlignUpDeprecatedDoNotUse(T size,T alignment)99*6777b538SAndroid Build Coastguard Worker inline constexpr T AlignUpDeprecatedDoNotUse(T size, T alignment) {
100*6777b538SAndroid Build Coastguard Worker   DCHECK(IsPowerOfTwoDeprecatedDoNotUse(alignment));
101*6777b538SAndroid Build Coastguard Worker   return (size + alignment - 1) & ~(alignment - 1);
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker // Advance |ptr| to the next multiple of alignment, which must be a power of
105*6777b538SAndroid Build Coastguard Worker // two. Defined for types where sizeof(T) is one byte.
106*6777b538SAndroid Build Coastguard Worker template <typename T>
107*6777b538SAndroid Build Coastguard Worker   requires(sizeof(T) == 1)
AlignUp(T * ptr,uintptr_t alignment)108*6777b538SAndroid Build Coastguard Worker inline T* AlignUp(T* ptr, uintptr_t alignment) {
109*6777b538SAndroid Build Coastguard Worker   return reinterpret_cast<T*>(
110*6777b538SAndroid Build Coastguard Worker       AlignUp(reinterpret_cast<uintptr_t>(ptr), alignment));
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker // Returns the integer i such as 2^i <= n < 2^(i+1).
114*6777b538SAndroid Build Coastguard Worker //
115*6777b538SAndroid Build Coastguard Worker // A common use for this function is to measure the number of bits required to
116*6777b538SAndroid Build Coastguard Worker // contain a value; for that case use std::bit_width().
117*6777b538SAndroid Build Coastguard Worker //
118*6777b538SAndroid Build Coastguard Worker // A common use for this function is to take its result and use it to left-shift
119*6777b538SAndroid Build Coastguard Worker // a bit; instead of doing so, use std::bit_floor().
Log2Floor(uint32_t n)120*6777b538SAndroid Build Coastguard Worker constexpr int Log2Floor(uint32_t n) {
121*6777b538SAndroid Build Coastguard Worker   return 31 - std::countl_zero(n);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker // Returns the integer i such as 2^(i-1) < n <= 2^i.
125*6777b538SAndroid Build Coastguard Worker //
126*6777b538SAndroid Build Coastguard Worker // A common use for this function is to measure the number of bits required to
127*6777b538SAndroid Build Coastguard Worker // contain a value; for that case use std::bit_width().
128*6777b538SAndroid Build Coastguard Worker //
129*6777b538SAndroid Build Coastguard Worker // A common use for this function is to take its result and use it to left-shift
130*6777b538SAndroid Build Coastguard Worker // a bit; instead of doing so, use std::bit_ceil().
Log2Ceiling(uint32_t n)131*6777b538SAndroid Build Coastguard Worker constexpr int Log2Ceiling(uint32_t n) {
132*6777b538SAndroid Build Coastguard Worker   // When n == 0, we want the function to return -1.
133*6777b538SAndroid Build Coastguard Worker   // When n == 0, (n - 1) will underflow to 0xFFFFFFFF, which is
134*6777b538SAndroid Build Coastguard Worker   // why the statement below starts with (n ? 32 : -1).
135*6777b538SAndroid Build Coastguard Worker   return (n ? 32 : -1) - std::countl_zero(n - 1);
136*6777b538SAndroid Build Coastguard Worker }
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker // Returns a value of type T with a single bit set in the left-most position.
139*6777b538SAndroid Build Coastguard Worker // Can be used instead of manually shifting a 1 to the left. Unlike the other
140*6777b538SAndroid Build Coastguard Worker // functions in this file, usable for any integral type.
141*6777b538SAndroid Build Coastguard Worker template <typename T>
142*6777b538SAndroid Build Coastguard Worker   requires std::integral<T>
LeftmostBit()143*6777b538SAndroid Build Coastguard Worker constexpr T LeftmostBit() {
144*6777b538SAndroid Build Coastguard Worker   T one(1u);
145*6777b538SAndroid Build Coastguard Worker   return one << (8 * sizeof(T) - 1);
146*6777b538SAndroid Build Coastguard Worker }
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker }  // namespace base::bits
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker #endif  // BASE_BITS_H_
151