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 |
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 | |
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 |
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 | |
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 |
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 | |
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 |
155 | struct 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 | |
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; |
176 | B() : A() {++count;} |
177 | B(const B &b) : A(b) {++count;} |
178 | virtual ~B() {--count;} |
179 | }; |
180 | |
181 | int B::count = 0; |
182 | |
183 | void reset_counters(); |
184 | |
185 | BOOST_MOVE_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(std::size_t 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_; |
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 | |