Added life cout and double destruction assertions to test integer-like classes.

Changelog updated with double destruction bugs fix.
This commit is contained in:
Ion Gaztañaga
2014-09-23 17:29:26 +02:00
parent 5477125eeb
commit 4d5b9a80cf
2 changed files with 105 additions and 21 deletions

View File

@@ -1060,6 +1060,7 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes_boost_1_57_00 Boost 1.57 Release] [section:release_notes_boost_1_57_00 Boost 1.57 Release]
* Added support for `initializer_list`. Contributed by Robert Matusewicz. * Added support for `initializer_list`. Contributed by Robert Matusewicz.
* Fixed double destruction bugs in vector and backward expansion capable allocators.
* Fixed bugs: * Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/10263 Trac #10263 (['"AIX 6.1 bug with sched_yield() function out of scope"])]. * [@https://svn.boost.org/trac/boost/ticket/10263 Trac #10263 (['"AIX 6.1 bug with sched_yield() function out of scope"])].
* [@https://github.com/boostorg/container/pull/16 GitHub #16: ['Fix iterators of incomplete type containers]]. Thanks to Mikael Persson. * [@https://github.com/boostorg/container/pull/16 GitHub #16: ['Fix iterators of incomplete type containers]]. Thanks to Mikael Persson.

View File

@@ -15,6 +15,8 @@
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <ostream> #include <ostream>
#include <climits>
#include <boost/assert.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
@@ -35,26 +37,38 @@ class movable_int
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int) BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int)
public: public:
static unsigned int count;
movable_int() movable_int()
: m_int(0) : m_int(0)
{} { ++count; }
explicit movable_int(int a) explicit movable_int(int a)
: m_int(a) : m_int(a)
{} {
//Disallow INT_MIN
BOOST_ASSERT(this->m_int != INT_MIN);
++count;
}
movable_int(BOOST_RV_REF(movable_int) mmi) movable_int(BOOST_RV_REF(movable_int) mmi)
: m_int(mmi.m_int) : m_int(mmi.m_int)
{ mmi.m_int = 0; } { mmi.m_int = 0; ++count; }
movable_int & operator= (BOOST_RV_REF(movable_int) mmi) movable_int & operator= (BOOST_RV_REF(movable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; } { this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_int & operator= (int i) movable_int & operator= (int i)
{ this->m_int = i; return *this; } { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; }
~movable_int() ~movable_int()
{ this->m_int = 0; } {
//Double destructor called
BOOST_ASSERT(this->m_int != INT_MIN);
this->m_int = INT_MIN;
--count;
}
friend bool operator ==(const movable_int &l, const movable_int &r) friend bool operator ==(const movable_int &l, const movable_int &r)
{ return l.m_int == r.m_int; } { return l.m_int == r.m_int; }
@@ -87,6 +101,8 @@ class movable_int
int m_int; int m_int;
}; };
unsigned int movable_int::count = 0;
inline movable_int produce_movable_int() inline movable_int produce_movable_int()
{ return movable_int(); } { return movable_int(); }
@@ -110,24 +126,36 @@ class movable_and_copyable_int
BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int) BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
public: public:
static unsigned int count;
movable_and_copyable_int() movable_and_copyable_int()
: m_int(0) : m_int(0)
{} { ++count; }
explicit movable_and_copyable_int(int a) explicit movable_and_copyable_int(int a)
: m_int(a) : m_int(a)
{} {
//Disallow INT_MIN
BOOST_ASSERT(this->m_int != INT_MIN);
++count;
}
movable_and_copyable_int(const movable_and_copyable_int& mmi) movable_and_copyable_int(const movable_and_copyable_int& mmi)
: m_int(mmi.m_int) : m_int(mmi.m_int)
{} { ++count; }
movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi) movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi)
: m_int(mmi.m_int) : m_int(mmi.m_int)
{ mmi.m_int = 0; } { mmi.m_int = 0; ++count; }
~movable_and_copyable_int() ~movable_and_copyable_int()
{ this->m_int = 0; } {
//Double destructor called
BOOST_ASSERT(this->m_int != INT_MIN);
this->m_int = INT_MIN;
--count;
}
movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi) movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
{ this->m_int = mi.m_int; return *this; } { this->m_int = mi.m_int; return *this; }
@@ -136,7 +164,7 @@ class movable_and_copyable_int
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; } { this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_and_copyable_int & operator= (int i) movable_and_copyable_int & operator= (int i)
{ this->m_int = i; return *this; } { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; }
friend bool operator ==(const movable_and_copyable_int &l, const movable_and_copyable_int &r) friend bool operator ==(const movable_and_copyable_int &l, const movable_and_copyable_int &r)
{ return l.m_int == r.m_int; } { return l.m_int == r.m_int; }
@@ -169,6 +197,8 @@ class movable_and_copyable_int
int m_int; int m_int;
}; };
unsigned int movable_and_copyable_int::count = 0;
inline movable_and_copyable_int produce_movable_and_copyable_int() inline movable_and_copyable_int produce_movable_and_copyable_int()
{ return movable_and_copyable_int(); } { return movable_and_copyable_int(); }
@@ -190,26 +220,38 @@ struct is_copyable<movable_and_copyable_int>
class copyable_int class copyable_int
{ {
public: public:
static unsigned int count;
copyable_int() copyable_int()
: m_int(0) : m_int(0)
{} { ++count; }
explicit copyable_int(int a) explicit copyable_int(int a)
: m_int(a) : m_int(a)
{} {
//Disallow INT_MIN
BOOST_ASSERT(this->m_int != INT_MIN);
++count;
}
copyable_int(const copyable_int& mmi) copyable_int(const copyable_int& mmi)
: m_int(mmi.m_int) : m_int(mmi.m_int)
{} { ++count; }
copyable_int & operator= (int i) copyable_int & operator= (int i)
{ this->m_int = i; return *this; } { this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this; }
copyable_int & operator= (const copyable_int &ci) copyable_int & operator= (const copyable_int &ci)
{ this->m_int = ci.m_int; return *this; } { this->m_int = ci.m_int; BOOST_ASSERT(this->m_int != INT_MIN); return *this; }
~copyable_int() ~copyable_int()
{ this->m_int = 0; } {
//Double destructor called
BOOST_ASSERT(this->m_int != INT_MIN);
this->m_int = INT_MIN;
--count;
}
friend bool operator ==(const copyable_int &l, const copyable_int &r) friend bool operator ==(const copyable_int &l, const copyable_int &r)
{ return l.m_int == r.m_int; } { return l.m_int == r.m_int; }
@@ -242,6 +284,8 @@ class copyable_int
int m_int; int m_int;
}; };
unsigned int copyable_int::count = 0;
inline copyable_int produce_copyable_int() inline copyable_int produce_copyable_int()
{ return copyable_int(); } { return copyable_int(); }
@@ -266,16 +310,19 @@ class non_copymovable_int
non_copymovable_int & operator= (const non_copymovable_int &mi); non_copymovable_int & operator= (const non_copymovable_int &mi);
public: public:
static unsigned int count;
non_copymovable_int() non_copymovable_int()
: m_int(0) : m_int(0)
{} { ++count; }
explicit non_copymovable_int(int a) explicit non_copymovable_int(int a)
: m_int(a) : m_int(a)
{} { ++count; }
~non_copymovable_int() ~non_copymovable_int()
{ m_int = 0; } { m_int = 0; --count; }
bool operator ==(const non_copymovable_int &mi) const bool operator ==(const non_copymovable_int &mi) const
{ return this->m_int == mi.m_int; } { return this->m_int == mi.m_int; }
@@ -308,6 +355,42 @@ class non_copymovable_int
int m_int; int m_int;
}; };
unsigned int non_copymovable_int::count = 0;
template<class T>
struct life_count
{
static unsigned check(unsigned) { return true; }
};
template<>
struct life_count< movable_int >
{
static unsigned check(unsigned c)
{ return c == movable_int::count; }
};
template<>
struct life_count< copyable_int >
{
static unsigned check(unsigned c)
{ return c == copyable_int::count; }
};
template<>
struct life_count< movable_and_copyable_int >
{
static unsigned check(unsigned c)
{ return c == movable_and_copyable_int::count; }
};
template<>
struct life_count< non_copymovable_int >
{
static unsigned check(unsigned c)
{ return c == non_copymovable_int::count; }
};
} //namespace test { } //namespace test {
} //namespace container { } //namespace container {