1c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===// 2c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// 3c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// The LLVM Compiler Infrastructure 4c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// 8c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===// 9c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 10c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// <memory> 11c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 12c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// unique_ptr 13c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 14c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Example move-only deleter 15c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 16c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#ifndef DELETER_H 17c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#define DELETER_H 18c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 19c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <type_traits> 20c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <cassert> 21c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 22c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 23c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass Deleter 24c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 25c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state_; 26c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 2773d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 28c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(const Deleter&); 29c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(const Deleter&); 3073d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 31c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&); 32c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&); 3373d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 34c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 35c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 3673d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 37c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 38c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&& r) 39c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 40c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r.state_; 41c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r.state_ = 0; 42c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 43c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 4473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 45c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);} 46c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;} 47c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(std::__rv<Deleter> r) 48c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 49c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r->state_; 50c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r->state_ = 0; 51c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 52c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 5373d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 54c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 55c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter() : state_(0) {} 56c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant explicit Deleter(int s) : state_(s) {} 57c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ~Deleter() {assert(state_ >= 0); state_ = -1;} 58c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 5973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 60c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 61c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter<U>&& d, 62c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 63c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : state_(d.state()) {d.set_state(0);} 64c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 65c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantprivate: 66c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 67c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(const Deleter<U>& d, 68c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 6973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 70c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 71c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter<U> d, 72c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 73c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : state_(d.state()) {} 7473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 75c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 76c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state() const {return state_;} 77c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void set_state(int i) {state_ = i;} 78c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 79c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void operator()(T* p) {delete p;} 80c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 81c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 82c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 83c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass Deleter<T[]> 84c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 85c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state_; 86c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 8773d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 88c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(const Deleter&); 89c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(const Deleter&); 9073d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 91c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&); 92c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&); 9373d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 94c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 95c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 9673d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 97c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 98c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&& r) 99c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 100c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r.state_; 101c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r.state_ = 0; 102c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 103c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 10473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 105c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);} 106c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;} 107c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(std::__rv<Deleter> r) 108c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 109c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r->state_; 110c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r->state_ = 0; 111c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 112c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 11373d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 114c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 115c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter() : state_(0) {} 116c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant explicit Deleter(int s) : state_(s) {} 117c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ~Deleter() {assert(state_ >= 0); state_ = -1;} 118c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 119c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state() const {return state_;} 120c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void set_state(int i) {state_ = i;} 121c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 122c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void operator()(T* p) {delete [] p;} 123c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 124c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 125c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 126c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantvoid 127c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantswap(Deleter<T>& x, Deleter<T>& y) 128c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 129c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter<T> t(std::move(x)); 130c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant x = std::move(y); 131c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant y = std::move(t); 132c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 133c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 134c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 135c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass CDeleter 136c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 137c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state_; 138c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 139c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 140c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 141c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant CDeleter() : state_(0) {} 142c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant explicit CDeleter(int s) : state_(s) {} 143c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ~CDeleter() {assert(state_ >= 0); state_ = -1;} 144c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 145c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 146c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant CDeleter(const CDeleter<U>& d) 147c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : state_(d.state()) {} 148c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 149c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state() const {return state_;} 150c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void set_state(int i) {state_ = i;} 151c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 152c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void operator()(T* p) {delete p;} 153c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 154c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 155c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 156c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass CDeleter<T[]> 157c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 158c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state_; 159c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 160c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 161c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 162c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant CDeleter() : state_(0) {} 163c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant explicit CDeleter(int s) : state_(s) {} 164c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ~CDeleter() {assert(state_ >= 0); state_ = -1;} 165c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 166c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state() const {return state_;} 167c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void set_state(int i) {state_ = i;} 168c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 169c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void operator()(T* p) {delete [] p;} 170c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 171c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 172c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 173c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantvoid 174c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantswap(CDeleter<T>& x, CDeleter<T>& y) 175c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 176c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant CDeleter<T> t(std::move(x)); 177c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant x = std::move(y); 178c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant y = std::move(t); 179c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 180c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 181c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#endif // DELETER_H 182