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
10 // constexpr destructors are only supported starting with clang 10
11 // UNSUPPORTED: clang-5, clang-6, clang-7, clang-8, clang-9
12 
13 // <memory>
14 
15 // template <class ForwardIt>
16 // constexpr void destroy(ForwardIt, ForwardIt);
17 
18 #include <memory>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 #include "test_iterators.h"
23 
24 struct Counted {
25     int* counter_;
26     TEST_CONSTEXPR Counted(int* counter) : counter_(counter) { ++*counter_; }
27     TEST_CONSTEXPR Counted(Counted const& other) : counter_(other.counter_) { ++*counter_; }
28     TEST_CONSTEXPR_CXX20 ~Counted() { --*counter_; }
29     friend void operator&(Counted) = delete;
30 };
31 
32 TEST_CONSTEXPR_CXX20 bool test()
33 {
34     using Alloc = std::allocator<Counted>;
35     int counter = 0;
36     int const N = 5;
37     Alloc alloc;
38     Counted* pool = std::allocator_traits<Alloc>::allocate(alloc, N);
39 
40     for (Counted* p = pool; p != pool + N; ++p)
41         std::allocator_traits<Alloc>::construct(alloc, p, &counter);
42     assert(counter == 5);
43 
44     std::destroy(pool, pool + 1);
45     assert(counter == 4);
46 
47     std::destroy(forward_iterator<Counted*>(pool + 1), forward_iterator<Counted*>(pool + 5));
48     assert(counter == 0);
49 
50     std::allocator_traits<Alloc>::deallocate(alloc, pool, N);
51 
52     return true;
53 }
54 
55 int main(int, char**)
56 {
57     test();
58 #if TEST_STD_VER > 17
59     static_assert(test());
60 #endif
61     return 0;
62 }
63