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
17using namespace boost::container::pmr;
18using namespace boost::container;
19
20void test_default_constructor()
21{
22 polymorphic_allocator<int> a;
23 BOOST_TEST(a.resource() == get_default_resource());
24}
25
26void test_resource_constructor()
27{
28 derived_from_memory_resource d;
29 polymorphic_allocator<int> b(&d);
30 BOOST_TEST(&d == b.resource());
31}
32
33void 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
41void 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
51void 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
66void 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
80void 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
146struct char_holder
147{
148 char m_char;
149 ~char_holder()
150 { destructor_called = true; }
151 static bool destructor_called;
152};
153
154bool char_holder::destructor_called = false;
155
156void 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
165void 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
175void test_resource()
176{
177 derived_from_memory_resource d;
178 polymorphic_allocator<int> p(&d);
179 BOOST_TEST(&d == p.resource());
180}
181
182int 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

source code of boost/libs/container/test/polymorphic_allocator_test.cpp