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