mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
New ContainerTest generic templates
This commit is contained in:
@@ -17,49 +17,303 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ContainerTests
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Counts the number of occurrences of each type of operation. */
|
||||
class Counts
|
||||
{
|
||||
public:
|
||||
typedef std::size_t count_type;
|
||||
|
||||
Counts ()
|
||||
: default_ctor (0)
|
||||
, copy_ctor (0)
|
||||
, copy_assign (0)
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
, move_ctor (0)
|
||||
, move_assign (0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
Counts (Counts const& other)
|
||||
: default_ctor (other.default_ctor)
|
||||
, copy_ctor (other.copy_ctor)
|
||||
, copy_assign (other.copy_assign)
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
, move_ctor (other.move_ctor)
|
||||
, move_assign (other.move_assign)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
Counts& operator= (Counts const& other)
|
||||
{
|
||||
default_ctor = other.default_ctor;
|
||||
copy_ctor = other.copy_ctor;
|
||||
copy_assign = other.copy_assign;
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
move_ctor = other.move_ctor;
|
||||
move_assign = other.move_assign;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline Counts operator- (Counts const& lhs, Counts const& rhs)
|
||||
{
|
||||
Counts result;
|
||||
result.default_ctor = lhs.default_ctor - rhs.default_ctor;
|
||||
result.copy_ctor = lhs.copy_ctor - rhs.copy_ctor;
|
||||
result.copy_assign = lhs.copy_assign - rhs.copy_assign;
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
result.move_ctor = lhs.move_ctor - rhs.move_ctor;
|
||||
result.move_assign = lhs.move_assign - rhs.move_assign;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
String toString () const
|
||||
{
|
||||
return String()
|
||||
+ "default_ctor(" + String::fromNumber (default_ctor) + ") "
|
||||
+ ", copy_ctor(" + String::fromNumber (copy_ctor) + ")"
|
||||
+ ", copy_assign(" + String::fromNumber (copy_assign) + ")"
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
+ ", move_ctor(" + String::fromNumber (move_ctor) + ")"
|
||||
+ ", move_assign(" + String::fromNumber (move_assign) + ")";
|
||||
#endif
|
||||
}
|
||||
|
||||
count_type default_ctor;
|
||||
count_type copy_ctor;
|
||||
count_type copy_assign;
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
count_type move_ctor;
|
||||
count_type move_assign;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Counts the number of element operations performed in a scope. */
|
||||
class ScopedCounts : public Uncopyable
|
||||
{
|
||||
public:
|
||||
ScopedCounts (Counts const& counts)
|
||||
: m_start (counts)
|
||||
, m_counts (counts)
|
||||
{
|
||||
}
|
||||
|
||||
Counts get () const
|
||||
{
|
||||
return m_counts - m_start;
|
||||
}
|
||||
|
||||
private:
|
||||
Counts const m_start;
|
||||
Counts const& m_counts;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* Base for element configurations. */
|
||||
class ElementConfigBase : public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef std::size_t IdType;
|
||||
};
|
||||
|
||||
/** Provides the element-specific configuration members. */
|
||||
template <class Params>
|
||||
class ElementConfig : public ElementConfigBase
|
||||
{
|
||||
public:
|
||||
static Counts& getCounts ()
|
||||
{
|
||||
static Counts counts;
|
||||
return counts;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Base for elements used in container unit tests. */
|
||||
class ElementBase
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
/** An object placed into a container for unit testing. */
|
||||
template <class Config>
|
||||
class Element : public ElementBase
|
||||
{
|
||||
public:
|
||||
typedef typename Config::IdType IdType;
|
||||
|
||||
Element ()
|
||||
: m_id (0)
|
||||
, m_msg (String::empty)
|
||||
{
|
||||
++Config::getCounts ().default_ctor;
|
||||
}
|
||||
|
||||
explicit Element (IdType id)
|
||||
: m_id (id)
|
||||
, m_msg (String::fromNumber (id))
|
||||
{
|
||||
}
|
||||
|
||||
Element (Element const& other)
|
||||
: m_id (other.m_id)
|
||||
, m_msg (other.m_msg)
|
||||
{
|
||||
++Config::getCounts ().copy_ctor;
|
||||
}
|
||||
|
||||
Element& operator= (Element const& other)
|
||||
{
|
||||
m_id = other.m_id;
|
||||
m_msg = other.m_msg;
|
||||
++Config::getCounts ().copy_assign;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Element (Element&& other)
|
||||
: m_id (other.m_id)
|
||||
, m_msg (other.m_msg)
|
||||
{
|
||||
other.m_msg = String::empty;
|
||||
++Config::getCounts ().move_ctor;
|
||||
}
|
||||
|
||||
Element& operator= (Element&& other)
|
||||
{
|
||||
m_id = other.m_id;
|
||||
m_msg = other.m_msg;
|
||||
other.m_msg = String::empty;
|
||||
++Config::getCounts ().move_assign;
|
||||
}
|
||||
#endif
|
||||
|
||||
IdType id () const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
String msg () const
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
|
||||
private:
|
||||
IdType m_id;
|
||||
String m_msg;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Base for test state parameters. */
|
||||
class StateBase : public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef int64 SeedType;
|
||||
};
|
||||
|
||||
/** Provides configuration-specific test state parameters. */
|
||||
template <class Params>
|
||||
class State : public StateBase
|
||||
{
|
||||
public:
|
||||
static Random& random ()
|
||||
{
|
||||
static Random generator (Params::seedValue);
|
||||
return generator;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ConfigBase
|
||||
{
|
||||
};
|
||||
|
||||
template <template <typename, class> class Container,
|
||||
class Params>
|
||||
class Config
|
||||
: public State <Params>
|
||||
, public ElementConfig <Params>
|
||||
{
|
||||
public:
|
||||
typedef Config ConfigType;
|
||||
typedef Params ParamsType;
|
||||
typedef State <Params> StateType;
|
||||
typedef ElementConfig <Params> ElementConfigType;
|
||||
typedef Element <ElementConfigType> ElementType;
|
||||
typedef Container <
|
||||
ElementType,
|
||||
std::allocator <char> > ContainerType;
|
||||
|
||||
typedef StateBase::SeedType SeedType;
|
||||
|
||||
// default seed
|
||||
static SeedType const seedValue = 69;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A generic container test. */
|
||||
template <class Params>
|
||||
class Test : public Params
|
||||
{
|
||||
public:
|
||||
typedef typename Params::StateType StateType;
|
||||
typedef typename Params::ElementConfigType ElementConfigType;
|
||||
typedef typename Params::ContainerType ContainerType;
|
||||
|
||||
void doInsert ()
|
||||
{
|
||||
m_container.reserve (Params::elementCount);
|
||||
for (typename ContainerType::size_type i = 0;
|
||||
i < Params::elementCount; ++i)
|
||||
{
|
||||
m_container.push_back (typename Params::ElementType ());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typename Params::ContainerType m_container;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class DynamicListTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
struct T
|
||||
struct Params : Config <DynamicList, Params>
|
||||
{
|
||||
T ()
|
||||
{
|
||||
}
|
||||
|
||||
explicit T (String what)
|
||||
: msg (what)
|
||||
{
|
||||
}
|
||||
|
||||
T& operator= (T const& other)
|
||||
{
|
||||
msg = other.msg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String msg;
|
||||
static SeedType const seedValue = 42;
|
||||
static ContainerType::size_type const elementCount = 100 * 1000;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
numberToAssign = 1000 * 1000,
|
||||
numberToReserve = 1000 * 1000,
|
||||
numberToMutate = 12139
|
||||
|
||||
};
|
||||
|
||||
void testAssign ()
|
||||
{
|
||||
String s;
|
||||
s << "assign (" << String::fromNumber <int> (numberToAssign) << ")";
|
||||
beginTestCase (s);
|
||||
|
||||
pass ();
|
||||
}
|
||||
typedef Test <Params> TestType;
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testAssign ();
|
||||
TestType test;
|
||||
|
||||
beginTestCase ("insert");
|
||||
|
||||
{
|
||||
ScopedCounts counts (TestType::getCounts ());
|
||||
test.doInsert ();
|
||||
this->logMessage (counts.get ().toString ());
|
||||
}
|
||||
|
||||
pass ();
|
||||
}
|
||||
|
||||
DynamicListTests () : UnitTest ("DynamicList", "beast")
|
||||
@@ -67,4 +321,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static DynamicListTests DynamicListTests;
|
||||
static DynamicListTests dynamicListTests;
|
||||
|
||||
}
|
||||
|
||||
@@ -23,87 +23,109 @@
|
||||
template <typename, typename>
|
||||
class DynamicList;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename I>
|
||||
template <class Container, bool IsConst>
|
||||
class DynamicListIterator
|
||||
: public std::iterator <std::bidirectional_iterator_tag,
|
||||
typename I::size_type>
|
||||
: public std::iterator <
|
||||
std::bidirectional_iterator_tag,
|
||||
typename Container::value_type,
|
||||
typename Container::difference_type,
|
||||
typename mpl::IfConst <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type,
|
||||
typename mpl::IfConst <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type>
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::IfConst <IsConst,
|
||||
typename List <typename Container::Item>::const_iterator,
|
||||
typename List <typename Container::Item>::iterator>::type iterator_type;
|
||||
|
||||
typedef typename mpl::IfConst <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type pointer;
|
||||
|
||||
typedef typename mpl::IfConst <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type reference;
|
||||
|
||||
public:
|
||||
typedef typename I::value_type ItemType; // this will be <Item>
|
||||
typedef typename ItemType::value_type T; // this is the original T
|
||||
DynamicListIterator ()
|
||||
{
|
||||
}
|
||||
|
||||
typedef typename copyconst <ItemType, T>::type
|
||||
|
||||
value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef typename I::size_type size_type;
|
||||
|
||||
DynamicListIterator (I iter = I ()) noexcept
|
||||
DynamicListIterator (iterator_type iter)
|
||||
: m_iter (iter)
|
||||
{
|
||||
}
|
||||
|
||||
#if 1
|
||||
template <typename J>
|
||||
DynamicListIterator (DynamicListIterator <J> const& other) noexcept
|
||||
DynamicListIterator (DynamicListIterator const& other)
|
||||
: m_iter (other.m_iter)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename J>
|
||||
DynamicListIterator& operator= (DynamicListIterator <J> const& other) noexcept
|
||||
template <bool OtherIsConst>
|
||||
DynamicListIterator (DynamicListIterator <Container, OtherIsConst> const& other)
|
||||
: m_iter (other.m_iter)
|
||||
{
|
||||
}
|
||||
|
||||
DynamicListIterator& operator= (DynamicListIterator const& other)
|
||||
{
|
||||
m_iter = other.m_iter;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename J>
|
||||
bool operator== (DynamicListIterator <J> const& other) const noexcept
|
||||
template <bool OtherIsConst>
|
||||
DynamicListIterator& operator= (DynamicListIterator <
|
||||
Container, OtherIsConst> const& other)
|
||||
{
|
||||
m_iter = other.m_iter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
bool operator== (DynamicListIterator <Container, OtherIsConst> const& other) const
|
||||
{
|
||||
return m_iter == other.m_iter;
|
||||
}
|
||||
|
||||
template <typename J>
|
||||
bool operator != (DynamicListIterator <J> const& other) const noexcept
|
||||
template <bool OtherIsConst>
|
||||
bool operator!= (DynamicListIterator <Container, OtherIsConst> const& other) const
|
||||
{
|
||||
return ! this->operator== (other);
|
||||
return ! ((*this) == other);
|
||||
}
|
||||
|
||||
reference operator* () const noexcept
|
||||
reference operator* () const
|
||||
{
|
||||
return dereference ();
|
||||
}
|
||||
|
||||
pointer operator-> () const noexcept
|
||||
pointer operator-> () const
|
||||
{
|
||||
return &dereference ();
|
||||
}
|
||||
|
||||
DynamicListIterator& operator++ () noexcept
|
||||
DynamicListIterator& operator++ ()
|
||||
{
|
||||
increment ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicListIterator operator++ (int) noexcept
|
||||
DynamicListIterator operator++ (int)
|
||||
{
|
||||
DynamicListIterator const result (*this);
|
||||
increment ();
|
||||
return result;
|
||||
}
|
||||
|
||||
DynamicListIterator& operator-- () noexcept
|
||||
DynamicListIterator& operator-- ()
|
||||
{
|
||||
decrement ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicListIterator operator-- (int) noexcept
|
||||
DynamicListIterator operator-- (int)
|
||||
{
|
||||
DynamicListIterator const result (*this);
|
||||
decrement ();
|
||||
@@ -114,28 +136,24 @@ private:
|
||||
template <typename, typename>
|
||||
friend class DynamicList;
|
||||
|
||||
typedef typename I::value_type Item;
|
||||
|
||||
reference dereference () const noexcept
|
||||
reference dereference () const
|
||||
{
|
||||
return *(m_iter->get ());
|
||||
}
|
||||
|
||||
void increment () noexcept
|
||||
void increment ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
void decrement () noexcept
|
||||
void decrement ()
|
||||
{
|
||||
--m_iter;
|
||||
}
|
||||
|
||||
I m_iter;
|
||||
iterator_type m_iter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A list that uses a very small number of dynamic allocations.
|
||||
@@ -155,7 +173,7 @@ private:
|
||||
Destructible
|
||||
*/
|
||||
template <typename T,
|
||||
typename Allocator = std::allocator <char> >
|
||||
class Allocator = std::allocator <char> >
|
||||
class DynamicList
|
||||
{
|
||||
private:
|
||||
@@ -175,34 +193,15 @@ public:
|
||||
typedef T& reference;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const& const_reference;
|
||||
|
||||
typedef DynamicList <
|
||||
T,
|
||||
Allocator> container_type;
|
||||
|
||||
private:
|
||||
struct Item : List <Item>::Node
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
T* get () noexcept
|
||||
{
|
||||
return reinterpret_cast <T*> (&storage [0]);
|
||||
}
|
||||
|
||||
T const* get () const noexcept
|
||||
{
|
||||
return reinterpret_cast <T const*> (&storage [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
// Lets hope this is padded correctly
|
||||
uint8 storage [sizeof (T)];
|
||||
};
|
||||
typedef DynamicListIterator <container_type, false> iterator;
|
||||
typedef DynamicListIterator <container_type, true> const_iterator;
|
||||
|
||||
public:
|
||||
typedef detail::DynamicListIterator <
|
||||
typename List <Item>::iterator> iterator;
|
||||
|
||||
typedef detail::DynamicListIterator <
|
||||
typename List <Item>::const_iterator> const_iterator;
|
||||
|
||||
explicit DynamicList (
|
||||
size_type blocksize = defaultBlocksize,
|
||||
Allocator const& allocator = Allocator ())
|
||||
@@ -418,6 +417,28 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <class, bool>
|
||||
friend class DynamicListIterator;
|
||||
|
||||
struct Item : List <Item>::Node
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
T* get () noexcept
|
||||
{
|
||||
return reinterpret_cast <T*> (&storage [0]);
|
||||
}
|
||||
|
||||
T const* get () const noexcept
|
||||
{
|
||||
return reinterpret_cast <T const*> (&storage [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
// Lets hope this is padded correctly
|
||||
uint8 storage [sizeof (T)];
|
||||
};
|
||||
|
||||
Item* alloc () noexcept
|
||||
{
|
||||
Item* item;
|
||||
|
||||
Reference in New Issue
Block a user