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
28template <class T, class... Args>
29concept HasMakeUniqueForOverwrite =
30 requires(Args&&... args) { std::make_unique_for_overwrite<T>(std::forward<Args>(args)...); };
31
32struct Foo {
33 int i;
34};
35
36// template<class T>
37// constexpr unique_ptr<T> make_unique_for_overwrite();
38static_assert(HasMakeUniqueForOverwrite<int>);
39static_assert(HasMakeUniqueForOverwrite<Foo>);
40static_assert(!HasMakeUniqueForOverwrite<int, int>);
41static_assert(!HasMakeUniqueForOverwrite<Foo, Foo>);
42
43// template<class T>
44// constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
45static_assert(HasMakeUniqueForOverwrite<int[], std::size_t>);
46static_assert(HasMakeUniqueForOverwrite<Foo[], std::size_t>);
47static_assert(!HasMakeUniqueForOverwrite<int[]>);
48static_assert(!HasMakeUniqueForOverwrite<Foo[]>);
49static_assert(!HasMakeUniqueForOverwrite<int[], std::size_t, int>);
50static_assert(!HasMakeUniqueForOverwrite<Foo[], std::size_t, int>);
51
52// template<class T, class... Args>
53// unspecified make_unique_for_overwrite(Args&&...) = delete;
54static_assert(!HasMakeUniqueForOverwrite<int[2]>);
55static_assert(!HasMakeUniqueForOverwrite<int[2], std::size_t>);
56static_assert(!HasMakeUniqueForOverwrite<int[2], int>);
57static_assert(!HasMakeUniqueForOverwrite<int[2], int, int>);
58static_assert(!HasMakeUniqueForOverwrite<Foo[2]>);
59static_assert(!HasMakeUniqueForOverwrite<Foo[2], std::size_t>);
60static_assert(!HasMakeUniqueForOverwrite<Foo[2], int>);
61static_assert(!HasMakeUniqueForOverwrite<Foo[2], int, int>);
62
63struct WithDefaultConstructor {
64 int i;
65 constexpr WithDefaultConstructor() : i(5) {}
66};
67
68TEST_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.
107struct WithCustomNew {
108 inline static bool customNewCalled = false;
109 inline static bool customNewArrCalled = false;
110
111 static void* operator new(std::size_t n) {
112 customNewCalled = true;
113 return ::operator new(n);
114 ;
115 }
116
117 static void* operator new[](std::size_t n) {
118 customNewArrCalled = true;
119 return ::operator new[](n);
120 }
121};
122
123void 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
141int 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

source code of libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.pass.cpp