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