16#ifndef RANS_INTERNAL_COMMON_UTILS_H_
17#define RANS_INTERNAL_COMMON_UTILS_H_
28#include <fairlogger/Logger.h>
33#define rans_likely(x) __builtin_expect((x), 1)
34#define rans_unlikely(x) __builtin_expect((x), 0)
43constexpr size_t toBits()
noexcept;
60 } mx = {(vx.i & 0x007FFFFF) | 0x3f000000};
63 y *= 1.1920928955078125e-7f;
65 return y - 124.22551499f - 1.498030302f * mx.f - 1.72587999f / (0.3520887068f + mx.f);
71 return sizeof(uint64_t) /
sizeof(T);
77 std::memcpy(&ret,
src, 8);
81inline void write64(
void* __restrict dest, uint64_t
src) { std::memcpy(dest, &
src, 8); };
86 return (
reinterpret_cast<uintptr_t
>(
address) << 3ull);
92 static_assert(std::is_integral_v<T>,
"Type is not integral");
93 static_assert(std::is_unsigned_v<T>,
"only defined for unsigned numbers");
96 if constexpr (
sizeof(T) <= 4) {
97 return static_cast<T
>(utils::toBits<uint32_t>() - __builtin_clz(
x) - 1);
99 return static_cast<T
>(utils::toBits<uint64_t>() - __builtin_clzl(
x) - 1);
103template <
typename T, std::enable_if_t<std::is_
unsigned_v<T>,
bool> = true>
106 return x > 0 && (
x & (
x - 1)) == 0;
111 const count_t roundedDown =
static_cast<count_t>(rescaledFrequency);
112 const double_t roundedDownD = roundedDown;
115 if (rescaledFrequency * rescaledFrequency <= (roundedDownD * (roundedDownD + 1.0))) {
120 return roundedDown + 1;
126 return (
static_cast<size_t>(1) << (
bits + 1)) - 1;
139 return std::ceil(std::log2(nSymbols));
155inline constexpr std::uint8_t
operator"" _u8(
unsigned long long int value) {
return static_cast<uint8_t
>(
value); };
156inline constexpr std::int8_t
operator"" _i8(
unsigned long long int value) {
return static_cast<int8_t
>(
value); };
158inline constexpr std::uint16_t
operator"" _u16(
unsigned long long int value) {
return static_cast<uint16_t
>(
value); };
159inline constexpr std::int16_t
operator"" _i16(
unsigned long long int value) {
return static_cast<int16_t
>(
value); };
165inline constexpr size_t pow2(
size_t n)
noexcept
170inline constexpr size_t toBits(
size_t bytes)
noexcept {
return bytes * 8; };
181 static_assert(std::is_integral_v<T>,
"Type is not integral");
182 static_assert(std::is_unsigned_v<T>,
"only defined for unsigned numbers");
183 if (
x >
static_cast<T
>(0)) {
184 return internal::log2UIntNZ<T>(
x);
186 return static_cast<T
>(0);
190template <
typename Freq_IT>
199template <
typename T, std::enable_if_t<std::is_
integral_v<T>,
bool> = true>
203 const int64_t diff =
max -
min;
214 size_t sanitizedPrecision{};
215 if (renormPrecision != 0) {
217 LOG_IF(
debug, (sanitizedPrecision != renormPrecision)) << fmt::format(
"Renorming precision {} is not in valid interval [{},{}], rounding to {} ",
224 sanitizedPrecision = 0;
226 return sanitizedPrecision;
230[[nodiscard]]
inline size_t constexpr nBytesTo(
size_t nBytes)
noexcept
232 const size_t nOthers = nBytes /
sizeof(T) + (nBytes %
sizeof(T) > 0);
239 const bool isZeroMessage = renormPrecision == 0;
240 return isInInterval || isZeroMessage;
243template <
typename IT>
246 const auto diff = std::distance(iteratorPosition, upperBound);
248 throw OutOfBoundsError(fmt::format(
"Bounds of buffer violated by {} elements", std::abs(diff)));
255 void start() { mStart = std::chrono::high_resolution_clock::now(); };
256 void stop() { mStop = std::chrono::high_resolution_clock::now(); };
259 std::chrono::duration<double, std::milli> duration = mStop - mStart;
260 return duration.count();
265 std::chrono::duration<double, std::ratio<1>> duration = mStop - mStart;
266 return duration.count();
270 std::chrono::time_point<std::chrono::high_resolution_clock> mStart;
271 std::chrono::time_point<std::chrono::high_resolution_clock> mStop;
281 mElems.emplace_back(elem);
287 auto printSymbols = [&](
auto begin,
auto end) {
289 for (
auto it = begin; it !=
end; ++it) {
290 os << +static_cast<T>(*it) <<
" ,";
292 os << +static_cast<T>(*
end);
296 if (!logger.mElems.empty()) {
297 if (logger.mReverse) {
298 printSymbols(logger.mElems.rbegin(), logger.mElems.rend());
300 printSymbols(logger.mElems.begin(), logger.mElems.end());
308 std::vector<T> mElems{};
309 bool mReverse{
false};
312template <
typename T,
typename IT>
313inline constexpr bool isCompatibleIter_v = std::is_convertible_v<typename std::iterator_traits<IT>::value_type, T>;
315template <
typename IT>
316inline constexpr bool isIntegralIter_v = std::is_integral_v<typename std::iterator_traits<IT>::value_type>;
std::array< int, 64 > reverse(std::array< int, 64 > a)
JSONArrayLogger & operator<<(const T &elem)
JSONArrayLogger(bool reverse=false)
friend std::ostream & operator<<(std::ostream &os, const JSONArrayLogger &logger)
double getDurationS() noexcept
double getDurationMS() noexcept
GLuint GLuint64EXT address
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLfloat distance
GLsizei const GLfloat * value
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLboolean GLboolean GLboolean GLboolean a
constexpr size_t MinRenormPrecisionBits
constexpr size_t MaxRenormPrecisionBits
constexpr bool isPow2(T x) noexcept
uint32_t safeadd(uint32_t a, uint32_t b)
uint64_t load64(const void *__restrict src)
void write64(void *__restrict dest, uint64_t src)
constexpr uintptr_t adr2Bits(T *address) noexcept
count_t roundSymbolFrequency(double_t rescaledFrequency)
constexpr size_t numBitsForNSymbols(size_t nSymbols) noexcept
constexpr float_t fastlog2(float_t x) noexcept
constexpr size_t numSymbolsWithNBits(size_t bits) noexcept
constexpr T log2UIntNZ(T x) noexcept
uint32_t symbolLengthBits(uint32_t x) noexcept
constexpr uint32_t getRangeBits(T min, T max) noexcept
constexpr size_t pow2(size_t n) noexcept
constexpr T log2UInt(T x) noexcept
constexpr bool isValidRenormingPrecision(size_t renormPrecision)
constexpr size_t toBits() noexcept
size_t constexpr nBytesTo(size_t nBytes) noexcept
constexpr bool isIntegralIter_v
void checkBounds(IT iteratorPosition, IT upperBound)
constexpr size_t toBytes(size_t bits) noexcept
size_t sanitizeRenormingBitRange(size_t renormPrecision)
Freq_IT advanceIter(Freq_IT iter, std::ptrdiff_t distance)
constexpr bool isCompatibleIter_v
Common utility functions.