mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Feature/pool ext variant pool ext (#433)
* added threads dependency to meson build because of pthread linkage problems (gcc version Debian 8.3.0-6) * initial version of generic_pool_ext, pool_ext and variant_pool_ext (extended unit tests) * format code * fix test_call_if_and_not_valid_returning_void by moving SetupFixture into namespace (to ensure correct test setup) Co-authored-by: Daniel B <daniel-brosche@users.noreply.github.com>
This commit is contained in:
parent
a6d8a6d1ef
commit
494059fd6b
@ -194,7 +194,140 @@ namespace etl
|
||||
generic_pool& operator =(const generic_pool&);
|
||||
};
|
||||
|
||||
template <const size_t VTypeSize, const size_t VAlignment>
|
||||
class generic_pool_ext : public etl::ipool {
|
||||
private:
|
||||
// The pool element.
|
||||
union element_internal {
|
||||
char* next; ///< Pointer to the next free element.
|
||||
char value[VTypeSize]; ///< Storage for value type.
|
||||
typename etl::type_with_alignment<VAlignment>::type dummy; ///< Dummy item to get correct alignment.
|
||||
};
|
||||
|
||||
static const size_t ELEMENT_INTERNAL_SIZE = sizeof(element_internal);
|
||||
|
||||
public:
|
||||
static ETL_CONSTANT size_t ALIGNMENT = VAlignment;
|
||||
static ETL_CONSTANT size_t TYPE_SIZE = VTypeSize;
|
||||
|
||||
using element = typename etl::aligned_storage<sizeof(element_internal), etl::alignment_of<element_internal>::value>::type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
generic_pool_ext(element* buffer, size_t size) : etl::ipool(reinterpret_cast<char*>(&buffer[0]), ELEMENT_INTERNAL_SIZE, size) {}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
/// Static asserts if the specified type is too large for the pool.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* allocate()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::allocate<U>();
|
||||
}
|
||||
|
||||
#if ETL_CPP11_NOT_SUPPORTED || ETL_POOL_CPP03_CODE || ETL_USING_STLPORT
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* create()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1>
|
||||
U* create(const T1& value1)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>(value1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 2 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2>
|
||||
U* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 3 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 4 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3, typename T4>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3, value4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename U, typename... Args>
|
||||
U* create(Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
return ipool::create<U>(etl::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void destroy(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= VAlignment, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= VTypeSize, "Type too large for pool");
|
||||
p_object->~U();
|
||||
ipool::release(p_object);
|
||||
}
|
||||
|
||||
private:
|
||||
// Should not be copied.
|
||||
generic_pool_ext(const generic_pool_ext&);
|
||||
generic_pool_ext& operator=(const generic_pool_ext&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -178,6 +178,123 @@ namespace etl
|
||||
pool(const pool&) ETL_DELETE;
|
||||
pool& operator =(const pool&) ETL_DELETE;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class pool_ext : public etl::generic_pool_ext<sizeof(T), etl::alignment_of<T>::value> {
|
||||
private:
|
||||
typedef etl::generic_pool_ext<sizeof(T), etl::alignment_of<T>::value> base_t;
|
||||
|
||||
public:
|
||||
using base_t::ALIGNMENT;
|
||||
using base_t::TYPE_SIZE;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
pool_ext(typename base_t::element* buffer, size_t size) : base_t(buffer, size) {}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// Uses the default constructor.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
/// Static asserts if the specified type is too large for the pool.
|
||||
//*************************************************************************
|
||||
T* allocate() { return base_t::template allocate<T>(); }
|
||||
|
||||
#if ETL_CPP11_NOT_SUPPORTED || ETL_POOL_CPP03_CODE || ETL_USING_STLPORT
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
T* create() { return base_t::template create<T>(); }
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T1>
|
||||
T* create(const T1& value1)
|
||||
{
|
||||
return base_t::template create<T>(value1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 2 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2>
|
||||
T* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
return base_t::template create<T>(value1, value2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 3 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
return base_t::template create<T>(value1, value2, value3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 4 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
return base_t::template create<T>(value1, value2, value3, value4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with variadic parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename... Args>
|
||||
T* create(Args&&... args)
|
||||
{
|
||||
return base_t::template create<T>(etl::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Releases the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U' object derived from 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void release(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<U, T>::value || etl::is_base_of<U, T>::value), "Pool does not contain this type");
|
||||
base_t::release(p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U' object derived from 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void destroy(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<U, T>::value), "Pool does not contain this type");
|
||||
base_t::destroy(p_object);
|
||||
}
|
||||
|
||||
private:
|
||||
// Should not be copied.
|
||||
pool_ext(const pool_ext&) ETL_DELETE;
|
||||
pool_ext& operator=(const pool_ext&) ETL_DELETE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -206,6 +206,132 @@ namespace etl
|
||||
variant_pool(const variant_pool&) ETL_DELETE;
|
||||
variant_pool& operator =(const variant_pool&) ETL_DELETE;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <typename T1,
|
||||
typename T2 = void,
|
||||
typename T3 = void,
|
||||
typename T4 = void,
|
||||
typename T5 = void,
|
||||
typename T6 = void,
|
||||
typename T7 = void,
|
||||
typename T8 = void,
|
||||
typename T9 = void,
|
||||
typename T10 = void,
|
||||
typename T11 = void,
|
||||
typename T12 = void,
|
||||
typename T13 = void,
|
||||
typename T14 = void,
|
||||
typename T15 = void,
|
||||
typename T16 = void>
|
||||
class variant_pool_ext
|
||||
: public etl::generic_pool_ext<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
|
||||
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment> {
|
||||
public:
|
||||
typedef etl::generic_pool_ext<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
|
||||
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment>
|
||||
base_t;
|
||||
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
variant_pool_ext(typename base_t::element* buffer, size_t size) : base_t(buffer, size) {}
|
||||
|
||||
#if ETL_CPP11_NOT_SUPPORTED || ETL_USING_STLPORT
|
||||
//*************************************************************************
|
||||
/// Creates the object. Default constructor.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* create()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Creates the object. One parameter constructor.
|
||||
//*************************************************************************
|
||||
template <typename T, typename TP1>
|
||||
T* create(const TP1& p1)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>(p1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Creates the object. Two parameter constructor.
|
||||
//*************************************************************************
|
||||
template <typename T, typename TP1, typename TP2>
|
||||
T* create(const TP1& p1, const TP2& p2)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>(p1, p2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Creates the object. Three parameter constructor.
|
||||
//*************************************************************************
|
||||
template <typename T, typename TP1, typename TP2, typename TP3>
|
||||
T* create(const TP1& p1, const TP2& p2, const TP3& p3)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>(p1, p2, p3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Creates the object. Four parameter constructor.
|
||||
//*************************************************************************
|
||||
template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
|
||||
T* create(const TP1& p1, const TP2& p2, const TP3& p3, const TP4& p4)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>(p1, p2, p3, p4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Creates the object from a type. Variadic parameter constructor.
|
||||
//*************************************************************************
|
||||
template <typename T, typename... Args>
|
||||
T* create(Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
return base_t::template create<T>(args...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
void destroy(const T* const p)
|
||||
{
|
||||
ETL_STATIC_ASSERT(
|
||||
(etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value || etl::is_base_of<T, T1>::value ||
|
||||
etl::is_base_of<T, T2>::value || etl::is_base_of<T, T3>::value || etl::is_base_of<T, T4>::value || etl::is_base_of<T, T5>::value ||
|
||||
etl::is_base_of<T, T6>::value || etl::is_base_of<T, T7>::value || etl::is_base_of<T, T8>::value || etl::is_base_of<T, T9>::value ||
|
||||
etl::is_base_of<T, T10>::value || etl::is_base_of<T, T11>::value || etl::is_base_of<T, T12>::value || etl::is_base_of<T, T13>::value ||
|
||||
etl::is_base_of<T, T14>::value || etl::is_base_of<T, T15>::value || etl::is_base_of<T, T16>::value),
|
||||
"Invalid type");
|
||||
|
||||
base_t::destroy(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the variant_pool.
|
||||
//*************************************************************************
|
||||
// redundant also declared in ipool::max_size()
|
||||
size_t max_size() const { return base_t::max_size(); }
|
||||
|
||||
private:
|
||||
variant_pool_ext(const variant_pool_ext&) ETL_DELETE;
|
||||
variant_pool_ext& operator=(const variant_pool_ext&) ETL_DELETE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -85,6 +85,7 @@ etl_test_sources = files(
|
||||
'test/test_parameter_type.cpp',
|
||||
'test/test_parity_checksum.cpp',
|
||||
'test/test_pool.cpp',
|
||||
'test/test_pool_external_buffer.cpp',
|
||||
'test/test_priority_queue.cpp',
|
||||
'test/test_queue.cpp',
|
||||
'test/test_queue_memory_model_small.cpp',
|
||||
@ -114,6 +115,7 @@ etl_test_sources = files(
|
||||
'test/test_variant_legacy.cpp',
|
||||
'test/test_variant_variadic.cpp',
|
||||
'test/test_variant_pool.cpp',
|
||||
'test/test_variant_pool_external_buffer.cpp',
|
||||
'test/test_variant_variadic.cpp',
|
||||
'test/test_vector.cpp',
|
||||
'test/test_vector_non_trivial.cpp',
|
||||
@ -179,6 +181,8 @@ unittestcpp_dep = dependency('UnitTest++',
|
||||
disabler: true,
|
||||
)
|
||||
|
||||
threads_dep = dependency('threads')
|
||||
|
||||
etl_unit_tests = executable('etl_unit_tests',
|
||||
include_directories: [
|
||||
include_directories('test'),
|
||||
@ -187,7 +191,7 @@ etl_unit_tests = executable('etl_unit_tests',
|
||||
include_directories('include')
|
||||
],
|
||||
sources: etl_test_sources,
|
||||
dependencies: unittestcpp_dep,
|
||||
dependencies: [unittestcpp_dep, threads_dep],
|
||||
cpp_args: [
|
||||
'-fexceptions',
|
||||
'-DENABLE_ETL_UNIT_TESTS',
|
||||
|
||||
@ -185,6 +185,7 @@ set(TEST_SOURCE_FILES
|
||||
test_parity_checksum.cpp
|
||||
test_pearson.cpp
|
||||
test_pool.cpp
|
||||
test_pool_external_buffer.cpp
|
||||
test_priority_queue.cpp
|
||||
test_quantize.cpp
|
||||
test_queue.cpp
|
||||
@ -257,6 +258,7 @@ set(TEST_SOURCE_FILES
|
||||
test_variant_legacy.cpp
|
||||
test_variant_variadic.cpp
|
||||
test_variant_pool.cpp
|
||||
test_variant_pool_external_buffer.cpp
|
||||
test_vector.cpp
|
||||
test_vector_external_buffer.cpp
|
||||
test_vector_non_trivial.cpp
|
||||
|
||||
@ -222,20 +222,20 @@ namespace
|
||||
const Test const_test_static;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Initialises the test results.
|
||||
//*****************************************************************************
|
||||
struct SetupFixture
|
||||
{
|
||||
SetupFixture()
|
||||
{
|
||||
function_called = false;
|
||||
parameter_correct = false;
|
||||
}
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
//*****************************************************************************
|
||||
// Initialises the test results.
|
||||
//*****************************************************************************
|
||||
struct SetupFixture
|
||||
{
|
||||
SetupFixture()
|
||||
{
|
||||
function_called = false;
|
||||
parameter_correct = false;
|
||||
}
|
||||
};
|
||||
|
||||
SUITE(test_delegate)
|
||||
{
|
||||
//*************************************************************************
|
||||
|
||||
496
test/test_pool_external_buffer.cpp
Normal file
496
test/test_pool_external_buffer.cpp
Normal file
@ -0,0 +1,496 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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 the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "data.h"
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "etl/pool.h"
|
||||
#include "etl/largest.h"
|
||||
|
||||
#if defined(ETL_COMPILER_GCC)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
typedef TestDataDC<std::string> Test_Data;
|
||||
typedef TestDataNDC<std::string> Test_Data2;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct D0
|
||||
{
|
||||
D0()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct D1
|
||||
{
|
||||
D1(const std::string& a_)
|
||||
: a(a_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
};
|
||||
|
||||
struct D2
|
||||
{
|
||||
D2(const std::string& a_, const std::string& b_)
|
||||
: a(a_),
|
||||
b(b_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
};
|
||||
|
||||
struct D3
|
||||
{
|
||||
D3(const std::string& a_, const std::string& b_, const std::string& c_)
|
||||
: a(a_),
|
||||
b(b_),
|
||||
c(c_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
std::string c;
|
||||
};
|
||||
|
||||
struct D4
|
||||
{
|
||||
D4(const std::string& a_, const std::string& b_, const std::string& c_, const std::string& d_)
|
||||
: a(a_),
|
||||
b(b_),
|
||||
c(c_),
|
||||
d(d_)
|
||||
{
|
||||
}
|
||||
|
||||
std::string a;
|
||||
std::string b;
|
||||
std::string c;
|
||||
std::string d;
|
||||
};
|
||||
|
||||
bool operator == (const D0&, const D0&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator == (const D1& lhs, const D1& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a);
|
||||
}
|
||||
|
||||
bool operator == (const D2& lhs, const D2& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b);
|
||||
}
|
||||
|
||||
bool operator == (const D3& lhs, const D3& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c);
|
||||
}
|
||||
|
||||
bool operator == (const D4& lhs, const D4& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d);
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D0&)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D1& d)
|
||||
{
|
||||
os << d.a;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D2& d)
|
||||
{
|
||||
os << d.a << " " << d.b;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D3& d)
|
||||
{
|
||||
os << d.a << " " << d.b << " " << d.c;
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const D4& d)
|
||||
{
|
||||
os << d.a << " " << d.b << " " << d.c << " " << d.d;
|
||||
return os;
|
||||
}
|
||||
|
||||
SUITE(test_pool_external_buffer)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_allocate)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
Test_Data* p1 = nullptr;
|
||||
Test_Data* p2 = nullptr;
|
||||
Test_Data* p3 = nullptr;
|
||||
Test_Data* p4 = nullptr;
|
||||
|
||||
CHECK_NO_THROW(p1 = pool.allocate());
|
||||
CHECK_NO_THROW(p2 = pool.allocate());
|
||||
CHECK_NO_THROW(p3 = pool.allocate());
|
||||
CHECK_NO_THROW(p4 = pool.allocate());
|
||||
|
||||
CHECK(p1 != p2);
|
||||
CHECK(p1 != p3);
|
||||
CHECK(p1 != p4);
|
||||
CHECK(p2 != p3);
|
||||
CHECK(p2 != p4);
|
||||
CHECK(p3 != p4);
|
||||
|
||||
CHECK_THROW(pool.allocate(), etl::pool_no_allocation);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_release)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
Test_Data* p1 = pool.allocate();
|
||||
Test_Data* p2 = pool.allocate();
|
||||
Test_Data* p3 = pool.allocate();
|
||||
Test_Data* p4 = pool.allocate();
|
||||
|
||||
CHECK_NO_THROW(pool.release(p2));
|
||||
CHECK_NO_THROW(pool.release(p3));
|
||||
CHECK_NO_THROW(pool.release(p1));
|
||||
CHECK_NO_THROW(pool.release(p4));
|
||||
|
||||
CHECK_EQUAL(4U, pool.available());
|
||||
|
||||
Test_Data not_in_pool;
|
||||
|
||||
CHECK_THROW(pool.release(¬_in_pool), etl::pool_object_not_in_pool);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_allocate_release)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
Test_Data* p1 = pool.allocate();
|
||||
Test_Data* p2 = pool.allocate();
|
||||
Test_Data* p3 = pool.allocate();
|
||||
Test_Data* p4 = pool.allocate();
|
||||
|
||||
// Allocated p1, p2, p3, p4
|
||||
|
||||
CHECK_EQUAL(0U, pool.available());
|
||||
|
||||
CHECK_NO_THROW(pool.release(p2));
|
||||
CHECK_NO_THROW(pool.release(p3));
|
||||
|
||||
// Allocated p1, p4
|
||||
|
||||
CHECK_EQUAL(2U, pool.available());
|
||||
|
||||
Test_Data* p5 = pool.allocate();
|
||||
Test_Data* p6 = pool.allocate();
|
||||
|
||||
// Allocated p1, p4, p5, p6
|
||||
|
||||
CHECK_EQUAL(0U, pool.available());
|
||||
|
||||
CHECK(p5 != p1);
|
||||
CHECK(p5 != p4);
|
||||
|
||||
CHECK(p6 != p1);
|
||||
CHECK(p6 != p4);
|
||||
|
||||
CHECK_NO_THROW(pool.release(p5));
|
||||
|
||||
// Allocated p1, p4, p6
|
||||
|
||||
CHECK_EQUAL(1U, pool.available());
|
||||
|
||||
Test_Data* p7 = pool.allocate();
|
||||
|
||||
// Allocated p1, p4, p6, p7
|
||||
|
||||
CHECK(p7 != p1);
|
||||
CHECK(p7 != p4);
|
||||
CHECK(p7 != p6);
|
||||
|
||||
CHECK(pool.full());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_available)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
CHECK_EQUAL(4U, pool.available());
|
||||
|
||||
Test_Data* p;
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(3U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(2U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(1U, pool.available());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(0U, pool.available());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_max_size)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
CHECK(pool.max_size() == 4U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_size)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
CHECK_EQUAL(0U, pool.size());
|
||||
|
||||
Test_Data* p;
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(1U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(2U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(3U, pool.size());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK_EQUAL(4U, pool.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_empty_full)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
CHECK(pool.empty());
|
||||
CHECK(!pool.full());
|
||||
|
||||
Test_Data* p;
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK(!pool.empty());
|
||||
CHECK(!pool.full());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK(!pool.empty());
|
||||
CHECK(!pool.full());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK(!pool.empty());
|
||||
CHECK(!pool.full());
|
||||
|
||||
p = pool.allocate();
|
||||
CHECK(!pool.empty());
|
||||
CHECK(pool.full());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_is_in_pool)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<Test_Data>::element[SIZE];
|
||||
etl::pool_ext<Test_Data> pool(buffer, SIZE);
|
||||
|
||||
Test_Data not_in_pool;
|
||||
|
||||
Test_Data* p1 = pool.allocate();
|
||||
|
||||
CHECK(pool.is_in_pool(p1));
|
||||
CHECK(!pool.is_in_pool(¬_in_pool));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_error)
|
||||
{
|
||||
struct Test
|
||||
{
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
};
|
||||
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<uint32_t>::element[SIZE];
|
||||
etl::pool_ext<uint32_t> pool(buffer, SIZE);
|
||||
|
||||
etl::ipool& ip = pool;
|
||||
|
||||
CHECK_THROW(ip.allocate<Test>(), etl::pool_element_size);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_create_destroy)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
|
||||
auto* buffer0 = new etl::pool_ext<D0>::element[SIZE];
|
||||
etl::pool_ext<D0> pool0(buffer0, SIZE);
|
||||
|
||||
auto* buffer1 = new etl::pool_ext<D1>::element[SIZE];
|
||||
etl::pool_ext<D1> pool1(buffer1, SIZE);
|
||||
|
||||
auto* buffer2 = new etl::pool_ext<D2>::element[SIZE];
|
||||
etl::pool_ext<D2> pool2(buffer2, SIZE);
|
||||
|
||||
auto* buffer3 = new etl::pool_ext<D3>::element[SIZE];
|
||||
etl::pool_ext<D3> pool3(buffer3, SIZE);
|
||||
|
||||
auto* buffer4 = new etl::pool_ext<D4>::element[SIZE];
|
||||
etl::pool_ext<D4> pool4(buffer4, SIZE);
|
||||
|
||||
|
||||
D0* p0 = pool0.create();
|
||||
D1* p1 = pool1.create("1");
|
||||
D2* p2 = pool2.create("1", "2");
|
||||
D3* p3 = pool3.create("1", "2", "3");
|
||||
D4* p4 = pool4.create("1", "2", "3", "4");
|
||||
|
||||
CHECK_EQUAL(pool0.max_size() - 1, pool0.available());
|
||||
CHECK_EQUAL(1U, pool0.size());
|
||||
|
||||
CHECK_EQUAL(pool1.max_size() - 1, pool1.available());
|
||||
CHECK_EQUAL(1U, pool1.size());
|
||||
|
||||
CHECK_EQUAL(pool2.max_size() - 1, pool2.available());
|
||||
CHECK_EQUAL(1U, pool2.size());
|
||||
|
||||
CHECK_EQUAL(pool3.max_size() - 1, pool3.available());
|
||||
CHECK_EQUAL(1U, pool3.size());
|
||||
|
||||
CHECK_EQUAL(pool4.max_size() - 1, pool4.available());
|
||||
CHECK_EQUAL(1U, pool4.size());
|
||||
|
||||
CHECK_EQUAL(D0(), *p0);
|
||||
CHECK_EQUAL(D1("1"), *p1);
|
||||
CHECK_EQUAL(D2("1", "2"), *p2);
|
||||
CHECK_EQUAL(D3("1", "2", "3"), *p3);
|
||||
CHECK_EQUAL(D4("1", "2", "3", "4"), *p4);
|
||||
|
||||
pool0.destroy<D0>(p0);
|
||||
pool1.destroy<D1>(p1);
|
||||
pool2.destroy<D2>(p2);
|
||||
pool3.destroy<D3>(p3);
|
||||
pool4.destroy<D4>(p4);
|
||||
|
||||
CHECK_EQUAL(pool0.max_size(), pool0.available());
|
||||
CHECK_EQUAL(0U, pool0.size());
|
||||
|
||||
CHECK_EQUAL(pool1.max_size(), pool1.available());
|
||||
CHECK_EQUAL(0U, pool1.size());
|
||||
|
||||
CHECK_EQUAL(pool2.max_size(), pool2.available());
|
||||
CHECK_EQUAL(0U, pool2.size());
|
||||
|
||||
CHECK_EQUAL(pool3.max_size(), pool3.available());
|
||||
CHECK_EQUAL(0U, pool3.size());
|
||||
|
||||
CHECK_EQUAL(pool4.max_size(), pool4.available());
|
||||
CHECK_EQUAL(0U, pool4.size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_allocate_release_non_class)
|
||||
{
|
||||
const size_t SIZE = 4;
|
||||
auto* buffer = new etl::pool_ext<int>::element[SIZE];
|
||||
etl::pool_ext<int> pool(buffer, SIZE);
|
||||
|
||||
int* i = pool.allocate();
|
||||
pool.release(i);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_issue_406_pool_of_c_array)
|
||||
{
|
||||
using elem_type = uint8_t[10];
|
||||
|
||||
const size_t SIZE = 3;
|
||||
auto* buffer = new etl::pool_ext<elem_type>::element[SIZE];
|
||||
etl::pool_ext<elem_type> memPool(buffer, SIZE);
|
||||
|
||||
CHECK_EQUAL(3, memPool.available());
|
||||
CHECK_EQUAL(0, memPool.size());
|
||||
|
||||
elem_type* memory = memPool.allocate();
|
||||
|
||||
CHECK_EQUAL(2, memPool.available());
|
||||
CHECK_EQUAL(1, memPool.size());
|
||||
|
||||
memPool.release(memory);
|
||||
|
||||
CHECK_EQUAL(3, memPool.available());
|
||||
CHECK_EQUAL(0, memPool.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(ETL_COMPILER_GCC)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
319
test/test_variant_pool_external_buffer.cpp
Normal file
319
test/test_variant_pool_external_buffer.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2017 jwellbelove
|
||||
|
||||
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 the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/variant_pool.h"
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool destructor;
|
||||
|
||||
//***********************************
|
||||
struct Base
|
||||
{
|
||||
Base()
|
||||
{
|
||||
destructor = false;
|
||||
}
|
||||
|
||||
virtual ~Base()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Set() = 0;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Derived1 : public Base
|
||||
{
|
||||
int i;
|
||||
|
||||
Derived1()
|
||||
: i(0)
|
||||
{
|
||||
}
|
||||
|
||||
~Derived1()
|
||||
{
|
||||
destructor = true;
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Derived2 : public Base
|
||||
{
|
||||
double d;
|
||||
|
||||
Derived2()
|
||||
: d(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
~Derived2()
|
||||
{
|
||||
destructor = true;
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
d = 1.2;
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Derived3 : public Base
|
||||
{
|
||||
std::string s;
|
||||
|
||||
Derived3()
|
||||
: s("constructed")
|
||||
{
|
||||
}
|
||||
|
||||
Derived3(const char* p1)
|
||||
: s("constructed")
|
||||
{
|
||||
s.append(p1);
|
||||
}
|
||||
|
||||
Derived3(const char* p1, const std::string& p2)
|
||||
: s("constructed")
|
||||
{
|
||||
s.append(p1);
|
||||
s.append(p2);
|
||||
}
|
||||
|
||||
Derived3(const char* p1, const std::string& p2, const char* p3)
|
||||
: s("constructed")
|
||||
{
|
||||
s.append(p1);
|
||||
s.append(p2);
|
||||
s.append(p3);
|
||||
}
|
||||
|
||||
Derived3(const char* p1, const std::string& p2, const char* p3, const std::string& p4)
|
||||
: s("constructed")
|
||||
{
|
||||
s.append(p1);
|
||||
s.append(p2);
|
||||
s.append(p3);
|
||||
s.append(p4);
|
||||
}
|
||||
|
||||
~Derived3()
|
||||
{
|
||||
destructor = true;
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
s = "set";
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct NonDerived
|
||||
{
|
||||
NonDerived()
|
||||
: s("constructed")
|
||||
{
|
||||
}
|
||||
|
||||
~NonDerived()
|
||||
{
|
||||
destructor = true;
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
s = "set";
|
||||
}
|
||||
|
||||
std::string s;
|
||||
};
|
||||
|
||||
const size_t SIZE = 5;
|
||||
|
||||
// Notice that the type declaration order is not important.
|
||||
typedef etl::variant_pool_ext<Derived1, NonDerived, Derived3, Derived2, int> Factory;
|
||||
|
||||
SUITE(test_variant_pool_external_buffer)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_sizes)
|
||||
{
|
||||
auto* buffer = new Factory::element[SIZE];
|
||||
Factory variant_pool(buffer, SIZE);
|
||||
|
||||
size_t ms = variant_pool.max_size();
|
||||
CHECK_EQUAL(SIZE, ms);
|
||||
CHECK_EQUAL(SIZE, variant_pool.available());
|
||||
CHECK_EQUAL(0U, variant_pool.size());
|
||||
CHECK(variant_pool.empty());
|
||||
CHECK(!variant_pool.full());
|
||||
|
||||
variant_pool.create<Derived1>();
|
||||
CHECK_EQUAL(SIZE - 1U, variant_pool.available());
|
||||
CHECK_EQUAL(1U, variant_pool.size());
|
||||
CHECK(!variant_pool.empty());
|
||||
CHECK(!variant_pool.full());
|
||||
|
||||
variant_pool.create<Derived1>();
|
||||
variant_pool.create<Derived1>();
|
||||
variant_pool.create<Derived1>();
|
||||
variant_pool.create<Derived1>();
|
||||
CHECK_EQUAL(0U, variant_pool.available());
|
||||
CHECK_EQUAL(SIZE, variant_pool.size());
|
||||
CHECK(!variant_pool.empty());
|
||||
CHECK(variant_pool.full());
|
||||
|
||||
CHECK_THROW(variant_pool.create<Derived1>(), etl::pool_no_allocation);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_create_release)
|
||||
{
|
||||
auto* buffer = new Factory::element[SIZE];
|
||||
Factory variant_pool(buffer, SIZE);
|
||||
|
||||
Base* p;
|
||||
|
||||
// Derived 1
|
||||
p = variant_pool.create<Derived1>();
|
||||
Derived1* pd1 = static_cast<Derived1*>(p);
|
||||
CHECK_EQUAL(0, pd1->i);
|
||||
p->Set();
|
||||
CHECK_EQUAL(1, pd1->i);
|
||||
variant_pool.destroy(p);
|
||||
CHECK(destructor);
|
||||
|
||||
// Derived 2
|
||||
destructor = false;
|
||||
p = variant_pool.create<Derived2>();
|
||||
Derived2* pd2 = static_cast<Derived2*>(p);
|
||||
CHECK_EQUAL(0.0, pd2->d);
|
||||
p->Set();
|
||||
CHECK_EQUAL(1.2, pd2->d);
|
||||
variant_pool.destroy(p);
|
||||
CHECK(destructor);
|
||||
|
||||
// Derived 3
|
||||
destructor = false;
|
||||
p = variant_pool.create<Derived3>();
|
||||
Derived3* pd3 = static_cast<Derived3*>(p);
|
||||
CHECK_EQUAL("constructed", pd3->s);
|
||||
p->Set();
|
||||
CHECK_EQUAL("set", pd3->s);
|
||||
variant_pool.destroy(p);
|
||||
CHECK(destructor);
|
||||
|
||||
// Non Derived
|
||||
destructor = false;
|
||||
NonDerived* pnd = variant_pool.create<NonDerived>();
|
||||
CHECK_EQUAL("constructed", pnd->s);
|
||||
pnd->Set();
|
||||
CHECK_EQUAL("set", pnd->s);
|
||||
variant_pool.destroy(pnd);
|
||||
CHECK(destructor);
|
||||
|
||||
// Integral
|
||||
int* pi = variant_pool.create<int>();
|
||||
variant_pool.destroy(pi);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_create_release_const)
|
||||
{
|
||||
auto* buffer = new Factory::element[SIZE];
|
||||
Factory variant_pool(buffer, SIZE);
|
||||
|
||||
const Derived1& d = *variant_pool.create<Derived1>();
|
||||
|
||||
CHECK_EQUAL(0, d.i);
|
||||
variant_pool.destroy(&d);
|
||||
CHECK(destructor);
|
||||
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_create_emplace)
|
||||
{
|
||||
auto* buffer = new Factory::element[SIZE];
|
||||
Factory variant_pool(buffer, SIZE);
|
||||
|
||||
Base* p;
|
||||
Derived3* pd3;
|
||||
|
||||
p = variant_pool.create<Derived3>("1");
|
||||
pd3 = static_cast<Derived3*>(p);
|
||||
CHECK_EQUAL("constructed1", pd3->s);
|
||||
variant_pool.destroy(p);
|
||||
|
||||
p = variant_pool.create<Derived3>("1", "2");
|
||||
pd3 = static_cast<Derived3*>(p);
|
||||
CHECK_EQUAL("constructed12", pd3->s);
|
||||
variant_pool.destroy(p);
|
||||
|
||||
p = variant_pool.create<Derived3>("1", "2", "3");
|
||||
pd3 = static_cast<Derived3*>(p);
|
||||
CHECK_EQUAL("constructed123", pd3->s);
|
||||
variant_pool.destroy(p);
|
||||
|
||||
p = variant_pool.create<Derived3>("1", "2", "3", "4");
|
||||
pd3 = static_cast<Derived3*>(p);
|
||||
CHECK_EQUAL("constructed1234", pd3->s);
|
||||
variant_pool.destroy(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_did_not_create)
|
||||
{
|
||||
auto* buffer1 = new Factory::element[SIZE];
|
||||
Factory variant_pool1(buffer1, SIZE);
|
||||
auto* buffer2 = new Factory::element[SIZE];
|
||||
Factory variant_pool2(buffer2, SIZE);
|
||||
|
||||
Base* p;
|
||||
|
||||
p = variant_pool1.create<Derived1>();
|
||||
CHECK_NO_THROW(variant_pool1.destroy(p));
|
||||
|
||||
p = variant_pool2.create<Derived1>();
|
||||
CHECK_THROW(variant_pool1.destroy(p), etl::pool_object_not_in_pool);
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user