1 | // allocate_shared_construct11_test.cpp |
2 | // |
3 | // Test whether allocate_shared uses construct/destroy in C++11 |
4 | // |
5 | // Copyright 2007-2009, 2014 Peter Dimov |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. |
8 | // See accompanying file LICENSE_1_0.txt or copy at |
9 | // http://www.boost.org/LICENSE_1_0.txt |
10 | |
11 | #include <boost/core/lightweight_test.hpp> |
12 | #include <boost/make_shared.hpp> |
13 | #include <boost/shared_ptr.hpp> |
14 | #include <boost/weak_ptr.hpp> |
15 | #include <cstddef> |
16 | |
17 | #if !defined( BOOST_NO_CXX11_ALLOCATOR ) |
18 | |
19 | template< class T > class cxx11_allocator |
20 | { |
21 | public: |
22 | |
23 | typedef T value_type; |
24 | |
25 | cxx11_allocator() |
26 | { |
27 | } |
28 | |
29 | template< class Y > cxx11_allocator( cxx11_allocator<Y> const & ) |
30 | { |
31 | } |
32 | |
33 | T * allocate( std::size_t n ) |
34 | { |
35 | return static_cast< T* >( ::operator new( n * sizeof( T ) ) ); |
36 | } |
37 | |
38 | void deallocate( T * p, std::size_t n ) |
39 | { |
40 | ::operator delete( p ); |
41 | } |
42 | |
43 | template<class... Args> void construct( T * p, Args&&... args ) |
44 | { |
45 | ::new( static_cast< void* >( p ) ) T( std::forward<Args>( args )... ); |
46 | } |
47 | |
48 | void destroy( T * p ) |
49 | { |
50 | p->~T(); |
51 | } |
52 | }; |
53 | |
54 | class X |
55 | { |
56 | private: |
57 | |
58 | X( X const & ); |
59 | X & operator=( X const & ); |
60 | |
61 | void * operator new( std::size_t n ) |
62 | { |
63 | BOOST_ERROR( "private X::new called" ); |
64 | return ::operator new( n ); |
65 | } |
66 | |
67 | void operator delete( void * p ) |
68 | { |
69 | BOOST_ERROR( "private X::delete called" ); |
70 | ::operator delete( p ); |
71 | } |
72 | |
73 | public: |
74 | |
75 | static int instances; |
76 | |
77 | int v; |
78 | |
79 | protected: |
80 | |
81 | explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 ) |
82 | { |
83 | ++instances; |
84 | } |
85 | |
86 | ~X() |
87 | { |
88 | --instances; |
89 | } |
90 | |
91 | friend class cxx11_allocator<X>; |
92 | }; |
93 | |
94 | int X::instances = 0; |
95 | |
96 | int main() |
97 | { |
98 | BOOST_TEST( X::instances == 0 ); |
99 | |
100 | { |
101 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>() ); |
102 | boost::weak_ptr<X> wp( pi ); |
103 | |
104 | BOOST_TEST( X::instances == 1 ); |
105 | BOOST_TEST( pi.get() != 0 ); |
106 | BOOST_TEST( pi->v == 0 ); |
107 | |
108 | pi.reset(); |
109 | |
110 | BOOST_TEST( X::instances == 0 ); |
111 | } |
112 | |
113 | { |
114 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1 ); |
115 | boost::weak_ptr<X> wp( pi ); |
116 | |
117 | BOOST_TEST( X::instances == 1 ); |
118 | BOOST_TEST( pi.get() != 0 ); |
119 | BOOST_TEST( pi->v == 1 ); |
120 | |
121 | pi.reset(); |
122 | |
123 | BOOST_TEST( X::instances == 0 ); |
124 | } |
125 | |
126 | { |
127 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2 ); |
128 | boost::weak_ptr<X> wp( pi ); |
129 | |
130 | BOOST_TEST( X::instances == 1 ); |
131 | BOOST_TEST( pi.get() != 0 ); |
132 | BOOST_TEST( pi->v == 1+2 ); |
133 | |
134 | pi.reset(); |
135 | |
136 | BOOST_TEST( X::instances == 0 ); |
137 | } |
138 | |
139 | { |
140 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3 ); |
141 | boost::weak_ptr<X> wp( pi ); |
142 | |
143 | BOOST_TEST( X::instances == 1 ); |
144 | BOOST_TEST( pi.get() != 0 ); |
145 | BOOST_TEST( pi->v == 1+2+3 ); |
146 | |
147 | pi.reset(); |
148 | |
149 | BOOST_TEST( X::instances == 0 ); |
150 | } |
151 | |
152 | { |
153 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4 ); |
154 | boost::weak_ptr<X> wp( pi ); |
155 | |
156 | BOOST_TEST( X::instances == 1 ); |
157 | BOOST_TEST( pi.get() != 0 ); |
158 | BOOST_TEST( pi->v == 1+2+3+4 ); |
159 | |
160 | pi.reset(); |
161 | |
162 | BOOST_TEST( X::instances == 0 ); |
163 | } |
164 | |
165 | { |
166 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4, args: 5 ); |
167 | boost::weak_ptr<X> wp( pi ); |
168 | |
169 | BOOST_TEST( X::instances == 1 ); |
170 | BOOST_TEST( pi.get() != 0 ); |
171 | BOOST_TEST( pi->v == 1+2+3+4+5 ); |
172 | |
173 | pi.reset(); |
174 | |
175 | BOOST_TEST( X::instances == 0 ); |
176 | } |
177 | |
178 | { |
179 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4, args: 5, args: 6 ); |
180 | boost::weak_ptr<X> wp( pi ); |
181 | |
182 | BOOST_TEST( X::instances == 1 ); |
183 | BOOST_TEST( pi.get() != 0 ); |
184 | BOOST_TEST( pi->v == 1+2+3+4+5+6 ); |
185 | |
186 | pi.reset(); |
187 | |
188 | BOOST_TEST( X::instances == 0 ); |
189 | } |
190 | |
191 | { |
192 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4, args: 5, args: 6, args: 7 ); |
193 | boost::weak_ptr<X> wp( pi ); |
194 | |
195 | BOOST_TEST( X::instances == 1 ); |
196 | BOOST_TEST( pi.get() != 0 ); |
197 | BOOST_TEST( pi->v == 1+2+3+4+5+6+7 ); |
198 | |
199 | pi.reset(); |
200 | |
201 | BOOST_TEST( X::instances == 0 ); |
202 | } |
203 | |
204 | { |
205 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4, args: 5, args: 6, args: 7, args: 8 ); |
206 | boost::weak_ptr<X> wp( pi ); |
207 | |
208 | BOOST_TEST( X::instances == 1 ); |
209 | BOOST_TEST( pi.get() != 0 ); |
210 | BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 ); |
211 | |
212 | pi.reset(); |
213 | |
214 | BOOST_TEST( X::instances == 0 ); |
215 | } |
216 | |
217 | { |
218 | boost::shared_ptr< X > pi = boost::allocate_shared< X >( a: cxx11_allocator<void>(), args: 1, args: 2, args: 3, args: 4, args: 5, args: 6, args: 7, args: 8, args: 9 ); |
219 | boost::weak_ptr<X> wp( pi ); |
220 | |
221 | BOOST_TEST( X::instances == 1 ); |
222 | BOOST_TEST( pi.get() != 0 ); |
223 | BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 ); |
224 | |
225 | pi.reset(); |
226 | |
227 | BOOST_TEST( X::instances == 0 ); |
228 | } |
229 | |
230 | return boost::report_errors(); |
231 | } |
232 | |
233 | #else // !defined( BOOST_NO_CXX11_ALLOCATOR ) |
234 | |
235 | int main() |
236 | { |
237 | return 0; |
238 | } |
239 | |
240 | #endif |
241 | |