From 362a5d3128e689ace6ff2546f4b97ff3885e67a2 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 28 Jan 2016 19:02:15 +0100 Subject: [PATCH] Modernize AutomemBase and add some assertions --- src/navigate/AutomemBase.hpp | 63 ++-------- src/navigate/AutomemBase.inl | 215 +++++++++++++-------------------- src/navigate/MaxSizedArray.inl | 16 +-- 3 files changed, 99 insertions(+), 195 deletions(-) diff --git a/src/navigate/AutomemBase.hpp b/src/navigate/AutomemBase.hpp index 0173f81..2227a7a 100644 --- a/src/navigate/AutomemBase.hpp +++ b/src/navigate/AutomemBase.hpp @@ -33,54 +33,6 @@ namespace din { const size_t MAX_STACK_ALLOC_SIZE = 128; - ///------------------------------------------------------------------------- - ///Heap-based allocation, constructs everything - ///------------------------------------------------------------------------- - template > - class AutomemBase_heap { - protected: - AutomemBase_heap ( void ); - AutomemBase_heap ( const AutomemBase_heap& parOther ); - AutomemBase_heap ( AutomemBase_heap&& parOther ); - ~AutomemBase_heap ( void ) = default; - - T* GetMemPtr ( void ) { return m_localMem; } - const T* GetMemPtr ( void ) const { return m_localMem; } - void AllocMemory ( void ); - void FreeMemory ( void ) noexcept; - void swap ( AutomemBase_heap& parOther ) noexcept { std::swap(m_localMem, parOther.m_localMem); } - private: -#if defined(ASSERTIONSENABLED) - typedef uintptr_t PTR_INT_TYPE; - static_assert(sizeof(PTR_INT_TYPE) == sizeof(T*), "Wrong uintptr_t size"); -#endif - void operator= (const AutomemBase_heap&); - T* m_localMem; - }; - - ///------------------------------------------------------------------------- - ///Stack-based allocation, constructs everything - ///------------------------------------------------------------------------- - template - class AutomemBase_stack { - protected: - AutomemBase_stack ( void ); - AutomemBase_stack ( const AutomemBase_stack& parOther ); - AutomemBase_stack ( AutomemBase_stack&& parOther ); - ~AutomemBase_stack ( void ) = default; - - T* GetMemPtr ( void ) { return m_localMem; } - const T* GetMemPtr ( void ) const { return m_localMem; } - void AllocMemory ( void ) { return; } - void FreeMemory ( void ) noexcept { return; } - private: -#if defined(ASSERTIONSENABLED) - typedef uintptr_t PTR_INT_TYPE; - static_assert(sizeof(PTR_INT_TYPE) == sizeof(T*), "Wrong uintptr_t size"); -#endif - T m_localMem[S]; - }; - ///------------------------------------------------------------------------- ///Heap-based allocation, only gets raw memory ///------------------------------------------------------------------------- @@ -89,11 +41,11 @@ namespace din { protected: AutomemRawBase_heap ( void ); AutomemRawBase_heap ( const AutomemRawBase_heap& ) = delete; //Copy ctor can't be implemented at this level + AutomemRawBase_heap ( AutomemRawBase_heap&& parOther ); - T* GetMemPtr ( void ) { return m_localMem; } - const T* GetMemPtr ( void ) const { return m_localMem; } - char* GetMemPtrAtIndex ( size_t parIndex ); - void AllocMemory ( void ); + template + T* GetNewT ( size_t parIndex, Args&&... parArgs ); + T* AllocMemory ( void ); void FreeMemory ( void ) noexcept; void swap ( AutomemRawBase_heap& parOther ) noexcept { std::swap(m_localMem, parOther.m_localMem); } private: @@ -117,10 +69,9 @@ namespace din { AutomemRawBase_stack ( AutomemRawBase_stack&& ) = delete; ~AutomemRawBase_stack ( void ) = default; - T* GetMemPtr ( void ) { return reinterpret_cast(&m_localMem[0]); } - const T* GetMemPtr ( void ) const { return reinterpret_cast(&m_localMem[0]); } - char* GetMemPtrAtIndex ( size_t parIndex ); - void AllocMemory ( void ); + template + T* GetNewT ( size_t parIndex, Args&&... parArgs ); + T* AllocMemory ( void ); void FreeMemory ( void ) noexcept { return; } private: #if defined(ASSERTIONSENABLED) diff --git a/src/navigate/AutomemBase.inl b/src/navigate/AutomemBase.inl index 784b2cc..91e51ce 100644 --- a/src/navigate/AutomemBase.inl +++ b/src/navigate/AutomemBase.inl @@ -16,144 +16,103 @@ */ namespace din { -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_heap::AutomemBase_heap() { -#if !defined(NDEBUG) - m_localMem = NULL; -#endif -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_heap::AutomemBase_heap (const AutomemBase_heap& parOther) { -#if !defined(NDEBUG) - m_localMem = NULL; -#endif - AllocMemory(); - std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + S, this->GetMemPtr()); -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_heap::AutomemBase_heap (AutomemBase_heap&& parOther) { - std::swap(parOther.m_localMem, this->m_localMem); -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -void AutomemBase_heap::AllocMemory() { -#if !defined(NDEBUG) - Assert(NULL == m_localMem); -#endif - m_localMem = A().allocate(S); - for (size_t z = 0; z < S; ++z) { - new(m_localMem + z) T; - } -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -void AutomemBase_heap::FreeMemory() noexcept { -#if !defined(NDEBUG) - Assert(NULL != m_localMem); -#endif - for (size_t z = 0; z < S; ++z) { - m_localMem->~T(); - } - A().deallocate(m_localMem, S); -#if !defined(NDEBUG) - m_localMem = NULL; -#endif -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_stack::AutomemBase_stack() { -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_stack::AutomemBase_stack (const AutomemBase_stack& parOther) { - std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + S, this->GetMemPtr()); -} - -///----------------------------------------------------------------------------- -///----------------------------------------------------------------------------- -template -AutomemBase_stack::AutomemBase_stack (AutomemBase_stack&& parOther) { - for (size_t z = 0; z < S; ++z) { - std::swap(m_localMem[z], parOther.m_localMem[z]); - } -} - -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -AutomemRawBase_heap::AutomemRawBase_heap() { -#if !defined(NDEBUG) - m_localMem = NULL; -#endif -} - -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -void AutomemRawBase_heap::AllocMemory() { -#if !defined(NDEBUG) - Assert(NULL == m_localMem); -#endif - m_localMem = A().allocate(S); + namespace { #if defined(ASSERTIONSENABLED) - assert(reinterpret_cast(m_localMem) % alignof(T) == 0); //Make sure alignment is correct + const char g_guard = 0xAB; #endif -} + } //unnamed namespace -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -void AutomemRawBase_heap::FreeMemory() noexcept { + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + AutomemRawBase_heap::AutomemRawBase_heap() { #if !defined(NDEBUG) - Assert(NULL != m_localMem); + m_localMem = nullptr; #endif - A().deallocate(m_localMem, S); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + AutomemRawBase_heap::AutomemRawBase_heap (AutomemRawBase_heap&& parOther) { #if !defined(NDEBUG) - m_localMem = NULL; + m_localMem = nullptr; #endif -} + this->swap(parOther); + } -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -char* AutomemRawBase_heap::GetMemPtrAtIndex (size_t parIndex) { - T* const retVal = GetMemPtr() + parIndex; - return reinterpret_cast(retVal); -} - -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -void AutomemRawBase_stack::AllocMemory() { + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + T* AutomemRawBase_heap::AllocMemory() { +#if !defined(NDEBUG) + Assert(nullptr == m_localMem); +#endif + m_localMem = A().allocate(S); #if defined(ASSERTIONSENABLED) - assert(reinterpret_cast(m_localMem) % alignof(T) == 0); //Make sure alignment is correct + assert(reinterpret_cast(m_localMem) % alignof(T) == 0); //Make sure alignment is correct + std::fill( + reinterpret_cast(&m_localMem[0]), + reinterpret_cast(&m_localMem[0]) + sizeof(m_localMem), + g_guard + ); #endif -} + return m_localMem; + } -///------------------------------------------------------------------------- -///------------------------------------------------------------------------- -template -char* AutomemRawBase_stack::GetMemPtrAtIndex (size_t parIndex) { - T* const retVal = GetMemPtr() + parIndex; -#if defined(ASSERTIONSENABLED) - assert(reinterpret_cast(retVal) % alignof(T) == 0); + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + void AutomemRawBase_heap::FreeMemory() noexcept { +#if !defined(NDEBUG) + Assert(nullptr != m_localMem); #endif - return reinterpret_cast(retVal); -} + A().deallocate(m_localMem, S); +#if !defined(NDEBUG) + m_localMem = nullptr; +#endif + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + template + T* AutomemRawBase_heap::GetNewT (size_t parIndex, Args&&... parArgs) { + assert(parIndex < S); + T* const location = m_localMem + parIndex; +#if defined(ASSERTIONSENABLED) + assert(reinterpret_cast(location) % alignof(T) == 0); + assert(g_guard == *reinterpret_cast(location)); +#endif + return new(location) T(std::forward(parArgs)...); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + T* AutomemRawBase_stack::AllocMemory() { +#if defined(ASSERTIONSENABLED) + assert(reinterpret_cast(m_localMem) % alignof(T) == 0); //Make sure alignment is correct + std::fill( + reinterpret_cast(&m_localMem[0]), + reinterpret_cast(&m_localMem[0]) + sizeof(m_localMem), + g_guard + ); +#endif + return reinterpret_cast(&m_localMem[0]); + } + + ///------------------------------------------------------------------------- + ///------------------------------------------------------------------------- + template + template + T* AutomemRawBase_stack::GetNewT (size_t parIndex, Args&&... parArgs) { + assert(parIndex < S); + auto* const location = &m_localMem[parIndex]; +#if defined(ASSERTIONSENABLED) + assert(reinterpret_cast(location) % alignof(T) == 0); + assert(g_guard == *reinterpret_cast(location)); +#endif + return new(location) T(std::forward(parArgs)...); + } } //namespace din diff --git a/src/navigate/MaxSizedArray.inl b/src/navigate/MaxSizedArray.inl index 3eb821c..c65cb30 100644 --- a/src/navigate/MaxSizedArray.inl +++ b/src/navigate/MaxSizedArray.inl @@ -20,9 +20,7 @@ namespace din { ///------------------------------------------------------------------------- template MaxSizedArray::MaxSizedArray() { - this->AllocMemory(); - //Careful here, I'm not sure this is valid c++ - m_localMem = reinterpret_cast(this->GetMemPtrAtIndex(0)); + m_localMem = this->AllocMemory(); m_used = 0; } @@ -33,8 +31,7 @@ namespace din { parent_type(), m_used(0) { - this->AllocMemory(); - m_localMem = reinterpret_cast(this->GetMemPtrAtIndex(0)); + m_localMem = this->AllocMemory(); const size_type count = parOther.size(); for (size_type z = 0; z < count; ++z) { this->push_back(parOther[z]); @@ -48,8 +45,7 @@ namespace din { parent_type(), m_used(0) { - this->AllocMemory(); - m_localMem = reinterpret_cast(this->GetMemPtrAtIndex(0)); + m_localMem = this->AllocMemory(); const size_type count = parOther.size(); for (size_type z = 0; z < count; ++z) { this->push_back(std::move(parOther[z])); @@ -83,8 +79,7 @@ namespace din { template void MaxSizedArray::push_back (value_type&& parNewItem) { assert(size() < capacity()); - char* buffer = this->GetMemPtrAtIndex(m_used); - new(buffer) T(std::move(parNewItem)); + this->GetNewT(m_used, std::move(parNewItem)); ++m_used; } @@ -93,8 +88,7 @@ namespace din { template void MaxSizedArray::push_back (const value_type& parNewItem) { assert(size() < capacity()); - char* buffer = this->GetMemPtrAtIndex(m_used); - new(buffer) T(parNewItem); + this->GetNewT(m_used, parNewItem); ++m_used; }