Home | History | Annotate | Download | only in unique.ptr.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(pointer)
     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 "test_macros.h"
     36 #include "unique_ptr_test_helper.h"
     37 
     38 // unique_ptr(pointer) ctor should only require default Deleter ctor
     39 
     40 template <bool IsArray>
     41 void test_pointer() {
     42   typedef typename std::conditional<!IsArray, A, A[]>::type ValueT;
     43   const int expect_alive = IsArray ? 5 : 1;
     44 #if TEST_STD_VER >= 11
     45   {
     46     using U1 = std::unique_ptr<ValueT>;
     47     using U2 = std::unique_ptr<ValueT, Deleter<ValueT> >;
     48 
     49     // Test for noexcept
     50     static_assert(std::is_nothrow_constructible<U1, A*>::value, "");
     51     static_assert(std::is_nothrow_constructible<U2, A*>::value, "");
     52 
     53     // Test for explicit
     54     static_assert(!std::is_convertible<A*, U1>::value, "");
     55     static_assert(!std::is_convertible<A*, U2>::value, "");
     56   }
     57 #endif
     58   {
     59     A* p = newValue<ValueT>(expect_alive);
     60     assert(A::count == expect_alive);
     61     std::unique_ptr<ValueT> s(p);
     62     assert(s.get() == p);
     63   }
     64   assert(A::count == 0);
     65   {
     66     A* p = newValue<ValueT>(expect_alive);
     67     assert(A::count == expect_alive);
     68     std::unique_ptr<ValueT, NCDeleter<ValueT> > s(p);
     69     assert(s.get() == p);
     70     assert(s.get_deleter().state() == 0);
     71   }
     72   assert(A::count == 0);
     73 }
     74 
     75 void test_derived() {
     76   {
     77     B* p = new B;
     78     assert(A::count == 1);
     79     assert(B::count == 1);
     80     std::unique_ptr<A> s(p);
     81     assert(s.get() == p);
     82   }
     83   assert(A::count == 0);
     84   assert(B::count == 0);
     85   {
     86     B* p = new B;
     87     assert(A::count == 1);
     88     assert(B::count == 1);
     89     std::unique_ptr<A, NCDeleter<A> > s(p);
     90     assert(s.get() == p);
     91     assert(s.get_deleter().state() == 0);
     92   }
     93   assert(A::count == 0);
     94   assert(B::count == 0);
     95 }
     96 
     97 #if TEST_STD_VER >= 11
     98 struct NonDefaultDeleter {
     99   NonDefaultDeleter() = delete;
    100   void operator()(void*) const {}
    101 };
    102 
    103 struct GenericDeleter {
    104   void operator()(void*) const;
    105 };
    106 #endif
    107 
    108 template <class T>
    109 void test_sfinae() {
    110 #if TEST_STD_VER >= 11
    111   { // the constructor does not participate in overload resultion when
    112     // the deleter is a pointer type
    113     using U = std::unique_ptr<T, void (*)(void*)>;
    114     static_assert(!std::is_constructible<U, T*>::value, "");
    115   }
    116   { // the constructor does not participate in overload resolution when
    117     // the deleter is not default constructible
    118     using Del = CDeleter<T>;
    119     using U1 = std::unique_ptr<T, NonDefaultDeleter>;
    120     using U2 = std::unique_ptr<T, Del&>;
    121     using U3 = std::unique_ptr<T, Del const&>;
    122     static_assert(!std::is_constructible<U1, T*>::value, "");
    123     static_assert(!std::is_constructible<U2, T*>::value, "");
    124     static_assert(!std::is_constructible<U3, T*>::value, "");
    125   }
    126 #endif
    127 }
    128 
    129 static void test_sfinae_runtime() {
    130 #if TEST_STD_VER >= 11
    131   { // the constructor does not participate in overload resolution when
    132     // a base <-> derived conversion would occur.
    133     using UA = std::unique_ptr<A[]>;
    134     using UAD = std::unique_ptr<A[], GenericDeleter>;
    135     using UAC = std::unique_ptr<const A[]>;
    136     using UB = std::unique_ptr<B[]>;
    137     using UBD = std::unique_ptr<B[], GenericDeleter>;
    138     using UBC = std::unique_ptr<const B[]>;
    139 
    140     static_assert(!std::is_constructible<UA, B*>::value, "");
    141     static_assert(!std::is_constructible<UB, A*>::value, "");
    142     static_assert(!std::is_constructible<UAD, B*>::value, "");
    143     static_assert(!std::is_constructible<UBD, A*>::value, "");
    144     static_assert(!std::is_constructible<UAC, const B*>::value, "");
    145     static_assert(!std::is_constructible<UBC, const A*>::value, "");
    146   }
    147 #endif
    148 }
    149 
    150 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
    151   { doIncompleteTypeTest(1, getNewIncomplete()); }
    152   checkNumIncompleteTypeAlive(0);
    153   {
    154     doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(
    155         1, getNewIncomplete());
    156   }
    157   checkNumIncompleteTypeAlive(0);
    158 })
    159 
    160 int main() {
    161   {
    162     test_pointer</*IsArray*/ false>();
    163     test_derived();
    164     test_sfinae<int>();
    165   }
    166   {
    167     test_pointer</*IsArray*/ true>();
    168     test_sfinae<int[]>();
    169     test_sfinae_runtime();
    170   }
    171 }
    172