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