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++98, c++03
10 
11 // <experimental/memory_resource>
12 
13 // template <class Alloc> class resource_adaptor_imp;
14 
15 // void * do_allocate(size_t size, size_t align)
16 // void   do_deallocate(void*, size_t, size_t)
17 
18 // When back-deploying to macosx10.7, the RTTI for exception classes
19 // incorrectly provided by libc++.dylib is mixed with the one in
20 // libc++abi.dylib and exceptions are not caught properly.
21 // XFAIL: with_system_cxx_lib=macosx10.7
22 
23 #include <experimental/memory_resource>
24 #include <type_traits>
25 #include <memory>
26 #include <exception>
27 #include <cassert>
28 
29 #include "test_macros.h"
30 #include "test_memory_resource.h"
31 
32 namespace ex = std::experimental::pmr;
33 
34 template <class Alloc>
check_allocate_deallocate()35 void check_allocate_deallocate()
36 {
37     typedef ex::resource_adaptor<Alloc> R1;
38     const std::size_t max_align = alignof(std::max_align_t);
39 
40     for (std::size_t s = 1; s < 5012; ++s)
41     {
42         for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2)
43         {
44             const std::size_t align_exp = align_req > max_align
45                                                     ? max_align : align_req;
46             AllocController P;
47             R1 r{Alloc(P)};
48             ex::memory_resource & m1 = r;
49 
50             void * const ret = m1.allocate(s, align_req);
51             assert(P.alive == 1);
52             assert(P.alloc_count == 1);
53             assert(P.checkAllocAtLeast(ret, s, align_exp));
54 
55             assert(((std::size_t)ret % align_exp) == 0);
56 
57             m1.deallocate(ret, s, align_req);
58             assert(P.alive == 0);
59             assert(P.dealloc_count == 1);
60             assert(P.checkDeallocMatchesAlloc());
61         }
62     }
63 }
64 
check_alloc_max_size()65 void check_alloc_max_size() {
66     using Alloc = NullAllocator<char>;
67     using R1 = ex::resource_adaptor<Alloc>;
68     const std::size_t max_align = alignof(std::max_align_t);
69 
70     auto check = [=](std::size_t s, std::size_t align_req) {
71         const std::size_t align_exp = align_req > max_align
72                                                 ? max_align : align_req;
73         AllocController P;
74         R1 r{Alloc(P)};
75         ex::memory_resource & m1 = r;
76 
77         void * const ret = m1.allocate(s, align_req);
78         assert(P.alive == 1);
79         assert(P.alloc_count == 1);
80         assert(P.checkAllocAtLeast(ret, s, align_exp));
81 
82         m1.deallocate(ret, s, align_req);
83         assert(P.alive == 0);
84         assert(P.dealloc_count == 1);
85         assert(P.checkDeallocMatchesAlloc());
86     };
87 
88     const std::size_t sizeTypeMax = ~0;
89     const std::size_t testSizeStart = sizeTypeMax - (max_align * 3);
90     const std::size_t testSizeEnd = sizeTypeMax - max_align;
91 
92     for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) {
93         for (std::size_t align=1; align <= (max_align * 2); align *= 2) {
94             check(size, align);
95         }
96     }
97 
98 #ifndef TEST_HAS_NO_EXCEPTIONS
99     for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) {
100         AllocController P;
101         R1 r{Alloc(P)};
102         ex::memory_resource & m1 = r;
103 
104         try {
105             m1.allocate(size);
106             assert(false);
107         } catch (std::exception const&) {
108         }
109     }
110 #endif
111 }
112 
main(int,char **)113 int main(int, char**)
114 {
115     check_allocate_deallocate<CountingAllocator<char>>();
116     check_allocate_deallocate<MinAlignedAllocator<char>>();
117     check_alloc_max_size();
118 
119   return 0;
120 }
121