Initialize boost git in 2.0_beta.
[external/boost.git] / libs / smart_ptr / test / shared_ptr_alloc2_test.cpp
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
12 #include <boost/detail/lightweight_test.hpp>
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 * )
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 }