AuROXTL/Include/auROXTL/auNumberUtils.hpp

97 lines
2.1 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auNumberUtils.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
template <typename A, typename B, typename Ret_t =
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
constexpr Ret_t AuMin(const A &a, const B &b)
{
return a < b ? a : b;
}
template <typename A, typename B, typename Ret_t =
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
constexpr Ret_t AuMax(const A &a, const B &b)
{
return a < b ? b : a;
}
template <class T>
constexpr const T AuConstPow(const T base, const AuUInt8 exponent)
{
return exponent ? base * AuConstPow(base, exponent - 1) : 1;
}
template <class T>
constexpr const T AuPageRoundUp(const T value, const T pageSize)
{
return (value + (pageSize - 1)) & ~(pageSize - 1);
}
template <class T>
constexpr const T AuPageRound(const T value, const T pageSize)
{
return value & ~(pageSize - 1);
}
// TODO: out of order
#include "auBitsUtils.hpp"
template <class T>
const bool AuIsPow2(const T value)
{
return (value) && (value & (value - 1) == 0);
}
template <class T>
const T AuNextPow2(const T value)
{
if constexpr (AuIsSame_v<T, AuUInt16> ||
AuIsSame_v<T, AuUInt8>)
{
return AuNextPow2<AuUInt32>(value);
}
else
{
AuUInt8 ret;
AuBitScanReverse(ret, value);
return T(1) << (T(ret) + T(1));
}
}
template <class T>
const T AuRoundUpPow2(const T value)
{
if constexpr (AuIsSame_v<T, AuUInt16> ||
AuIsSame_v<T, AuUInt8>)
{
return AuRoundUpPow2<AuUInt32>(value);
}
else
{
AuUInt8 ret;
AuBitScanReverse(ret, value);
return T(1) << (T(ret) + T(T(1) << T(ret) == value ? 0 : 1));
}
}
template <class T>
const T AuRoundDownPow2(const T value)
{
if constexpr (AuIsSame_v<T, AuUInt16> ||
AuIsSame_v<T, AuUInt8>)
{
return AuRoundDownPow2<AuUInt32>(value);
}
else
{
AuUInt8 ret;
AuBitScanReverse(ret, value);
return T(1) << T(ret);
}
}