/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: CppHeapWrapper.hpp Date: 2023-12-22 Author: Reece ***/ #pragma once namespace Aurora::Memory { template struct CppHeapWrapper { using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = AuTrueType; using is_always_equal = AuTrueType; #if defined(AU_LANG_CPP_17) using pointer = T *; using const_pointer = const T *; using reference = T &; using const_reference = const T &; template struct rebind { using other = CppHeapWrapper; }; T *address(T &val) const noexcept { return std::addressof(val); } const T *address(const T &val) const noexcept { return std::addressof(val); } #endif inline CppHeapWrapper(std::shared_ptr pHeap) : pHeap(pHeap) { } inline CppHeapWrapper(CppHeapWrapper *pFuckCppRetardsFixYourWorthlessSpec) : pFuckCppRetardsFixYourWorthlessSpec(pFuckCppRetardsFixYourWorthlessSpec) { } inline CppHeapWrapper(const CppHeapWrapper &fuckCpp) : pFuckCppRetardsFixYourWorthlessSpec((CppHeapWrapper *)&fuckCpp) { } AU_MOVE(CppHeapWrapper) AU_DEF(CppHeapWrapper) constexpr void deallocate(const T *pType, const size_t count) { this->GetHeap()->Free((T *)pType); } constexpr AU_ALLOC T *allocate(const size_t count) { if (!count) { return nullptr; } auto pData = this->GetHeap()->FAlloc(count * sizeof(T), alignof(T)); if (!pData) { throw std::bad_alloc(); } return (T *)pData; } template void construct(U *p, Args&&... args) { if constexpr (AuIsClass_v) { new ((void *)p) T(AuForward(args)...); } } template void construct_at(U *p, Args&&... args) { if constexpr (AuIsClass_v) { new ((void *)p) T(AuForward(args)...); } } #if defined(AU_LANG_CPP_23) constexpr std::allocation_result allocate_at_least(const size_t count) { auto pThat = this->allocate(count); return { (T *)pThat, this->GetHeap()->GetChunkSize(pThat) / sizeof(T) }; } #endif std::shared_ptr &GetHeap() { if (this->pFuckCppRetardsFixYourWorthlessSpec) { return this->pFuckCppRetardsFixYourWorthlessSpec->GetHeap(); } else { return this->pHeap; } } void SetHeap(std::shared_ptr pHeap) { if (this->pFuckCppRetardsFixYourWorthlessSpec) { this->pFuckCppRetardsFixYourWorthlessSpec->SetHeap(pHeap); } else { this->pHeap = pHeap; } } private: std::shared_ptr pHeap; CppHeapWrapper *pFuckCppRetardsFixYourWorthlessSpec {}; }; }