• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Howard Hinnant 2009
4 // (C) Copyright Ion Gaztanaga 2014-2014.
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/move for documentation.
11 //
12 //////////////////////////////////////////////////////////////////////////////
13 #ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
14 #define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
15 #include <boost/move/core.hpp>
16 #include <boost/move/detail/unique_ptr_meta_utils.hpp>
17 #include <boost/static_assert.hpp>
18 
19 //////////////////////////////////////////////
20 //
21 // The initial implementation of these tests
22 // was written by Howard Hinnant.
23 //
24 // These test were later refactored grouping
25 // and porting them to Boost.Move.
26 //
27 // Many thanks to Howard for releasing his C++03
28 // unique_ptr implementation with such detailed
29 // test cases.
30 //
31 //////////////////////////////////////////////
32 
33 //A deleter that can only default constructed
34 template <class T>
35 class def_constr_deleter
36 {
37    int state_;
38    def_constr_deleter(const def_constr_deleter&);
39    def_constr_deleter& operator=(const def_constr_deleter&);
40 
41    public:
42    typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
43    static const bool is_array = ::boost::move_upmu::is_array<T>::value;
44 
def_constr_deleter()45    def_constr_deleter() : state_(5) {}
46 
def_constr_deleter(int s)47    explicit def_constr_deleter(int s) : state_(s) {}
48 
state() const49    int state() const {return state_;}
50 
set_state(int s)51    void set_state(int s) {state_ = s;}
52 
operator ()(element_type * p) const53    void operator()(element_type* p) const
54    {  is_array ? delete []p : delete p;   }
55 
operator ()(element_type * p)56    void operator()(element_type* p)
57    {  ++state_;   is_array ? delete []p : delete p;  }
58 };
59 
60 //A deleter that can be copy constructed
61 template <class T>
62 class copy_constr_deleter
63 {
64    int state_;
65 
66    public:
67    typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
68    static const bool is_array = ::boost::move_upmu::is_array<T>::value;
69 
copy_constr_deleter()70    copy_constr_deleter() : state_(5) {}
71 
72    template<class U>
copy_constr_deleter(const copy_constr_deleter<U> &,typename boost::move_upd::enable_def_del<U,T>::type * =0)73    copy_constr_deleter(const copy_constr_deleter<U>&
74       , typename boost::move_upd::enable_def_del<U, T>::type* =0)
75    {  state_ = 5; }
76 
copy_constr_deleter(int s)77    explicit copy_constr_deleter(int s) : state_(s) {}
78 
79    template <class U>
80    typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
operator =(const copy_constr_deleter<U> & d)81       operator=(const copy_constr_deleter<U> &d)
82    {
83       state_ = d.state();
84       return *this;
85    }
86 
state() const87    int state() const          {return state_;}
88 
set_state(int s)89    void set_state(int s)      {state_ = s;}
90 
operator ()(element_type * p) const91    void operator()(element_type* p) const
92    {  is_array ? delete []p : delete p;   }
93 
operator ()(element_type * p)94    void operator()(element_type* p)
95    {  ++state_;   is_array ? delete []p : delete p;  }
96 };
97 
98 //A deleter that can be only move constructed
99 template <class T>
100 class move_constr_deleter
101 {
102    int state_;
103 
104    BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
105 
106    public:
107    typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
108    static const bool is_array = ::boost::move_upmu::is_array<T>::value;
109 
move_constr_deleter()110    move_constr_deleter() : state_(5) {}
111 
move_constr_deleter(BOOST_RV_REF (move_constr_deleter)r)112    move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
113       : state_(r.state_)
114    {  r.state_ = 0;  }
115 
move_constr_deleter(int s)116    explicit move_constr_deleter(int s) : state_(s) {}
117 
118    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)119    move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
120       , typename boost::move_upd::enable_def_del<U, T>::type* =0)
121       : state_(d.state())
122    { d.set_state(0);  }
123 
operator =(BOOST_RV_REF (move_constr_deleter)r)124    move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
125    {
126       state_ = r.state_;
127       r.state_ = 0;
128       return *this;
129    }
130 
131    template <class U>
132    typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
operator =(BOOST_RV_REF (move_constr_deleter<U>)d)133       operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
134    {
135       state_ = d.state();
136       d.set_state(0);
137       return *this;
138    }
139 
state() const140    int state() const          {return state_;}
141 
set_state(int s)142    void set_state(int s)      {state_ = s;}
143 
operator ()(element_type * p) const144    void operator()(element_type* p) const
145    {  is_array ? delete []p : delete p;   }
146 
operator ()(element_type * p)147    void operator()(element_type* p)
148    {  ++state_;   is_array ? delete []p : delete p;  }
149 
operator ==(const move_constr_deleter & x,const move_constr_deleter & y)150    friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
151       {return x.state_ == y.state_;}
152 };
153 
154 //A base class containing state with a static instance counter
155 struct A
156 {
157    int state_;
158    static int count;
159 
AA160    A()               : state_(999)      {++count;}
AA161    explicit A(int i) : state_(i)        {++count;}
AA162    A(const A& a)     : state_(a.state_) {++count;}
operator =A163    A& operator=(const A& a) { state_ = a.state_; return *this; }
setA164    void set(int i)   {state_ = i;}
~AA165    virtual ~A()      {--count;}
operator ==(const A & x,const A & y)166    friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
167 };
168 
169 int A::count = 0;
170 
171 //A class derived from A with a static instance counter
172 struct B
173    : public A
174 {
175    static int count;
BB176    B() : A() {++count;}
BB177    B(const B &b) : A(b) {++count;}
~BB178    virtual ~B() {--count;}
179 };
180 
181 int B::count = 0;
182 
183 void reset_counters();
184 
185 BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
186 
187 //Incomplete Type function declarations
188 struct I;
189 void check(int i);
190 I* get();
191 I* get_array(int i);
192 
193 #include <boost/move/unique_ptr.hpp>
194 
195 template <class T, class D = ::boost::movelib::default_delete<T> >
196 struct J
197 {
198    typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
199    typedef typename unique_ptr_type::element_type element_type;
200    boost::movelib::unique_ptr<T, D> a_;
JJ201    J() {}
JJ202    explicit J(element_type*a) : a_(a) {}
203    ~J();
204 
getJ205    element_type* get() const {return a_.get();}
get_deleterJ206    D& get_deleter() {return a_.get_deleter();}
207 };
208 
209 #endif   //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
210