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// Test unique_ptr converting move ctor 15c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 16c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <memory> 17c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <cassert> 18c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 19c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// test converting move ctor. Should only require a MoveConstructible deleter, or if 20c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// deleter is a reference, not even that. 21c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Explicit version 22c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 23c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantstruct A 24c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 25c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant static int count; 26c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant A() {++count;} 27c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant A(const A&) {++count;} 28c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant virtual ~A() {--count;} 29c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 30c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 31c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint A::count = 0; 32c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 33c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantstruct B 34c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : public A 35c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 36c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant static int count; 37c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant B() {++count;} 38c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant B(const B&) {++count;} 39c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant virtual ~B() {--count;} 40c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 41c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 42c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint B::count = 0; 43c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 44c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T> 45c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass Deleter 46c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 47c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state_; 48c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 4973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 50c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(const Deleter&); 51c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(const Deleter&); 5273d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 53c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&); 54c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&); 5573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 56c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 57c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 5873d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 59c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 60c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(Deleter&& r) 61c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 62c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r.state_; 63c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r.state_ = 0; 64c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 65c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 6673d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 67c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);} 68c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;} 69c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter& operator=(std::__rv<Deleter> r) 70c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 71c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant state_ = r->state_; 72c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant r->state_ = 0; 73c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return *this; 74c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 7573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 76c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 77c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter() : state_(5) {} 78c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 7973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 80c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 81c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter<U>&& d, 82c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 83c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : state_(d.state()) {d.set_state(0);} 84c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 85c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantprivate: 86c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 87c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(const Deleter<U>& d, 88c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 8973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 90c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant template <class U> 91c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Deleter(Deleter<U> d, 92c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 93c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant : state_(d.state()) {} 9473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 95c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic: 96c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant int state() const {return state_;} 97c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void set_state(int i) {state_ = i;} 98c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 99c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant void operator()(T* p) {delete p;} 100c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}; 101c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 102c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint main() 103c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{ 104c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant { 105c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant const std::unique_ptr<B, Deleter<B> > s(new B); 106c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant A* p = s.get(); 107c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant std::unique_ptr<A, Deleter<A> > s2(s); 108c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(s2.get() == p); 109c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(s.get() == 0); 110c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(A::count == 1); 111c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(B::count == 1); 112c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(s2.get_deleter().state() == 5); 113c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(s.get_deleter().state() == 0); 114c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 115c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(A::count == 0); 116c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant assert(B::count == 0); 117c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 118