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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // template<class T>
12 // constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array
13 //
14 // template<class T>
15 // constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
16 //
17 // template<class T, class... Args>
18 // unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N]
19
20 #include <cassert>
21 #include <concepts>
22 #include <cstring>
23 #include <memory>
24 #include <utility>
25
26 #include "test_macros.h"
27
28 template <class T, class... Args>
29 concept HasMakeUniqueForOverwrite =
30 requires(Args&&... args) { std::make_unique_for_overwrite<T>(std::forward<Args>(args)...); };
31
32 struct Foo {
33 int i;
34 };
35
36 // template<class T>
37 // constexpr unique_ptr<T> make_unique_for_overwrite();
38 static_assert(HasMakeUniqueForOverwrite<int>);
39 static_assert(HasMakeUniqueForOverwrite<Foo>);
40 static_assert(!HasMakeUniqueForOverwrite<int, int>);
41 static_assert(!HasMakeUniqueForOverwrite<Foo, Foo>);
42
43 // template<class T>
44 // constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
45 static_assert(HasMakeUniqueForOverwrite<int[], std::size_t>);
46 static_assert(HasMakeUniqueForOverwrite<Foo[], std::size_t>);
47 static_assert(!HasMakeUniqueForOverwrite<int[]>);
48 static_assert(!HasMakeUniqueForOverwrite<Foo[]>);
49 static_assert(!HasMakeUniqueForOverwrite<int[], std::size_t, int>);
50 static_assert(!HasMakeUniqueForOverwrite<Foo[], std::size_t, int>);
51
52 // template<class T, class... Args>
53 // unspecified make_unique_for_overwrite(Args&&...) = delete;
54 static_assert(!HasMakeUniqueForOverwrite<int[2]>);
55 static_assert(!HasMakeUniqueForOverwrite<int[2], std::size_t>);
56 static_assert(!HasMakeUniqueForOverwrite<int[2], int>);
57 static_assert(!HasMakeUniqueForOverwrite<int[2], int, int>);
58 static_assert(!HasMakeUniqueForOverwrite<Foo[2]>);
59 static_assert(!HasMakeUniqueForOverwrite<Foo[2], std::size_t>);
60 static_assert(!HasMakeUniqueForOverwrite<Foo[2], int>);
61 static_assert(!HasMakeUniqueForOverwrite<Foo[2], int, int>);
62
63 struct WithDefaultConstructor {
64 int i;
WithDefaultConstructorWithDefaultConstructor65 constexpr WithDefaultConstructor() : i(5) {}
66 };
67
test()68 TEST_CONSTEXPR_CXX23 bool test() {
69 // single int
70 {
71 std::same_as<std::unique_ptr<int>> decltype(auto) ptr = std::make_unique_for_overwrite<int>();
72 // memory is available for write, otherwise constexpr test would fail
73 *ptr = 5;
74 }
75
76 // unbounded array int[]
77 {
78 std::same_as<std::unique_ptr<int[]>> decltype(auto) ptrs = std::make_unique_for_overwrite<int[]>(3);
79
80 // memory is available for write, otherwise constexpr test would fail
81 ptrs[0] = 3;
82 ptrs[1] = 4;
83 ptrs[2] = 5;
84 }
85
86 // single with default constructor
87 {
88 std::same_as<std::unique_ptr<WithDefaultConstructor>> decltype(auto) ptr =
89 std::make_unique_for_overwrite<WithDefaultConstructor>();
90 assert(ptr->i == 5);
91 }
92
93 // unbounded array with default constructor
94 {
95 std::same_as<std::unique_ptr<WithDefaultConstructor[]>> decltype(auto) ptrs =
96 std::make_unique_for_overwrite<WithDefaultConstructor[]>(3);
97 assert(ptrs[0].i == 5);
98 assert(ptrs[1].i == 5);
99 assert(ptrs[2].i == 5);
100 }
101
102 return true;
103 }
104
105 // The standard specifically says to use `new (p) T`, which means that we should pick up any
106 // custom in-class operator new if there is one.
107 struct WithCustomNew {
108 inline static bool customNewCalled = false;
109 inline static bool customNewArrCalled = false;
110
operator newWithCustomNew111 static void* operator new(std::size_t n) {
112 customNewCalled = true;
113 return ::operator new(n);
114 ;
115 }
116
operator new[]WithCustomNew117 static void* operator new[](std::size_t n) {
118 customNewArrCalled = true;
119 return ::operator new[](n);
120 }
121 };
122
testCustomNew()123 void testCustomNew() {
124 // single with custom operator new
125 {
126 [[maybe_unused]] std::same_as<std::unique_ptr<WithCustomNew>> decltype(auto) ptr =
127 std::make_unique_for_overwrite<WithCustomNew>();
128
129 assert(WithCustomNew::customNewCalled);
130 }
131
132 // unbounded array with custom operator new
133 {
134 [[maybe_unused]] std::same_as<std::unique_ptr<WithCustomNew[]>> decltype(auto) ptr =
135 std::make_unique_for_overwrite<WithCustomNew[]>(3);
136
137 assert(WithCustomNew::customNewArrCalled);
138 }
139 }
140
main(int,char **)141 int main(int, char**) {
142 test();
143 testCustomNew();
144 #if TEST_STD_VER >= 23
145 static_assert(test());
146 #endif
147
148 return 0;
149 }
150