#pragma once #include "vm_ptr.h" namespace vm { template struct page_allocator { static inline vm::addr_t alloc(u32 size, u32 align) { return vm::cast(vm::alloc(size, Location, std::max(align, 0x10000))); } static inline void dealloc(u32 addr, u32 size = 0) noexcept { return vm::dealloc_verbose_nothrow(addr, Location); } }; template struct stack_allocator { static inline vm::addr_t alloc(u32 size, u32 align) { return vm::cast(T::stack_push(size, align)); } static inline void dealloc(u32 addr, u32 size) noexcept { T::stack_pop_verbose(addr, size); } }; // General variable base class template class _var_base final : public _ptr_base { using pointer = _ptr_base; public: // Unmoveable object _var_base(const _var_base&) = delete; _var_base& operator=(const _var_base&) = delete; _var_base() : pointer(A::alloc(sizeof(T), alignof(T))) { } _var_base(const T& right) : _var_base() { std::memcpy(pointer::get_ptr(), &right, sizeof(T)); } ~_var_base() { if (pointer::addr()) { A::dealloc(pointer::addr(), sizeof(T)); } } }; // Dynamic length array variable specialization template class _var_base final : public _ptr_base { using pointer = _ptr_base; u32 m_size; public: _var_base(const _var_base&) = delete; _var_base& operator=(const _var_base&) = delete; _var_base(u32 count) : pointer(A::alloc(u32{sizeof(T)} * count, alignof(T))) , m_size(u32{sizeof(T)} * count) { } // Initialize via the iterator template _var_base(u32 count, I&& it) : _var_base(count) { std::copy_n(std::forward(it), count, pointer::get_ptr()); } ~_var_base() { if (pointer::addr()) { A::dealloc(pointer::addr(), m_size); } } // Remove operator -> T* operator->() const = delete; u32 get_count() const { return m_size / u32{sizeof(T)}; } auto begin() const { return *this + 0; } auto end() const { return *this + get_count(); } }; // LE variable template using varl = _var_base, A>; // BE variable template using varb = _var_base, A>; inline namespace ps3_ { // BE variable template > using var = varb; // Make BE variable initialized from value template > [[nodiscard]] auto make_var(const T& value) { return (varb(value)); } // Make char[] variable initialized from std::string template > [[nodiscard]] auto make_str(const std::string& str) { return (_var_base(size32(str) + 1, str.c_str())); } // Global HLE variable template struct gvar : ptr { }; } // namespace ps3_ } // namespace vm