this repo has no description
at trunk 144 lines 4.2 kB view raw
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