diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index fc3b525..2b89b6f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -14,6 +14,7 @@ option( BUILD_UNITTESTS "Build unit tests." ON ) add_definitions( -DCPPCORE_BUILD ) add_definitions( -D_VARIADIC_MAX=10 ) +add_definitions( -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1) INCLUDE_DIRECTORIES( BEFORE ${CMAKE_HOME_DIRECTORY}/.. diff --git a/include/cppcore/CPPCoreCommon.h b/include/cppcore/CPPCoreCommon.h index d6851e1..bf2e46e 100644 --- a/include/cppcore/CPPCoreCommon.h +++ b/include/cppcore/CPPCoreCommon.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2016 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -24,6 +24,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include +#include +#include namespace CPPCore { @@ -81,8 +84,9 @@ void ContainerClear( T & ctr, void( *DeleterFunc )( T & ) = nullptr ) { /// @param name [in] The name of the class. //------------------------------------------------------------------------------------------------- #define CPPCORE_NONE_COPYING( name ) \ -private:\ +public: \ name( const name & ) = delete ;\ + name( name && ) = delete; \ name &operator = ( const name & ) = delete; //------------------------------------------------------------------------------------------------- diff --git a/include/cppcore/Common/Variant.h b/include/cppcore/Common/Variant.h index ded8014..898b260 100644 --- a/include/cppcore/Common/Variant.h +++ b/include/cppcore/Common/Variant.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2017 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -87,7 +87,12 @@ class Variant { /// @return TYpe enum of the current dynamic type of the instance. Type getType() const; + /// @brief Will set the payload to the given value. + /// @param value [in] The new given payload. void setByte(unsigned char value); + + /// @brief Will return the current payload as a byte value. + /// @return The byte value. unsigned char getByte() const; /// @brief Sets a new integer value, old values will be released and destroyed. diff --git a/include/cppcore/Memory/TPoolAllocator.h b/include/cppcore/Memory/TPoolAllocator.h index 2771409..0876b86 100644 --- a/include/cppcore/Memory/TPoolAllocator.h +++ b/include/cppcore/Memory/TPoolAllocator.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2016 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -22,23 +22,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ #pragma once -#include +#include #include -#include namespace CPPCore { - //------------------------------------------------------------------------------------------------- - /// @class TPoolAllocator - /// @ingroup CPPCore - /// - /// @brief This class implements a simple poll-based allocation scheme. - /// Initially you have to define its size. Each allocation will be done from this initially created - /// pool. You have to release all pooled instances after the usage. - /// This allocation scheme is fast and does no call any new-calls during the lifetime of the - /// allocator. - //------------------------------------------------------------------------------------------------- - template +//------------------------------------------------------------------------------------------------- +/// @class TPoolAllocator +/// @ingroup CPPCore +/// +/// @brief This class implements a simple poll-based allocation scheme. +/// Initially you have to define its size. Each allocation will be done from this initially created +/// pool. You have to release all pooled instances after the usage. +/// This allocation scheme is fast and does no call any new-calls during the lifetime of the +/// allocator. +//------------------------------------------------------------------------------------------------- +template class TPoolAllocator { public: TPoolAllocator(); @@ -52,29 +51,62 @@ class TPoolAllocator { size_t reservedMem() const; size_t freeMem() const; void dumpAllocations(CString & allocs); + void resize(size_t growSize ); + + CPPCORE_NONE_COPYING(TPoolAllocator) private: - size_t m_poolsize; - T *m_pool; - size_t m_currentIdx; + struct Pool { + size_t m_poolsize; + T *m_pool; + size_t m_currentIdx; + Pool *m_next; + + Pool() + : m_poolsize(0u) + , m_pool(nullptr) + , m_currentIdx(0u) + , m_next(nullptr) { + // empty + } + + Pool(size_t numItems, Pool *prev) + : m_poolsize(numItems) + , m_pool(nullptr) + , m_currentIdx(0u) + , m_next(prev) { + m_pool = new T[m_poolsize]; + } + + ~Pool() { + delete[] m_pool; + m_pool = nullptr; + } + + CPPCORE_NONE_COPYING(Pool) + }; + + Pool *m_first; + Pool *m_current; + size_t m_capacity; }; template inline TPoolAllocator::TPoolAllocator() -: m_poolsize(0) -, m_pool(nullptr) -, m_currentIdx(0) { +: m_first(nullptr) +, m_current(nullptr) +, m_capacity(0L) { // empty } template inline TPoolAllocator::TPoolAllocator(size_t numItems) -: m_poolsize(numItems) -, m_pool(nullptr) -, m_currentIdx( 0 ) { - m_pool = new T[m_poolsize]; +: m_first(nullptr) +, m_current(nullptr) { + m_first = new Pool(numItems); + m_current = m_first; } template @@ -86,57 +118,84 @@ TPoolAllocator::~TPoolAllocator() { template inline T *TPoolAllocator::alloc() { - if ( m_currentIdx == m_poolsize ) { + if (nullptr == m_current) { return nullptr; } + + if (m_current->m_currentIdx == m_current->m_poolsize) { + resize(m_current->m_poolsize); + } + + T *ptr(&m_current->m_pool[m_current->m_currentIdx]); + m_current->m_currentIdx++; - ++m_currentIdx; - return &m_pool[m_currentIdx-1]; + return ptr; } template inline void TPoolAllocator::release() { - m_currentIdx = 0; + if (nullptr == m_current) { + return; + } + + m_current->m_currentIdx = 0; } template inline void TPoolAllocator::reserve(size_t size) { clear(); - m_pool = new T[ size ]; - m_poolsize = size; + + m_first = new Pool(size, nullptr); + m_current = m_first; + + m_current->m_pool = new T[size]; + m_current->m_poolsize = size; + + m_capacity = size; } template inline void TPoolAllocator::clear() { - if (nullptr == m_pool) { + if (nullptr == m_current) { return; } - delete [] m_pool; - m_pool = nullptr; - m_currentIdx = 0; - m_poolsize = 0; + Pool *next(m_first); + while ( nullptr != next) { + Pool *current = next; + next = current->m_next; + delete current; + } + m_current = nullptr; } template inline size_t TPoolAllocator::capacity() const { - return m_poolsize; + if (nullptr == m_current) { + return 0L; + } + + return m_current->m_poolsize; } template inline size_t TPoolAllocator::reservedMem() const { - return m_poolsize * sizeof(T); + return m_capacity; } template inline size_t TPoolAllocator::freeMem() const { - return m_poolsize - m_currentIdx; + if (nullptr == m_current) { + return 0L; + } + + return (m_current->m_poolsize - m_current->m_currentIdx); } template @@ -144,8 +203,27 @@ inline void TPoolAllocator::dumpAllocations(CString & allocs) { allocs.clear(); char buffer[512]; - sprintf(buffer, "Number allocations = %d\n", (int)m_currentIdx); + ::sprintf(buffer, "Number allocations = %zu\n", m_current->m_currentIdx); allocs.set(buffer); } +template +inline +void TPoolAllocator::resize(size_t growSize) { + if (nullptr != m_current) { + if (growSize < m_current->m_poolsize) { + return; + } + } + + if (nullptr == m_first) { + m_first = new Pool(growSize, nullptr); + m_current = m_first; + } else { + m_current->m_next = new Pool(growSize, nullptr); + m_current = m_current->m_next; + } + m_capacity += m_current->m_poolsize; } + +} // Namespace CPPCore diff --git a/include/cppcore/Memory/TStackAllocator.h b/include/cppcore/Memory/TStackAllocator.h index dc9fc8a..000b4a9 100644 --- a/include/cppcore/Memory/TStackAllocator.h +++ b/include/cppcore/Memory/TStackAllocator.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2016 Kim Kulling +Copyright (c) 2014-2019 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -22,9 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ #pragma once -#include +#include #include -#include namespace CPPCore { @@ -52,11 +51,11 @@ class TStackAllocator { size_t reservedMem() const; size_t freeMem() const; void dumpAllocations( CString & allocs ); - TStackAllocator( const TStackAllocator & ) = delete; - TStackAllocator &operator = ( const TStackAllocator & ) = delete; + + CPPCORE_NONE_COPYING(TStackAllocator) private: - typedef unsigned char byte_t; + using byte_t = unsigned char; struct Header { size_t m_size; }; @@ -171,7 +170,7 @@ inline void TStackAllocator::dumpAllocations( CString & allocs ) { allocs.clear(); char buffer[ 512 ]; - sprintf( buffer, "Number allocations = %d\n", ( int ) m_numAllocs ); + sprintf( buffer, "Number allocations = %zu\n", m_numAllocs ); allocs.set( buffer ); } diff --git a/test/container/TArrayTest.cpp b/test/container/TArrayTest.cpp index 00bce1c..468012c 100644 --- a/test/container/TArrayTest.cpp +++ b/test/container/TArrayTest.cpp @@ -65,7 +65,7 @@ TEST_F( TArrayTest, constructTest ) { TEST_F( TArrayTest, constructWithSizeTest) { TArray arrayInstance( 4 ); - EXPECT_EQ( 4, arrayInstance.size() ); + EXPECT_EQ( 4u, arrayInstance.size() ); } TEST_F( TArrayTest, addTest) { @@ -73,7 +73,7 @@ TEST_F( TArrayTest, addTest) { arrayInstance.add( 0.0f ); arrayInstance.add( 1.0f ); - EXPECT_EQ( 2, arrayInstance.size() ); + EXPECT_EQ( 2u, arrayInstance.size() ); EXPECT_EQ( 0.0f, arrayInstance[ 0 ] ); EXPECT_EQ( 1.0f, arrayInstance[ 1 ] ); } @@ -84,13 +84,13 @@ TEST_F( TArrayTest, addItemsTest ) { float data[2] = { 0, 1 }; arrayInstance.add( data, 2 ); - EXPECT_EQ( 3, arrayInstance.size() ); + EXPECT_EQ( 3u, arrayInstance.size() ); EXPECT_EQ( 0.0f, arrayInstance[ 0 ] ); EXPECT_EQ( 0.0f, arrayInstance[ 1 ] ); EXPECT_EQ( 1.0f, arrayInstance[ 2 ] ); arrayInstance.add( nullptr, 0 ); - EXPECT_EQ( 3, arrayInstance.size() ); + EXPECT_EQ( 3u, arrayInstance.size() ); } TEST_F( TArrayTest, accessTest) { diff --git a/test/memory/TPoolAllocatorTest.cpp b/test/memory/TPoolAllocatorTest.cpp index fb46075..f1597d3 100644 --- a/test/memory/TPoolAllocatorTest.cpp +++ b/test/memory/TPoolAllocatorTest.cpp @@ -61,7 +61,7 @@ TEST_F(TPoolAllocatorTest, alloc_access_Test) { } PoolItem *nullItem = allocator.alloc(); - EXPECT_EQ(nullptr, nullItem); + EXPECT_NE(nullptr, nullItem); } TEST_F(TPoolAllocatorTest, countAllocsTest) { @@ -84,8 +84,18 @@ TEST_F(TPoolAllocatorTest, getAllocsTest) { TEST_F(TPoolAllocatorTest, clearTest ) { TPoolAllocator allocator; - allocator.reserve( 100 ); + allocator.reserve( 100u ); allocator.clear(); EXPECT_EQ( allocator.freeMem(), 0u ); } +TEST_F(TPoolAllocatorTest, resizeTest) { + TPoolAllocator allocator; + allocator.resize(100); + //allocator.resize(100); + + for (size_t i = 0; i < 200; ++i) { + EXPECT_NE(nullptr, allocator.alloc()); + } + EXPECT_EQ(200u, allocator.reservedMem()); +}