1
0
Fork 0
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:
King_DuckZ 2016-01-28 19:02:15 +01:00
parent 394ae7672a
commit 362a5d3128
3 changed files with 99 additions and 195 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;
}