]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <boost/config.hpp> |
2 | ||
3 | // shared_ptr_alloc2_test.cpp | |
4 | // | |
5 | // Copyright (c) 2005 Peter Dimov | |
6 | // | |
7 | // Distributed under the Boost Software License, Version 1.0. (See | |
8 | // accompanying file LICENSE_1_0.txt or copy at | |
9 | // http://www.boost.org/LICENSE_1_0.txt) | |
10 | ||
11 | ||
f67539c2 | 12 | #include <boost/core/lightweight_test.hpp> |
7c673cae FG |
13 | #include <boost/shared_ptr.hpp> |
14 | #include <memory> | |
15 | #include <cstddef> | |
16 | ||
17 | // test_allocator | |
18 | ||
19 | struct test_allocator_base | |
20 | { | |
21 | int id_; | |
22 | ||
23 | static int last_global_id_; | |
24 | static int count_; | |
25 | ||
26 | explicit test_allocator_base( int id ): id_( id ) | |
27 | { | |
28 | } | |
29 | }; | |
30 | ||
31 | int test_allocator_base::last_global_id_ = 0; | |
32 | int test_allocator_base::count_ = 0; | |
33 | ||
34 | template<class T> class test_allocator: public test_allocator_base | |
35 | { | |
36 | public: | |
37 | ||
38 | typedef T * pointer; | |
39 | typedef T const * const_pointer; | |
40 | typedef T & reference; | |
41 | typedef T const & const_reference; | |
42 | typedef T value_type; | |
43 | typedef std::size_t size_type; | |
44 | typedef std::ptrdiff_t difference_type; | |
45 | ||
46 | private: | |
47 | ||
48 | static T * last_pointer_; | |
49 | static std::size_t last_n_; | |
50 | static int last_id_; | |
51 | ||
52 | public: | |
53 | ||
54 | template<class U> struct rebind | |
55 | { | |
56 | typedef test_allocator<U> other; | |
57 | }; | |
58 | ||
59 | pointer address( reference r ) const | |
60 | { | |
61 | return &r; | |
62 | } | |
63 | ||
64 | const_pointer address( const_reference s ) const | |
65 | { | |
66 | return &s; | |
67 | } | |
68 | ||
69 | explicit test_allocator( int id = 0 ): test_allocator_base( id ) | |
70 | { | |
71 | } | |
72 | ||
73 | template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r ) | |
74 | { | |
75 | } | |
76 | ||
77 | template<class U> test_allocator & operator=( test_allocator<U> const & r ) | |
78 | { | |
79 | test_allocator_base::operator=( r ); | |
80 | return *this; | |
81 | } | |
82 | ||
83 | void deallocate( pointer p, size_type n ) | |
84 | { | |
85 | BOOST_TEST( p == last_pointer_ ); | |
86 | BOOST_TEST( n == last_n_ ); | |
87 | BOOST_TEST( id_ == last_id_ ); | |
88 | ||
89 | --count_; | |
90 | ||
91 | ::operator delete( p ); | |
92 | } | |
93 | ||
94 | pointer allocate( size_type n, void const * = 0 ) | |
95 | { | |
96 | T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) ); | |
97 | ||
98 | last_pointer_ = p; | |
99 | last_n_ = n; | |
100 | last_id_ = id_; | |
101 | ||
102 | last_global_id_ = id_; | |
103 | ++count_; | |
104 | ||
105 | return p; | |
106 | } | |
107 | ||
108 | void construct( pointer p, T const & t ) | |
109 | { | |
110 | ::new( p ) T( t ); | |
111 | } | |
112 | ||
113 | void destroy( pointer p ) | |
114 | { | |
115 | p->~T(); | |
116 | } | |
117 | ||
118 | size_type max_size() const | |
119 | { | |
120 | return size_type( -1 ) / sizeof( T ); | |
121 | } | |
122 | }; | |
123 | ||
124 | template<class T> T * test_allocator<T>::last_pointer_ = 0; | |
125 | template<class T> std::size_t test_allocator<T>::last_n_ = 0; | |
126 | template<class T> int test_allocator<T>::last_id_ = 0; | |
127 | ||
128 | template<class T, class U> inline bool operator==( test_allocator<T> const & a1, test_allocator<U> const & a2 ) | |
129 | { | |
130 | return a1.id_ == a2.id_; | |
131 | } | |
132 | ||
133 | template<class T, class U> inline bool operator!=( test_allocator<T> const & a1, test_allocator<U> const & a2 ) | |
134 | { | |
135 | return a1.id_ != a2.id_; | |
136 | } | |
137 | ||
138 | template<> class test_allocator<void>: public test_allocator_base | |
139 | { | |
140 | public: | |
141 | ||
142 | typedef void * pointer; | |
143 | typedef void const * const_pointer; | |
144 | typedef void value_type; | |
145 | ||
146 | template<class U> struct rebind | |
147 | { | |
148 | typedef test_allocator<U> other; | |
149 | }; | |
150 | ||
151 | explicit test_allocator( int id = 0 ): test_allocator_base( id ) | |
152 | { | |
153 | } | |
154 | ||
155 | template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r ) | |
156 | { | |
157 | } | |
158 | ||
159 | template<class U> test_allocator & operator=( test_allocator<U> const & r ) | |
160 | { | |
161 | test_allocator_base::operator=( r ); | |
162 | return *this; | |
163 | } | |
164 | }; | |
165 | ||
166 | // | |
167 | ||
168 | struct X | |
169 | { | |
170 | static int instances; | |
171 | ||
172 | X() | |
173 | { | |
174 | ++instances; | |
175 | } | |
176 | ||
177 | ~X() | |
178 | { | |
179 | --instances; | |
180 | } | |
181 | ||
182 | private: | |
183 | ||
184 | X( X const & ); | |
185 | X & operator=( X const & ); | |
186 | }; | |
187 | ||
188 | int X::instances = 0; | |
189 | ||
190 | int main() | |
191 | { | |
192 | BOOST_TEST( X::instances == 0 ); | |
193 | ||
194 | boost::shared_ptr<void> pv( new X, boost::checked_deleter<X>(), std::allocator<X>() ); | |
195 | ||
196 | BOOST_TEST( X::instances == 1 ); | |
197 | ||
198 | pv.reset( new X, boost::checked_deleter<X>(), test_allocator<float>( 42 ) ); | |
199 | ||
200 | BOOST_TEST( X::instances == 1 ); | |
201 | ||
202 | BOOST_TEST( test_allocator_base::last_global_id_ == 42 ); | |
203 | BOOST_TEST( test_allocator_base::count_ > 0 ); | |
204 | ||
205 | pv.reset(); | |
206 | ||
207 | BOOST_TEST( X::instances == 0 ); | |
208 | BOOST_TEST( test_allocator_base::count_ == 0 ); | |
209 | ||
210 | pv.reset( new X, boost::checked_deleter<X>(), test_allocator<void>( 43 ) ); | |
211 | ||
212 | BOOST_TEST( X::instances == 1 ); | |
213 | BOOST_TEST( test_allocator_base::last_global_id_ == 43 ); | |
214 | ||
215 | pv.reset( new X, boost::checked_deleter<X>(), std::allocator<void>() ); | |
216 | ||
217 | BOOST_TEST( X::instances == 1 ); | |
218 | ||
219 | pv.reset(); | |
220 | ||
221 | BOOST_TEST( X::instances == 0 ); | |
222 | ||
223 | return boost::report_errors(); | |
224 | } |