[+] Document auCopyMoveUtils

[*] Memory Model
[*] TryConstruct shall permit extensions of the bool class (use it like a tag)
[*] Formatting
This commit is contained in:
Reece Wilson 2022-03-26 12:02:08 +00:00
parent 8f5029a120
commit 74a0e92d32
6 changed files with 86 additions and 45 deletions

View File

@ -26,6 +26,7 @@ namespace Aurora::Memory
inline virtual void *Get() override
{
ThrowNullException();
return {};
}
};
@ -88,7 +89,7 @@ namespace Aurora::Memory
}
template <class T_t, typename B_t>
ExSharedPtr(ExSharedPtr<T_t, B_t> &&in, element_type *ptr) : Base_t(in.BasePointerType(), ptr)
ExSharedPtr(ExSharedPtr<T_t, B_t> &&in, element_type *ptr) : Base_t(AuMove(in.BasePointerType()), ptr)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();

View File

@ -143,23 +143,35 @@ static AuUInt8 AuPopCnt(T in)
{
#if defined(AURORA_COMPILER_MSVC)
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
#if defined(AURORA_ARCH_X64)
if constexpr (sizeof(T) == sizeof(AuUInt64))
return _mm_popcnt_u64(static_cast<AuUInt64>(in));
else
#endif
#if defined(AURORA_ARCH_X64)
if constexpr (sizeof(T) == sizeof(AuUInt64))
{
return _mm_popcnt_u64(static_cast<AuUInt64>(in));
}
else
#endif
if constexpr (sizeof(T) == sizeof(unsigned int))
{
return __popcnt(static_cast<unsigned int>(in));
}
else if constexpr (sizeof(T) <= sizeof(AuUInt16))
{
return __popcnt16(static_cast<AuUInt16>(in));
}
#endif
#else
if constexpr (sizeof(T) == sizeof(unsigned long long))
{
return __builtin_popcountll(static_cast<unsigned long long>(in));
}
else if constexpr (sizeof(T) == sizeof(unsigned long))
{
return __builtin_popcountl(static_cast<unsigned long>(in));
}
else if constexpr (sizeof(T) == sizeof(unsigned int))
{
return __builtin_popcount(static_cast<unsigned int>(in));
}
#endif
#if defined(AU_CPU_ENDIAN_LITTLE)
@ -191,15 +203,12 @@ static AuUInt8 AuPopCnt(T in)
}
#endif
if constexpr (sizeof(T) == sizeof(AuUInt16))
if constexpr ((sizeof(T) == sizeof(AuUInt16)) ||
(sizeof(T) == sizeof(AuUInt8)))
{
return AuPopCnt<AuUInt32>(in);
return AuPopCnt<AuUInt32>(AuUInt32(in));
}
else if constexpr (sizeof(T) == sizeof(AuUInt16))
{
return AuPopCnt<AuUInt32>(in);
}
return {};
}

View File

@ -7,30 +7,56 @@
***/
#pragma once
/**
* @brief Upcasts R-Value upcastable @param arg.
* For an L-Value equivalent hint, use AuReference
* @tparam T
* @param arg
* @return
*/
template <class T>
constexpr AuRemoveReference_t<T> &&AuMove(T &&arg)
{
return static_cast<AuRemoveReference_t<T> &&>(arg);
}
/**
* @brief Upcasts L-Value upcastable @param arg.
* For an R-Value equivalent hint, use AuMove
* @tparam T An expression to implicitly upcast to an L-value
* @param arg
* @return
*/
template <class T>
constexpr T &AuReference(T &arg)
{
return static_cast<T &>(arg);
}
/**
* @brief Preserves R or L value without reducing; implicit AuMove or AuReference
* @tparam T An expression to implicitly upcast to an R-value
* @param arg
* @return
*/
template <class T>
constexpr T &&AuForward(AuRemoveReference_t<T> &arg)
{
return static_cast<T &&>(arg);
}
/**
* @brief Preserves R or L value without reducing; implicit AuMove or AuReference
* @tparam T
* @param arg
* @return
*/
template <class T>
constexpr T &&AuForward(AuRemoveReference_t<T> &&arg)
{
return static_cast<T &&>(arg);
}
template <class T>
constexpr T &AuReference(T &arg)
{
return static_cast<T &>(arg);
}
template <class T, class U = T>
inline T AuExchange(T &obj, U &&newValue)
{

View File

@ -114,13 +114,14 @@ template <class Z, typename T>
static void auline AuSafeDelete(T *in)
{
static_assert(AuIsBaseOf_v<T, AuRemovePointer_t<Z>>, "Couldn't not safe delete from type T because it is not derived from Z");
auto cast = dynamic_cast<Z>(in);
if (cast == nullptr)
if (in == nullptr)
{
Z re;
SysPanic("Tried to free: 0x{:x}, type \"{}\" was not inherited from \"{}\"", AuUInt(in), typeid(in).name(), typeid(re).name());
SysPanic("Tried to free: 0x{:x}, type \"{}\" / \"{}\"", AuUInt(in), typeid(in).name(), typeid(re).name());
}
delete cast;
delete static_cast<Z>(in);
}
#else

View File

@ -17,5 +17,5 @@ struct AuCtorCode_t
}
static constexpr AuCtorCode_t Failed () { return AuCtorCode_t {false}; }
static constexpr AuCtorCode_t Success() { return AuCtorCode_t {true}; }
static constexpr AuCtorCode_t Success() { return AuCtorCode_t {true}; }
};

View File

@ -7,43 +7,45 @@
***/
#pragma once
template <class T, typename ... Args>
inline T AuTryConstruct(AuCtorCode_t &status, Args&& ... args)
#define _AU_TRYCONTRUST_CHECKCODE AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<CtorCode_t, AuCtorCode_t> || AuIsBaseOf_v<AuCtorCode_t, CtorCode_t>)
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline T AuTryConstruct(CtorCode_t &status, Args&& ... args)
{
if constexpr (AuIsConstructible<T, AuCtorCode_t &, Args ...>::type::value)
if constexpr (AuIsConstructible_v<T, AuCtorCode_t &, Args ...>)
{
status = AuCtorCode_t::Failed();
status = CtorCode_t::Failed();
return T(status, AuForward<T>(args)...);
}
else
{
try
{
status = AuCtorCode_t::Success();
status = CtorCode_t::Success();
return T(AuForward<T>(args)...);
}
catch (...)
{
status = AuCtorCode_t::Failed();
status = CtorCode_t::Failed();
return T();
}
}
}
template <class T, typename ... Args>
inline AuPair<AuCtorCode_t, T> AuTryConstructPair(Args&& ... args)
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline AuPair<CtorCode_t, T> AuTryConstructPair(Args&& ... args)
{
AuCtorCode_t code;
T object = AuTryConstruct<T, Args...>(AuReference(code), AuForward<Args>(args)...);
CtorCode_t code;
T object = AuTryConstruct<T, CtorCode_t, Args...>(AuReference(code), AuForward<Args>(args)...);
return AuMakePair(AuMove(code), AuMove(object));
}
template <class T, typename ... Args>
inline T AuTryConstructWithDefault(AuCtorCode_t &status, T &&def, Args&& ... args)
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline T AuTryConstructWithDefault(CtorCode_t &status, T &&def, Args&& ... args)
{
if constexpr (AuIsConstructible<T, AuCtorCode_t &, Args ...>::type::value)
if constexpr (AuIsConstructible_v<T, CtorCode_t &, Args ...>)
{
status = AuCtorCode_t::Failed();
status = CtorCode_t::Failed();
T returnValue = T(status, AuForward<T>(args)...);
if (!status)
{
@ -55,21 +57,23 @@ inline T AuTryConstructWithDefault(AuCtorCode_t &status, T &&def, Args&& ... arg
{
try
{
status = AuCtorCode_t::Success();
status = CtorCode_t::Success();
return T(AuForward<T>(args)...);
}
catch (...)
{
status = AuCtorCode_t::Failed();
status = CtorCode_t::Failed();
return AuMove(def);
}
}
}
template <class T, typename ... Args>
inline AuPair<AuCtorCode_t, T> AuTryConstructWithDefaultPair(T &&def, Args&& ... args)
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline AuPair<CtorCode_t, T> AuTryConstructWithDefaultPair(T &&def, Args&& ... args)
{
AuCtorCode_t code;
T object = AuTryConstructWithDefault<T, Args...>(AuReference(code), AuFoward(def), AuForward<Args>(args)...);
CtorCode_t code;
T object = AuTryConstructWithDefault<T, CtorCode_t, Args...>(AuReference(code), AuFoward(def), AuForward<Args>(args)...);
return AuMakePair(AuMove(code), AuMove(object));
}
}
#undef _AU_TRYCONTRUST_CHECKCODE