1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
10 #include <boost/container/pmr/resource_adaptor.hpp>
11 #include <boost/core/lightweight_test.hpp>
12 #include "propagation_test_allocator.hpp"
13 #include "derived_from_memory_resource.hpp"
14 #include <boost/container/new_allocator.hpp>
17 using namespace boost::container::pmr
;
19 static const std::size_t max_alignment_value
= boost::move_detail::alignment_of
<boost::move_detail::max_align_t
>::value
;
21 void test_default_constructor()
23 typedef propagation_test_allocator
<char, 0> alloc_t
;
24 resource_adaptor
<alloc_t
> ra
;
25 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
28 void test_copy_constructor()
30 typedef propagation_test_allocator
<char, 0> alloc_t
;
31 resource_adaptor
<alloc_t
> ra
;
32 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
33 resource_adaptor
<alloc_t
> rb(ra
);
34 BOOST_TEST(rb
.get_allocator().m_default_contructed
== false);
35 BOOST_TEST(rb
.get_allocator().m_move_contructed
== false);
38 void test_move_constructor()
40 typedef propagation_test_allocator
<char, 0> alloc_t
;
41 resource_adaptor
<alloc_t
> ra
;
42 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
43 resource_adaptor
<alloc_t
> rb(::boost::move(ra
));
44 BOOST_TEST(rb
.get_allocator().m_default_contructed
== false);
45 BOOST_TEST(rb
.get_allocator().m_move_contructed
== true);
48 void test_lvalue_alloc_constructor()
50 typedef propagation_test_allocator
<char, 0> alloc_t
;
52 resource_adaptor
<alloc_t
> ra(a
);
53 BOOST_TEST(ra
.get_allocator().m_default_contructed
== false);
54 BOOST_TEST(ra
.get_allocator().m_move_contructed
== false);
57 void test_rvalue_alloc_constructor()
59 typedef propagation_test_allocator
<char, 0> alloc_t
;
61 resource_adaptor
<alloc_t
> ra(::boost::move(a
));
62 BOOST_TEST(ra
.get_allocator().m_default_contructed
== false);
63 BOOST_TEST(ra
.get_allocator().m_move_contructed
== true);
66 void test_copy_assign()
68 typedef propagation_test_allocator
<char, 0> alloc_t
;
69 resource_adaptor
<alloc_t
> ra
;
70 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
71 resource_adaptor
<alloc_t
> rb
;
72 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
74 BOOST_TEST(rb
.get_allocator().m_move_contructed
== false);
75 BOOST_TEST(rb
.get_allocator().m_move_assigned
== false);
78 void test_move_assign()
80 typedef propagation_test_allocator
<char, 0> alloc_t
;
81 resource_adaptor
<alloc_t
> ra
;
82 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
83 resource_adaptor
<alloc_t
> rb
;
84 BOOST_TEST(ra
.get_allocator().m_default_contructed
== true);
85 rb
= ::boost::move(ra
);
86 BOOST_TEST(rb
.get_allocator().m_move_contructed
== false);
87 BOOST_TEST(rb
.get_allocator().m_move_assigned
== true);
93 typedef char value_type
;
97 { typedef stateful other
; };
103 char *allocate(std::size_t n
)
104 { allocate_size
= n
; return allocate_return
; }
106 void deallocate(char *p
, std::size_t n
)
107 { deallocate_p
= p
; deallocate_size
= n
; }
109 friend bool operator==(const stateful
&l
, const stateful
&r
)
110 { return l
.m_u
== r
.m_u
; }
112 friend bool operator!=(const stateful
&l
, const stateful
&r
)
113 { return l
.m_u
!= r
.m_u
; }
117 std::size_t allocate_size
;
118 char *allocate_return
;
119 std::size_t deallocate_size
;
123 void test_get_allocator()
127 resource_adaptor
<stateful
> ra(a
);
128 const resource_adaptor
<stateful
> & cra
= ra
;
129 BOOST_TEST( ra
.get_allocator().m_u
== 999);
130 BOOST_TEST(cra
.get_allocator().m_u
== 999);
133 typedef resource_adaptor
<stateful
> stateful_resource_adaptor_t
;
135 struct derived_from_resource_adaptor_stateful
136 : public stateful_resource_adaptor_t
139 typedef stateful_resource_adaptor_t base_t
;
140 using base_t::do_allocate
;
141 using base_t::do_deallocate
;
142 using base_t::do_is_equal
;
145 void test_do_allocate_deallocate()
148 derived_from_resource_adaptor_stateful dra
;
150 dra
.get_allocator().allocate_return
= &dummy
;
151 void *allocate_ret
= dra
.do_allocate(998, 1);
152 BOOST_TEST(allocate_ret
== &dummy
);
153 BOOST_TEST(dra
.get_allocator().allocate_size
== 998);
156 derived_from_resource_adaptor_stateful dra
;
158 dra
.do_deallocate(&dummy
, 1234, 1);
159 BOOST_TEST(dra
.get_allocator().deallocate_p
== &dummy
);
160 BOOST_TEST(dra
.get_allocator().deallocate_size
== 1234);
163 //Overaligned allocation
164 derived_from_resource_adaptor_stateful dra
;
165 const std::size_t alignment
= max_alignment_value
*2u;
166 const std::size_t bytes
= alignment
/2;
167 char dummy
[alignment
*2u+sizeof(void*)];
168 dra
.get_allocator().allocate_return
= dummy
;
171 void *allocate_ret
= dra
.do_allocate(bytes
, alignment
);
172 BOOST_TEST( (char*)allocate_ret
>= (dummy
+sizeof(void*)) && (char*)allocate_ret
< (dummy
+ sizeof(dummy
)) );
173 BOOST_TEST( (std::size_t(allocate_ret
) & (alignment
- 1u)) == 0 );
174 BOOST_TEST( dra
.get_allocator().allocate_size
>= (alignment
/2+sizeof(void*)) );
177 dra
.do_deallocate(allocate_ret
, bytes
, alignment
);
178 BOOST_TEST(dra
.get_allocator().deallocate_p
== dummy
);
179 BOOST_TEST(dra
.get_allocator().deallocate_size
== dra
.get_allocator().allocate_size
);
182 typedef resource_adaptor
< boost::container::new_allocator
<int> > new_resource_alloc_t
;
183 new_resource_alloc_t ra
;
184 boost::container::pmr::memory_resource
&mr
= ra
;
186 //new_allocator, low alignment
187 mr
.deallocate(mr
.allocate(16, 1), 16, 1);
189 //new_allocator, high alignment
190 mr
.deallocate(mr
.allocate(16, max_alignment_value
*4u), 16, max_alignment_value
*4u);
193 typedef resource_adaptor
<std ::allocator
<int> > new_resource_alloc_t
;
194 new_resource_alloc_t ra
;
195 boost::container::pmr::memory_resource
&mr
= ra
;
197 //std::allocator, low alignment
198 mr
.deallocate(mr
.allocate(16, 1), 16, 1);
200 //std::allocator, high alignment
201 mr
.deallocate(mr
.allocate(16, max_alignment_value
*4u), 16, max_alignment_value
*4u);
205 void test_do_is_equal()
207 derived_from_resource_adaptor_stateful dra
;
208 derived_from_memory_resource dmr
;
209 //Different dynamic type must return false
210 BOOST_TEST(dra
.do_is_equal(dmr
) == false);
212 //Same dynamic type with same state must return true
213 derived_from_resource_adaptor_stateful dra2
;
214 BOOST_TEST(dra
.do_is_equal(dra2
) == true);
216 //Same dynamic type with different state must return false
217 dra2
.get_allocator().m_u
= 1234;
218 BOOST_TEST(dra
.do_is_equal(dra2
) == false);
223 test_default_constructor();
224 test_copy_constructor();
225 test_move_constructor();
226 test_lvalue_alloc_constructor();
227 test_rvalue_alloc_constructor();
230 test_get_allocator();
231 test_do_allocate_deallocate();
233 return ::boost::report_errors();