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 //=============================================================================
     15 // TESTING std::unique_ptr::unique_ptr()
     16 //
     17 // Concerns:
     18 //   1 The pointer constructor works for any default constructible deleter types.
     19 //   2 The pointer constructor accepts pointers to derived types.
     20 //   2 The stored type 'T' is allowed to be incomplete.
     21 //
     22 // Plan
     23 //  1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
     24 //   types (C-1)
     25 //  2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
     26 //    types where 'D' is derived from 'T'. (C-1,2)
     27 //  3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
     28 //    types where 'T' is an incomplete type (C-1,3)
     29 
     30 // Test unique_ptr(pointer) ctor
     31 
     32 #include <memory>
     33 #include <cassert>
     34 
     35 #include "../../deleter.h"
     36 
     37 // unique_ptr(pointer) ctor should only require default Deleter ctor
     38 
     39 struct A
     40 {
     41     static int count;
     42     A() {++count;}
     43     A(const A&) {++count;}
     44     virtual ~A() {--count;}
     45 };
     46 
     47 int A::count = 0;
     48 
     49 
     50 struct B
     51     : public A
     52 {
     53     static int count;
     54     B() {++count;}
     55     B(const B&) {++count;}
     56     virtual ~B() {--count;}
     57 };
     58 
     59 int B::count = 0;
     60 
     61 
     62 struct IncompleteT;
     63 
     64 IncompleteT* getIncomplete();
     65 void checkNumIncompleteTypeAlive(int i);
     66 
     67 template <class Del = std::default_delete<IncompleteT> >
     68 struct StoresIncomplete {
     69   std::unique_ptr<IncompleteT, Del> m_ptr;
     70   StoresIncomplete() {}
     71   explicit StoresIncomplete(IncompleteT* ptr) : m_ptr(ptr) {}
     72   ~StoresIncomplete();
     73 
     74   IncompleteT* get() const { return m_ptr.get(); }
     75   Del& get_deleter() { return m_ptr.get_deleter(); }
     76 };
     77 
     78 void test_pointer()
     79 {
     80     {
     81         A* p = new A;
     82         assert(A::count == 1);
     83         std::unique_ptr<A> s(p);
     84         assert(s.get() == p);
     85     }
     86     assert(A::count == 0);
     87     {
     88         A* p = new A;
     89         assert(A::count == 1);
     90         std::unique_ptr<A, NCDeleter<A> > s(p);
     91         assert(s.get() == p);
     92         assert(s.get_deleter().state() == 0);
     93     }
     94     assert(A::count == 0);
     95 }
     96 
     97 void test_derived()
     98 {
     99     {
    100         B* p = new B;
    101         assert(A::count == 1);
    102         assert(B::count == 1);
    103         std::unique_ptr<A> s(p);
    104         assert(s.get() == p);
    105     }
    106     assert(A::count == 0);
    107     assert(B::count == 0);
    108     {
    109         B* p = new B;
    110         assert(A::count == 1);
    111         assert(B::count == 1);
    112         std::unique_ptr<A, NCDeleter<A> > s(p);
    113         assert(s.get() == p);
    114         assert(s.get_deleter().state() == 0);
    115     }
    116     assert(A::count == 0);
    117     assert(B::count == 0);
    118 }
    119 
    120 void test_incomplete()
    121 {
    122     {
    123         IncompleteT* p = getIncomplete();
    124         checkNumIncompleteTypeAlive(1);
    125         StoresIncomplete<> s(p);
    126         assert(s.get() == p);
    127     }
    128     checkNumIncompleteTypeAlive(0);
    129     {
    130         IncompleteT* p = getIncomplete();
    131         checkNumIncompleteTypeAlive(1);
    132         StoresIncomplete< NCDeleter<IncompleteT> > s(p);
    133         assert(s.get() == p);
    134         assert(s.get_deleter().state() == 0);
    135     }
    136     checkNumIncompleteTypeAlive(0);
    137 }
    138 
    139 struct IncompleteT {
    140     static int count;
    141     IncompleteT() { ++count; }
    142     ~IncompleteT() {--count; }
    143 };
    144 
    145 int IncompleteT::count = 0;
    146 
    147 IncompleteT* getIncomplete() {
    148     return new IncompleteT;
    149 }
    150 
    151 void checkNumIncompleteTypeAlive(int i) {
    152     assert(IncompleteT::count == i);
    153 }
    154 
    155 template <class Del>
    156 StoresIncomplete<Del>::~StoresIncomplete() { }
    157 
    158 int main()
    159 {
    160     test_pointer();
    161     test_derived();
    162     test_incomplete();
    163 }
    164