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: no-exceptions
10
11// ensure that __uninitialized_allocator_copy calls the proper construct and destruct functions
12
13#include <algorithm>
14#include <iterator>
15#include <memory>
16
17#include "test_allocator.h"
18
19template <class T>
20class construct_counting_allocator {
21public:
22 using value_type = T;
23
24 int* constructed_count_;
25 int* max_constructed_count_;
26
27 construct_counting_allocator(int* constructed_count, int* max_constructed_count)
28 : constructed_count_(constructed_count), max_constructed_count_(max_constructed_count) {}
29
30 template <class... Args>
31 void construct(T* ptr, Args&&... args) {
32 ::new (static_cast<void*>(ptr)) T(args...);
33 ++*constructed_count_;
34 *max_constructed_count_ = std::max(*max_constructed_count_, *constructed_count_);
35 }
36
37 void destroy(T* ptr) {
38 --*constructed_count_;
39 ptr->~T();
40 }
41};
42
43int throw_if_zero = 15;
44
45struct ThrowSometimes {
46 ThrowSometimes() = default;
47 ThrowSometimes(const ThrowSometimes&) {
48 if (--throw_if_zero == 0)
49 throw 1;
50 }
51};
52
53int main(int, char**) {
54 int constructed_count = 0;
55 int max_constructed_count = 0;
56 construct_counting_allocator<ThrowSometimes> alloc(&constructed_count, &max_constructed_count);
57 ThrowSometimes in[20];
58 TEST_ALIGNAS_TYPE(ThrowSometimes) char out[sizeof(ThrowSometimes) * 20];
59 try {
60 std::__uninitialized_allocator_copy(
61 alloc, std::begin(arr&: in), std::end(arr&: in), reinterpret_cast<ThrowSometimes*>(std::begin(out)));
62 } catch (...) {
63 }
64
65 assert(constructed_count == 0);
66 assert(max_constructed_count == 14);
67}
68

source code of libcxx/test/libcxx/memory/uninitialized_allocator_copy.pass.cpp