12561885fSEric Fiselier //===----------------------------------------------------------------------===//
22561885fSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62561885fSEric Fiselier //
72561885fSEric Fiselier //===----------------------------------------------------------------------===//
82561885fSEric Fiselier 
92561885fSEric Fiselier // <memory>
102561885fSEric Fiselier 
112561885fSEric Fiselier // unique_ptr
122561885fSEric Fiselier 
132561885fSEric Fiselier //=============================================================================
142561885fSEric Fiselier // TESTING std::unique_ptr::unique_ptr(pointer)
152561885fSEric Fiselier //
162561885fSEric Fiselier // Concerns:
172561885fSEric Fiselier //   1 The pointer constructor works for any default constructible deleter types.
182561885fSEric Fiselier //   2 The pointer constructor accepts pointers to derived types.
192561885fSEric Fiselier //   2 The stored type 'T' is allowed to be incomplete.
202561885fSEric Fiselier //
212561885fSEric Fiselier // Plan
222561885fSEric Fiselier //  1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
232561885fSEric Fiselier //   types (C-1)
242561885fSEric Fiselier //  2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
252561885fSEric Fiselier //    types where 'D' is derived from 'T'. (C-1,2)
262561885fSEric Fiselier //  3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
272561885fSEric Fiselier //    types where 'T' is an incomplete type (C-1,3)
282561885fSEric Fiselier 
292561885fSEric Fiselier // Test unique_ptr(pointer) ctor
302561885fSEric Fiselier 
312561885fSEric Fiselier #include <memory>
322561885fSEric Fiselier #include <cassert>
332561885fSEric Fiselier 
342561885fSEric Fiselier #include "test_macros.h"
352561885fSEric Fiselier #include "unique_ptr_test_helper.h"
362561885fSEric Fiselier 
372561885fSEric Fiselier // unique_ptr(pointer) ctor should only require default Deleter ctor
382561885fSEric Fiselier 
392561885fSEric Fiselier template <bool IsArray>
test_pointer()402561885fSEric Fiselier void test_pointer() {
412561885fSEric Fiselier   typedef typename std::conditional<!IsArray, A, A[]>::type ValueT;
422561885fSEric Fiselier   const int expect_alive = IsArray ? 5 : 1;
432561885fSEric Fiselier #if TEST_STD_VER >= 11
442561885fSEric Fiselier   {
452561885fSEric Fiselier     using U1 = std::unique_ptr<ValueT>;
462561885fSEric Fiselier     using U2 = std::unique_ptr<ValueT, Deleter<ValueT> >;
4747272722SEric Fiselier 
4847272722SEric Fiselier     // Test for noexcept
492561885fSEric Fiselier     static_assert(std::is_nothrow_constructible<U1, A*>::value, "");
502561885fSEric Fiselier     static_assert(std::is_nothrow_constructible<U2, A*>::value, "");
5147272722SEric Fiselier 
5247272722SEric Fiselier     // Test for explicit
5347272722SEric Fiselier     static_assert(!std::is_convertible<A*, U1>::value, "");
5447272722SEric Fiselier     static_assert(!std::is_convertible<A*, U2>::value, "");
552561885fSEric Fiselier   }
562561885fSEric Fiselier #endif
572561885fSEric Fiselier   {
582561885fSEric Fiselier     A* p = newValue<ValueT>(expect_alive);
592561885fSEric Fiselier     assert(A::count == expect_alive);
602561885fSEric Fiselier     std::unique_ptr<ValueT> s(p);
612561885fSEric Fiselier     assert(s.get() == p);
622561885fSEric Fiselier   }
632561885fSEric Fiselier   assert(A::count == 0);
642561885fSEric Fiselier   {
652561885fSEric Fiselier     A* p = newValue<ValueT>(expect_alive);
662561885fSEric Fiselier     assert(A::count == expect_alive);
672561885fSEric Fiselier     std::unique_ptr<ValueT, NCDeleter<ValueT> > s(p);
682561885fSEric Fiselier     assert(s.get() == p);
692561885fSEric Fiselier     assert(s.get_deleter().state() == 0);
702561885fSEric Fiselier   }
712561885fSEric Fiselier   assert(A::count == 0);
72*68e2231fSJohan Berg   {
73*68e2231fSJohan Berg     A* p = newValue<ValueT>(expect_alive);
74*68e2231fSJohan Berg     assert(A::count == expect_alive);
75*68e2231fSJohan Berg     std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > s(p);
76*68e2231fSJohan Berg     assert(s.get() == p);
77*68e2231fSJohan Berg     assert(s.get_deleter().state() == 0);
78*68e2231fSJohan Berg   }
79*68e2231fSJohan Berg   assert(A::count == 0);
802561885fSEric Fiselier }
812561885fSEric Fiselier 
test_derived()822561885fSEric Fiselier void test_derived() {
832561885fSEric Fiselier   {
842561885fSEric Fiselier     B* p = new B;
852561885fSEric Fiselier     assert(A::count == 1);
862561885fSEric Fiselier     assert(B::count == 1);
872561885fSEric Fiselier     std::unique_ptr<A> s(p);
882561885fSEric Fiselier     assert(s.get() == p);
892561885fSEric Fiselier   }
902561885fSEric Fiselier   assert(A::count == 0);
912561885fSEric Fiselier   assert(B::count == 0);
922561885fSEric Fiselier   {
932561885fSEric Fiselier     B* p = new B;
942561885fSEric Fiselier     assert(A::count == 1);
952561885fSEric Fiselier     assert(B::count == 1);
962561885fSEric Fiselier     std::unique_ptr<A, NCDeleter<A> > s(p);
972561885fSEric Fiselier     assert(s.get() == p);
982561885fSEric Fiselier     assert(s.get_deleter().state() == 0);
992561885fSEric Fiselier   }
1002561885fSEric Fiselier   assert(A::count == 0);
1012561885fSEric Fiselier   assert(B::count == 0);
1022561885fSEric Fiselier }
1032561885fSEric Fiselier 
1042561885fSEric Fiselier #if TEST_STD_VER >= 11
1052561885fSEric Fiselier struct NonDefaultDeleter {
1062561885fSEric Fiselier   NonDefaultDeleter() = delete;
operator ()NonDefaultDeleter1072561885fSEric Fiselier   void operator()(void*) const {}
1082561885fSEric Fiselier };
1092561885fSEric Fiselier 
1102561885fSEric Fiselier struct GenericDeleter {
1112561885fSEric Fiselier   void operator()(void*) const;
1122561885fSEric Fiselier };
1132561885fSEric Fiselier #endif
1142561885fSEric Fiselier 
1152561885fSEric Fiselier template <class T>
test_sfinae()1162561885fSEric Fiselier void test_sfinae() {
11747272722SEric Fiselier #if TEST_STD_VER >= 11
118437e0e51SStephan T. Lavavej   { // the constructor does not participate in overload resolution when
1192561885fSEric Fiselier     // the deleter is a pointer type
1202561885fSEric Fiselier     using U = std::unique_ptr<T, void (*)(void*)>;
1212561885fSEric Fiselier     static_assert(!std::is_constructible<U, T*>::value, "");
1222561885fSEric Fiselier   }
1232561885fSEric Fiselier   { // the constructor does not participate in overload resolution when
1242561885fSEric Fiselier     // the deleter is not default constructible
1252561885fSEric Fiselier     using Del = CDeleter<T>;
1262561885fSEric Fiselier     using U1 = std::unique_ptr<T, NonDefaultDeleter>;
1272561885fSEric Fiselier     using U2 = std::unique_ptr<T, Del&>;
1282561885fSEric Fiselier     using U3 = std::unique_ptr<T, Del const&>;
1292561885fSEric Fiselier     static_assert(!std::is_constructible<U1, T*>::value, "");
1302561885fSEric Fiselier     static_assert(!std::is_constructible<U2, T*>::value, "");
1312561885fSEric Fiselier     static_assert(!std::is_constructible<U3, T*>::value, "");
1322561885fSEric Fiselier   }
1332561885fSEric Fiselier #endif
1342561885fSEric Fiselier }
1352561885fSEric Fiselier 
test_sfinae_runtime()1362561885fSEric Fiselier static void test_sfinae_runtime() {
1372561885fSEric Fiselier #if TEST_STD_VER >= 11
1382561885fSEric Fiselier   { // the constructor does not participate in overload resolution when
1392561885fSEric Fiselier     // a base <-> derived conversion would occur.
1402561885fSEric Fiselier     using UA = std::unique_ptr<A[]>;
1412561885fSEric Fiselier     using UAD = std::unique_ptr<A[], GenericDeleter>;
1422561885fSEric Fiselier     using UAC = std::unique_ptr<const A[]>;
1432561885fSEric Fiselier     using UB = std::unique_ptr<B[]>;
1442561885fSEric Fiselier     using UBD = std::unique_ptr<B[], GenericDeleter>;
1452561885fSEric Fiselier     using UBC = std::unique_ptr<const B[]>;
1462561885fSEric Fiselier 
1472561885fSEric Fiselier     static_assert(!std::is_constructible<UA, B*>::value, "");
1482561885fSEric Fiselier     static_assert(!std::is_constructible<UB, A*>::value, "");
1492561885fSEric Fiselier     static_assert(!std::is_constructible<UAD, B*>::value, "");
1502561885fSEric Fiselier     static_assert(!std::is_constructible<UBD, A*>::value, "");
1512561885fSEric Fiselier     static_assert(!std::is_constructible<UAC, const B*>::value, "");
1522561885fSEric Fiselier     static_assert(!std::is_constructible<UBC, const A*>::value, "");
1532561885fSEric Fiselier   }
1542561885fSEric Fiselier #endif
1552561885fSEric Fiselier }
1562561885fSEric Fiselier 
1572561885fSEric Fiselier DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
1582561885fSEric Fiselier   { doIncompleteTypeTest(1, getNewIncomplete()); }
1592561885fSEric Fiselier   checkNumIncompleteTypeAlive(0);
1602561885fSEric Fiselier   {
1612561885fSEric Fiselier     doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(
1622561885fSEric Fiselier         1, getNewIncomplete());
1632561885fSEric Fiselier   }
1642561885fSEric Fiselier   checkNumIncompleteTypeAlive(0);
1652561885fSEric Fiselier })
1662561885fSEric Fiselier 
main(int,char **)1672df59c50SJF Bastien int main(int, char**) {
1682561885fSEric Fiselier   {
1692561885fSEric Fiselier     test_pointer</*IsArray*/ false>();
1702561885fSEric Fiselier     test_derived();
1712561885fSEric Fiselier     test_sfinae<int>();
1722561885fSEric Fiselier   }
1732561885fSEric Fiselier   {
1742561885fSEric Fiselier     test_pointer</*IsArray*/ true>();
1752561885fSEric Fiselier     test_sfinae<int[]>();
1762561885fSEric Fiselier     test_sfinae_runtime();
1772561885fSEric Fiselier   }
1782df59c50SJF Bastien 
1792df59c50SJF Bastien   return 0;
1802561885fSEric Fiselier }
181