blob: 71421464df2bd7a818478586e5cf56c875ec5d7f [file] [log] [blame]
Eric Fiselierff624752016-12-14 21:29:29 +00001//===----------------------------------------------------------------------===//
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
Stephan T. Lavavej851ea6e2017-12-13 00:51:31 +000029// - If uses_allocator_v<T, inner_allocator_type> is false and
Eric Fiselierff624752016-12-14 21:29:29 +000030// 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() {
Eric Fiselierff624752016-12-14 21:29:29 +000034 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>;
Eric Fiselierff624752016-12-14 21:29:29 +000043 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() {
Eric Fiselierff624752016-12-14 21:29:29 +000067 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>;
Eric Fiselierff624752016-12-14 21:29:29 +000076 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() {
Eric Fiselierff624752016-12-14 21:29:29 +0000100 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>;
Eric Fiselierff624752016-12-14 21:29:29 +0000109 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}