[+] AuClamp and AuInvoke

This commit is contained in:
Reece Wilson 2024-03-01 22:33:50 +00:00
parent a43817624d
commit cb6bf3ec74
5 changed files with 267 additions and 150 deletions

View File

@ -11,7 +11,7 @@
// Exception model
////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined(AUROXTL_NO_TRY)
#if !defined(AUROXTL_NO_TRY) && !defined(AURORA_ROXTL_NO_TRY)
#define AUROXTL_COMMODITY_TRY try
#define AUROXTL_COMMODITY_CATCH catch (...)
#else
@ -19,6 +19,13 @@
#define AUROXTL_COMMODITY_CATCH while (0)
#endif
#if !defined(AUROXTL_NO_CONSTEXPR) && !defined(AURORA_ROXTL_NO_CONSTEXPR)
#define AUROXTL_CONSTEXPR constexpr
#else
#define AUROXTL_CONSTEXPR
#endif
////////////////////////////////////////////////////////////////////////////////////////////////
// Stinky container config (leave it alone)
////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -9,32 +9,32 @@
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)
AUROXTL_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)
AUROXTL_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)
AUROXTL_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)
AUROXTL_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)
AUROXTL_CONSTEXPR const T AuPageRound(const T value, const T pageSize)
{
return value & ~(pageSize - 1);
}
@ -95,3 +95,91 @@ const T AuRoundDownPow2(const T value)
return T(1) << T(ret);
}
}
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;
}

View File

@ -4,33 +4,18 @@
File: auOptional.hpp
Date: 2022-2-1
Author: Reece
Warning: deprecated
***/
#pragma once
#include "ThirdParty/tartanllamaOptional.hpp"
#if defined(DO_NOT_USEtartanllama)
#if !defined(AURORA_RUNTIME_AU_OPTIONAL)
#define AURORA_RUNTIME_AU_OPTIONAL std::optional
#endif
#else
#include "ThirdParty/tartanllamaOptional.hpp"
#if !defined(AURORA_RUNTIME_AU_OPTIONAL)
#define AURORA_RUNTIME_AU_OPTIONAL tl::optional
#endif
#endif
#if defined(_AURORA_AVOID_DUMB_STL_TYPES)
template <class T>
using AuOptional = AuOptionalEx<T>;
#else
template <class T>
using AuOptional = AURORA_RUNTIME_AU_OPTIONAL<T>;
#if !defined(AURORA_RUNTIME_AU_OPTIONAL)
#define AURORA_RUNTIME_AU_OPTIONAL tl::optional
#endif
template <class T>
using AuOptional = AURORA_RUNTIME_AU_OPTIONAL<T>;
template <class T>
constexpr inline bool AuIsOptional_v = __audetail::AuHashas_value_v<T>;

View File

@ -4,104 +4,15 @@
File: auOptionalEx.hpp
Date: 2022-3-23
Author: Reece
Warning: deprecated
***/
#pragma once
#include "auCopyMoveUtils.hpp"
#include "auHashUtils.hpp"
#if defined(DO_NOT_USEtartanllama)
// @DEPRECATED
// WONT FINISH, probably
// Use forked tartanllama optional instead (aurora should compile with either)
template <class T>
struct AuOptionalEx
{
bool hasValue;
T type;
AuOptionalEx() : hasValue(false)
{}
AuOptionalEx(const T &value) : type(value), hasValue(true)
{}
AuOptionalEx(T &&value) : type(value), hasValue(true)
{}
T &Value()
{
return type;
}
const T &Value() const
{
return type;
}
template <class U>
constexpr T ValueOr(U &&defaultValue) const &
{
return bool(*this) ? value() : static_cast<T>(AuForward<U>(defaultValue));
}
template <class U>
constexpr T ValueOr(U &&defaultValue) &&
{
return bool(*this) ? AuMove(value()) : static_cast<T>(AuForward<U>(defaultValue));
}
bool HasValue() const
{
return this->hasValue;
}
operator bool() const
{
return this->hasValue;
}
T &value()
{
return this->type;
}
const T &value() const
{
return this->type;
}
bool has_value() const
{
return this->hasValue;
}
AuUInt HashCode() const
{
return AuHashCode(type);
}
void Reset()
{
this->type = {};
this->hasValue = {};
}
void Swap(AuOptionalEx &&ex)
{
AuSwap(this->type, ex.type);
AuSwap(this->hasValue, ex.hasValue);
}
// TODO finish me
};
#else
#include "ThirdParty/tartanllamaOptional.hpp"
template <typename T>
using AuOptionalEx = tl::optional<T>;
#endif

View File

@ -4,22 +4,23 @@
File: auTemplateMeta.hpp
Date: 2022-2-1
Author: Reece
Note: most of this code assumes C++17 or greater
***/
#pragma once
template <bool v>
struct AuBoolType
{
static constexpr bool value = v;
static AUROXTL_CONSTEXPR bool value = v;
using value_type = bool;
using type = AuBoolType;
constexpr operator value_type() const noexcept
AUROXTL_CONSTEXPR operator value_type() const noexcept
{
return value;
}
constexpr value_type operator()() const noexcept
AUROXTL_CONSTEXPR value_type operator()() const noexcept
{
return value;
}
@ -56,13 +57,13 @@ struct AuIsSame<T, T> : AuTrueType
{};
template <class T, class U>
inline constexpr bool AuIsSame_v = AuIsSame<T, U>::value;
inline AUROXTL_CONSTEXPR bool AuIsSame_v = AuIsSame<T, U>::value;
template <class>
inline constexpr bool AuIsConst_v = false;
inline AUROXTL_CONSTEXPR bool AuIsConst_v = false;
template <class T>
inline constexpr bool AuIsConst_v<const T> = true;
inline AUROXTL_CONSTEXPR bool AuIsConst_v<const T> = true;
namespace _audetail
{
@ -93,7 +94,7 @@ struct AuIsClass : decltype(_audetail::IsClass<T>(nullptr))
{};
template <class T>
inline constexpr bool AuIsClass_v = AuIsClass<T>::value;
inline AUROXTL_CONSTEXPR bool AuIsClass_v = AuIsClass<T>::value;
template <class Base, typename Derived>
struct AuIsBaseOf :
@ -105,43 +106,43 @@ struct AuIsBaseOf :
{};
template <class Base, typename Derived>
inline constexpr bool AuIsBaseOf_v = AuIsBaseOf<Base, Derived>::value;
inline AUROXTL_CONSTEXPR bool AuIsBaseOf_v = AuIsBaseOf<Base, Derived>::value;
template <class>
inline constexpr bool AuIsPointer_v = false;
inline AUROXTL_CONSTEXPR bool AuIsPointer_v = false;
template <class T>
inline constexpr bool AuIsPointer_v<T *> = true;
inline AUROXTL_CONSTEXPR bool AuIsPointer_v<T *> = true;
template <class T>
inline constexpr bool AuIsPointer_v<T *const> = true;
inline AUROXTL_CONSTEXPR bool AuIsPointer_v<T *const> = true;
template <class T>
inline constexpr bool AuIsPointer_v<T *volatile> = true;
inline AUROXTL_CONSTEXPR bool AuIsPointer_v<T *volatile> = true;
template <class T>
inline constexpr bool AuIsPointer_v<T *const volatile> = true;
inline AUROXTL_CONSTEXPR bool AuIsPointer_v<T *const volatile> = true;
template <class>
inline constexpr bool AuIsReference_v = false;
inline AUROXTL_CONSTEXPR bool AuIsReference_v = false;
template <class T>
inline constexpr bool AuIsReference_v<T &> = true;
inline AUROXTL_CONSTEXPR bool AuIsReference_v<T &> = true;
template <class T>
inline constexpr bool AuIsReference_v<T &&> = true;
inline AUROXTL_CONSTEXPR bool AuIsReference_v<T &&> = true;
template <class>
inline constexpr bool AuIsLValueReference_v = false;
inline AUROXTL_CONSTEXPR bool AuIsLValueReference_v = false;
template <class T>
inline constexpr bool AuIsLValueReference_v<T &> = true;
inline AUROXTL_CONSTEXPR bool AuIsLValueReference_v<T &> = true;
template <class>
inline constexpr bool AuIsRValueReference_v = false;
inline AUROXTL_CONSTEXPR bool AuIsRValueReference_v = false;
template <class T>
inline constexpr bool AuIsRValueReference_v<T &&> = true;
inline AUROXTL_CONSTEXPR bool AuIsRValueReference_v<T &&> = true;
template <class T>
struct AuRemovePointer
@ -180,7 +181,7 @@ template <class T>
using AuIsVoid = AuIsSame<void, T>;
template <class T>
inline constexpr bool AuIsVoid_v = AuIsVoid<T>::value;
inline AUROXTL_CONSTEXPR bool AuIsVoid_v = AuIsVoid<T>::value;
template <class T>
struct AuRemoveReference
@ -310,13 +311,13 @@ template <class ... Ts>
using AuVoid_t = void;
template <class>
constexpr inline bool AuIsArray_v = false;
AUROXTL_CONSTEXPR inline bool AuIsArray_v = false;
template <class T, size_t Len>
inline constexpr bool AuIsArray_v<T[Len]> = true;
inline AUROXTL_CONSTEXPR bool AuIsArray_v<T[Len]> = true;
template <class T>
inline constexpr bool AuIsArray_v<T[]> = true;
inline AUROXTL_CONSTEXPR bool AuIsArray_v<T[]> = true;
template <bool Test, class T = void>
using AuEnableIf_t = typename AuEnableIf<Test, T>::type;
@ -324,8 +325,8 @@ using AuEnableIf_t = typename AuEnableIf<Test, T>::type;
template <class T, class ... Args>
struct AuIsConstructible
{
template <class C, class ... Args2> static constexpr AuTrueType Test(decltype(::new C(AuDeclVal<Args2>()...)));
template <class C, class ... Args2> static constexpr AuFalseType Test(...);
template <class C, class ... Args2> static AUROXTL_CONSTEXPR AuTrueType Test(decltype(::new C(AuDeclVal<Args2>()...)));
template <class C, class ... Args2> static AUROXTL_CONSTEXPR AuFalseType Test(...);
using type = decltype(Test<T, Args...>(0));
};
@ -333,7 +334,7 @@ template <class T, class ... Args>
using AuIsConstructible_t = typename AuIsConstructible<T, Args ...>::type;
template <class T, class ... Args>
inline constexpr bool AuIsConstructible_v = AuIsConstructible<T, Args ...>::type::value;
inline AUROXTL_CONSTEXPR bool AuIsConstructible_v = AuIsConstructible<T, Args ...>::type::value;
template <bool Test, class T, class T2>
struct AuConditional
@ -371,8 +372,8 @@ template <template <class...> class Base, typename Derived>
struct AuIsBaseOfTemplateImpl
{
template <class... Ts>
static constexpr AuTrueType Test(const Base<Ts...> *);
static constexpr AuFalseType Test(...);
static AUROXTL_CONSTEXPR AuTrueType Test(const Base<Ts...> *);
static AUROXTL_CONSTEXPR AuFalseType Test(...);
using type = decltype(Test(AuDeclVal<AuRemoveReference_t<Derived> *>()));
};
@ -380,7 +381,9 @@ template <template <class...> class Base, typename Derived>
using AuIsBaseOfTemplate = typename AuIsBaseOfTemplateImpl<Base, Derived>::type;
template <template <class...> class Base, typename Derived>
inline constexpr bool AuIsBaseOfTemplate_v = AuIsBaseOfTemplateImpl<Base, Derived>::type::value;
inline AUROXTL_CONSTEXPR bool AuIsBaseOfTemplate_v = AuIsBaseOfTemplateImpl<Base, Derived>::type::value;
#if !defined(AURORA_ROXTL_NO_STD)
// :(
// we have a boost licensed call traits in auv8pp
@ -394,13 +397,15 @@ inline constexpr bool AuIsBaseOfTemplate_v = AuIsBaseOfTemplateImpl<Base, Derive
using AuResultOf_t = typename std::invoke_result_t<T, Args...>;
#endif
#endif
template <class Func, class ...Params>
struct AuCallable : decltype(_audetail::IsCallable<Func, Params...>(0))
{
};
template <class F, class... Args>
constexpr auto AuIsCallable_v = AuCallable<F, Args...>::value;
AUROXTL_CONSTEXPR auto AuIsCallable_v = AuCallable<F, Args...>::value;
#include "auCopyMoveUtils.hpp"
@ -431,6 +436,43 @@ static auto AuGetAmbiguousMethod2(Ret_t(T :: *a)(Args...))
}
// According to MSVC: "only function types and reference types can't be const qualified"
#if 0
// MSVCs implementation is as follows:
// Our implementation is found in ./auTemplateMetaIsFunction.hpp
template <class T>
AUROXTL_CONSTEXPR bool AuIsFunction_v = !AuIsConst_v<const T> && !AuIsReference_v<T>;
template <class T>
struct AuIsFunction : AuBoolType<AuIsFunction_v<T>>
{ };
#endif
// Continuing on: this is how MSVC defines std::is_object in contrast to std::is_function
template <class T>
AUROXTL_CONSTEXPR bool AuIsObject_v = AuIsConst_v<const T> && !AuIsVoid_v<T>;
template <class T>
struct AuIsObject : AuBoolType<AuIsObject_v<T>>
{ };
#if defined(AURORA_COMPILER_CLANG)
template <class T>
AUROXTL_CONSTEXPR bool AuIsMemberFunctionPointer_v = __is_member_function_pointer(T);
template <class T>
AUROXTL_CONSTEXPR bool AuIsMemberPointer_v = __is_member_pointer(T);
#elif defined(AURORA_COMPILER_MSVC) || defined(AURORA_ROXTL_NO_NO_STD)
template <class T>
AUROXTL_CONSTEXPR bool AuIsMemberFunctionPointer_v = std::is_member_function_pointer_v<T>;
template <class T>
AUROXTL_CONSTEXPR bool AuIsMemberPointer_v = std::is_member_object_pointer_v<T> || AuIsMemberFunctionPointer_v<T>;
#endif
// I dont think I can easily implement these in templates
// For the sake of syntax sugar, these will be macros for now
#define AuGetAmbiguousMethod(Ret_t, Args, T, Method) AuGetAmbiguousMethod2<Ret_t, T, AU_BRACKET_SCOPE Args >(&T::Method)
@ -492,6 +534,65 @@ namespace _audetail
: common_type<typename common_type<T1, T2>::type, R...>
{ };
}
// yoinking: https://en.cppreference.com/w/cpp/utility/functional/invoke
template<class>
AUROXTL_CONSTEXPR bool is_reference_wrapper_v = false;
#if !defined(AURORA_ROXTL_NO_STD)
template<class U>
AUROXTL_CONSTEXPR bool is_reference_wrapper_v<std::reference_wrapper<U>> = true;
#endif
#if !defined(AU_LANG_CPP_14)
template<class T>
using remove_cvref_t = AuRemoveCV_t<AuRemoveReference_t<T>>;
template<class C, class Pointed, class Object, class... Args>
AUROXTL_CONSTEXPR decltype(auto) invoke_memptr(Pointed C:: *member, Object &&object,
Args&&... args)
{
using object_t = remove_cvref_t<Object>;
AUROXTL_CONSTEXPR bool bIsMemberFunction = AuIsFunction_v<Pointed>;
AUROXTL_CONSTEXPR bool bIsWrapped = is_reference_wrapper_v<object_t>;
AUROXTL_CONSTEXPR bool bIsDerivedObject = AuIsSame_v<C, object_t> || AuIsBaseOf_v<C, object_t>;
if AUROXTL_CONSTEXPR (bIsMemberFunction)
{
if AUROXTL_CONSTEXPR (bIsDerivedObject)
{
return (AuForward<Object>(object).*member)(AuForward<Args>(args)...);
}
else if AUROXTL_CONSTEXPR (bIsWrapped)
{
return (object.get().*member)(AuForward<Args>(args)...);
}
else
{
return ((*AuForward<Object>(object)).*member)(AuForward<Args>(args)...);
}
}
else
{
static_assert(AuIsObject_v<Pointed> && sizeof...(args) == 0);
if AUROXTL_CONSTEXPR (bIsDerivedObject)
{
return AuForward<Object>(object).*member;
}
else if AUROXTL_CONSTEXPR (bIsWrapped)
{
return object.get().*member;
}
else
{
return (*AuForward<Object>(object)).*member;
}
}
}
#endif
}
template <class T, class T2>
@ -499,3 +600,28 @@ using AuCommonType = typename _audetail::common_type<T, T2>;
template <class T, class T2>
using AuCommonType_t = typename _audetail::common_type<T, T2>::type;
#if !defined(AU_LANG_CPP_14)
template <class F, class... Args>
AUROXTL_CONSTEXPR AuResultOf_t<F, Args...> AuInvoke(F &&f, Args&&... args)
{
if AUROXTL_CONSTEXPR (AuIsMemberPointer_v<_audetail::remove_cvref_t<F>>)
{
return _audetail::invoke_memptr(f, AuForward<Args>(args)...);
}
else
{
return AuForward<F>(f)(AuForward<Args>(args)...);
}
}
#else
template <class F, class... Args>
AuResultOf_t<F, Args...> AuInvoke(F &&f, Args&&... args)
{
return AuForward<F>(std::invoke(f, AuForward<Args>(args)...));
}
#endif