4 // Copyright (c) 2002, 2003 Peter Dimov
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
11 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
13 #include <boost/assert.hpp>
17 int const m
= 2; // m * sizeof(int) must be aligned appropriately
19 // magic values to mark heap blocks with
21 int const allocated_scalar
= 0x1234560C;
22 int const allocated_array
= 0x1234560A;
23 int const adopted_scalar
= 0x0567890C;
24 int const adopted_array
= 0x0567890A;
25 int const deleted
= 0x498769DE;
27 using namespace std
; // for compilers where things aren't in std
31 static new_handler
get_new_handler()
33 new_handler p
= set_new_handler(0);
38 static void * allocate(size_t n
, int mark
)
44 pm
= static_cast<int*>(malloc(n
+ m
* sizeof(int)));
48 if(new_handler pnh
= get_new_handler())
63 void * operator new(size_t n
) throw(bad_alloc
)
65 void * p
= allocate(n
, allocated_scalar
);
67 #if !defined(BOOST_NO_EXCEPTIONS)
69 if(p
== 0) throw bad_alloc();
76 #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
78 void * operator new(size_t n
, nothrow_t
const &) throw()
80 return allocate(n
, allocated_scalar
);
85 void * operator new[](size_t n
) throw(bad_alloc
)
87 void * p
= allocate(n
, allocated_array
);
89 #if !defined(BOOST_NO_EXCEPTIONS)
91 if(p
== 0) throw bad_alloc();
98 #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
100 void * operator new[](size_t n
, nothrow_t
const &) throw()
102 return allocate(n
, allocated_array
);
112 void sp_scalar_constructor_hook(void * p
)
116 int * pm
= static_cast<int*>(p
);
119 BOOST_ASSERT(*pm
!= adopted_scalar
); // second smart pointer to the same address
120 BOOST_ASSERT(*pm
!= allocated_array
); // allocated with new[]
121 BOOST_ASSERT(*pm
== allocated_scalar
); // not allocated with new
123 *pm
= adopted_scalar
;
126 void sp_scalar_constructor_hook(void * px
, std::size_t, void *)
128 sp_scalar_constructor_hook(px
);
131 void sp_scalar_destructor_hook(void * p
)
135 int * pm
= static_cast<int*>(p
);
138 BOOST_ASSERT(*pm
== adopted_scalar
); // attempt to destroy nonmanaged block
140 *pm
= allocated_scalar
;
143 void sp_scalar_destructor_hook(void * px
, std::size_t, void *)
145 sp_scalar_destructor_hook(px
);
148 // It is not possible to handle the array hooks in a portable manner.
149 // The implementation typically reserves a bit of storage for the number
150 // of objects in the array, and the argument of the array hook isn't
151 // equal to the return value of operator new[].
153 void sp_array_constructor_hook(void * /* p */)
158 // adjust p depending on the implementation
160 int * pm = static_cast<int*>(p);
163 BOOST_ASSERT(*pm != adopted_array); // second smart array pointer to the same address
164 BOOST_ASSERT(*pm != allocated_scalar); // allocated with new
165 BOOST_ASSERT(*pm == allocated_array); // not allocated with new[]
171 void sp_array_destructor_hook(void * /* p */)
176 // adjust p depending on the implementation
178 int * pm = static_cast<int*>(p);
181 BOOST_ASSERT(*pm == adopted_array); // attempt to destroy nonmanaged block
183 *pm = allocated_array;
191 void operator delete(void * p
) throw()
195 int * pm
= static_cast<int*>(p
);
198 BOOST_ASSERT(*pm
!= deleted
); // double delete
199 BOOST_ASSERT(*pm
!= adopted_scalar
); // delete p.get();
200 BOOST_ASSERT(*pm
!= allocated_array
); // allocated with new[]
201 BOOST_ASSERT(*pm
== allocated_scalar
); // not allocated with new
208 #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
210 void operator delete(void * p
, nothrow_t
const &) throw()
212 ::operator delete(p
);
217 void operator delete[](void * p
) throw()
221 int * pm
= static_cast<int*>(p
);
224 BOOST_ASSERT(*pm
!= deleted
); // double delete
225 BOOST_ASSERT(*pm
!= adopted_scalar
); // delete p.get();
226 BOOST_ASSERT(*pm
!= allocated_scalar
); // allocated with new
227 BOOST_ASSERT(*pm
== allocated_array
); // not allocated with new[]
234 #if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
236 void operator delete[](void * p
, nothrow_t
const &) throw()
238 ::operator delete[](p
);
243 #endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS)