Home | History | Annotate | Download | only in unique.ptr.special
      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 swap
     15 
     16 #include <memory>
     17 #include <cassert>
     18 
     19 #include "test_macros.h"
     20 #include "deleter_types.h"
     21 
     22 struct A
     23 {
     24     int state_;
     25     static int count;
     26     A() : state_(0) {++count;}
     27     explicit A(int i) : state_(i) {++count;}
     28     A(const A& a) : state_(a.state_) {++count;}
     29     A& operator=(const A& a) {state_ = a.state_; return *this;}
     30     ~A() {--count;}
     31 
     32     friend bool operator==(const A& x, const A& y)
     33         {return x.state_ == y.state_;}
     34 };
     35 
     36 int A::count = 0;
     37 
     38 template <class T>
     39 struct NonSwappableDeleter {
     40   explicit NonSwappableDeleter(int) {}
     41   NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
     42   void operator()(T*) const {}
     43 private:
     44   NonSwappableDeleter(NonSwappableDeleter const&);
     45 
     46 };
     47 
     48 int main()
     49 {
     50     {
     51     A* p1 = new A(1);
     52     std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
     53     A* p2 = new A(2);
     54     std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));
     55     assert(s1.get() == p1);
     56     assert(*s1 == A(1));
     57     assert(s1.get_deleter().state() == 1);
     58     assert(s2.get() == p2);
     59     assert(*s2 == A(2));
     60     assert(s2.get_deleter().state() == 2);
     61     swap(s1, s2);
     62     assert(s1.get() == p2);
     63     assert(*s1 == A(2));
     64     assert(s1.get_deleter().state() == 2);
     65     assert(s2.get() == p1);
     66     assert(*s2 == A(1));
     67     assert(s2.get_deleter().state() == 1);
     68     assert(A::count == 2);
     69     }
     70     assert(A::count == 0);
     71     {
     72     A* p1 = new A[3];
     73     std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));
     74     A* p2 = new A[3];
     75     std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));
     76     assert(s1.get() == p1);
     77     assert(s1.get_deleter().state() == 1);
     78     assert(s2.get() == p2);
     79     assert(s2.get_deleter().state() == 2);
     80     swap(s1, s2);
     81     assert(s1.get() == p2);
     82     assert(s1.get_deleter().state() == 2);
     83     assert(s2.get() == p1);
     84     assert(s2.get_deleter().state() == 1);
     85     assert(A::count == 6);
     86     }
     87     assert(A::count == 0);
     88 #if TEST_STD_VER >= 11
     89     {
     90         // test that unique_ptr's specialized swap is disabled when the deleter
     91         // is non-swappable. Instead we should pick up the generic swap(T, T)
     92         // and perform 3 move constructions.
     93         typedef NonSwappableDeleter<int> D;
     94         D  d(42);
     95         int x = 42;
     96         int y = 43;
     97         std::unique_ptr<int, D&> p(&x, d);
     98         std::unique_ptr<int, D&> p2(&y, d);
     99         std::swap(p, p2);
    100     }
    101 #endif
    102 }
    103