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// <memory>
12
13// template <class T, class ...Args>
14// constexpr T* construct_at(T* location, Args&& ...args);
15
16#include <cassert>
17#include <cstddef>
18#include <memory>
19#include <utility>
20
21#include "test_iterators.h"
22
23struct Foo {
24 constexpr Foo() {}
25 constexpr Foo(int a, char b, double c) : a_(a), b_(b), c_(c) {}
26 constexpr Foo(int a, char b, double c, int* count) : Foo(a, b, c) { *count += 1; }
27 constexpr bool operator==(Foo const& other) const { return a_ == other.a_ && b_ == other.b_ && c_ == other.c_; }
28
29private:
30 int a_;
31 char b_;
32 double c_;
33};
34
35struct Counted {
36 int& count_;
37 constexpr Counted(int& count) : count_(count) { ++count; }
38 constexpr Counted(Counted const& that) : count_(that.count_) { ++count_; }
39 constexpr ~Counted() { --count_; }
40};
41
42constexpr bool test() {
43 {
44 int i = 99;
45 int* res = std::construct_at(&i);
46 assert(res == &i);
47 assert(*res == 0);
48 }
49
50 {
51 int i = 0;
52 int* res = std::construct_at(&i, 42);
53 assert(res == &i);
54 assert(*res == 42);
55 }
56
57 {
58 Foo foo = {};
59 int count = 0;
60 Foo* res = std::construct_at(&foo, 42, 'x', 123.89, &count);
61 assert(res == &foo);
62 assert(*res == Foo(42, 'x', 123.89));
63 assert(count == 1);
64 }
65
66 {
67 std::allocator<Counted> a;
68 Counted* p = a.allocate(n: 2);
69 int count = 0;
70 std::construct_at(p, count);
71 assert(count == 1);
72 std::construct_at(p + 1, count);
73 assert(count == 2);
74 (p + 1)->~Counted();
75 assert(count == 1);
76 p->~Counted();
77 assert(count == 0);
78 a.deallocate(p: p, t: 2);
79 }
80
81 return true;
82}
83
84template <class... Args>
85constexpr bool can_construct_at = requires { std::construct_at(std::declval<Args>()...); };
86
87// Check that SFINAE works.
88static_assert(can_construct_at<int*, int>);
89static_assert(can_construct_at<Foo*, int, char, double>);
90static_assert(!can_construct_at<Foo*, int, char>);
91static_assert(!can_construct_at<Foo*, int, char, double, int>);
92static_assert(!can_construct_at<std::nullptr_t, int, char, double>);
93static_assert(!can_construct_at<int*, int, char, double>);
94static_assert(!can_construct_at<contiguous_iterator<Foo*>, int, char, double>);
95// Can't construct function pointers.
96static_assert(!can_construct_at<int (*)()>);
97static_assert(!can_construct_at<int (*)(), std::nullptr_t>);
98
99int main(int, char**) {
100 test();
101 static_assert(test());
102 return 0;
103}
104

source code of libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp