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/detail/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
cxx11_allocator()25 cxx11_allocator()
26 {
27 }
28
cxx11_allocator(cxx11_allocator<Y> const &)29 template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
30 {
31 }
32
allocate(std::size_t n)33 T * allocate( std::size_t n )
34 {
35 return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
36 }
37
deallocate(T * p,std::size_t n)38 void deallocate( T * p, std::size_t n )
39 {
40 ::operator delete( p );
41 }
42
construct(T * p,Args &&...args)43 template<class... Args> void construct( T * p, Args&&... args )
44 {
45 ::new( static_cast< void* >( p ) ) T( std::forward<Args>( args )... );
46 }
47
destroy(T * p)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
operator new(std::size_t n)61 void * operator new( std::size_t n )
62 {
63 BOOST_ERROR( "private X::new called" );
64 return ::operator new( n );
65 }
66
operator delete(void * p)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
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)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
~X()86 ~X()
87 {
88 --instances;
89 }
90
91 friend class cxx11_allocator<X>;
92 };
93
94 int X::instances = 0;
95
main()96 int main()
97 {
98 BOOST_TEST( X::instances == 0 );
99
100 {
101 boost::shared_ptr< X > pi = boost::allocate_shared< X >( 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 >( cxx11_allocator<void>(), 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 >( cxx11_allocator<void>(), 1, 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 >( cxx11_allocator<void>(), 1, 2, 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 >( cxx11_allocator<void>(), 1, 2, 3, 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 >( cxx11_allocator<void>(), 1, 2, 3, 4, 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 >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 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 >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 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 >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 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 >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 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
main()235 int main()
236 {
237 return 0;
238 }
239
240 #endif
241