1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/container for documentation. |
8 | // |
9 | ////////////////////////////////////////////////////////////////////////////// |
10 | #include <boost/container/pmr/polymorphic_allocator.hpp> |
11 | #include <boost/container/pmr/global_resource.hpp> |
12 | #include <boost/core/lightweight_test.hpp> |
13 | |
14 | #include "derived_from_memory_resource.hpp" |
15 | #include "propagation_test_allocator.hpp" |
16 | |
17 | using namespace boost::container::pmr; |
18 | using namespace boost::container; |
19 | |
20 | void test_default_constructor() |
21 | { |
22 | polymorphic_allocator<int> a; |
23 | BOOST_TEST(a.resource() == get_default_resource()); |
24 | } |
25 | |
26 | void test_resource_constructor() |
27 | { |
28 | derived_from_memory_resource d; |
29 | polymorphic_allocator<int> b(&d); |
30 | BOOST_TEST(&d == b.resource()); |
31 | } |
32 | |
33 | void test_copy_constructor() |
34 | { |
35 | derived_from_memory_resource d; |
36 | polymorphic_allocator<int> b(&d); |
37 | polymorphic_allocator<int> c(b); |
38 | BOOST_TEST(b.resource() == c.resource()); |
39 | } |
40 | |
41 | void test_copy_assignment() |
42 | { |
43 | derived_from_memory_resource d; |
44 | polymorphic_allocator<int> b(&d); |
45 | polymorphic_allocator<int> c; |
46 | BOOST_TEST(c.resource() == get_default_resource()); |
47 | c = b; |
48 | BOOST_TEST(c.resource() == b.resource()); |
49 | } |
50 | |
51 | void test_allocate() |
52 | { |
53 | int dummy; |
54 | derived_from_memory_resource d; |
55 | polymorphic_allocator<int> p(&d); |
56 | d.reset(); |
57 | d.do_allocate_return = &dummy; |
58 | p.allocate(n: 2); |
59 | BOOST_TEST(d.do_allocate_called == true); |
60 | BOOST_TEST(d.do_allocate_return == &dummy); |
61 | //It shall allocate 2*sizeof(int), alignment_of<int> |
62 | BOOST_TEST(d.do_allocate_bytes == 2*sizeof(int)); |
63 | BOOST_TEST(d.do_allocate_alignment == dtl::alignment_of<int>::value); |
64 | } |
65 | |
66 | void test_deallocate() |
67 | { |
68 | int dummy; |
69 | derived_from_memory_resource d; |
70 | polymorphic_allocator<int> p(&d); |
71 | d.reset(); |
72 | p.deallocate(p: &dummy, n: 3); |
73 | BOOST_TEST(d.do_deallocate_called == true); |
74 | //It shall deallocate 2*sizeof(int), alignment_of<int> |
75 | BOOST_TEST(d.do_deallocate_p == &dummy); |
76 | BOOST_TEST(d.do_deallocate_bytes == 3*sizeof(int)); |
77 | BOOST_TEST(d.do_deallocate_alignment == dtl::alignment_of<int>::value); |
78 | } |
79 | |
80 | void test_construct() |
81 | { |
82 | //0 arg |
83 | { |
84 | typedef allocator_argument_tester<NotUsesAllocator, 0> value_type; |
85 | value_type value; |
86 | value.~value_type(); |
87 | polymorphic_allocator<int> pa; |
88 | pa.construct(p: &value); |
89 | BOOST_TEST(value.construction_type == NotUsesAllocator); |
90 | BOOST_TEST(value.value == 0); |
91 | value.~value_type(); |
92 | } |
93 | { |
94 | typedef allocator_argument_tester<ErasedTypePrefix, 0> value_type; |
95 | value_type value; |
96 | value.~value_type(); |
97 | polymorphic_allocator<int> pa; |
98 | pa.construct(p: &value); |
99 | BOOST_TEST(value.construction_type == ConstructiblePrefix); |
100 | BOOST_TEST(value.value == 0); |
101 | value.~value_type(); |
102 | } |
103 | { |
104 | typedef allocator_argument_tester<ErasedTypeSuffix, 0> value_type; |
105 | value_type value; |
106 | value.~value_type(); |
107 | polymorphic_allocator<int> pa; |
108 | pa.construct(p: &value); |
109 | BOOST_TEST(value.construction_type == ConstructibleSuffix); |
110 | BOOST_TEST(value.value == 0); |
111 | value.~value_type(); |
112 | } |
113 | //1 arg |
114 | { |
115 | typedef allocator_argument_tester<NotUsesAllocator, 0> value_type; |
116 | value_type value; |
117 | value.~value_type(); |
118 | polymorphic_allocator<int> pa; |
119 | pa.construct(p: &value, args: 2); |
120 | BOOST_TEST(value.construction_type == NotUsesAllocator); |
121 | BOOST_TEST(value.value == 2); |
122 | value.~value_type(); |
123 | } |
124 | { |
125 | typedef allocator_argument_tester<ErasedTypePrefix, 0> value_type; |
126 | value_type value; |
127 | value.~value_type(); |
128 | polymorphic_allocator<int> pa; |
129 | pa.construct(p: &value, args: 3); |
130 | BOOST_TEST(value.construction_type == ConstructiblePrefix); |
131 | BOOST_TEST(value.value == 3); |
132 | value.~value_type(); |
133 | } |
134 | { |
135 | typedef allocator_argument_tester<ErasedTypeSuffix, 0> value_type; |
136 | value_type value; |
137 | value.~value_type(); |
138 | polymorphic_allocator<int> pa; |
139 | pa.construct(p: &value, args: 4); |
140 | BOOST_TEST(value.construction_type == ConstructibleSuffix); |
141 | BOOST_TEST(value.value == 4); |
142 | value.~value_type(); |
143 | } |
144 | } |
145 | |
146 | struct char_holder |
147 | { |
148 | char m_char; |
149 | ~char_holder() |
150 | { destructor_called = true; } |
151 | static bool destructor_called; |
152 | }; |
153 | |
154 | bool char_holder::destructor_called = false; |
155 | |
156 | void test_destroy() |
157 | { |
158 | char_holder ch; |
159 | polymorphic_allocator<int> p; |
160 | BOOST_TEST(char_holder::destructor_called == false); |
161 | p.destroy(p: &ch); |
162 | BOOST_TEST(char_holder::destructor_called == true); |
163 | } |
164 | |
165 | void test_select_on_container_copy_construction() |
166 | { |
167 | //select_on_container_copy_construction shall return |
168 | //a default constructed polymorphic_allocator |
169 | //which uses the default resource. |
170 | derived_from_memory_resource d; |
171 | polymorphic_allocator<int> p(&d); |
172 | BOOST_TEST(get_default_resource() == p.select_on_container_copy_construction().resource()); |
173 | } |
174 | |
175 | void test_resource() |
176 | { |
177 | derived_from_memory_resource d; |
178 | polymorphic_allocator<int> p(&d); |
179 | BOOST_TEST(&d == p.resource()); |
180 | } |
181 | |
182 | int main() |
183 | { |
184 | test_default_constructor(); |
185 | test_resource_constructor(); |
186 | test_copy_constructor(); |
187 | test_copy_assignment(); |
188 | test_allocate(); |
189 | test_deallocate(); |
190 | test_construct(); |
191 | test_destroy(); |
192 | test_select_on_container_copy_construction(); |
193 | test_resource(); |
194 | return ::boost::report_errors(); |
195 | } |
196 | |