/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auMemoryModel.hpp Date: 2022-2-1 Author: Reece ***/ #pragma once #include "auTypes.hpp" #if !defined(AURORA_RUNTIME_AU_SHARED_PTR) #define AURORA_RUNTIME_AU_SHARED_PTR std::shared_ptr #endif #if !defined(AURORA_RUNTIME_AU_WEAK_PTR) #define AURORA_RUNTIME_AU_WEAK_PTR std::weak_ptr #endif template using AuWPtr = AURORA_RUNTIME_AU_WEAK_PTR; #if !defined(AURORA_RUNTIME_AU_UNIQUE_PTR) #define AURORA_RUNTIME_AU_UNIQUE_PTR std::unique_ptr #endif #if !defined(AURORA_RUNTIME_AU_DEFAULT_DELETER) #define AURORA_RUNTIME_AU_DEFAULT_DELETER std::default_delete #endif template using AuDefaultDeleter = AURORA_RUNTIME_AU_DEFAULT_DELETER; #include "Shims/ExtendStlLikeSharedPtr.hpp" template using AuSPtr = typename Aurora::Memory::ExSharedPtr>; template using AuUPtr = AURORA_RUNTIME_AU_UNIQUE_PTR; #if !defined(AU_AuEnableSharedFromThis) #define AU_AuEnableSharedFromThis template struct AuEnableSharedFromThis : Aurora::Memory::ExSharedFromThis> {}; #endif #if !defined(AURORA_RUNTIME_MAKE_SHARED) #define AURORA_RUNTIME_MAKE_SHARED std::make_shared #endif template static auline AuSPtr AuMakeShared(Args&&... args) { try { return AURORA_RUNTIME_MAKE_SHARED(AuForward(args)...); } catch (...) { return {}; } } template static auline AuSPtr AuMakeSharedArray(AuUInt count) { try { #if defined(AU_LANG_CPP_20) && 0 return AURORA_RUNTIME_AU_SHARED_PTR(count); #else return AURORA_RUNTIME_AU_SHARED_PTR(new T[count], AuDefaultDeleter()); #endif } catch (...) { return {}; } } template static AuSPtr AuUnsafeRaiiToShared(T *in) { return AuSPtr(in, [](T *) {}); } template static AuSPtr AuUnsafeRaiiToShared(const AuUPtr &in) { return AuSPtr(in.get(), [](T *) {}); } template static constexpr int AuArraySize(const T(&array)[Z]) { return Z; } #if defined(DEBUG) || defined(STAGING) template static auline void AU_NORETURN SysPanic(T... args); template static void auline AuSafeDelete(T *in) { static_assert(AuIsBaseOf_v>, "Couldn't not safe delete from type T because it is not derived from Z"); auto cast = dynamic_cast(in); if (cast == nullptr) { Z re; SysPanic("Tried to free: 0x{:x}, type \"{}\" was not inherited from \"{}\"", AuUInt(in), typeid(in).name(), typeid(re).name()); } delete cast; } #else template static void auline AuSafeDelete(T *in) { static_assert(AuIsBaseOf_v>, "Couldn't not safe delete from type T because it is not derived from Z"); delete static_cast(in); } #endif