210 lines
5.6 KiB
C++
210 lines
5.6 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (C) Copyright Howard Hinnant 2009
|
|
// (C) Copyright Ion Gaztanaga 2014-2014.
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// See http://www.boost.org/libs/move for documentation.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
|
|
#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
|
|
#include <boost/move/core.hpp>
|
|
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
|
#include <boost/static_assert.hpp>
|
|
|
|
//////////////////////////////////////////////
|
|
//
|
|
// The initial implementation of these tests
|
|
// was written by Howard Hinnant.
|
|
//
|
|
// These test were later refactored grouping
|
|
// and porting them to Boost.Move.
|
|
//
|
|
// Many thanks to Howard for releasing his C++03
|
|
// unique_ptr implementation with such detailed
|
|
// test cases.
|
|
//
|
|
//////////////////////////////////////////////
|
|
|
|
//A deleter that can only default constructed
|
|
template <class T>
|
|
class def_constr_deleter
|
|
{
|
|
int state_;
|
|
def_constr_deleter(const def_constr_deleter&);
|
|
def_constr_deleter& operator=(const def_constr_deleter&);
|
|
|
|
public:
|
|
typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
|
|
static const bool is_array = ::boost::move_upmu::is_array<T>::value;
|
|
|
|
def_constr_deleter() : state_(5) {}
|
|
|
|
explicit def_constr_deleter(int s) : state_(s) {}
|
|
|
|
int state() const {return state_;}
|
|
|
|
void set_state(int s) {state_ = s;}
|
|
|
|
void operator()(element_type* p) const
|
|
{ is_array ? delete []p : delete p; }
|
|
|
|
void operator()(element_type* p)
|
|
{ ++state_; is_array ? delete []p : delete p; }
|
|
};
|
|
|
|
//A deleter that can be copy constructed
|
|
template <class T>
|
|
class copy_constr_deleter
|
|
{
|
|
int state_;
|
|
|
|
public:
|
|
typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
|
|
static const bool is_array = ::boost::move_upmu::is_array<T>::value;
|
|
|
|
copy_constr_deleter() : state_(5) {}
|
|
|
|
template<class U>
|
|
copy_constr_deleter(const copy_constr_deleter<U>&
|
|
, typename boost::move_upd::enable_def_del<U, T>::type* =0)
|
|
{ state_ = 5; }
|
|
|
|
explicit copy_constr_deleter(int s) : state_(s) {}
|
|
|
|
template <class U>
|
|
typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
|
|
operator=(const copy_constr_deleter<U> &d)
|
|
{
|
|
state_ = d.state();
|
|
return *this;
|
|
}
|
|
|
|
int state() const {return state_;}
|
|
|
|
void set_state(int s) {state_ = s;}
|
|
|
|
void operator()(element_type* p) const
|
|
{ is_array ? delete []p : delete p; }
|
|
|
|
void operator()(element_type* p)
|
|
{ ++state_; is_array ? delete []p : delete p; }
|
|
};
|
|
|
|
//A deleter that can be only move constructed
|
|
template <class T>
|
|
class move_constr_deleter
|
|
{
|
|
int state_;
|
|
|
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
|
|
|
|
public:
|
|
typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
|
|
static const bool is_array = ::boost::move_upmu::is_array<T>::value;
|
|
|
|
move_constr_deleter() : state_(5) {}
|
|
|
|
move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
|
|
: state_(r.state_)
|
|
{ r.state_ = 0; }
|
|
|
|
explicit move_constr_deleter(int s) : state_(s) {}
|
|
|
|
template <class U>
|
|
move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
|
|
, typename boost::move_upd::enable_def_del<U, T>::type* =0)
|
|
: state_(d.state())
|
|
{ d.set_state(0); }
|
|
|
|
move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
|
|
{
|
|
state_ = r.state_;
|
|
r.state_ = 0;
|
|
return *this;
|
|
}
|
|
|
|
template <class U>
|
|
typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
|
|
operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
|
|
{
|
|
state_ = d.state();
|
|
d.set_state(0);
|
|
return *this;
|
|
}
|
|
|
|
int state() const {return state_;}
|
|
|
|
void set_state(int s) {state_ = s;}
|
|
|
|
void operator()(element_type* p) const
|
|
{ is_array ? delete []p : delete p; }
|
|
|
|
void operator()(element_type* p)
|
|
{ ++state_; is_array ? delete []p : delete p; }
|
|
|
|
friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
|
|
{return x.state_ == y.state_;}
|
|
};
|
|
|
|
//A base class containing state with a static instance counter
|
|
struct A
|
|
{
|
|
int state_;
|
|
static int count;
|
|
|
|
A() : state_(999) {++count;}
|
|
explicit A(int i) : state_(i) {++count;}
|
|
A(const A& a) : state_(a.state_) {++count;}
|
|
A& operator=(const A& a) { state_ = a.state_; return *this; }
|
|
void set(int i) {state_ = i;}
|
|
virtual ~A() {--count;}
|
|
friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
|
|
};
|
|
|
|
int A::count = 0;
|
|
|
|
//A class derived from A with a static instance counter
|
|
struct B
|
|
: public A
|
|
{
|
|
static int count;
|
|
B() : A() {++count;}
|
|
B(const B &b) : A(b) {++count;}
|
|
virtual ~B() {--count;}
|
|
};
|
|
|
|
int B::count = 0;
|
|
|
|
void reset_counters();
|
|
|
|
BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
|
|
|
|
//Incomplete Type function declarations
|
|
struct I;
|
|
void check(int i);
|
|
I* get();
|
|
I* get_array(int i);
|
|
|
|
#include <boost/move/unique_ptr.hpp>
|
|
|
|
template <class T, class D = ::boost::movelib::default_delete<T> >
|
|
struct J
|
|
{
|
|
typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
|
|
typedef typename unique_ptr_type::element_type element_type;
|
|
boost::movelib::unique_ptr<T, D> a_;
|
|
J() {}
|
|
explicit J(element_type*a) : a_(a) {}
|
|
~J();
|
|
|
|
element_type* get() const {return a_.get();}
|
|
D& get_deleter() {return a_.get_deleter();}
|
|
};
|
|
|
|
#endif //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
|