127 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <memory>10 11// unique_ptr12 13//=============================================================================14// TESTING std::unique_ptr::unique_ptr()15//16// Concerns:17// 1 The default constructor works for any default constructible deleter types.18// 2 The stored type 'T' is allowed to be incomplete.19//20// Plan21// 1 Default construct unique_ptr's with various deleter types (C-1)22// 2 Default construct a unique_ptr with an incomplete element_type and23// various deleter types (C-1,2)24 25#include <memory>26#include <cassert>27#include "test_macros.h"28 29#include "test_macros.h"30#include "deleter_types.h"31#include "unique_ptr_test_helper.h"32 33#if TEST_STD_VER >= 1134TEST_CONSTINIT std::unique_ptr<int> global_static_unique_ptr_single;35TEST_CONSTINIT std::unique_ptr<int[]> global_static_unique_ptr_runtime;36 37struct NonDefaultDeleter {38 NonDefaultDeleter() = delete;39 TEST_CONSTEXPR_CXX23 void operator()(void*) const {}40};41#endif42 43template <class ElemType>44TEST_CONSTEXPR_CXX23 void test_sfinae() {45#if TEST_STD_VER >= 1146 { // the constructor does not participate in overload resolution when47 // the deleter is a pointer type48 using U = std::unique_ptr<ElemType, void (*)(void*)>;49 static_assert(!std::is_default_constructible<U>::value, "");50 }51 { // the constructor does not participate in overload resolution when52 // the deleter is not default constructible53 using Del = CDeleter<ElemType>;54 using U1 = std::unique_ptr<ElemType, NonDefaultDeleter>;55 using U2 = std::unique_ptr<ElemType, Del&>;56 using U3 = std::unique_ptr<ElemType, Del const&>;57 static_assert(!std::is_default_constructible<U1>::value, "");58 static_assert(!std::is_default_constructible<U2>::value, "");59 static_assert(!std::is_default_constructible<U3>::value, "");60 }61#endif62}63 64template <class ElemType>65TEST_CONSTEXPR_CXX23 bool test_basic() {66#if TEST_STD_VER >= 1167 {68 using U1 = std::unique_ptr<ElemType>;69 using U2 = std::unique_ptr<ElemType, Deleter<ElemType> >;70 static_assert(std::is_nothrow_default_constructible<U1>::value, "");71 static_assert(std::is_nothrow_default_constructible<U2>::value, "");72 }73#endif74 {75 std::unique_ptr<ElemType> p;76 assert(p.get() == 0);77 }78 {79 std::unique_ptr<ElemType, NCDeleter<ElemType> > p;80 assert(p.get() == 0);81 assert(p.get_deleter().state() == 0);82 p.get_deleter().set_state(5);83 assert(p.get_deleter().state() == 5);84 }85// TODO: Remove this check once https://llvm.org/PR154567 is fixed86#if TEST_STD_VER >= 23 && defined(TEST_COMPILER_CLANG)87 if (!TEST_IS_CONSTANT_EVALUATED)88#endif89 {90 std::unique_ptr<ElemType, DefaultCtorDeleter<ElemType> > p;91 assert(p.get() == 0);92 assert(p.get_deleter().state() == 0);93 }94 95 return true;96}97 98DEFINE_AND_RUN_IS_INCOMPLETE_TEST({99 doIncompleteTypeTest(0);100 doIncompleteTypeTest<IncompleteType, Deleter<IncompleteType> >(0);101} {102 doIncompleteTypeTest<IncompleteType[]>(0);103 doIncompleteTypeTest<IncompleteType[], Deleter<IncompleteType[]> >(0);104})105 106TEST_CONSTEXPR_CXX23 bool test() {107 {108 test_sfinae<int>();109 test_basic<int>();110 }111 {112 test_sfinae<int[]>();113 test_basic<int[]>();114 }115 116 return true;117}118 119int main(int, char**) {120 test();121#if TEST_STD_VER >= 23122 static_assert(test());123#endif124 125 return 0;126}127