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 29namespace ex = std::experimental::pmr; 30 31template <size_t S, size_t Align> 32void 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 47template <size_t S> 48void 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 84int 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