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// <memory>
10
11// allocator:
12// constexpr T* allocate(size_t n);
13
14#include <memory>
15#include <cassert>
16#include <cstddef> // for std::max_align_t
17
18#include "test_macros.h"
19#include "count_new.h"
20
21
22#ifdef TEST_HAS_NO_ALIGNED_ALLOCATION
23static const bool UsingAlignedNew = false;
24#else
25static const bool UsingAlignedNew = true;
26#endif
27
28#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
29static const std::size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
30#else
31static const std::size_t MaxAligned = std::alignment_of<std::max_align_t>::value;
32#endif
33
34static const std::size_t OverAligned = MaxAligned * 2;
35
36
37template <std::size_t Align>
38struct TEST_ALIGNAS(Align) AlignedType {
39 char data;
40 static int constructed;
41 AlignedType() { ++constructed; }
42 AlignedType(AlignedType const&) { ++constructed; }
43 ~AlignedType() { --constructed; }
44};
45template <std::size_t Align>
46int AlignedType<Align>::constructed = 0;
47
48
49template <std::size_t Align>
50void test_aligned() {
51 typedef AlignedType<Align> T;
52 T::constructed = 0;
53 globalMemCounter.reset();
54 std::allocator<T> a;
55 const bool IsOverAlignedType = Align > MaxAligned;
56 const bool ExpectAligned = IsOverAlignedType && UsingAlignedNew;
57 {
58 assert(globalMemCounter.checkOutstandingNewEq(0));
59 assert(T::constructed == 0);
60 globalMemCounter.last_new_size = 0;
61 globalMemCounter.last_new_align = 0;
62 T* ap = a.allocate(n: 3);
63 DoNotOptimize(ap);
64 assert(globalMemCounter.checkOutstandingNewEq(1));
65 assert(globalMemCounter.checkNewCalledEq(1));
66 assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
67 assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(T)));
68 assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0));
69 assert(T::constructed == 0);
70 globalMemCounter.last_delete_align = 0;
71 a.deallocate(p: ap, t: 3);
72 assert(globalMemCounter.checkOutstandingNewEq(0));
73 assert(globalMemCounter.checkDeleteCalledEq(1));
74 assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
75 assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0));
76 assert(T::constructed == 0);
77 }
78}
79
80#if TEST_STD_VER > 17
81template <std::size_t Align>
82constexpr bool test_aligned_constexpr() {
83 typedef AlignedType<Align> T;
84 std::allocator<T> a;
85 T* ap = a.allocate(3);
86 a.deallocate(ap, 3);
87
88 return true;
89}
90#endif
91
92int main(int, char**) {
93 test_aligned<1>();
94 test_aligned<2>();
95 test_aligned<4>();
96 test_aligned<8>();
97 test_aligned<16>();
98 test_aligned<MaxAligned>();
99 test_aligned<OverAligned>();
100 test_aligned<OverAligned * 2>();
101
102#if TEST_STD_VER > 17
103 static_assert(test_aligned_constexpr<1>());
104 static_assert(test_aligned_constexpr<2>());
105 static_assert(test_aligned_constexpr<4>());
106 static_assert(test_aligned_constexpr<8>());
107 static_assert(test_aligned_constexpr<16>());
108 static_assert(test_aligned_constexpr<MaxAligned>());
109 static_assert(test_aligned_constexpr<OverAligned>());
110 static_assert(test_aligned_constexpr<OverAligned * 2>());
111#endif
112
113 return 0;
114}
115

source code of libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp