this repo has no description
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */
2#pragma once
3
4#include <cstdlib>
5#include <cstring>
6#include <memory>
7#include <type_traits>
8
9#include "asserts.h"
10#include "globals.h"
11
12namespace py {
13
14class Utils {
15 public:
16 template <typename T>
17 static bool isAligned(T x, int n) {
18 DCHECK(isPowerOfTwo(n), "must be power of 2");
19 return (x & (n - 1)) == 0;
20 }
21
22 template <typename T>
23 static bool isPowerOfTwo(T x) {
24 return (x & (x - 1)) == 0;
25 }
26
27 template <typename T>
28 static bool fits(word value) {
29 return static_cast<word>(static_cast<T>(value)) == value;
30 }
31
32 template <typename T>
33 static T roundDown(T x, int n) {
34 DCHECK(isPowerOfTwo(n), "must be power of 2");
35 return (x & -n);
36 }
37
38 template <typename T>
39 static T roundUp(T x, int n) {
40 return roundDown(x + n - 1, n);
41 }
42
43 template <typename T>
44 static T roundUpDiv(T denominator, int divisor) {
45 if (isPowerOfTwo(divisor)) {
46 return roundUp(denominator, divisor) >> (highestBit(divisor) - 1);
47 }
48 return (denominator + (divisor - 1)) / divisor;
49 }
50
51 template <typename T>
52 static T nextPowerOfTwo(T x) {
53 // Turn off all but msb.
54 while ((x & (x - 1u)) != 0) {
55 x &= x - 1u;
56 }
57 return x << 1u;
58 }
59
60 template <typename T>
61 static T rotateLeft(T x, int n) {
62 return (x << n) | (x >> (-n & (sizeof(T) * kBitsPerByte - 1)));
63 }
64
65 template <typename T>
66 static T maximum(T x, T y) {
67 return x > y ? x : y;
68 }
69
70 // Search forwards through `haystack` looking for `needle`. Return the byte
71 // offset, or -1 if not found.
72 static word memoryFind(const byte* haystack, word haystack_len,
73 const byte* needle, word needle_len);
74
75 // Search forwards through `haystack` looking for `needle`. Return the byte
76 // offset, or -1 if not found.
77 static word memoryFindChar(const byte* haystack, word haystack_len,
78 byte needle);
79
80 // Search backwards through `haystack` looking for `needle`. Return the byte
81 // offset, or -1 if not found.
82 static word memoryFindCharReverse(const byte* haystack, word haystack_len,
83 byte needle);
84
85 // Search backwards through `haystack` looking for `needle`. Return the byte
86 // offset, or -1 if not found.
87 static word memoryFindReverse(const byte* haystack, word haystack_len,
88 const byte* needle, word needle_len);
89
90 template <typename T>
91 static T minimum(T x, T y) {
92 return x < y ? x : y;
93 }
94
95 static int highestBit(word x) {
96 return x == 0 ? 0 : kBitsPerWord - __builtin_clzl(x);
97 }
98
99 // Returns the number of leading redundant sign bits.
100 // This is equivalent to gccs __builtin_clrsbl but works for any compiler.
101 static int numRedundantSignBits(word x) {
102#if __has_builtin(__builtin_clrsbl) || \
103 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
104 static_assert(sizeof(x) == sizeof(long),
105 "Need to choose matching clrsbX builtin");
106 return __builtin_clrsbl(x);
107#else
108 if (x < 0) x = ~x;
109 if (x == 0) return sizeof(x) * kBitsPerByte - 1;
110 return __builtin_clzl(x) - 1;
111#endif
112 }
113
114 template <typename T>
115 static T readBytes(void* addr) {
116 T dest;
117 std::memcpy(&dest, addr, sizeof(dest));
118 return dest;
119 }
120
121 // Print the current traceback, information about the pending exception, if
122 // one is set, and call std::abort().
123 [[noreturn]] static void printDebugInfoAndAbort();
124
125 private:
126 DISALLOW_IMPLICIT_CONSTRUCTORS(Utils);
127};
128
129// Convenience wrappers to enable templates based on signed or unsigned integral
130// types.
131template <typename T, typename R>
132using if_signed_t = typename std::enable_if<std::is_signed<T>::value, R>::type;
133template <typename T, typename R>
134using if_unsigned_t =
135 typename std::enable_if<std::is_unsigned<T>::value, R>::type;
136
137// std::unique_ptr for objects created with std::malloc() rather than new.
138struct FreeDeleter {
139 void operator()(void* ptr) const { std::free(ptr); }
140};
141template <typename T>
142using unique_c_ptr = std::unique_ptr<T, FreeDeleter>;
143
144} // namespace py