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 // REQUIRES: c++experimental 11 // UNSUPPORTED: c++98, c++03 12 13 // <experimental/memory_resource> 14 15 // template <class T> class polymorphic_allocator 16 17 // T* polymorphic_allocator<T>::allocate(size_t n) 18 19 #include <experimental/memory_resource> 20 #include <limits> 21 #include <memory> 22 #include <exception> 23 #include <type_traits> 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 <size_t S, size_t Align> 32 void testForSizeAndAlign() { 33 using T = typename std::aligned_storage<S, Align>::type; 34 TestResource R; 35 ex::polymorphic_allocator<T> a(&R); 36 37 for (int N = 1; N <= 5; ++N) { 38 auto ret = a.allocate(N); 39 assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); 40 41 a.deallocate(ret, N); 42 R.reset(); 43 } 44 } 45 46 #ifndef TEST_HAS_NO_EXCEPTIONS 47 template <size_t S> 48 void testAllocForSizeThrows() { 49 using T = typename std::aligned_storage<S>::type; 50 using Alloc = ex::polymorphic_allocator<T>; 51 using Traits = std::allocator_traits<Alloc>; 52 NullResource R; 53 Alloc a(&R); 54 55 // Test that allocating exactly the max size does not throw. 56 size_t maxSize = Traits::max_size(a); 57 try { 58 a.allocate(maxSize); 59 } catch (...) { 60 assert(false); 61 } 62 63 size_t sizeTypeMax = std::numeric_limits<std::size_t>::max(); 64 if (maxSize != sizeTypeMax) 65 { 66 // Test that allocating size_t(~0) throws bad alloc. 67 try { 68 a.allocate(sizeTypeMax); 69 assert(false); 70 } catch (std::exception const&) { 71 } 72 73 // Test that allocating even one more than the max size does throw. 74 size_t overSize = maxSize + 1; 75 try { 76 a.allocate(overSize); 77 assert(false); 78 } catch (std::exception const&) { 79 } 80 } 81 } 82 #endif // TEST_HAS_NO_EXCEPTIONS 83 84 int main() 85 { 86 { 87 ex::polymorphic_allocator<int> a; 88 static_assert(std::is_same<decltype(a.allocate(0)), int*>::value, ""); 89 static_assert(!noexcept(a.allocate(0)), ""); 90 } 91 { 92 constexpr std::size_t MA = alignof(std::max_align_t); 93 testForSizeAndAlign<1, 1>(); 94 testForSizeAndAlign<1, 2>(); 95 testForSizeAndAlign<1, MA>(); 96 testForSizeAndAlign<2, 2>(); 97 testForSizeAndAlign<73, alignof(void*)>(); 98 testForSizeAndAlign<73, MA>(); 99 testForSizeAndAlign<13, MA>(); 100 } 101 #ifndef TEST_HAS_NO_EXCEPTIONS 102 { 103 testAllocForSizeThrows<1>(); 104 testAllocForSizeThrows<2>(); 105 testAllocForSizeThrows<4>(); 106 testAllocForSizeThrows<8>(); 107 testAllocForSizeThrows<16>(); 108 testAllocForSizeThrows<73>(); 109 testAllocForSizeThrows<13>(); 110 } 111 #endif 112 } 113