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/smart_ptr/detail/sp_counted_base.hpp> 22 : #include <boost/smart_ptr/detail/deprecated_macros.hpp> 23 : #include <boost/core/checked_delete.hpp> 24 : #include <boost/core/addressof.hpp> 25 : #include <boost/config.hpp> 26 : 27 : #include <memory> // std::allocator, std::allocator_traits 28 : #include <cstddef> // std::size_t 29 : 30 : namespace boost 31 : { 32 : 33 : namespace detail 34 : { 35 : 36 : // get_local_deleter 37 : 38 : template<class D> class local_sp_deleter; 39 : 40 0 : template<class D> D * get_local_deleter( D * /*p*/ ) noexcept 41 : { 42 0 : return 0; 43 : } 44 : 45 : template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept; 46 : 47 : // 48 : 49 : template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base 50 : { 51 : private: 52 : 53 : X * px_; 54 : 55 : sp_counted_impl_p( sp_counted_impl_p const & ); 56 : sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); 57 : 58 : typedef sp_counted_impl_p<X> this_type; 59 : 60 : public: 61 : 62 320886 : explicit sp_counted_impl_p( X * px ): px_( px ) 63 213924 : { 64 213924 : } 65 : 66 88656 : void dispose() noexcept override 67 : { 68 88656 : boost::checked_delete( px_ ); 69 88656 : } 70 : 71 0 : void * get_deleter( sp_typeinfo_ const & ) noexcept override 72 : { 73 0 : return 0; 74 : } 75 : 76 0 : void * get_local_deleter( sp_typeinfo_ const & ) noexcept override 77 : { 78 0 : return 0; 79 : } 80 : 81 0 : void * get_untyped_deleter() noexcept override 82 : { 83 0 : return 0; 84 : } 85 : }; 86 : 87 : template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base 88 : { 89 : private: 90 : 91 : P ptr; // copy constructor must not throw 92 : D del; // copy/move constructor must not throw 93 : 94 : sp_counted_impl_pd( sp_counted_impl_pd const & ); 95 : sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); 96 : 97 : typedef sp_counted_impl_pd<P, D> this_type; 98 : 99 : public: 100 : 101 : // pre: d(p) must not throw 102 : 103 : sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) ) 104 : { 105 : } 106 : 107 12510 : sp_counted_impl_pd( P p ): ptr( p ), del() 108 8340 : { 109 8340 : } 110 : 111 1194 : void dispose() noexcept override 112 : { 113 1194 : del( ptr ); 114 1194 : } 115 : 116 0 : void * get_deleter( sp_typeinfo_ const & ti ) noexcept override 117 : { 118 0 : return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0; 119 : } 120 : 121 0 : void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override 122 : { 123 0 : return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; 124 : } 125 : 126 4170 : void * get_untyped_deleter() noexcept override 127 : { 128 4170 : return &reinterpret_cast<char&>( del ); 129 : } 130 : }; 131 : 132 : template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base 133 : { 134 : private: 135 : 136 : P p_; // copy constructor must not throw 137 : D d_; // copy/move constructor must not throw 138 : A a_; // copy constructor must not throw 139 : 140 : sp_counted_impl_pda( sp_counted_impl_pda const & ); 141 : sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); 142 : 143 : typedef sp_counted_impl_pda<P, D, A> this_type; 144 : 145 : public: 146 : 147 : // pre: d( p ) must not throw 148 : 149 : sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a ) 150 : { 151 : } 152 : 153 : sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a ) 154 : { 155 : } 156 : 157 : void dispose() noexcept override 158 : { 159 : d_( p_ ); 160 : } 161 : 162 : void destroy() noexcept override 163 : { 164 : typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2; 165 : 166 : A2 a2( a_ ); 167 : 168 : this->~this_type(); 169 : 170 : a2.deallocate( this, 1 ); 171 : } 172 : 173 : void * get_deleter( sp_typeinfo_ const & ti ) noexcept override 174 : { 175 : return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0; 176 : } 177 : 178 : void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override 179 : { 180 : return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0; 181 : } 182 : 183 : void * get_untyped_deleter() noexcept override 184 : { 185 : return &reinterpret_cast<char&>( d_ ); 186 : } 187 : }; 188 : 189 : } // namespace detail 190 : 191 : } // namespace boost 192 : 193 : #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED