1 // Copyright 2015 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_SRC_CORE_UTIL_USEFUL_H
16 #define GRPC_SRC_CORE_UTIL_USEFUL_H
17
18 #include <grpc/support/port_platform.h>
19
20 #include <cstddef>
21 #include <limits>
22
23 #include "absl/log/check.h"
24 #include "absl/numeric/bits.h"
25 #include "absl/strings/string_view.h"
26 #include "absl/types/variant.h"
27
28 /// useful utilities that don't belong anywhere else
29
30 namespace grpc_core {
31
32 template <typename T>
Clamp(T val,T min,T max)33 T Clamp(T val, T min, T max) {
34 if (val < min) return min;
35 if (max < val) return max;
36 return val;
37 }
38
39 // Set the n-th bit of i
40 template <typename T>
SetBit(T * i,size_t n)41 T SetBit(T* i, size_t n) {
42 return *i |= (T(1) << n);
43 }
44
45 // Clear the n-th bit of i
46 template <typename T>
ClearBit(T * i,size_t n)47 T ClearBit(T* i, size_t n) {
48 return *i &= ~(T(1) << n);
49 }
50
51 // Get the n-th bit of i
52 template <typename T>
GetBit(T i,size_t n)53 bool GetBit(T i, size_t n) {
54 return (i & (T(1) << n)) != 0;
55 }
56
57 // This function uses operator< to implement a qsort-style comparison, whereby:
58 // if a is smaller than b, a number smaller than 0 is returned.
59 // if a is bigger than b, a number greater than 0 is returned.
60 // if a is neither smaller nor bigger than b, 0 is returned.
61 template <typename T>
QsortCompare(const T & a,const T & b)62 int QsortCompare(const T& a, const T& b) {
63 if (a < b) return -1;
64 if (b < a) return 1;
65 return 0;
66 }
67
68 template <typename... X>
QsortCompare(const absl::variant<X...> & a,const absl::variant<X...> & b)69 int QsortCompare(const absl::variant<X...>& a, const absl::variant<X...>& b) {
70 const int index = QsortCompare(a.index(), b.index());
71 if (index != 0) return index;
72 return absl::visit(
73 [&](const auto& x) {
74 return QsortCompare(x, absl::get<absl::remove_cvref_t<decltype(x)>>(b));
75 },
76 a);
77 }
78
QsortCompare(absl::string_view a,absl::string_view b)79 inline int QsortCompare(absl::string_view a, absl::string_view b) {
80 return a.compare(b);
81 }
82
QsortCompare(const std::string & a,const std::string & b)83 inline int QsortCompare(const std::string& a, const std::string& b) {
84 return a.compare(b);
85 }
86
87 template <typename A, typename B>
QsortCompare(const std::pair<A,B> & a,const std::pair<A,B> & b)88 int QsortCompare(const std::pair<A, B>& a, const std::pair<A, B>& b) {
89 const int first = QsortCompare(a.first, b.first);
90 if (first != 0) return first;
91 return QsortCompare(a.second, b.second);
92 }
93
94 template <typename T>
HashPointer(T * p,size_t range)95 constexpr size_t HashPointer(T* p, size_t range) {
96 return (((reinterpret_cast<size_t>(p)) >> 4) ^
97 ((reinterpret_cast<size_t>(p)) >> 9) ^
98 ((reinterpret_cast<size_t>(p)) >> 14)) %
99 range;
100 }
101
102 // Compute a+b.
103 // If the result is greater than MAX, return MAX.
104 // If the result is less than MIN, return MIN.
105 template <typename T>
SaturatingAdd(T a,T b)106 inline T SaturatingAdd(T a, T b) {
107 if (a > 0) {
108 if (b > std::numeric_limits<T>::max() - a) {
109 return std::numeric_limits<T>::max();
110 }
111 } else if (b < std::numeric_limits<T>::min() - a) {
112 return std::numeric_limits<T>::min();
113 }
114 return a + b;
115 }
116
MixHash32(uint32_t a,uint32_t b)117 inline uint32_t MixHash32(uint32_t a, uint32_t b) {
118 return absl::rotl(a, 2u) ^ b;
119 }
120
RoundUpToPowerOf2(uint32_t v)121 inline uint32_t RoundUpToPowerOf2(uint32_t v) {
122 v--;
123 v |= v >> 1;
124 v |= v >> 2;
125 v |= v >> 4;
126 v |= v >> 8;
127 v |= v >> 16;
128 v++;
129 return v;
130 }
131
132 // Return a value with only the lowest bit left on.
LowestOneBit(uint8_t x)133 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint8_t LowestOneBit(uint8_t x) {
134 return x & -x;
135 }
136
LowestOneBit(uint16_t x)137 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint16_t LowestOneBit(uint16_t x) {
138 return x & -x;
139 }
140
LowestOneBit(uint32_t x)141 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t LowestOneBit(uint32_t x) {
142 return x & -x;
143 }
144
LowestOneBit(uint64_t x)145 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint64_t LowestOneBit(uint64_t x) {
146 return x & -x;
147 }
148
149 } // namespace grpc_core
150
151 #define GPR_ARRAY_SIZE(array) (sizeof(array) / sizeof(*(array)))
152
153 #endif // GRPC_SRC_CORE_UTIL_USEFUL_H
154