[+] Added sources

This commit is contained in:
Reece Wilson 2022-04-01 05:06:53 +01:00
commit a19ae800aa
54 changed files with 5579 additions and 0 deletions

6
Aurora.json Normal file
View File

@ -0,0 +1,6 @@
{
"name": "auROXTL",
"type": "generic",
"include": "Include",
"noLink": true
}

32
Include/auROXTL.hpp Normal file
View File

@ -0,0 +1,32 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auROXTL.hpp
Date: 2022-2-2
Author: Reece
***/
#pragma once
#include <AuroraEnvironment.h>
#include <AuroraTypes.hpp>
#if defined(_AUHAS_AURORAENUM)
#include <AuroraForEach.hpp>
#include <AuroraInterfaces.hpp>
#include <AuroraEnum.hpp>
#endif
#if defined(_AUHAS_FMT)
#include <fmt/format.h>
#endif
#include "auROXTL/AU_Z.hpp"
#include "auROXTL/AU_MACROS.hpp"
#include "auROXTLTypes.hpp"
#if defined(_AUHAS_AURORAENUM)
#define _ALLOW_AURORA_ENUM_AUENVHPP
#include <AuroraCommon.hpp>
#endif
#include "auROXTLUtils.hpp"

View File

@ -0,0 +1,190 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuroraMacros.hpp
File: AU_MACROS.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
#define AU_COPY(type) type(const type&) = default; type &operator=(const type &) = default;
#define AU_MOVE(type) type(type&&) = default; type &operator=(type &&) = default;
#define AU_COPY_MOVE(type) AU_COPY(type) AU_MOVE(type)
#define AU_NO_COPY(type) type(const type&) = delete;
#define AU_NO_MOVE(type) type(type&&) = delete;
#define AU_NO_COPY_NO_MOVE(type) AU_NO_COPY(type) AU_NO_MOVE(type)
#if !defined(AU_SHARED_FROM_THIS)
#define AU_SHARED_FROM_THIS (AuStaticPointerCast<AuRemovePointer_t<decltype(this)>>(this->SharedFromThis()))
#endif
#if !defined(AU_WEAK_FROM_THIS)
#define AU_WEAK_FROM_THIS (AuWPtr<AuRemovePointer_t<decltype(this)>>(AuStaticPointerCast<AuRemovePointer_t<decltype(this)>>(this->SharedFromThis())))
#endif
#define AU_BRACKET_SCOPE(...) __VA_ARGS__
#if !defined(AU_TEMPLATE_ENABLE_WHEN)
#define AU_TEMPLATE_ENABLE_WHEN(...) typename AuEnableIf<__VA_ARGS__>::type* = nullptr
#endif
#define AU_WHAT(n) n
/// @hideinitializer
#define _AU_STRINGIFY(in) #in
#define AU_STRINGIFY(in) _AU_STRINGIFY(in)
/// @hideinitializer
#define _AU_CONCAT(a, b) a ## b
#define AU_CONCAT(a, b) _AU_CONCAT(a, b)
/// @hideinitializer
#define _AUKCON_STRINGIFY_X(in) AU_STRINGIFY(in)
#if !defined(AU_SHARED_API_EX)
#define AU_SHARED_API_EX(vis, name, type, ...) \
\
vis type *name ## New(__VA_ARGS__); \
vis void name ## Release(type *); \
static inline void name ## Destroy(type *val) \
{ \
name ## Release(val); \
} \
\
struct CppDeleter ## name \
{ \
void operator()(type *t) \
{ \
name ## Release(t); \
} \
}; \
\
using name ## Unique_t = AURORA_RUNTIME_AU_UNIQUE_PTR<type, CppDeleter ## name>; \
template <class ... T> \
name ## Unique_t name ## Unique(T... args) \
{ \
return name ## Unique_t(name ## New(args...)); \
} \
\
using name ## Shared_t = AuSPtr<type>; \
template <class ... T> \
name ## Shared_t name ## Shared(T... args) \
{ \
return name ## Shared_t(name ## New(args...), name ## Release); \
}
#endif
#if !defined(AU_SHARED_API)
#define AU_SHARED_API(name, type, ...) AU_SHARED_API_EX(, name, type, #__VA_ARGS__)
#endif
#if !defined(AU_NOINLINE)
#if defined(AURORA_COMPILER_MSVC)
#define AU_NOINLINE __declspec(noinline)
#else
#define AU_NOINLINE __attribute__((noinline))
#endif
#endif
#if !defined(AU_INLINE)
#if defined(AURORA_COMPILER_MSVC)
#define AU_INLINE __forceinline
#else
#define AU_INLINE __attribute__((always_inline))
#endif
#endif
#if !defined(AU_NORETURN)
#if defined(AURORA_COMPILER_MSVC)
#define AU_NORETURN __declspec(noreturn)
#elif (defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC))
#define AU_NORETURN __attribute__((noreturn))
#elif defined(AU_LANG_CPP)
#define AU_NORETURN [[noreturn]]
#else
#define AU_NORETURN
#endif
#endif
#if !defined(AU_ALLOC)
#if defined(AURORA_PLATFORM_WIN32)
#define AU_ALLOC __declspec(allocator)
#elif defined(AURORA_COMPILER_CLANG)
#define AU_ALLOC __declspec(allocator)
#elif defined(AURORA_COMPILER_GCC)
#define AU_ALLOC __attribute__((malloc))
#else
#define AU_ALLOC
#endif
#endif
#if !defined(NO__NEW)
#if !defined(_new)
#define _new new (std::nothrow)
#endif
#endif
#if !defined(NO__INLINE)
#if !defined(auline)
#define auline AU_INLINE
#endif
#endif
#if !defined(AU_FWD)
#define AU_FWD(var) AuForward<decltype(var)>(var)
#endif
#if !defined(AU_THROW_STRING)
#define AU_THROW_STRING(var) throw AuString(var)
#endif
#define AU_ITERATE_ARRAY(index, arry) AuUInt index = 0; index < AuArraySize(arry); index++
#define AU_ITERATE_N(index, n) AuUInt index = 0; index < n; index++
#define AU_ITERATE_N_TO_X(index, n, x) AuUInt index = n; index < x; index++
#define AU_ITERATE_BACKWARDS(index, lastIdx) AuUInt index = lastIdx; index <= 0; index--
#define AU_ITR_ARRAY AU_ITERATE_ARRAY
#define AU_ITR_N AU_ITERATE_N
#define AU_ITR_N_TO_X AU_ITERATE_N_TO_X
#define AU_ITR_BACKWARDS AU_ITERATE_BACKWARDS
#define AU_STRIP_BRACKETS_IMPL(...) __VA_ARGS__
#if !defined(AU_STRIP_BRACKETS)
#define AU_STRIP_BRACKETS(X) AU_WHAT(AU_STRIP_BRACKETS_IMPL X)
#endif
#if !defined(AU_STRIP)
#define AU_STRIP AU_STRIP_BRACKETS
#endif
#if !defined(AU_EMIT_FIRST)
#define AU_EMIT_FIRST(a, b)a
#endif
#if !defined(AU_EMIT_SECOND)
#define AU_EMIT_SECOND(a, b)b
#endif
#if !defined(AU_EMIT_BOTH)
#define AU_EMIT_BOTH(a, b)a, a
#endif
#if !defined(AuBindThis)
#define AuBindThis(method, ...) std::bind(method, this, ## __VA_ARGS__)
#endif
#if !defined(AuSharedFromThis)
#define AuSharedFromThis() AU_SHARED_FROM_THIS
#endif
#if !defined(AuWeakFromThis)
#define AuWeakFromThis() AU_SHARED_FROM_THIS
#endif
#define AU_EMIT_FIRST_COMMA_FIRST(n)n
#define AU_EMIT_FIRST_COMMA_OTHERS(n),n
#include "Objects/Objects.hpp"

73
Include/auROXTL/AU_Z.hpp Normal file
View File

@ -0,0 +1,73 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AU_Z.hpp
Date: 2022-3-26
Author: Reece
***/
#pragma once
////////////////////////////////////////////////////////////////////////////////////////////////
// Exception model
////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined(AUROXTL_NO_TRY)
#define AUROXTL_COMMODITY_TRY try
#define AUROXTL_COMMODITY_CATCH catch (...)
#else
#define AUROXTL_COMMODITY_TRY
#define AUROXTL_COMMODITY_CATCH while (0)
#endif
////////////////////////////////////////////////////////////////////////////////////////////////
// Stinky container config (leave it alone)
////////////////////////////////////////////////////////////////////////////////////////////////
#if (!defined(AURORA_ENGINE_KERNEL) && \
!defined(_AUHAS_AURORARUNTIME))
// If we're in our ecosystem, assume global allocator override in all modules
// std::allocator __will__ be Aurora::memory backed no matter what
//
// Externally, however, the ABI of the type matters.
// > We want the differing ABI for std
// > We want customers' STLs' containers' move/copy semantics to apply
// > ...w/o copying between container types
//
// Therefore, `#if !defined(aurora)
// #define USE_STL //(for source compatibility)
// #endif `
#define AURORA_ROXTL_ALLOCATORS_USE_STD
#endif
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
// Crossing API boundaries will resort in an alloc + copy
// Don't enable unless you're in the ecosystem
// Default behaviour (omitted): use the exact std::string type
#define AURORA_ROXTL_CONTAINERS_USE_PURE
#endif
////////////////////////////////////////////////////////////////////////////////////////////////
// Memory, AuSPtr, and Friends
////////////////////////////////////////////////////////////////////////////////////////////////
#if defined(AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED)
#define _AURORA_NULLEXPT_ENABLE_UB
#endif
#if defined(AURORA_ROXTL_NULL_POINTER_CHECKS_USE_COMPARE_OVER_INDIRECT_JMP)
#define _AURORA_NULLEXPT_BRANCH
#endif
#if defined(AURORA_ROXTL_NULL_POINTER_COMPARE_MODE_AGGRESSIVE)
#define _AURORA_NULLEXPT_BRANCH_BUG_CHECK
#endif
////////////////////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////////////////////
//#define _AURORA_NULLEXPT_USE_TRY_EMPLACE_AFTER_FIND

View File

@ -0,0 +1,131 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Objects.hpp
File: AuroraMacros.hpp
File: AU_MACROS.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
/*
AU_DEFINE_FOR_VA(Object,
(AU_DEFINE_CTOR_VA, // initializer-list-like ctor (extending a struct or adding a ctor will break initializer lists)
AU_DEFINE_THIS_MOVE_CTOR_VA, // add move `Object(Object &&)`
AU_DEFINE_EQUALS_VA, // add equals operator
AU_DEFINE_MOVE_VA, // add move assignment operator
AU_DEFINE_COPY_VA), // add copy assignment operator
(id, task));
*/
/// @hideinitializer
#define AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(variable) AuRemoveConst_t<AuRemoveReference_t<decltype(variable)>>
/// @hideinitializer
#define AU_EMIT_CTOR_CPY(pair) const AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(pair) &pair
/// @hideinitializer
#define AU_EMIT_CTOR_CPY_SECOND(pair) ,AU_EMIT_CTOR_CPY(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_MOV(pair) AU_EMIT_FIRST_TYPEREDUCED_PAIR_REDUCED(pair) &&pair
/// @hideinitializer
#define AU_EMIT_CTOR_MOV_SECOND(pair) ,AU_EMIT_CTOR_MOV(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN(pair) pair(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN_SECOND(pair) ,AU_EMIT_CTOR_ASSIGN(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN2(pair) pair(cpy.pair)
/// @hideinitializer
#define AU_EMIT_CTOR_ASSIGN2_SECOND(pair) ,AU_EMIT_CTOR_ASSIGN2(pair)
/// @hideinitializer
#define AU_EMIT_CTOR_MOVE_ASSIGN2(pair) pair(AuMove(cpy.pair))
/// @hideinitializer
#define AU_EMIT_CTOR_MOVE_ASSIGN2_SECOND(pair) ,AU_EMIT_CTOR_MOVE_ASSIGN2(pair)
/// @hideinitializer
#define AU_DEFINE_CTOR_VA_(thisType, args) AU_DEFINE_CTOR_CPY_VA(thisType, args) AU_DEFINE_CTOR_MOV_VA(thisType, args)
/// @deprecated
#define AU_DEFINE_CTOR_ONE(thisType, pairTypeName) AU_DEFINE_CTOR_VA_(thisType, (AU_EMIT_SECOND pairTypeName))
/// @hideinitializer
#define AU_DEFINE_EQUALS_VA_A(name) this->name == ref.name
/// @hideinitializer
#define AU_DEFINE_EQUALS_VA_B(name) && AU_DEFINE_EQUALS_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_EQUALS_HASHCODE_A(name) AuHashCode(this->name)
/// @hideinitializer
#define AU_DEFINE_EQUALS_HASHCODE_B(name) ^ AU_DEFINE_EQUALS_HASHCODE_A(name)
/// @hideinitializer
#define AU_DEFINE_MOVE_VA_A(name) this->name = AuMove(ref.name);
/// @hideinitializer
#define AU_DEFINE_MOVE_VA_B(name) AU_DEFINE_MOVE_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_COPY_VA_A(name) this->name = ref.name;
/// @hideinitializer
#define AU_DEFINE_COPY_VA_B(name) AU_DEFINE_COPY_VA_A(name)
/// @hideinitializer
#define AU_DEFINE_CTOR_CPY_VA(thisType, args) \
inline thisType(AU_FOR_EACH_FIRST(AU_EMIT_CTOR_CPY, AU_EMIT_CTOR_CPY_SECOND, AU_STRIP_BRACKETS(args))) : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN, AU_EMIT_CTOR_ASSIGN_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_CTOR_MOV_VA(thisType, args) \
inline thisType(AU_FOR_EACH_FIRST(AU_EMIT_CTOR_MOV, AU_EMIT_CTOR_MOV_SECOND, AU_STRIP_BRACKETS(args))) noexcept : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN, AU_EMIT_CTOR_ASSIGN_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_THIS_COPY_CTOR_VA(thisType, args) \
inline thisType(const thisType &cpy) : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_ASSIGN2, AU_EMIT_CTOR_ASSIGN2_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_THIS_MOVE_CTOR_VA(thisType, args) \
inline thisType(thisType &&cpy) noexcept : AU_FOR_EACH_FIRST(AU_EMIT_CTOR_MOVE_ASSIGN2, AU_EMIT_CTOR_MOVE_ASSIGN2_SECOND, AU_STRIP_BRACKETS(args)) \
{}
/// @hideinitializer
#define AU_DEFINE_FOR_VA_(pair, func) func(AU_EMIT_SECOND pair, AU_STRIP_BRACKETS(AU_EMIT_FIRST pair))
///
#define AU_DEFINE_HASHCODE_VA(thisType, args) AuUInt HashCode() const noexcept { return AU_FOR_EACH_FIRST(AU_DEFINE_EQUALS_HASHCODE_A, AU_DEFINE_EQUALS_HASHCODE_B, AU_STRIP_BRACKETS(args)) ; }
///
#define AU_DEFINE_CTOR_VA(thisType, args) AU_DEFINE_CTOR_CPY_VA(thisType, args) AU_DEFINE_CTOR_MOV_VA(thisType, args)
///
#define AU_DEFINE_EQUALS_VA(thisType, args) bool operator==(const thisType & ref) const noexcept { return AU_FOR_EACH_FIRST(AU_DEFINE_EQUALS_VA_A, AU_DEFINE_EQUALS_VA_B, AU_STRIP_BRACKETS(args)) ; }
///
#define AU_DEFINE_MOVE_VA(thisType, args) thisType& operator=( thisType && ref) noexcept { AU_FOR_EACH_FIRST(AU_DEFINE_MOVE_VA_A, AU_DEFINE_MOVE_VA_B, AU_STRIP_BRACKETS(args)) return *this; }
///
#define AU_DEFINE_COPY_VA(thisType, args) thisType& operator=(const thisType & ref) { AU_FOR_EACH_FIRST(AU_DEFINE_COPY_VA_A, AU_DEFINE_COPY_VA_B, AU_STRIP_BRACKETS(args)) return *this; }
//
#define AU_DEFINE_FOR_VA(type, arry, members) AU_FOR_EACH_THAT(AU_DEFINE_FOR_VA_, ((members), type), AU_STRIP_BRACKETS(arry))

View File

@ -0,0 +1,8 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ModuleApi.hpp
Date: 2022-3-31
Author: Reece
***/
#pragma once

View File

@ -0,0 +1,11 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Objects.hpp
Date: 2022-3-31
Author: Reece
***/
#pragma once
#include "ClassHelpers.hpp"
#include "ModuleApi.hpp"

View File

@ -0,0 +1,401 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ExtendStlLikeSharedPtr.hpp
Date: 2022-1-25
Author: Reece
***/
#pragma once
//#include <auROXTL/auCastUtils.hpp>
#include <auROXTL/auCopyMoveUtils.hpp>
namespace Aurora::Memory
{
inline void ThrowNullException();
namespace _detail
{
struct IPtrGet
{
virtual void *Get() = 0;
};
struct IPtrNoOpGet : IPtrGet
{
inline virtual void *Get() override
{
ThrowNullException();
return {};
}
};
inline IPtrNoOpGet gNoop;
}
template <class TType_t, class Base_t>
struct ExSharedPtr : Base_t
#if !defined(_AURORA_NULLEXPT_ENABLE_UB) && !defined(_AURORA_NULLEXPT_BRANCH)
, private _detail::IPtrGet
#endif
{
using element_type = typename Base_t::element_type;
using weak_type = typename Base_t::weak_type;
using base_type = Base_t;
using Base_t::Base_t;
ExSharedPtr() : Base_t()
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(Base_t &&in) : Base_t(in)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(ExSharedPtr &&in) : Base_t(in)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(const ExSharedPtr &in) : Base_t(in)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class T_t, typename B_t>
ExSharedPtr(const ExSharedPtr<T_t, B_t> &in) : Base_t(in.BasePointerType(), static_cast<T_t *>(in.get()))
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class T_t, typename B_t>
ExSharedPtr(ExSharedPtr<T_t, B_t> &&in) : Base_t(in.BasePointerType(), static_cast<T_t *>(in.get()))
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class T_t, typename B_t>
ExSharedPtr(ExSharedPtr<T_t, B_t> &&in, element_type *ptr) : Base_t(AuMove(in.BasePointerType()), ptr)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(Base_t &&in, element_type *ptr) : Base_t(in, ptr)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class T_t, typename B_t>
ExSharedPtr(const ExSharedPtr<T_t, B_t> &in, element_type *ptr) : Base_t(in.BasePointerType(), ptr)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(const Base_t &in, element_type *ptr) : Base_t(in, ptr)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
ExSharedPtr(const Base_t &in) : Base_t(in)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class Y = element_type, class Deleter_t, class Alloc_t>
ExSharedPtr(Y *in, Deleter_t del, Alloc_t alloc) : Base_t(in, del, alloc)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class Y = element_type, class Deleter_t>
ExSharedPtr(Y *in, Deleter_t del) : Base_t(in, del)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template < class Y, class Deleter >
ExSharedPtr(AURORA_RUNTIME_AU_UNIQUE_PTR<Y, Deleter> &&r) : Base_t(r)
{
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
template <class T_t, typename B_t>
void swap(ExSharedPtr<T_t, B_t> &in)
{
Base_t::swap(in.BasePointerType());
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
void swap(Base_t &r)
{
Base_t::swap(r);
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
}
void reset()
{
Base_t::reset();
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
#if !defined(_AURORA_NULLEXPT_BRANCH)
ptr = &_detail::gNoop;
#endif
#endif
}
operator const Base_t &() const noexcept
{
return *this;
}
// required for move casts
operator Base_t &() noexcept
{
return *this;
}
const Base_t &BasePointerType() const noexcept
{
return *this;
}
Base_t &BasePointerType() noexcept
{
return *this;
}
operator bool() const noexcept
{
return Base_t::operator bool();
}
ExSharedPtr &operator =(const Base_t &in) noexcept
{
Base_t::operator=(in);
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
return *this;
}
template <class T_t, typename B_t>
ExSharedPtr &operator =(ExSharedPtr<T_t, B_t> &&in) noexcept
{
Base_t::operator=(AuMove(in.BasePointerType()));
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
return *this;
}
ExSharedPtr &operator =(Base_t &&in) noexcept
{
Base_t::operator=(in);
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
return *this;
}
ExSharedPtr &operator =(const ExSharedPtr &in) noexcept
{
Base_t::operator=(in);
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
return *this;
}
template <class T_t, typename B_t>
ExSharedPtr &operator =(const ExSharedPtr<T_t, B_t> &in) noexcept
{
Base_t::operator=(in.BasePointerType());
#if !defined(_AURORA_NULLEXPT_ENABLE_UB)
_cache();
#endif
return *this;
}
template <class TType2_t = TType_t>
TType2_t &operator*() const
{
return *operator->();
}
template <class TType2_t = TType_t>
TType2_t *operator->() const
{
#if defined(_AURORA_NULLEXPT_ENABLE_UB)
return Base_t::operator->();
#elif !defined(_AURORA_NULLEXPT_BRANCH)
return reinterpret_cast<TType2_t *>(ptr->Get());
#else
throwif();
return Base_t::operator->();
#endif
}
template <class TType2_t = TType_t>
TType2_t &operator*()
{
return *operator->();
}
template <class TType2_t = TType_t>
TType2_t *operator->()
{
#if defined(_AURORA_NULLEXPT_ENABLE_UB)
return Base_t::operator->();
#elif !defined(_AURORA_NULLEXPT_BRANCH)
return reinterpret_cast<TType2_t *>(ptr->Get());
#else
throwif();
return Base_t::operator->();
#endif
}
element_type *get() const
{
return Base_t::get();
}
#define ADD_OPERATOR(op) \
template <class T > \
bool operator op(const T &rhs) noexcept \
{ \
return static_cast<Base_t &>(*this) op(rhs); \
} \
\
template < class T > \
bool operator op(std::nullptr_t rhs) noexcept \
{ \
return static_cast<Base_t &>(*this) op(rhs); \
}
ADD_OPERATOR(==)
ADD_OPERATOR(!=)
#if defined(AU_LANG_CPP_20)
template < class T >
std::strong_ordering operator<=>(const T &rhs) noexcept
{
return Base_t::operator<=>(rhs);
}
#else
ADD_OPERATOR(>)
ADD_OPERATOR(<)
ADD_OPERATOR(<=)
ADD_OPERATOR(=>)
#endif
private:
#if defined(_AURORA_NULLEXPT_ENABLE_UB)
void _cache()
{}
#elif !defined(_AURORA_NULLEXPT_BRANCH)
_detail::IPtrGet * ptr;
inline virtual void *Get() override
{
return Base_t::operator->();
}
auline void _cache()
{
if (Base_t::operator bool())
{
ptr = this;
}
else
{
ptr = &_detail::gNoop;
}
}
#else
bool cached {};
auline void throwif() const
{
if (!cached) [[unlikely]]
{
#if defined(_AURORA_NULLEXPT_BRANCH_BUG_CHECK)
if (!Base_t::operator bool()) [[likely]]
#endif
{
AU_THROW_STRING("ExSharedPointer Null Access Violation");
}
}
}
auline void throwif()
{
if (!cached) [[unlikely]]
{
#if defined(_AURORA_NULLEXPT_BRANCH_BUG_CHECK)
cached = Base_t::operator bool();
if (!cached) [[likely]]
#endif
{
AU_THROW_STRING("ExSharedPointer Null Access Violation");
}
}
}
auline void _cache()
{
cached = Base_t::operator bool();
}
#endif
};
template <class TType_t, class Base_t>
struct ExSharedFromThis : Base_t
{
ExSharedPtr<TType_t, AURORA_RUNTIME_AU_SHARED_PTR<TType_t>> SharedFromThis()
{
return Base_t::shared_from_this();
}
};
}

View File

@ -0,0 +1,15 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auArray.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
#if !defined(AURORA_RUNTIME_AU_ARRAY)
#define AURORA_RUNTIME_AU_ARRAY std::array
#endif
template <class T, size_t Z>
using AuArray = AURORA_RUNTIME_AU_ARRAY<T, Z>;

View File

@ -0,0 +1,312 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auAtomic.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
template <class T>
struct AuAtomicUtils
{
/**
* @brief Generic bitwise (1 << offset)
* @return original value
* @warning T is bound by platform and compiler constraints
*/
static T Set(T *in, AuUInt8 offset);
/**
* @brief Adds addend to in
* @return updated value
* @warning T is bound by platform and compiler constraints
*/
static T Add(T *in, T addend);
/**
* @brief Subtracts the minuend from in
* @return updated value
* @warning T is bound by platform and compiler constraints
*/
static T Sub(T *in, T minuend);
/**
* @brief Generic compare exchange
* @param replace replacement value for in if in matches compare
* @param compare required reference value
* @return original value
* @warning T is bound by platform and compiler constraints
*/
static T CompareExchange(T *in, T replace, T compare);
/**
* @brief { return *in & (1 << offset); in |= (1 << offset) }
* @param in
* @param offset Bit index
* @return *in & (1 << offset)
* @warning T is bound by platform and compiler constraints
*/
static bool TestAndSet(T *in, const AuUInt8 offset);
};
#if defined(AURORA_COMPILER_MSVC)
template <>
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::CompareExchange(AuUInt64 *in, AuUInt64 replace, AuUInt64 compare)
{
return static_cast<AuUInt64>(_InterlockedCompareExchange64(reinterpret_cast<long long volatile *>(in), static_cast<long long>(replace), static_cast<long long>(compare)));
}
template <>
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::CompareExchange(AuUInt32 *in, AuUInt32 replace, AuUInt32 compare)
{
return static_cast<AuUInt32>(_InterlockedCompareExchange(reinterpret_cast<long volatile *>(in), static_cast<long>(replace), static_cast<long>(compare)));
}
template <>
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::CompareExchange(AuUInt16 *in, AuUInt16 replace, AuUInt16 compare)
{
return static_cast<AuUInt16>(_InterlockedCompareExchange16(reinterpret_cast<short volatile *>(in), static_cast<short>(replace), static_cast<short>(compare)));
}
template <>
inline auline AuInt64 AuAtomicUtils<AuInt64>::CompareExchange(AuInt64 *in, AuInt64 replace, AuInt64 compare)
{
return _InterlockedCompareExchange64(reinterpret_cast<long long volatile *>(in), static_cast<long long>(replace), static_cast<long long>(compare));
}
template <>
inline auline AuInt32 AuAtomicUtils<AuInt32>::CompareExchange(AuInt32 *in, AuInt32 replace, AuInt32 compare)
{
return _InterlockedCompareExchange(reinterpret_cast<long volatile *>(in), static_cast<long>(replace), static_cast<long>(compare));
}
template <>
inline auline AuInt16 AuAtomicUtils<AuInt16>::CompareExchange(AuInt16 *in, AuInt16 replace, AuInt16 compare)
{
return _InterlockedCompareExchange16(reinterpret_cast<short volatile *>(in), static_cast<short>(replace), static_cast<short>(compare));
}
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::Add(AuUInt64 *in, AuUInt64 addend)
{
return static_cast<AuUInt64>(_InterlockedExchangeAdd64(reinterpret_cast<long long volatile *>(in), static_cast<long long>(addend)) + static_cast<long long>(addend));
}
#endif
template <>
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::Add(AuUInt32 *in, AuUInt32 addend)
{
return static_cast<AuUInt32>(_InterlockedExchangeAdd(reinterpret_cast<long volatile *>(in), static_cast<long>(addend)) + static_cast<long>(addend));
}
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuInt64 AuAtomicUtils<AuInt64>::Add(AuInt64 *in, AuInt64 addend)
{
return _InterlockedExchangeAdd64(reinterpret_cast<long long volatile *>(in), static_cast<long long>(addend)) + static_cast<long long>(addend);
}
#endif
template <>
inline auline AuInt32 AuAtomicUtils<AuInt32>::Add(AuInt32 *in, AuInt32 addend)
{
return _InterlockedExchangeAdd(reinterpret_cast<long volatile *>(in), static_cast<long>(addend)) + static_cast<long>(addend);
}
// TODO:
#if 0
template <>
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Add(AuUInt16 *in, AuUInt16 addend)
{
return {};
}
#endif
template <>
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::Sub(AuUInt64 *in, AuUInt64 minuend)
{
return Add(in, AuUInt64(0) - minuend);
}
template <>
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::Sub(AuUInt32 *in, AuUInt32 minuend)
{
return Add(in, AuUInt32(0) - minuend);
}
// TODO:
#if 0
template <>
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Sub(AuUInt16 *in, AuUInt16 minuend)
{
return {};
}
#endif
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::Set(AuUInt64 *in, AuUInt8 offset)
{
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), AuUInt64(1) << offset);
}
#endif
template <>
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::Set(AuUInt32 *in, AuUInt8 offset)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
}
template <>
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Set(AuUInt16 *in, AuUInt8 offset)
{
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), 1 << offset);
}
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuInt64 AuAtomicUtils<AuInt64>::Set(AuInt64 *in, AuUInt8 offset)
{
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), AuUInt64(1) << offset);
}
#endif
template <>
inline auline AuInt32 AuAtomicUtils<AuInt32>::Set(AuInt32 *in, AuUInt8 offset)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
}
template <>
inline auline long AuAtomicUtils<long>::Set(long *in, AuUInt8 offset)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
}
template <>
inline auline unsigned long AuAtomicUtils<unsigned long>::Set(unsigned long *in, AuUInt8 offset)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
}
template <>
inline auline AuInt16 AuAtomicUtils<AuInt16>::Set(AuInt16 *in, AuUInt8 offset)
{
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), 1 << offset);
}
#elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC)
template <class T>
inline auline T AuAtomicUtils<T>::CompareExchange(T *in, T replace, T compare)
{
return __sync_val_compare_and_swap(in, compare, replace);
}
template <class T>
inline auline T AuAtomicUtils<T>::Add(T *in, T addend)
{
return __sync_add_and_fetch(in, addend);
}
template <class T>
inline auline T AuAtomicUtils<T>::Sub(T *in, T minuend)
{
return __sync_sub_and_fetch(in, minuend);
}
template <class T>
inline auline T AuAtomicUtils<T>::Set(T *in, AuUInt8 offset)
{
return __sync_fetch_and_or(in, T(1) << offset);
}
#endif
template <class T>
inline auline bool AuAtomicUtils<T>::TestAndSet(T *in, const AuUInt8 offset)
{
return AuAtomicUtils<T>::Set(in, offset) & (1 << offset);
}
#if defined(AURORA_COMPILER_MSVC) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
template <>
inline auline bool AuAtomicUtils<unsigned long>::TestAndSet(unsigned long *in, const AuUInt8 offset)
{
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
}
template <>
inline auline bool AuAtomicUtils<long>::TestAndSet(long *in, const AuUInt8 offset)
{
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
}
template <>
inline auline bool AuAtomicUtils<AuUInt32>::TestAndSet(AuUInt32 *in, const AuUInt8 offset)
{
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
}
template <>
inline auline bool AuAtomicUtils<AuInt32>::TestAndSet(AuInt32 *in, const AuUInt8 offset)
{
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
}
#if !defined(AURORA_IS_32BIT)
template <>
inline auline bool AuAtomicUtils<AuUInt64>::TestAndSet(AuUInt64 *in, const AuUInt8 offset)
{
return _interlockedbittestandset64(reinterpret_cast<volatile long long *>(in), offset);
}
template <>
inline auline bool AuAtomicUtils<AuInt64>::TestAndSet(AuInt64 *in, const AuUInt8 offset)
{
return _interlockedbittestandset64(reinterpret_cast<volatile long long *>(in), offset);
}
#endif
#endif
template <class T>
auline
T AuAtomicSet(T *in, AuUInt8 offset)
{
return AuAtomicUtils<T>::Set(in, offset);
}
template <class T>
auline
T AuAtomicAdd(T *in, T addend)
{
return AuAtomicUtils<T>::Add(in, addend);
}
template <class T>
auline
T AuAtomicSub(T *in, T minuend)
{
return AuAtomicUtils<T>::Sub(in, minuend);
}
template <class T>
auline
T AuAtomicCompareExchange(T *in, T replace, T compare)
{
return AuAtomicUtils<T>::CompareExchange(in, replace, compare);
}
template <class T>
auline
bool AuAtomicTestAndSet(T *in, AuUInt8 offset)
{
return AuAtomicUtils<T>::TestAndSet(in, offset);
}

17
Include/auROXTL/auBST.hpp Normal file
View File

@ -0,0 +1,17 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auBST.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
#if !defined(AURORA_RUNTIME_AU_BST)
#define AURORA_RUNTIME_AU_BST std::map
#endif
#include "auHashUtils.hpp"
template <class T, typename Z, typename LessThan_t = AuHash::less<T>>
using AuBST = AURORA_RUNTIME_AU_BST<T, Z, LessThan_t>;

View File

@ -0,0 +1,222 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auBitsUtils.hpp
Date: 2022-2-1
Author: Reece
***/
#pragma once
template <class T>
static auline bool AuTestBit(T value, AuUInt8 idx)
{
return value & (T(1) << T(idx));
}
template <class T>
static auline void AuSetBit(T &value, AuUInt8 idx)
{
value |= T(1) << T(idx);
}
template <class T>
static auline void AuClearBit(T &value, AuUInt8 idx)
{
value &= ~(T(1) << T(idx));
}
template <class T>
static auline bool AuBitScanForward(AuUInt8 &index, T value)
{
unsigned long ret;
bool success;
success = false;
index = 0;
#if defined(AURORA_COMPILER_MSVC)
if constexpr (sizeof(T) == sizeof(AuUInt64))
#if defined(AURORA_IS_32BIT)
if (!_BitScanForward(&ret, static_cast<AuUInt32>(value & 0xffffffff)))
{
if (!_BitScanForward(&ret, static_cast<AuUInt32>((value >> 32) & 0xffffffff)))
{
return false;
}
ret += 32;
}
#else
success = _BitScanForward64(&ret, static_cast<AuUInt64>(value));
#endif
else success = _BitScanForward(&ret, static_cast<unsigned long>(value));
#elif defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG)
if (value == 0)
{
return false;
}
if constexpr (sizeof(T) == sizeof(AuUInt64))
{
#if defined(AURORA_IS_32BIT)
auto lower = static_cast<AuUInt32>(value & 0xffffffff));
if (lower == 0)
{
ret = __builtin_ctzl(static_cast<AuUInt32>((value >> 32) & 0xffffffff));
ret += 32;
}
else
{
ret = __builtin_ctzl(static_cast<AuUInt32>(lower));
}
#else
ret = __builtin_ctzll(static_cast<AuUInt64>(value));
#endif
}
else if constexpr (sizeof(T) == sizeof(unsigned long))
{
ret = __builtin_ctzl(static_cast<unsigned long>(value));
}
else if constexpr (sizeof(T) == sizeof(unsigned int))
{
ret = __builtin_ctz(static_cast<unsigned int>(value));
}
success = true;
#endif
index = ret;
return success;
}
template <class T>
struct AuHalfWord
{
using ReturnType_t = AuConditional_t<AuIsSame_v<T, AuUInt64>, AuUInt32, AuConditional_t<AuIsSame_v<T, AuUInt32>, AuUInt32, AuConditional_t<AuIsSame_v<T, AuUInt16>, AuUInt8, AuFalseType>>>;
static ReturnType_t ToLower(T in)
{
if constexpr (AuIsSame_v<T, AuUInt64>)
{
return in & AuUInt64(0xFFFFFFFF);
}
else if constexpr (AuIsSame_v<T, AuUInt32>)
{
return in & 0xFFFF;
}
else if constexpr (AuIsSame_v<T, AuUInt16>)
{
return in & 0xFF;
}
else
{
return {};
}
}
static ReturnType_t ToHigher(T in)
{
if constexpr (AuIsSame_v<T, AuUInt64>)
{
return (in >> AuUInt64(32)) & AuUInt64(0xFFFFFFFF);
}
else if constexpr (AuIsSame_v<T, AuUInt32>)
{
return (in >> 16) & 0xFFFF;
}
else if constexpr (AuIsSame_v<T, AuUInt16>)
{
return (in >> 8) & 0xFF;
}
else
{
return {};
}
}
};
template <class T>
static auto AuBitsToLower(T in)
{
return AuHalfWord<T>::ToLower(in);
}
template <class T>
static auto AuBitsToHigher(T in)
{
return AuHalfWord<T>::ToHigher(in);
}
template <class T>
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 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)
if constexpr (sizeof(T) == sizeof(AuUInt64))
{
const AuUInt64 m1 = 0x5555555555555555ll;
const AuUInt64 m2 = 0x3333333333333333ll;
const AuUInt64 m4 = 0x0F0F0F0F0F0F0F0Fll;
const AuUInt64 h01 = 0x0101010101010101ll;
in -= (in >> 1) & m1;
in = (in & m2) + ((in >> 2) & m2);
in = (in + (in >> 4)) & m4;
return (in * h01) >> 56;
}
else if constexpr (sizeof(T) == sizeof(AuUInt32))
{
const AuUInt32 m1 = 0x55555555l;
const AuUInt32 m2 = 0x33333333l;
const AuUInt32 m4 = 0x0F0F0F0Fl;
const AuUInt32 h01 = 0x01010101l;
in -= (in >> 1) & m1;
in = (in & m2) + ((in >> 2) & m2);
in = (in + (in >> 4)) & m4;
return (in * h01) >> 24;
}
#endif
if constexpr ((sizeof(T) == sizeof(AuUInt16)) ||
(sizeof(T) == sizeof(AuUInt8)))
{
return AuPopCnt<AuUInt32>(AuUInt32(in));
}
return {};
}
// TODO: AuBitScanReverse

View File

@ -0,0 +1,136 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auCastUtils.hpp
Date: 2022-2-10
Author: Reece
***/
#pragma once
template <class T, class Z>
static constexpr AuSPtr<T> AuStaticCast(const AuSPtr<Z> &other)
{
return AuSPtr<T>(other, static_cast<T *>(other.get()));
}
template <class T, class Z>
static constexpr AuSPtr<T> AuStaticCast(AuSPtr<Z> &&other)
{
return AuSPtr<T>(AuMove(other), static_cast<T *>(other.get()));
}
template <class T, class Z>
static constexpr AuConditional_t<AuIsPointer_v<T>, T, T *> AuStaticCast(Z *other)
{
return static_cast<AuConditional_t<AuIsPointer_v<T>, T, T *>>(other);
}
template <class T, class Z, AU_TEMPLATE_ENABLE_WHEN(!AuIsBaseOfTemplate_v<AURORA_RUNTIME_AU_SHARED_PTR, Z>)>
static constexpr AuConditional_t<AuIsReference_v<T>, T, T &> AuStaticCast(Z &other)
{
return static_cast<AuConditional_t<AuIsReference_v<T>, T, T &>>(AuForward(other));
}
template <class T, class Z, AU_TEMPLATE_ENABLE_WHEN(!AuIsBaseOfTemplate_v<AURORA_RUNTIME_AU_SHARED_PTR, Z>)>
static constexpr AuConditional_t<AuIsReference_v<T>, T, T &&> AuStaticCast(Z &&other)
{
return static_cast<AuConditional_t<AuIsReference_v<T>, T, T &&>>(AuMove(other));
}
template <class T, class Z, AU_TEMPLATE_ENABLE_WHEN(!AuIsPointer_v<T> && !AuIsPointer_v<Z>)>
static constexpr T AuStaticCast(Z other)
{
return static_cast<T>(other);
}
template <class T, class Z>
static constexpr AuConditional_t<AuIsPointer_v<T>, T, T *> AuConstCast(Z *other)
{
return const_cast<AuConditional_t<AuIsPointer_v<T>, T, T *>>(other);
}
template <class T, class Z, AU_TEMPLATE_ENABLE_WHEN(!AuIsBaseOfTemplate_v<AURORA_RUNTIME_AU_SHARED_PTR, Z>)>
static constexpr AuConditional_t<AuIsReference_v<T>, T, T &> AuConstCast(Z &other)
{
return const_cast<AuConditional_t<AuIsReference_v<T>, T, T &>>(AuForward(other));
}
template <class T, class Z, AU_TEMPLATE_ENABLE_WHEN(!AuIsBaseOfTemplate_v<AURORA_RUNTIME_AU_SHARED_PTR, Z>)>
static constexpr AuConditional_t<AuIsReference_v<T>, T, T &&> AuConstCast(Z &&other)
{
return const_cast<AuConditional_t<AuIsReference_v<T>, T, T &&>>(AuMove(other));
}
template <class T, class Z>
static constexpr AuSPtr<T> AuConstCast(const AuSPtr<Z> &other)
{
return AuSPtr<T>(other, const_cast<T *>(other.get()));
}
template <class T, class Z>
static constexpr AuSPtr<T> AuConstCast(AuSPtr<Z> &&other)
{
return AuSPtr<T>(AuMove(other), const_cast<T *>(other.get()));
}
template <class T, class Z>
static constexpr AuConditional_t<AuIsClass_v<T> && !AuIsPointer_v<T> && AuIsPointer_v<Z>, T *, T> AuReinterpretCast(Z other)
{
return reinterpret_cast<AuConditional_t<AuIsClass_v<T> && !AuIsPointer_v<T> &&AuIsPointer_v<Z>, T *, T>>(other);
}
template <class T, class Z>
static constexpr AuSPtr<T> AuReinterpretCast(const AuSPtr<Z> &other)