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