//===----------------------------------------------------------------------===// // // 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: no-exceptions // ensure that __uninitialized_allocator_copy calls the proper construct and destruct functions #include #include #include #include "test_allocator.h" template class construct_counting_allocator { public: using value_type = T; int* constructed_count_; int* max_constructed_count_; construct_counting_allocator(int* constructed_count, int* max_constructed_count) : constructed_count_(constructed_count), max_constructed_count_(max_constructed_count) {} template void construct(T* ptr, Args&&... args) { ::new (static_cast(ptr)) T(args...); ++*constructed_count_; *max_constructed_count_ = std::max(*max_constructed_count_, *constructed_count_); } void destroy(T* ptr) { --*constructed_count_; ptr->~T(); } }; int throw_if_zero = 15; struct ThrowSometimes { ThrowSometimes() = default; ThrowSometimes(const ThrowSometimes&) { if (--throw_if_zero == 0) throw 1; } }; int main(int, char**) { int constructed_count = 0; int max_constructed_count = 0; construct_counting_allocator alloc(&constructed_count, &max_constructed_count); ThrowSometimes in[20]; TEST_ALIGNAS_TYPE(ThrowSometimes) char out[sizeof(ThrowSometimes) * 20]; try { std::__uninitialized_allocator_copy( alloc, std::begin(in), std::end(in), reinterpret_cast(std::begin(out))); } catch (...) { } assert(constructed_count == 0); assert(max_constructed_count == 14); }