mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Added life cout and double destruction assertions to test integer-like classes.
Changelog updated with double destruction bugs fix.
This commit is contained in:
@@ -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.
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user