Line data Source code
1 : #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED 2 : #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED 3 : 4 : // MS compatible compilers support #pragma once 5 : 6 : #if defined(_MSC_VER) && (_MSC_VER >= 1020) 7 : # pragma once 8 : #endif 9 : 10 : // 11 : // detail/sp_counted_impl.hpp 12 : // 13 : // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 14 : // Copyright 2004-2005 Peter Dimov 15 : // 16 : // Distributed under the Boost Software License, Version 1.0. (See 17 : // accompanying file LICENSE_1_0.txt or copy at 18 : // http://www.boost.org/LICENSE_1_0.txt) 19 : // 20 : 21 : #include <boost/config.hpp> 22 : 23 : #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) 24 : # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. 25 : #endif 26 : 27 : #include <boost/checked_delete.hpp> 28 : #include <boost/smart_ptr/detail/sp_counted_base.hpp> 29 : #include <boost/smart_ptr/detail/sp_noexcept.hpp> 30 : #include <boost/core/addressof.hpp> 31 : 32 : #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) 33 : #include <boost/smart_ptr/detail/quick_allocator.hpp> 34 : #endif 35 : 36 : #if defined(BOOST_SP_USE_STD_ALLOCATOR) 37 : #include <memory> // std::allocator 38 : #endif 39 : 40 : #include <cstddef> // std::size_t 41 : 42 : namespace boost 43 : { 44 : 45 : #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) 46 : 47 : void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn ); 48 : void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); 49 : 50 : #endif 51 : 52 : namespace detail 53 : { 54 : 55 : // get_local_deleter 56 : 57 : template<class D> class local_sp_deleter; 58 : 59 0 : template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT 60 : { 61 : return 0; 62 : } 63 : 64 : template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT; 65 : 66 : // 67 : 68 : template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base 69 : { 70 : private: 71 : 72 : X * px_; 73 : 74 : sp_counted_impl_p( sp_counted_impl_p const & ); 75 : sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); 76 : 77 : typedef sp_counted_impl_p<X> this_type; 78 : 79 : public: 80 : 81 0 : explicit sp_counted_impl_p( X * px ): px_( px ) 82 : { 83 : #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) 84 : boost::sp_scalar_constructor_hook( px, sizeof(X), this ); 85 : #endif 86 : } 87 : 88 0 : virtual void dispose() BOOST_SP_NOEXCEPT 89 : { 90 : #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) 91 : boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); 92 : #endif 93 0 : boost::checked_delete( px_ ); 94 0 : } 95 : 96 0 : virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT 97 : { 98 0 : return 0; 99 : } 100 : 101 0 : virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT 102 : { 103 0 : return 0; 104 : } 105 : 106 0 : virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT 107 : { 108 0 : return 0; 109 : } 110 : 111 : #if defined(BOOST_SP_USE_STD_ALLOCATOR) 112 : 113 : void * operator new( std::size_t ) 114 : { 115 : return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) ); 116 : } 117 : 118 : void operator delete( void * p ) 119 : { 120 : std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 ); 121 : } 122 : 123 : #endif 124 : 125 : #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) 126 : 127 : void * operator new( std::size_t ) 128 : { 129 : return quick_allocator<this_type>::alloc(); 130 : } 131 : 132 : void operator delete( void * p ) 133 : { 134 : quick_allocator<this_type>::dealloc( p ); 135 : } 136 : 137 : #endif 138 : }; 139 : 140 : // 141 : // Borland's Codeguard trips up over the -Vx- option here: 142 : // 143 : #ifdef __CODEGUARD__ 144 : # pragma option push -Vx- 145 : #endif 146 : 147 : template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base 148 : { 149 : private: 150 : 151 : P ptr; // copy constructor must not throw 152 : D del; // copy constructor must not throw 153 : 154 : sp_counted_impl_pd( sp_counted_impl_pd const & ); 155 : sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); 156 : 157 : typedef sp_counted_impl_pd<P, D> this_type; 158 : 159 : public: 160 : 161 : // pre: d(p) must not throw 162 : 163 0 : sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d ) 164 : { 165 : } 166 : 167 : sp_counted_impl_pd( P p ): ptr( p ), del() 168 : { 169 : } 170 : 171 0 : virtual void dispose() BOOST_SP_NOEXCEPT 172 : { 173 0 : del( ptr ); 174 0 : } 175 : 176 0 : virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT 177 : { 178 0 : return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0; 179 : } 180 : 181 0 : virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT 182 : { 183 0 : return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; 184 : } 185 : 186 0 : virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT 187 : { 188 0 : return &reinterpret_cast<char&>( del ); 189 : } 190 : 191 : #if defined(BOOST_SP_USE_STD_ALLOCATOR) 192 : 193 : void * operator new( std::size_t ) 194 : { 195 : return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) ); 196 : } 197 : 198 : void operator delete( void * p ) 199 : { 200 : std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 ); 201 : } 202 : 203 : #endif 204 : 205 : #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) 206 : 207 : void * operator new( std::size_t ) 208 : { 209 : return quick_allocator<this_type>::alloc(); 210 : } 211 : 212 : void operator delete( void * p ) 213 : { 214 : quick_allocator<this_type>::dealloc( p ); 215 : } 216 : 217 : #endif 218 : }; 219 : 220 : template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base 221 : { 222 : private: 223 : 224 : P p_; // copy constructor must not throw 225 : D d_; // copy constructor must not throw 226 : A a_; // copy constructor must not throw 227 : 228 : sp_counted_impl_pda( sp_counted_impl_pda const & ); 229 : sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); 230 : 231 : typedef sp_counted_impl_pda<P, D, A> this_type; 232 : 233 : public: 234 : 235 : // pre: d( p ) must not throw 236 : 237 : sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a ) 238 : { 239 : } 240 : 241 : sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a ) 242 : { 243 : } 244 : 245 : virtual void dispose() BOOST_SP_NOEXCEPT 246 : { 247 : d_( p_ ); 248 : } 249 : 250 : virtual void destroy() BOOST_SP_NOEXCEPT 251 : { 252 : #if !defined( BOOST_NO_CXX11_ALLOCATOR ) 253 : 254 : typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2; 255 : 256 : #else 257 : 258 : typedef typename A::template rebind< this_type >::other A2; 259 : 260 : #endif 261 : 262 : A2 a2( a_ ); 263 : 264 : this->~this_type(); 265 : 266 : a2.deallocate( this, 1 ); 267 : } 268 : 269 : virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT 270 : { 271 : return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0; 272 : } 273 : 274 : virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT 275 : { 276 : return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0; 277 : } 278 : 279 : virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT 280 : { 281 : return &reinterpret_cast<char&>( d_ ); 282 : } 283 : }; 284 : 285 : #ifdef __CODEGUARD__ 286 : # pragma option pop 287 : #endif 288 : 289 : } // namespace detail 290 : 291 : } // namespace boost 292 : 293 : #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED