diff --git a/modules/beast_core/containers/DynamicList.cpp b/modules/beast_core/containers/DynamicList.cpp index e32a065f4..f2dd8b3b2 100644 --- a/modules/beast_core/containers/DynamicList.cpp +++ b/modules/beast_core/containers/DynamicList.cpp @@ -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 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 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 State : public StateBase +{ +public: + static Random& random () + { + static Random generator (Params::seedValue); + return generator; + } +}; + +//------------------------------------------------------------------------------ + +class ConfigBase +{ +}; + +template