[+] Added sources
This commit is contained in:
commit
a19ae800aa
6
Aurora.json
Normal file
6
Aurora.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "auROXTL",
|
||||
"type": "generic",
|
||||
"include": "Include",
|
||||
"noLink": true
|
||||
}
|
32
Include/auROXTL.hpp
Normal file
32
Include/auROXTL.hpp
Normal 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"
|
190
Include/auROXTL/AU_MACROS.hpp
Normal file
190
Include/auROXTL/AU_MACROS.hpp
Normal 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
73
Include/auROXTL/AU_Z.hpp
Normal 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
|
131
Include/auROXTL/Objects/ClassHelpers.hpp
Normal file
131
Include/auROXTL/Objects/ClassHelpers.hpp
Normal 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))
|
8
Include/auROXTL/Objects/ModuleApi.hpp
Normal file
8
Include/auROXTL/Objects/ModuleApi.hpp
Normal 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
|
11
Include/auROXTL/Objects/Objects.hpp
Normal file
11
Include/auROXTL/Objects/Objects.hpp
Normal 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"
|
401
Include/auROXTL/STLShims/ExtendStlLikeSharedPtr.hpp
Normal file
401
Include/auROXTL/STLShims/ExtendStlLikeSharedPtr.hpp
Normal 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();
|
||||
}
|
||||
};
|
||||
}
|
15
Include/auROXTL/auArray.hpp
Normal file
15
Include/auROXTL/auArray.hpp
Normal 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>;
|
312
Include/auROXTL/auAtomic.hpp
Normal file
312
Include/auROXTL/auAtomic.hpp
Normal 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
17
Include/auROXTL/auBST.hpp
Normal 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>;
|
222
Include/auROXTL/auBitsUtils.hpp
Normal file
222
Include/auROXTL/auBitsUtils.hpp
Normal 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
|
136
Include/auROXTL/auCastUtils.hpp
Normal file
136
Include/auROXTL/auCastUtils.hpp
Normal 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)
|
||||