Home | History | Annotate | Download | only in unique.ptr.single.ctor
      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 // Test unique_ptr move ctor
     15 
     16 #include <memory>
     17 #include <cassert>
     18 
     19 // test move ctor.  Should only require a MoveConstructible deleter, or if
     20 //    deleter is a reference, not even that.
     21 
     22 struct A
     23 {
     24     static int count;
     25     A() {++count;}
     26     A(const A&) {++count;}
     27     ~A() {--count;}
     28 };
     29 
     30 int A::count = 0;
     31 
     32 template <class T>
     33 class Deleter
     34 {
     35     int state_;
     36 
     37 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     38     Deleter(const Deleter&);
     39     Deleter& operator=(const Deleter&);
     40 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     41     Deleter(Deleter&);
     42     Deleter& operator=(Deleter&);
     43 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     44 
     45 public:
     46 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     47     Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
     48     Deleter& operator=(Deleter&& r)
     49     {
     50         state_ = r.state_;
     51         r.state_ = 0;
     52         return *this;
     53     }
     54 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     55     operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
     56     Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
     57     Deleter& operator=(std::__rv<Deleter> r)
     58     {
     59         state_ = r->state_;
     60         r->state_ = 0;
     61         return *this;
     62     }
     63 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     64 
     65     Deleter() : state_(5) {}
     66 
     67 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     68     template <class U>
     69         Deleter(Deleter<U>&& d,
     70             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
     71             : state_(d.state()) {d.set_state(0);}
     72 
     73 private:
     74     template <class U>
     75         Deleter(const Deleter<U>& d,
     76             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
     77 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     78     template <class U>
     79         Deleter(Deleter<U> d,
     80             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
     81             : state_(d.state()) {}
     82 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     83 public:
     84     int state() const {return state_;}
     85     void set_state(int i) {state_ = i;}
     86 
     87     void operator()(T* p) {delete p;}
     88 };
     89 
     90 class CDeleter
     91 {
     92     int state_;
     93 
     94     CDeleter(CDeleter&);
     95     CDeleter& operator=(CDeleter&);
     96 public:
     97 
     98     CDeleter() : state_(5) {}
     99 
    100     int state() const {return state_;}
    101     void set_state(int s) {state_ = s;}
    102 
    103     void operator()(A* p) {delete p;}
    104 };
    105 
    106 std::unique_ptr<A>
    107 source1()
    108 {
    109     return std::unique_ptr<A>(new A);
    110 }
    111 
    112 void sink1(std::unique_ptr<A> p)
    113 {
    114 }
    115 
    116 std::unique_ptr<A, Deleter<A> >
    117 source2()
    118 {
    119     return std::unique_ptr<A, Deleter<A> >(new A);
    120 }
    121 
    122 void sink2(std::unique_ptr<A, Deleter<A> > p)
    123 {
    124 }
    125 
    126 std::unique_ptr<A, CDeleter&>
    127 source3()
    128 {
    129     static CDeleter d;
    130     return std::unique_ptr<A, CDeleter&>(new A, d);
    131 }
    132 
    133 void sink3(std::unique_ptr<A, CDeleter&> p)
    134 {
    135 }
    136 
    137 int main()
    138 {
    139     sink1(source1());
    140     sink2(source2());
    141     sink3(source3());
    142     assert(A::count == 0);
    143 }
    144