mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2024-11-25 00:53:43 +00:00
Modernize AutomemBase and add some assertions
This commit is contained in:
parent
394ae7672a
commit
362a5d3128
3 changed files with 99 additions and 195 deletions
|
@ -33,54 +33,6 @@
|
|||
namespace din {
|
||||
const size_t MAX_STACK_ALLOC_SIZE = 128;
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///Heap-based allocation, constructs everything
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A=std::allocator<T> >
|
||||
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 <typename T, size_t S>
|
||||
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 <typename... Args>
|
||||
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<T*>(&m_localMem[0]); }
|
||||
const T* GetMemPtr ( void ) const { return reinterpret_cast<const T*>(&m_localMem[0]); }
|
||||
char* GetMemPtrAtIndex ( size_t parIndex );
|
||||
void AllocMemory ( void );
|
||||
template <typename... Args>
|
||||
T* GetNewT ( size_t parIndex, Args&&... parArgs );
|
||||
T* AllocMemory ( void );
|
||||
void FreeMemory ( void ) noexcept { return; }
|
||||
private:
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
|
|
|
@ -16,144 +16,103 @@
|
|||
*/
|
||||
|
||||
namespace din {
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemBase_heap<T, S, A>::AutomemBase_heap() {
|
||||
#if !defined(NDEBUG)
|
||||
m_localMem = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemBase_heap<T, S, A>::AutomemBase_heap (const AutomemBase_heap& parOther) {
|
||||
#if !defined(NDEBUG)
|
||||
m_localMem = NULL;
|
||||
#endif
|
||||
AllocMemory();
|
||||
std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + S, this->GetMemPtr());
|
||||
}
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemBase_heap<T, S, A>::AutomemBase_heap (AutomemBase_heap&& parOther) {
|
||||
std::swap(parOther.m_localMem, this->m_localMem);
|
||||
}
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
void AutomemBase_heap<T, S, A>::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 <typename T, size_t S, typename A>
|
||||
void AutomemBase_heap<T, S, A>::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 <typename T, size_t S>
|
||||
AutomemBase_stack<T, S>::AutomemBase_stack() {
|
||||
}
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
AutomemBase_stack<T, S>::AutomemBase_stack (const AutomemBase_stack& parOther) {
|
||||
std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + S, this->GetMemPtr());
|
||||
}
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
AutomemBase_stack<T, S>::AutomemBase_stack (AutomemBase_stack&& parOther) {
|
||||
for (size_t z = 0; z < S; ++z) {
|
||||
std::swap(m_localMem[z], parOther.m_localMem[z]);
|
||||
}
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemRawBase_heap<T, S, A>::AutomemRawBase_heap() {
|
||||
#if !defined(NDEBUG)
|
||||
m_localMem = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
void AutomemRawBase_heap<T, S, A>::AllocMemory() {
|
||||
#if !defined(NDEBUG)
|
||||
Assert(NULL == m_localMem);
|
||||
#endif
|
||||
m_localMem = A().allocate(S);
|
||||
namespace {
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
|
||||
const char g_guard = 0xAB;
|
||||
#endif
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
void AutomemRawBase_heap<T, S, A>::FreeMemory() noexcept {
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemRawBase_heap<T, S, A>::AutomemRawBase_heap() {
|
||||
#if !defined(NDEBUG)
|
||||
Assert(NULL != m_localMem);
|
||||
m_localMem = nullptr;
|
||||
#endif
|
||||
A().deallocate(m_localMem, S);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
AutomemRawBase_heap<T, S, A>::AutomemRawBase_heap (AutomemRawBase_heap&& parOther) {
|
||||
#if !defined(NDEBUG)
|
||||
m_localMem = NULL;
|
||||
m_localMem = nullptr;
|
||||
#endif
|
||||
}
|
||||
this->swap(parOther);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
char* AutomemRawBase_heap<T, S, A>::GetMemPtrAtIndex (size_t parIndex) {
|
||||
T* const retVal = GetMemPtr() + parIndex;
|
||||
return reinterpret_cast<char*>(retVal);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
void AutomemRawBase_stack<T, S>::AllocMemory() {
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
T* AutomemRawBase_heap<T, S, A>::AllocMemory() {
|
||||
#if !defined(NDEBUG)
|
||||
Assert(nullptr == m_localMem);
|
||||
#endif
|
||||
m_localMem = A().allocate(S);
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
|
||||
std::fill(
|
||||
reinterpret_cast<char*>(&m_localMem[0]),
|
||||
reinterpret_cast<char*>(&m_localMem[0]) + sizeof(m_localMem),
|
||||
g_guard
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return m_localMem;
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
char* AutomemRawBase_stack<T, S>::GetMemPtrAtIndex (size_t parIndex) {
|
||||
T* const retVal = GetMemPtr() + parIndex;
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(retVal) % alignof(T) == 0);
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
void AutomemRawBase_heap<T, S, A>::FreeMemory() noexcept {
|
||||
#if !defined(NDEBUG)
|
||||
Assert(nullptr != m_localMem);
|
||||
#endif
|
||||
return reinterpret_cast<char*>(retVal);
|
||||
}
|
||||
A().deallocate(m_localMem, S);
|
||||
#if !defined(NDEBUG)
|
||||
m_localMem = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
template <typename... Args>
|
||||
T* AutomemRawBase_heap<T, S, A>::GetNewT (size_t parIndex, Args&&... parArgs) {
|
||||
assert(parIndex < S);
|
||||
T* const location = m_localMem + parIndex;
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(location) % alignof(T) == 0);
|
||||
assert(g_guard == *reinterpret_cast<const char*>(location));
|
||||
#endif
|
||||
return new(location) T(std::forward<Args...>(parArgs)...);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
T* AutomemRawBase_stack<T, S>::AllocMemory() {
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
|
||||
std::fill(
|
||||
reinterpret_cast<char*>(&m_localMem[0]),
|
||||
reinterpret_cast<char*>(&m_localMem[0]) + sizeof(m_localMem),
|
||||
g_guard
|
||||
);
|
||||
#endif
|
||||
return reinterpret_cast<T*>(&m_localMem[0]);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S>
|
||||
template <typename... Args>
|
||||
T* AutomemRawBase_stack<T, S>::GetNewT (size_t parIndex, Args&&... parArgs) {
|
||||
assert(parIndex < S);
|
||||
auto* const location = &m_localMem[parIndex];
|
||||
#if defined(ASSERTIONSENABLED)
|
||||
assert(reinterpret_cast<PTR_INT_TYPE>(location) % alignof(T) == 0);
|
||||
assert(g_guard == *reinterpret_cast<const char*>(location));
|
||||
#endif
|
||||
return new(location) T(std::forward<Args...>(parArgs)...);
|
||||
}
|
||||
} //namespace din
|
||||
|
|
|
@ -20,9 +20,7 @@ namespace din {
|
|||
///-------------------------------------------------------------------------
|
||||
template <typename T, size_t S, typename A>
|
||||
MaxSizedArray<T, S, A>::MaxSizedArray() {
|
||||
this->AllocMemory();
|
||||
//Careful here, I'm not sure this is valid c++
|
||||
m_localMem = reinterpret_cast<T*>(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<T*>(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<T*>(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 <typename T, size_t S, typename A>
|
||||
void MaxSizedArray<T, S, A>::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 <typename T, size_t S, typename A>
|
||||
void MaxSizedArray<T, S, A>::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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue