diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index afc4e78..106428d 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) #include @@ -37,7 +38,6 @@ #include // std::less #include // std::bad_alloc #include // std::type_info in get_deleter -#include // std::size_t #ifdef __BORLANDC__ # pragma warn -8027 // Functions containing try are not expanded inline @@ -46,126 +46,11 @@ namespace boost { -// Debug hooks - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); -void sp_array_constructor_hook(void * px); -void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); -void sp_array_destructor_hook(void * px); - -#endif - namespace detail { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) -template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) -{ - boost::sp_scalar_constructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) -{ - boost::sp_array_constructor_hook(px); -} - -template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) -{ - boost::sp_scalar_destructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) -{ - boost::sp_array_destructor_hook(px); -} - -template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -#endif - -// -// Borland's Codeguard trips up over the -Vx- option here: -// -#ifdef __CODEGUARD__ -# pragma option push -Vx- -#endif - -template class sp_counted_base_impl: public sp_counted_base -{ -private: - - P ptr; // copy constructor must not throw - D del; // copy constructor must not throw - - sp_counted_base_impl(sp_counted_base_impl const &); - sp_counted_base_impl & operator= (sp_counted_base_impl const &); - - typedef sp_counted_base_impl this_type; - -public: - - // pre: d(p) must not throw - - sp_counted_base_impl(P p, D d): ptr(p), del(d) - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_constructor_hook(this, p, d, 0); -#endif - } - - virtual void dispose() // nothrow - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_destructor_hook(this, ptr, del, 0); -#endif - del(ptr); - } - - virtual void * get_deleter(std::type_info const & ti) - { - return ti == typeid(D)? &del: 0; - } - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) - - void * operator new(std::size_t) - { - return std::allocator().allocate(1, static_cast(0)); - } - - void operator delete(void * p) - { - std::allocator().deallocate(static_cast(p), 1); - } - -#endif - -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) - - void * operator new(std::size_t) - { - return quick_allocator::alloc(); - } - - void operator delete(void * p) - { - quick_allocator::dealloc(p); - } - -#endif -}; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - int const shared_count_id = 0x2C35F101; int const weak_count_id = 0x298C38A4; @@ -203,7 +88,7 @@ public: try { - pi_ = new sp_counted_base_impl(p, d); + pi_ = new sp_counted_impl_pd(p, d); } catch(...) { @@ -213,7 +98,7 @@ public: #else - pi_ = new sp_counted_base_impl(p, d); + pi_ = new sp_counted_impl_pd(p, d); if(pi_ == 0) { @@ -229,7 +114,7 @@ public: // auto_ptr is special cased to provide the strong guarantee template - explicit shared_count(std::auto_ptr & r): pi_(new sp_counted_base_impl< Y *, checked_deleter >(r.get(), checked_deleter())) + explicit shared_count(std::auto_ptr & r): pi_(new sp_counted_impl_pd< Y *, checked_deleter >(r.get(), checked_deleter())) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) , id_(shared_count_id) #endif @@ -304,10 +189,6 @@ public: } }; -#ifdef __CODEGUARD__ -# pragma option pop -#endif - class weak_count { diff --git a/include/boost/detail/sp_counted_impl.hpp b/include/boost/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..8d3c8c7 --- /dev/null +++ b/include/boost/detail/sp_counted_impl.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_impl.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#include // std::allocator +#include // std::type_info in get_deleter +#include // std::size_t + +namespace boost +{ + +// Debug hooks + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); +void sp_array_constructor_hook(void * px); +void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); +void sp_array_destructor_hook(void * px); + +#endif + +namespace detail +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) +{ + boost::sp_scalar_constructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) +{ + boost::sp_array_constructor_hook(px); +} + +template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter const &, int) +{ + boost::sp_scalar_destructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter const &, int) +{ + boost::sp_array_destructor_hook(px); +} + +template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +#endif + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_impl_pd: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_impl_pd(sp_counted_impl_pd const &); + sp_counted_impl_pd & operator= (sp_counted_impl_pd const &); + + typedef sp_counted_impl_pd this_type; + +public: + + // pre: d(p) must not throw + + sp_counted_impl_pd(P p, D d): ptr(p), del(d) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_constructor_hook(this, p, d, 0); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_destructor_hook(this, ptr, del, 0); +#endif + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new(std::size_t) + { + return std::allocator().allocate(1, static_cast(0)); + } + + void operator delete(void * p) + { + std::allocator().deallocate(static_cast(p), 1); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new(std::size_t) + { + return quick_allocator::alloc(); + } + + void operator delete(void * p) + { + quick_allocator::dealloc(p); + } + +#endif +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED