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]
* Added support for `initializer_list`. Contributed by Robert Matusewicz.
* Fixed double destruction bugs in vector and backward expansion capable allocators.
* Fixed bugs:
* [@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.

View File

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