/*** 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 , A, AuCommonType_t>> AUROXTL_CONSTEXPR Ret_t AuMin(const A &a, const B &b) { return a < b ? a : b; } template , A, AuCommonType_t>> AUROXTL_CONSTEXPR Ret_t AuMax(const A &a, const B &b) { return a < b ? b : a; } template AUROXTL_CONSTEXPR const T AuConstPow(const T base, const AuUInt8 exponent) { return exponent ? base * AuConstPow(base, exponent - 1) : 1; } template AUROXTL_CONSTEXPR const T AuPageRoundUp(const T value, const T pageSize) { return (value + (pageSize - 1)) & ~(pageSize - 1); } template AUROXTL_CONSTEXPR const T AuPageRound(const T value, const T pageSize) { return value & ~(pageSize - 1); } // TODO: out of order #include "auBitsUtils.hpp" template const bool AuIsPow2(const T value) { return (value) && ((value & (value - 1)) == 0); } template const T AuNextPow2(const T value) { if constexpr (AuIsSame_v || AuIsSame_v) { return AuNextPow2(value); } else { AuUInt8 ret; AuBitScanReverse(ret, value); return T(1) << (T(ret) + T(1)); } } template const T AuRoundUpPow2(const T value) { if constexpr (AuIsSame_v || AuIsSame_v) { return AuRoundUpPow2(value); } else { AuUInt8 ret; AuBitScanReverse(ret, value); return T(1) << (T(ret) + T(T(1) << T(ret) == value ? 0 : 1)); } } template const T AuRoundDownPow2(const T value) { if constexpr (AuIsSame_v || AuIsSame_v) { return AuRoundDownPow2(value); } else { AuUInt8 ret; AuBitScanReverse(ret, value); return T(1) << T(ret); } } namespace AuHash { template struct less; template struct equal; } template struct AuLess { // intentionally not constexpr (but it should compile down to nothing) bool operator()(const T &lhs, const T &rhs) const { return (AuHash::less {})(lhs, rhs); } }; template <> struct AuLess { // intentionally not constexpr (but it should compile down to nothing) template bool operator()(const T &lhs, const T &rhs) const { return (AuHash::less {})(lhs, rhs); } }; template struct AuGreater { // intentionally not constexpr (but it should compile down to nothing) bool operator()(const T &lhs, const T &rhs) const { return !((AuHash::equal {})(lhs, rhs)) && !((AuHash::less {})(lhs, rhs)); } }; template <> struct AuGreater { // intentionally not constexpr (but it should compile down to nothing) template bool operator()(const T &lhs, const T &rhs) const { return !((AuHash::equal {})(lhs, rhs)) && !((AuHash::less {})(lhs, rhs)); } }; template struct AuEqual { // intentionally not constexpr (but it should compile down to nothing) bool operator()(const T &lhs, const T &rhs) const { return (AuHash::equal {})(lhs, rhs); } }; template <> struct AuEqual { // intentionally not constexpr (but it should compile down to nothing) template bool operator()(const T &lhs, const T &rhs) const { return (AuHash::equal {})(lhs, rhs); } }; // intentionally not constexpr (but it should compile down to nothing) template const T &AuClamp(const T &v, const T &lo, const T &hi) { return AuClamp(v, lo, hi, AuLess {}); } // intentionally not constexpr (but it should compile down to nothing) template const T &AuClamp(const T &v, const T &lo, const T &hi, Compare comp) { return comp(v, lo) ? lo : comp(hi, v) ? hi : v; }