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

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