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 <cstddef>
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
34template <class T>
35class 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
45 def_constr_deleter() : state_(5) {}
46
47 explicit def_constr_deleter(int s) : state_(s) {}
48
49 int state() const {return state_;}
50
51 void set_state(int s) {state_ = s;}
52
53 void operator()(element_type* p) const
54 { is_array ? delete []p : delete p; }
55
56 void operator()(element_type* p)
57 { ++state_; is_array ? delete []p : delete p; }
58};
59
60//A deleter that can be copy constructed
61template <class T>
62class 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
70 copy_constr_deleter() : state_(5) {}
71
72 template<class U>
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
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
81 operator=(const copy_constr_deleter<U> &d)
82 {
83 state_ = d.state();
84 return *this;
85 }
86
87 int state() const {return state_;}
88
89 void set_state(int s) {state_ = s;}
90
91 void operator()(element_type* p) const
92 { is_array ? delete []p : delete p; }
93
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
99template <class T>
100class 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
110 move_constr_deleter() : state_(5) {}
111
112 move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
113 : state_(r.state_)
114 { r.state_ = 0; }
115
116 explicit move_constr_deleter(int s) : state_(s) {}
117
118 template <class U>
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
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
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
140 int state() const {return state_;}
141
142 void set_state(int s) {state_ = s;}
143
144 void operator()(element_type* p) const
145 { is_array ? delete []p : delete p; }
146
147 void operator()(element_type* p)
148 { ++state_; is_array ? delete []p : delete p; }
149
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
155struct A
156{
157 int state_;
158 static int count;
159
160 A() : state_(999) {++count;}
161 explicit A(int i) : state_(i) {++count;}
162 A(const A& a) : state_(a.state_) {++count;}
163 A& operator=(const A& a) { state_ = a.state_; return *this; }
164 void set(int i) {state_ = i;}
165 virtual ~A() {--count;}
166 friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
167};
168
169int A::count = 0;
170
171//A class derived from A with a static instance counter
172struct B
173 : public A
174{
175 static int count;
176 B() : A() {++count;}
177 B(const B &b) : A(b) {++count;}
178 virtual ~B() {--count;}
179};
180
181int B::count = 0;
182
183void reset_counters();
184
185BOOST_MOVE_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
186
187//Incomplete Type function declarations
188struct I;
189void check(int i);
190I* get();
191I* get_array(std::size_t i);
192
193#include <boost/move/unique_ptr.hpp>
194
195template <class T, class D = ::boost::movelib::default_delete<T> >
196struct 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_;
201 J() {}
202 explicit J(element_type*a) : a_(a) {}
203 ~J();
204
205 element_type* get() const {return a_.get();}
206 D& get_deleter() {return a_.get_deleter();}
207};
208
209#endif //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
210

source code of boost/libs/move/test/unique_ptr_test_utils_beg.hpp