2022-04-01 04:06:53 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: auNumberUtils.hpp
|
|
|
|
Date: 2022-2-1
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#pragma once
|
|
|
|
|
2023-10-17 02:26:43 +00:00
|
|
|
template <typename A, typename B, typename Ret_t =
|
|
|
|
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
|
2024-03-01 22:33:50 +00:00
|
|
|
AUROXTL_CONSTEXPR Ret_t AuMin(const A &a, const B &b)
|
2022-04-01 04:06:53 +00:00
|
|
|
{
|
|
|
|
return a < b ? a : b;
|
|
|
|
}
|
|
|
|
|
2023-10-17 02:26:43 +00:00
|
|
|
template <typename A, typename B, typename Ret_t =
|
|
|
|
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
|
2024-03-01 22:33:50 +00:00
|
|
|
AUROXTL_CONSTEXPR Ret_t AuMax(const A &a, const B &b)
|
2022-04-01 04:06:53 +00:00
|
|
|
{
|
|
|
|
return a < b ? b : a;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
2024-03-01 22:33:50 +00:00
|
|
|
AUROXTL_CONSTEXPR const T AuConstPow(const T base, const AuUInt8 exponent)
|
2022-04-01 04:06:53 +00:00
|
|
|
{
|
|
|
|
return exponent ? base * AuConstPow(base, exponent - 1) : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
2024-03-01 22:33:50 +00:00
|
|
|
AUROXTL_CONSTEXPR const T AuPageRoundUp(const T value, const T pageSize)
|
2022-04-01 04:06:53 +00:00
|
|
|
{
|
|
|
|
return (value + (pageSize - 1)) & ~(pageSize - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
2024-03-01 22:33:50 +00:00
|
|
|
AUROXTL_CONSTEXPR const T AuPageRound(const T value, const T pageSize)
|
2022-04-01 04:06:53 +00:00
|
|
|
{
|
|
|
|
return value & ~(pageSize - 1);
|
2023-11-18 02:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: out of order
|
|
|
|
#include "auBitsUtils.hpp"
|
|
|
|
|
2024-01-07 03:40:04 +00:00
|
|
|
template <class T>
|
|
|
|
const bool AuIsPow2(const T value)
|
|
|
|
{
|
2024-02-23 11:45:24 +00:00
|
|
|
return (value) && ((value & (value - 1)) == 0);
|
2024-01-07 03:40:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 02:02:34 +00:00
|
|
|
template <class T>
|
|
|
|
const T AuRoundUpPow2(const T value)
|
|
|
|
{
|
2024-01-07 03:40:04 +00:00
|
|
|
if constexpr (AuIsSame_v<T, AuUInt16> ||
|
|
|
|
AuIsSame_v<T, AuUInt8>)
|
2023-11-18 02:02:34 +00:00
|
|
|
{
|
|
|
|
return AuRoundUpPow2<AuUInt32>(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AuUInt8 ret;
|
|
|
|
AuBitScanReverse(ret, value);
|
2024-01-07 03:40:04 +00:00
|
|
|
return T(1) << (T(ret) + T(T(1) << T(ret) == value ? 0 : 1));
|
2023-11-18 02:02:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
const T AuRoundDownPow2(const T value)
|
|
|
|
{
|
2024-01-07 03:40:04 +00:00
|
|
|
if constexpr (AuIsSame_v<T, AuUInt16> ||
|
|
|
|
AuIsSame_v<T, AuUInt8>)
|
2023-11-18 02:02:34 +00:00
|
|
|
{
|
|
|
|
return AuRoundDownPow2<AuUInt32>(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AuUInt8 ret;
|
|
|
|
AuBitScanReverse(ret, value);
|
2024-01-07 03:40:04 +00:00
|
|
|
return T(1) << T(ret);
|
2023-11-18 02:02:34 +00:00
|
|
|
}
|
2024-03-01 22:33:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace AuHash
|
|
|
|
{
|
|
|
|
template <class T>
|
|
|
|
struct less;
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
struct equal;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T = void>
|
|
|
|
struct AuLess
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return (AuHash::less<T> {})(lhs, rhs);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct AuLess<void>
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
template <class T>
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return (AuHash::less<T> {})(lhs, rhs);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T = void>
|
|
|
|
struct AuGreater
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return !((AuHash::equal<T> {})(lhs, rhs)) &&
|
|
|
|
!((AuHash::less<T> {})(lhs, rhs));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct AuGreater<void>
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
template <class T>
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return !((AuHash::equal<T> {})(lhs, rhs)) &&
|
|
|
|
!((AuHash::less<T> {})(lhs, rhs));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T = void>
|
|
|
|
struct AuEqual
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return (AuHash::equal<T> {})(lhs, rhs);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct AuEqual<void>
|
|
|
|
{
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
template <class T>
|
|
|
|
bool operator()(const T &lhs, const T &rhs) const
|
|
|
|
{
|
|
|
|
return (AuHash::equal<T> {})(lhs, rhs);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// intentionally not constexpr (but it should compile down to nothing)
|
|
|
|
template <class T>
|
|
|
|
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 <class T, class Compare>
|
|
|
|
const T &AuClamp(const T &v, const T &lo, const T &hi, Compare comp)
|
|
|
|
{
|
|
|
|
return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
|
2022-04-01 04:06:53 +00:00
|
|
|
}
|