diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -395,6 +395,10 @@ template unique_ptr make_unique(size_t n); // C++14 template unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] +template unique_ptr make_unique_for_overwrite(); // C++20 +template unique_ptr make_unique_for_overwrite(size_t n); // C++20 +template unspecified make_unique_for_overwrite(Args&&...) = delete; // C++20, T == U[N] + template basic_ostream& operator<< (basic_ostream& os, unique_ptr const& p); @@ -2829,6 +2833,31 @@ typename __unique_if<_Tp>::__unique_array_known_bound make_unique(_Args&&...) = delete; +#if _LIBCPP_STD_VER > 17 + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __unique_if<_Tp>::__unique_single +make_unique_for_overwrite() +{ + return unique_ptr<_Tp>(new _Tp); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename __unique_if<_Tp>::__unique_array_unknown_bound +make_unique_for_overwrite(size_t __n) +{ + typedef typename remove_extent<_Tp>::type _Up; + return unique_ptr<_Tp>(new _Up[__n]); +} + +template + typename __unique_if<_Tp>::__unique_array_known_bound + make_unique_for_overwrite(_Args&&...) = delete; + +#endif // _LIBCPP_STD_VER > 17 + #endif // _LIBCPP_STD_VER > 11 template diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include +#include +#include + +#include "test_macros.h" + +struct InitializationVerifier { + static constexpr int kValue = 0x24; + + static void* operator new(size_t n) = delete; + + static void* operator new[](size_t n) { + void* ret = ::operator new[](n); + memset(ret, kValue, n); + return ret; + } + + int a; + int b; +}; + +// The only way to create an unique_ptr is to default construct them. + +class foo { +public: + foo() : val_(3) {} + int get() const { return val_; } + +private: + int val_; +}; + +int main(int, char**) { + { + auto p1 = std::make_unique_for_overwrite(5); + int pattern; + memset(&pattern, InitializationVerifier::kValue, sizeof(pattern)); + for (int i = 0; i < 5; ++i) { + assert(p1[i].a == pattern); + assert(p1[i].b == pattern); + } + } + + { + auto p2 = std::make_unique_for_overwrite(5); + for (int i = 0; i < 5; ++i) + assert(p2[i].size() == 0); + } + + { + auto p3 = std::make_unique_for_overwrite(7); + for (int i = 0; i < 7; ++i) + assert(p3[i].get() == 3); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array1.compile.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array1.compile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array1.compile.verify.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include +#include + +int main(int, char**) { + auto up1 = std::make_unique_for_overwrite( + "error"); // expected-error@-1 {{no matching function for call to 'make_unique_for_overwrite'}} + + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array2.compile.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array2.compile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array2.compile.verify.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include + +int main(int, char**) { + auto up2 = std::make_unique_for_overwrite( + 10, 20, 30, + 40); // expected-error@-2 {{no matching function for call to 'make_unique_for_overwrite'}} + + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array3.compile.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array3.compile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array3.compile.verify.cpp @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include + +int main(int, char**) { + std::make_unique_for_overwrite< + int[5]>(); // expected-error@-1 {{call to deleted function 'make_unique_for_overwrite'}} + + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array4.compile.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array4.compile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.array4.compile.verify.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include + +int main(int, char**) { + std::make_unique_for_overwrite( + 11, 22, 33, 44, + 55); // expected-error@-2 {{call to deleted function 'make_unique_for_overwrite'}} + + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.single.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.single.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +#include +#include +#include + +#include "test_macros.h" + +struct InitializationVerifier { + static constexpr int kValue = 0x42; + + static void* operator new(size_t n) { + void* ret = ::operator new(n); + memset(ret, kValue, n); + return ret; + } + + static void* operator new[](size_t n) = delete; + + int a; + int b; +}; + +int main(int, char**) { + { + std::unique_ptr p1 = + std::make_unique_for_overwrite(); + + int pattern; + memset(&pattern, InitializationVerifier::kValue, sizeof(pattern)); + assert(p1->a == pattern); + assert(p1->b == pattern); + } + + { + std::unique_ptr p2 = + std::make_unique_for_overwrite(); + assert(*p2 == ""); + } + + return 0; +} diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -124,7 +124,7 @@ P0972R0LWG<chrono> zero(), min(), and max() should be noexceptSan DiegoComplete8.0 P1006R1LWGConstexpr in std::pointer_traitsSan DiegoComplete8.0 P1007R3LWGstd::assume_alignedSan Diego - P1020R1LWGSmart pointer creation with default initializationSan Diego + P1020R1LWGSmart pointer creation with default initializationSan DiegoIn Progress P1032R1LWGMisc constexpr bitsSan Diego P1085R2LWGShould Span be Regular?San DiegoComplete8.0 P1123R0LWGEditorial Guidance for merging P0019r8 and P0528r3San Diego @@ -240,7 +240,7 @@ P1963LWGFixing US 313Prague P1964LWGWording for boolean-testablePrague P1970LWGConsistency for size() functions: Add ranges::ssizePrague - P1973LWGRename "_default_init" Functions, Rev1Prague + P1973LWGRename "_default_init" Functions, Rev1PragueIn Progress P1976LWGFixed-size span construction from dynamic rangePragueComplete11.0 P1981LWGRename leap to leap_secondPrague P1982LWGRename link to time_zone_linkPrague