1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef SUPPORT_TEST_STD_MEMORY_RESOURCE_H
10 #define SUPPORT_TEST_STD_MEMORY_RESOURCE_H
13 #include <memory_resource>
14 #include <type_traits>
21 #include "test_macros.h"
22 #include "controlled_allocators.h"
23 #include "uses_alloc_types.h"
25 template <class ProviderT
, int = 0>
26 class TestResourceImp
: public std::pmr::memory_resource
{
28 static int resource_alive
;
29 static int resource_constructed
;
30 static int resource_destructed
;
32 static void resetStatics() {
33 assert(resource_alive
== 0);
35 resource_constructed
= 0;
36 resource_destructed
= 0;
39 using memory_resource
= std::pmr::memory_resource
;
40 using Provider
= ProviderT
;
44 explicit TestResourceImp(int val
= 0) : value(val
) {
46 ++resource_constructed
;
49 ~TestResourceImp() noexcept
{
51 ++resource_destructed
;
58 AllocController
& getController() { return C
; }
60 bool checkAlloc(void* p
, std::size_t s
, std::size_t a
) const { return C
.checkAlloc(p
, s
, a
); }
62 bool checkDealloc(void* p
, std::size_t s
, std::size_t a
) const { return C
.checkDealloc(p
, s
, a
); }
64 bool checkIsEqualCalledEq(int n
) const { return C
.checkIsEqualCalledEq(n
); }
67 virtual void* do_allocate(std::size_t s
, std::size_t a
) {
68 if (C
.throw_on_alloc
) {
69 #ifndef TEST_HAS_NO_EXCEPTIONS
70 throw TestException
{};
75 void* ret
= P
.allocate(s
, a
);
76 C
.countAlloc(ret
, s
, a
);
80 virtual void do_deallocate(void* p
, std::size_t s
, std::size_t a
) {
81 C
.countDealloc(p
, s
, a
);
82 P
.deallocate(p
, s
, a
);
85 virtual bool do_is_equal(memory_resource
const& other
) const noexcept
{
87 TestResourceImp
const* o
= dynamic_cast<TestResourceImp
const*>(&other
);
88 return o
&& o
->value
== value
;
92 mutable AllocController C
;
94 DISALLOW_COPY(TestResourceImp
);
97 template <class Provider
, int N
>
98 int TestResourceImp
<Provider
, N
>::resource_alive
= 0;
100 template <class Provider
, int N
>
101 int TestResourceImp
<Provider
, N
>::resource_constructed
= 0;
103 template <class Provider
, int N
>
104 int TestResourceImp
<Provider
, N
>::resource_destructed
= 0;
106 struct NullProvider
{
108 void* allocate(std::size_t, size_t) {
109 #ifndef TEST_HAS_NO_EXCEPTIONS
110 throw std::runtime_error("");
115 void deallocate(void*, std::size_t, size_t) {}
119 DISALLOW_COPY(NullProvider
);
122 struct NewDeleteProvider
{
123 NewDeleteProvider() {}
124 void* allocate(std::size_t s
, size_t) { return ::operator new(s
); }
125 void deallocate(void* p
, std::size_t, size_t) { ::operator delete(p
); }
129 DISALLOW_COPY(NewDeleteProvider
);
132 template <std::size_t Size
= 4096 * 10> // 10 pages worth of memory.
133 struct BufferProvider
{
135 void* next
= &buffer
;
136 std::size_t space
= Size
;
140 void* allocate(std::size_t s
, size_t a
) {
141 void* ret
= std::align(a
, s
, next
, space
);
142 if (ret
== nullptr) {
143 #ifndef TEST_HAS_NO_EXCEPTIONS
144 throw std::bad_alloc();
153 void deallocate(void*, std::size_t, size_t) {}
161 DISALLOW_COPY(BufferProvider
);
164 using NullResource
= TestResourceImp
<NullProvider
, 0>;
165 using NewDeleteResource
= TestResourceImp
<NewDeleteProvider
, 0>;
166 using TestResource
= TestResourceImp
<BufferProvider
<>, 0>;
167 using TestResource1
= TestResourceImp
<BufferProvider
<>, 1>;
168 using TestResource2
= TestResourceImp
<BufferProvider
<>, 2>;
170 #endif /* SUPPORT_TEST_STD_MEMORY_RESOURCE_H */