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// <scoped_allocator> 13 14// template <class OtherAlloc, class ...InnerAlloc> 15// class scoped_allocator_adaptor 16 17// template <class T, class ...Args> 18// void scoped_allocator_adaptor::construct(T*, Args&&...) 19 20#include <scoped_allocator> 21#include <type_traits> 22#include <utility> 23#include <tuple> 24#include <cassert> 25#include <cstdlib> 26#include "uses_alloc_types.hpp" 27#include "controlled_allocators.hpp" 28 29// - If uses_allocator_v<T, inner_allocator_type> is false and 30// is_constructible_v<T, Args...> is true, calls 31// OUTERMOST_ALLOC_TRAITS(*this)::construct( 32// OUTERMOST (*this), p, std::forward<Args>(args)...). 33void test_bullet_one() { 34 using VoidAlloc2 = CountingAllocator<void, 2>; 35 36 AllocController POuter; 37 AllocController PInner; 38 { 39 using T = NotUsesAllocator<VoidAlloc2, 3>; 40 using Outer = CountingAllocator<T, 1>; 41 using Inner = CountingAllocator<T, 2>; 42 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 43 static_assert(!std::uses_allocator<T, Outer>::value, ""); 44 static_assert(!std::uses_allocator<T, Inner>::value, ""); 45 T* ptr = (T*)::operator new(sizeof(T)); 46 Outer O(POuter); 47 Inner I(PInner); 48 SA A(O, I); 49 int x = 42; 50 int const& cx = x; 51 A.construct(ptr, x, cx, std::move(x)); 52 assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_None))); 53 assert((POuter.checkConstruct<int&, int const&, int&&>(O, ptr))); 54 A.destroy(ptr); 55 ::operator delete((void*)ptr); 56 } 57 PInner.reset(); 58 POuter.reset(); 59} 60 61 62// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and 63// is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is 64// true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p, 65// allocator_arg, inner_allocator(), std::forward<Args>(args)...). 66void test_bullet_two() { 67 using VoidAlloc2 = CountingAllocator<void, 2>; 68 69 AllocController POuter; 70 AllocController PInner; 71 { 72 using T = UsesAllocatorV1<VoidAlloc2, 3>; 73 using Outer = CountingAllocator<T, 1>; 74 using Inner = CountingAllocator<T, 2>; 75 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 76 static_assert(!std::uses_allocator<T, Outer>::value, ""); 77 static_assert(std::uses_allocator<T, Inner>::value, ""); 78 T* ptr = (T*)::operator new(sizeof(T)); 79 Outer O(POuter); 80 Inner I(PInner); 81 SA A(O, I); 82 int x = 42; 83 int const& cx = x; 84 A.construct(ptr, x, cx, std::move(x)); 85 assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I))); 86 assert((POuter.checkConstruct<std::allocator_arg_t const&, 87 SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr))); 88 A.destroy(ptr); 89 ::operator delete((void*)ptr); 90 } 91 PInner.reset(); 92 POuter.reset(); 93} 94 95// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and 96// is_constructible_v<T, Args..., inner_allocator_type&> is true, calls 97// OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p, 98// std::forward<Args>(args)..., inner_allocator()). 99void test_bullet_three() { 100 using VoidAlloc2 = CountingAllocator<void, 2>; 101 102 AllocController POuter; 103 AllocController PInner; 104 { 105 using T = UsesAllocatorV2<VoidAlloc2, 3>; 106 using Outer = CountingAllocator<T, 1>; 107 using Inner = CountingAllocator<T, 2>; 108 using SA = std::scoped_allocator_adaptor<Outer, Inner>; 109 static_assert(!std::uses_allocator<T, Outer>::value, ""); 110 static_assert(std::uses_allocator<T, Inner>::value, ""); 111 T* ptr = (T*)::operator new(sizeof(T)); 112 Outer O(POuter); 113 Inner I(PInner); 114 SA A(O, I); 115 int x = 42; 116 int const& cx = x; 117 A.construct(ptr, x, cx, std::move(x)); 118 assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I))); 119 assert((POuter.checkConstruct< 120 int&, int const&, int&&, 121 SA::inner_allocator_type&>(O, ptr))); 122 A.destroy(ptr); 123 ::operator delete((void*)ptr); 124 } 125 PInner.reset(); 126 POuter.reset(); 127} 128 129int main() { 130 test_bullet_one(); 131 test_bullet_two(); 132 test_bullet_three(); 133} 134