• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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