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]
|
[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.
|
||||||
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user