1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <memory> 11 12 // unique_ptr 13 14 // Example move-only deleter 15 16 #ifndef SUPPORT_DELETER_TYPES_H 17 #define SUPPORT_DELETER_TYPES_H 18 19 #include <type_traits> 20 #include <utility> 21 #include <cassert> 22 23 #include "test_macros.h" 24 #include "min_allocator.h" 25 26 #if TEST_STD_VER >= 11 27 28 template <class T> 29 class Deleter 30 { 31 int state_; 32 33 Deleter(const Deleter&); 34 Deleter& operator=(const Deleter&); 35 36 public: 37 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 38 Deleter& operator=(Deleter&& r) 39 { 40 state_ = r.state_; 41 r.state_ = 0; 42 return *this; 43 } 44 45 46 Deleter() : state_(0) {} 47 explicit Deleter(int s) : state_(s) {} 48 ~Deleter() {assert(state_ >= 0); state_ = -1;} 49 50 template <class U> 51 Deleter(Deleter<U>&& d, 52 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 53 : state_(d.state()) {d.set_state(0);} 54 55 private: 56 template <class U> 57 Deleter(const Deleter<U>& d, 58 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 59 public: 60 int state() const {return state_;} 61 void set_state(int i) {state_ = i;} 62 63 void operator()(T* p) {delete p;} 64 }; 65 66 template <class T> 67 class Deleter<T[]> 68 { 69 int state_; 70 71 Deleter(const Deleter&); 72 Deleter& operator=(const Deleter&); 73 74 public: 75 76 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 77 Deleter& operator=(Deleter&& r) 78 { 79 state_ = r.state_; 80 r.state_ = 0; 81 return *this; 82 } 83 84 Deleter() : state_(0) {} 85 explicit Deleter(int s) : state_(s) {} 86 ~Deleter() {assert(state_ >= 0); state_ = -1;} 87 88 int state() const {return state_;} 89 void set_state(int i) {state_ = i;} 90 91 void operator()(T* p) {delete [] p;} 92 }; 93 94 #else // TEST_STD_VER < 11 95 96 template <class T> 97 class Deleter 98 { 99 mutable int state_; 100 101 public: 102 Deleter() : state_(0) {} 103 explicit Deleter(int s) : state_(s) {} 104 105 Deleter(Deleter const & other) : state_(other.state_) { 106 other.state_ = 0; 107 } 108 Deleter& operator=(Deleter const& other) { 109 state_ = other.state_; 110 other.state_ = 0; 111 return *this; 112 } 113 114 ~Deleter() {assert(state_ >= 0); state_ = -1;} 115 116 template <class U> 117 Deleter(Deleter<U> d, 118 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 119 : state_(d.state()) {} 120 121 public: 122 int state() const {return state_;} 123 void set_state(int i) {state_ = i;} 124 125 void operator()(T* p) {delete p;} 126 }; 127 128 template <class T> 129 class Deleter<T[]> 130 { 131 mutable int state_; 132 133 public: 134 135 Deleter(Deleter const& other) : state_(other.state_) { 136 other.state_ = 0; 137 } 138 Deleter& operator=(Deleter const& other) { 139 state_ = other.state_; 140 other.state_ = 0; 141 return *this; 142 } 143 144 Deleter() : state_(0) {} 145 explicit Deleter(int s) : state_(s) {} 146 ~Deleter() {assert(state_ >= 0); state_ = -1;} 147 148 int state() const {return state_;} 149 void set_state(int i) {state_ = i;} 150 151 void operator()(T* p) {delete [] p;} 152 }; 153 154 #endif 155 156 template <class T> 157 void 158 swap(Deleter<T>& x, Deleter<T>& y) 159 { 160 Deleter<T> t(std::move(x)); 161 x = std::move(y); 162 y = std::move(t); 163 } 164 165 166 template <class T> 167 class CDeleter 168 { 169 int state_; 170 171 public: 172 173 CDeleter() : state_(0) {} 174 explicit CDeleter(int s) : state_(s) {} 175 ~CDeleter() {assert(state_ >= 0); state_ = -1;} 176 177 template <class U> 178 CDeleter(const CDeleter<U>& d) 179 : state_(d.state()) {} 180 181 int state() const {return state_;} 182 void set_state(int i) {state_ = i;} 183 184 void operator()(T* p) {delete p;} 185 }; 186 187 template <class T> 188 class CDeleter<T[]> 189 { 190 int state_; 191 192 public: 193 194 CDeleter() : state_(0) {} 195 explicit CDeleter(int s) : state_(s) {} 196 template <class U> 197 CDeleter(const CDeleter<U>& d) 198 : state_(d.state()) {} 199 200 ~CDeleter() {assert(state_ >= 0); state_ = -1;} 201 202 int state() const {return state_;} 203 void set_state(int i) {state_ = i;} 204 205 void operator()(T* p) {delete [] p;} 206 }; 207 208 template <class T> 209 void 210 swap(CDeleter<T>& x, CDeleter<T>& y) 211 { 212 CDeleter<T> t(std::move(x)); 213 x = std::move(y); 214 y = std::move(t); 215 } 216 217 // Non-copyable deleter 218 template <class T> 219 class NCDeleter 220 { 221 int state_; 222 NCDeleter(NCDeleter const&); 223 NCDeleter& operator=(NCDeleter const&); 224 public: 225 226 NCDeleter() : state_(0) {} 227 explicit NCDeleter(int s) : state_(s) {} 228 ~NCDeleter() {assert(state_ >= 0); state_ = -1;} 229 230 int state() const {return state_;} 231 void set_state(int i) {state_ = i;} 232 233 void operator()(T* p) {delete p;} 234 }; 235 236 237 template <class T> 238 class NCDeleter<T[]> 239 { 240 int state_; 241 NCDeleter(NCDeleter const&); 242 NCDeleter& operator=(NCDeleter const&); 243 public: 244 245 NCDeleter() : state_(0) {} 246 explicit NCDeleter(int s) : state_(s) {} 247 ~NCDeleter() {assert(state_ >= 0); state_ = -1;} 248 249 int state() const {return state_;} 250 void set_state(int i) {state_ = i;} 251 252 void operator()(T* p) {delete [] p;} 253 }; 254 255 256 // Non-copyable deleter 257 template <class T> 258 class NCConstDeleter 259 { 260 int state_; 261 NCConstDeleter(NCConstDeleter const&); 262 NCConstDeleter& operator=(NCConstDeleter const&); 263 public: 264 265 NCConstDeleter() : state_(0) {} 266 explicit NCConstDeleter(int s) : state_(s) {} 267 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} 268 269 int state() const {return state_;} 270 void set_state(int i) {state_ = i;} 271 272 void operator()(T* p) const {delete p;} 273 }; 274 275 276 template <class T> 277 class NCConstDeleter<T[]> 278 { 279 int state_; 280 NCConstDeleter(NCConstDeleter const&); 281 NCConstDeleter& operator=(NCConstDeleter const&); 282 public: 283 284 NCConstDeleter() : state_(0) {} 285 explicit NCConstDeleter(int s) : state_(s) {} 286 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} 287 288 int state() const {return state_;} 289 void set_state(int i) {state_ = i;} 290 291 void operator()(T* p) const {delete [] p;} 292 }; 293 294 295 // Non-copyable deleter 296 template <class T> 297 class CopyDeleter 298 { 299 int state_; 300 public: 301 302 CopyDeleter() : state_(0) {} 303 explicit CopyDeleter(int s) : state_(s) {} 304 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} 305 306 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} 307 CopyDeleter& operator=(CopyDeleter const& other) { 308 state_ = other.state_; 309 return *this; 310 } 311 312 int state() const {return state_;} 313 void set_state(int i) {state_ = i;} 314 315 void operator()(T* p) {delete p;} 316 }; 317 318 319 template <class T> 320 class CopyDeleter<T[]> 321 { 322 int state_; 323 324 public: 325 326 CopyDeleter() : state_(0) {} 327 explicit CopyDeleter(int s) : state_(s) {} 328 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} 329 330 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} 331 CopyDeleter& operator=(CopyDeleter const& other) { 332 state_ = other.state_; 333 return *this; 334 } 335 336 int state() const {return state_;} 337 void set_state(int i) {state_ = i;} 338 339 void operator()(T* p) {delete [] p;} 340 }; 341 342 343 struct test_deleter_base 344 { 345 static int count; 346 static int dealloc_count; 347 }; 348 349 int test_deleter_base::count = 0; 350 int test_deleter_base::dealloc_count = 0; 351 352 template <class T> 353 class test_deleter 354 : public test_deleter_base 355 { 356 int state_; 357 358 public: 359 360 test_deleter() : state_(0) {++count;} 361 explicit test_deleter(int s) : state_(s) {++count;} 362 test_deleter(const test_deleter& d) 363 : state_(d.state_) {++count;} 364 ~test_deleter() {assert(state_ >= 0); --count; state_ = -1;} 365 366 int state() const {return state_;} 367 void set_state(int i) {state_ = i;} 368 369 void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;} 370 #if TEST_STD_VER >= 11 371 test_deleter* operator&() const = delete; 372 #else 373 private: 374 test_deleter* operator&() const; 375 #endif 376 }; 377 378 template <class T> 379 void 380 swap(test_deleter<T>& x, test_deleter<T>& y) 381 { 382 test_deleter<T> t(std::move(x)); 383 x = std::move(y); 384 y = std::move(t); 385 } 386 387 #if TEST_STD_VER >= 11 388 389 template <class T, size_t ID = 0> 390 class PointerDeleter 391 { 392 PointerDeleter(const PointerDeleter&); 393 PointerDeleter& operator=(const PointerDeleter&); 394 395 public: 396 typedef min_pointer<T, std::integral_constant<size_t, ID>> pointer; 397 398 PointerDeleter() = default; 399 PointerDeleter(PointerDeleter&&) = default; 400 PointerDeleter& operator=(PointerDeleter&&) = default; 401 explicit PointerDeleter(int) {} 402 403 template <class U> 404 PointerDeleter(PointerDeleter<U, ID>&&, 405 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 406 {} 407 408 void operator()(pointer p) { if (p) { delete std::addressof(*p); }} 409 410 private: 411 template <class U> 412 PointerDeleter(const PointerDeleter<U, ID>&, 413 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 414 }; 415 416 417 template <class T, size_t ID> 418 class PointerDeleter<T[], ID> 419 { 420 PointerDeleter(const PointerDeleter&); 421 PointerDeleter& operator=(const PointerDeleter&); 422 423 public: 424 typedef min_pointer<T, std::integral_constant<size_t, ID> > pointer; 425 426 PointerDeleter() = default; 427 PointerDeleter(PointerDeleter&&) = default; 428 PointerDeleter& operator=(PointerDeleter&&) = default; 429 explicit PointerDeleter(int) {} 430 431 template <class U> 432 PointerDeleter(PointerDeleter<U, ID>&&, 433 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 434 {} 435 436 void operator()(pointer p) { if (p) { delete [] std::addressof(*p); }} 437 438 private: 439 template <class U> 440 PointerDeleter(const PointerDeleter<U, ID>&, 441 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 442 }; 443 444 #endif // TEST_STD_VER >= 11 445 446 #endif // SUPPORT_DELETER_TYPES_H 447