1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <experimental/memory_resource> 13 14 // template <class Alloc> class resource_adaptor_imp; 15 16 // void * do_allocate(size_t size, size_t align) 17 // void do_deallocate(void*, size_t, size_t) 18 19 20 #include <experimental/memory_resource> 21 #include <type_traits> 22 #include <memory> 23 #include <exception> 24 #include <cassert> 25 26 #include "test_macros.h" 27 #include "test_memory_resource.hpp" 28 29 namespace ex = std::experimental::pmr; 30 31 template <class Alloc> 32 void check_allocate_deallocate() 33 { 34 typedef ex::resource_adaptor<Alloc> R1; 35 const std::size_t max_align = alignof(std::max_align_t); 36 37 for (std::size_t s = 1; s < 5012; ++s) 38 { 39 for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2) 40 { 41 const std::size_t align_exp = align_req > max_align 42 ? max_align : align_req; 43 AllocController P; 44 R1 r{Alloc(P)}; 45 ex::memory_resource & m1 = r; 46 47 void * const ret = m1.allocate(s, align_req); 48 assert(P.alive == 1); 49 assert(P.alloc_count == 1); 50 assert(P.checkAllocAtLeast(ret, s, align_exp)); 51 52 assert(((std::size_t)ret % align_exp) == 0); 53 54 m1.deallocate(ret, s, align_req); 55 assert(P.alive == 0); 56 assert(P.dealloc_count == 1); 57 assert(P.checkDeallocMatchesAlloc()); 58 } 59 } 60 } 61 62 void check_alloc_max_size() { 63 using Alloc = NullAllocator<char>; 64 using R1 = ex::resource_adaptor<Alloc>; 65 const std::size_t max_align = alignof(std::max_align_t); 66 67 auto check = [=](std::size_t s, std::size_t align_req) { 68 const std::size_t align_exp = align_req > max_align 69 ? max_align : align_req; 70 AllocController P; 71 R1 r{Alloc(P)}; 72 ex::memory_resource & m1 = r; 73 74 void * const ret = m1.allocate(s, align_req); 75 assert(P.alive == 1); 76 assert(P.alloc_count == 1); 77 assert(P.checkAllocAtLeast(ret, s, align_exp)); 78 79 m1.deallocate(ret, s, align_req); 80 assert(P.alive == 0); 81 assert(P.dealloc_count == 1); 82 assert(P.checkDeallocMatchesAlloc()); 83 }; 84 85 const std::size_t sizeTypeMax = ~0; 86 const std::size_t testSizeStart = sizeTypeMax - (max_align * 3); 87 const std::size_t testSizeEnd = sizeTypeMax - max_align; 88 89 for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) { 90 for (std::size_t align=1; align <= (max_align * 2); align *= 2) { 91 check(size, align); 92 } 93 } 94 95 #ifndef TEST_HAS_NO_EXCEPTIONS 96 for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) { 97 AllocController P; 98 R1 r{Alloc(P)}; 99 ex::memory_resource & m1 = r; 100 101 try { 102 m1.allocate(size); 103 assert(false); 104 } catch (std::exception const&) { 105 } 106 } 107 #endif 108 } 109 110 int main() 111 { 112 check_allocate_deallocate<CountingAllocator<char>>(); 113 check_allocate_deallocate<MinAlignedAllocator<char>>(); 114 check_alloc_max_size(); 115 } 116