xref: /aosp_15_r20/external/abseil-cpp/absl/numeric/bits.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2020 The Abseil Authors
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker //
15*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
16*9356374aSAndroid Build Coastguard Worker // File: bits.h
17*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
18*9356374aSAndroid Build Coastguard Worker //
19*9356374aSAndroid Build Coastguard Worker // This file contains implementations of C++20's bitwise math functions, as
20*9356374aSAndroid Build Coastguard Worker // defined by:
21*9356374aSAndroid Build Coastguard Worker //
22*9356374aSAndroid Build Coastguard Worker // P0553R4:
23*9356374aSAndroid Build Coastguard Worker //  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html
24*9356374aSAndroid Build Coastguard Worker // P0556R3:
25*9356374aSAndroid Build Coastguard Worker //  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0556r3.html
26*9356374aSAndroid Build Coastguard Worker // P1355R2:
27*9356374aSAndroid Build Coastguard Worker //  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1355r2.html
28*9356374aSAndroid Build Coastguard Worker // P1956R1:
29*9356374aSAndroid Build Coastguard Worker //  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1956r1.pdf
30*9356374aSAndroid Build Coastguard Worker //
31*9356374aSAndroid Build Coastguard Worker // When using a standard library that implements these functions, we use the
32*9356374aSAndroid Build Coastguard Worker // standard library's implementation.
33*9356374aSAndroid Build Coastguard Worker 
34*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_NUMERIC_BITS_H_
35*9356374aSAndroid Build Coastguard Worker #define ABSL_NUMERIC_BITS_H_
36*9356374aSAndroid Build Coastguard Worker 
37*9356374aSAndroid Build Coastguard Worker #include <cstdint>
38*9356374aSAndroid Build Coastguard Worker #include <limits>
39*9356374aSAndroid Build Coastguard Worker #include <type_traits>
40*9356374aSAndroid Build Coastguard Worker 
41*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
42*9356374aSAndroid Build Coastguard Worker 
43*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
44*9356374aSAndroid Build Coastguard Worker #include <bit>
45*9356374aSAndroid Build Coastguard Worker #endif
46*9356374aSAndroid Build Coastguard Worker 
47*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
48*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/internal/bits.h"
49*9356374aSAndroid Build Coastguard Worker 
50*9356374aSAndroid Build Coastguard Worker namespace absl {
51*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
52*9356374aSAndroid Build Coastguard Worker 
53*9356374aSAndroid Build Coastguard Worker // https://github.com/llvm/llvm-project/issues/64544
54*9356374aSAndroid Build Coastguard Worker // libc++ had the wrong signature for std::rotl and std::rotr
55*9356374aSAndroid Build Coastguard Worker // prior to libc++ 18.0.
56*9356374aSAndroid Build Coastguard Worker //
57*9356374aSAndroid Build Coastguard Worker #if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) &&     \
58*9356374aSAndroid Build Coastguard Worker     (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 180000)
59*9356374aSAndroid Build Coastguard Worker using std::rotl;
60*9356374aSAndroid Build Coastguard Worker using std::rotr;
61*9356374aSAndroid Build Coastguard Worker 
62*9356374aSAndroid Build Coastguard Worker #else
63*9356374aSAndroid Build Coastguard Worker 
64*9356374aSAndroid Build Coastguard Worker // Rotating functions
65*9356374aSAndroid Build Coastguard Worker template <class T>
66*9356374aSAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT constexpr
67*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
68*9356374aSAndroid Build Coastguard Worker     rotl(T x, int s) noexcept {
69*9356374aSAndroid Build Coastguard Worker   return numeric_internal::RotateLeft(x, s);
70*9356374aSAndroid Build Coastguard Worker }
71*9356374aSAndroid Build Coastguard Worker 
72*9356374aSAndroid Build Coastguard Worker template <class T>
73*9356374aSAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT constexpr
74*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
75*9356374aSAndroid Build Coastguard Worker     rotr(T x, int s) noexcept {
76*9356374aSAndroid Build Coastguard Worker   return numeric_internal::RotateRight(x, s);
77*9356374aSAndroid Build Coastguard Worker }
78*9356374aSAndroid Build Coastguard Worker 
79*9356374aSAndroid Build Coastguard Worker #endif
80*9356374aSAndroid Build Coastguard Worker 
81*9356374aSAndroid Build Coastguard Worker // https://github.com/llvm/llvm-project/issues/64544
82*9356374aSAndroid Build Coastguard Worker // libc++ had the wrong signature for std::rotl and std::rotr
83*9356374aSAndroid Build Coastguard Worker // prior to libc++ 18.0.
84*9356374aSAndroid Build Coastguard Worker //
85*9356374aSAndroid Build Coastguard Worker #if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)
86*9356374aSAndroid Build Coastguard Worker 
87*9356374aSAndroid Build Coastguard Worker using std::countl_one;
88*9356374aSAndroid Build Coastguard Worker using std::countl_zero;
89*9356374aSAndroid Build Coastguard Worker using std::countr_one;
90*9356374aSAndroid Build Coastguard Worker using std::countr_zero;
91*9356374aSAndroid Build Coastguard Worker using std::popcount;
92*9356374aSAndroid Build Coastguard Worker 
93*9356374aSAndroid Build Coastguard Worker #else
94*9356374aSAndroid Build Coastguard Worker 
95*9356374aSAndroid Build Coastguard Worker // Counting functions
96*9356374aSAndroid Build Coastguard Worker //
97*9356374aSAndroid Build Coastguard Worker // While these functions are typically constexpr, on some platforms, they may
98*9356374aSAndroid Build Coastguard Worker // not be marked as constexpr due to constraints of the compiler/available
99*9356374aSAndroid Build Coastguard Worker // intrinsics.
100*9356374aSAndroid Build Coastguard Worker template <class T>
101*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CLZ inline
102*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
countl_zero(T x)103*9356374aSAndroid Build Coastguard Worker     countl_zero(T x) noexcept {
104*9356374aSAndroid Build Coastguard Worker   return numeric_internal::CountLeadingZeroes(x);
105*9356374aSAndroid Build Coastguard Worker }
106*9356374aSAndroid Build Coastguard Worker 
107*9356374aSAndroid Build Coastguard Worker template <class T>
108*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CLZ inline
109*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
countl_one(T x)110*9356374aSAndroid Build Coastguard Worker     countl_one(T x) noexcept {
111*9356374aSAndroid Build Coastguard Worker   // Avoid integer promotion to a wider type
112*9356374aSAndroid Build Coastguard Worker   return countl_zero(static_cast<T>(~x));
113*9356374aSAndroid Build Coastguard Worker }
114*9356374aSAndroid Build Coastguard Worker 
115*9356374aSAndroid Build Coastguard Worker template <class T>
116*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CTZ inline
117*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
countr_zero(T x)118*9356374aSAndroid Build Coastguard Worker     countr_zero(T x) noexcept {
119*9356374aSAndroid Build Coastguard Worker   return numeric_internal::CountTrailingZeroes(x);
120*9356374aSAndroid Build Coastguard Worker }
121*9356374aSAndroid Build Coastguard Worker 
122*9356374aSAndroid Build Coastguard Worker template <class T>
123*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CTZ inline
124*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
countr_one(T x)125*9356374aSAndroid Build Coastguard Worker     countr_one(T x) noexcept {
126*9356374aSAndroid Build Coastguard Worker   // Avoid integer promotion to a wider type
127*9356374aSAndroid Build Coastguard Worker   return countr_zero(static_cast<T>(~x));
128*9356374aSAndroid Build Coastguard Worker }
129*9356374aSAndroid Build Coastguard Worker 
130*9356374aSAndroid Build Coastguard Worker template <class T>
131*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline
132*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
popcount(T x)133*9356374aSAndroid Build Coastguard Worker     popcount(T x) noexcept {
134*9356374aSAndroid Build Coastguard Worker   return numeric_internal::Popcount(x);
135*9356374aSAndroid Build Coastguard Worker }
136*9356374aSAndroid Build Coastguard Worker 
137*9356374aSAndroid Build Coastguard Worker #endif
138*9356374aSAndroid Build Coastguard Worker 
139*9356374aSAndroid Build Coastguard Worker #if (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker using std::bit_ceil;
142*9356374aSAndroid Build Coastguard Worker using std::bit_floor;
143*9356374aSAndroid Build Coastguard Worker using std::bit_width;
144*9356374aSAndroid Build Coastguard Worker using std::has_single_bit;
145*9356374aSAndroid Build Coastguard Worker 
146*9356374aSAndroid Build Coastguard Worker #else
147*9356374aSAndroid Build Coastguard Worker 
148*9356374aSAndroid Build Coastguard Worker // Returns: true if x is an integral power of two; false otherwise.
149*9356374aSAndroid Build Coastguard Worker template <class T>
150*9356374aSAndroid Build Coastguard Worker constexpr inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type
has_single_bit(T x)151*9356374aSAndroid Build Coastguard Worker has_single_bit(T x) noexcept {
152*9356374aSAndroid Build Coastguard Worker   return x != 0 && (x & (x - 1)) == 0;
153*9356374aSAndroid Build Coastguard Worker }
154*9356374aSAndroid Build Coastguard Worker 
155*9356374aSAndroid Build Coastguard Worker // Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any
156*9356374aSAndroid Build Coastguard Worker // fractional part discarded.
157*9356374aSAndroid Build Coastguard Worker template <class T>
158*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CLZ inline
159*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, int>::type
bit_width(T x)160*9356374aSAndroid Build Coastguard Worker     bit_width(T x) noexcept {
161*9356374aSAndroid Build Coastguard Worker   return std::numeric_limits<T>::digits - countl_zero(x);
162*9356374aSAndroid Build Coastguard Worker }
163*9356374aSAndroid Build Coastguard Worker 
164*9356374aSAndroid Build Coastguard Worker // Returns: If x == 0, 0; otherwise the maximal value y such that
165*9356374aSAndroid Build Coastguard Worker // has_single_bit(y) is true and y <= x.
166*9356374aSAndroid Build Coastguard Worker template <class T>
167*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CLZ inline
168*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
bit_floor(T x)169*9356374aSAndroid Build Coastguard Worker     bit_floor(T x) noexcept {
170*9356374aSAndroid Build Coastguard Worker   return x == 0 ? 0 : T{1} << (bit_width(x) - 1);
171*9356374aSAndroid Build Coastguard Worker }
172*9356374aSAndroid Build Coastguard Worker 
173*9356374aSAndroid Build Coastguard Worker // Returns: N, where N is the smallest power of 2 greater than or equal to x.
174*9356374aSAndroid Build Coastguard Worker //
175*9356374aSAndroid Build Coastguard Worker // Preconditions: N is representable as a value of type T.
176*9356374aSAndroid Build Coastguard Worker template <class T>
177*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_CONSTEXPR_CLZ inline
178*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
bit_ceil(T x)179*9356374aSAndroid Build Coastguard Worker     bit_ceil(T x) {
180*9356374aSAndroid Build Coastguard Worker   // If T is narrower than unsigned, T{1} << bit_width will be promoted.  We
181*9356374aSAndroid Build Coastguard Worker   // want to force it to wraparound so that bit_ceil of an invalid value are not
182*9356374aSAndroid Build Coastguard Worker   // core constant expressions.
183*9356374aSAndroid Build Coastguard Worker   //
184*9356374aSAndroid Build Coastguard Worker   // BitCeilNonPowerOf2 triggers an overflow in constexpr contexts if we would
185*9356374aSAndroid Build Coastguard Worker   // undergo promotion to unsigned but not fit the result into T without
186*9356374aSAndroid Build Coastguard Worker   // truncation.
187*9356374aSAndroid Build Coastguard Worker   return has_single_bit(x) ? T{1} << (bit_width(x) - 1)
188*9356374aSAndroid Build Coastguard Worker                            : numeric_internal::BitCeilNonPowerOf2(x);
189*9356374aSAndroid Build Coastguard Worker }
190*9356374aSAndroid Build Coastguard Worker 
191*9356374aSAndroid Build Coastguard Worker #endif
192*9356374aSAndroid Build Coastguard Worker 
193*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
194*9356374aSAndroid Build Coastguard Worker }  // namespace absl
195*9356374aSAndroid Build Coastguard Worker 
196*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_NUMERIC_BITS_H_
197