File indexing completed on 2025-12-17 10:04:13
0001 #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <boost/smart_ptr/shared_ptr.hpp>
0018 #include <boost/smart_ptr/detail/shared_count.hpp>
0019 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
0020 #include <boost/core/checked_delete.hpp>
0021 #include <boost/assert.hpp>
0022 #include <boost/config.hpp>
0023 #include <boost/config/workaround.hpp>
0024
0025 #include <algorithm> // for std::swap
0026 #include <functional> // for std::less
0027 #include <cstddef> // for std::ptrdiff_t
0028
0029 namespace boost
0030 {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 template<class T> class shared_array
0041 {
0042 private:
0043
0044
0045 typedef checked_array_deleter<T> deleter;
0046 typedef shared_array<T> this_type;
0047
0048 public:
0049
0050 typedef T element_type;
0051
0052 shared_array() noexcept : px( 0 ), pn()
0053 {
0054 }
0055
0056 shared_array( std::nullptr_t ) noexcept : px( 0 ), pn()
0057 {
0058 }
0059
0060 template<class Y>
0061 explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
0062 {
0063 boost::detail::sp_assert_convertible< Y[], T[] >();
0064 }
0065
0066
0067
0068
0069
0070
0071
0072 template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
0073 {
0074 boost::detail::sp_assert_convertible< Y[], T[] >();
0075 }
0076
0077
0078
0079 template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
0080 {
0081 boost::detail::sp_assert_convertible< Y[], T[] >();
0082 }
0083
0084
0085
0086
0087 shared_array( shared_array const & r ) noexcept : px( r.px ), pn( r.pn )
0088 {
0089 }
0090
0091 shared_array( shared_array && r ) noexcept : px( r.px ), pn()
0092 {
0093 pn.swap( r.pn );
0094 r.px = 0;
0095 }
0096
0097
0098
0099 template<class Y>
0100 shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
0101 noexcept : px( r.px ), pn( r.pn )
0102 {
0103 boost::detail::sp_assert_convertible< Y[], T[] >();
0104 }
0105
0106
0107
0108 template< class Y >
0109 shared_array( shared_array<Y> const & r, element_type * p ) noexcept : px( p ), pn( r.pn )
0110 {
0111 }
0112
0113
0114
0115 shared_array & operator=( shared_array const & r ) noexcept
0116 {
0117 this_type( r ).swap( *this );
0118 return *this;
0119 }
0120
0121 template<class Y>
0122 shared_array & operator=( shared_array<Y> const & r ) noexcept
0123 {
0124 this_type( r ).swap( *this );
0125 return *this;
0126 }
0127
0128 shared_array & operator=( shared_array && r ) noexcept
0129 {
0130 this_type( static_cast< shared_array && >( r ) ).swap( *this );
0131 return *this;
0132 }
0133
0134 template<class Y>
0135 shared_array & operator=( shared_array<Y> && r ) noexcept
0136 {
0137 this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
0138 return *this;
0139 }
0140
0141 void reset() noexcept
0142 {
0143 this_type().swap( *this );
0144 }
0145
0146 template<class Y> void reset( Y * p )
0147 {
0148 BOOST_ASSERT( p == 0 || p != px );
0149 this_type( p ).swap( *this );
0150 }
0151
0152 template<class Y, class D> void reset( Y * p, D d )
0153 {
0154 this_type( p, d ).swap( *this );
0155 }
0156
0157 template<class Y, class D, class A> void reset( Y * p, D d, A a )
0158 {
0159 this_type( p, d, a ).swap( *this );
0160 }
0161
0162 template<class Y> void reset( shared_array<Y> const & r, element_type * p ) noexcept
0163 {
0164 this_type( r, p ).swap( *this );
0165 }
0166
0167 T & operator[] (std::ptrdiff_t i) const BOOST_SP_NOEXCEPT_WITH_ASSERT
0168 {
0169 BOOST_ASSERT(px != 0);
0170 BOOST_ASSERT(i >= 0);
0171 return px[i];
0172 }
0173
0174 T * get() const noexcept
0175 {
0176 return px;
0177 }
0178
0179 explicit operator bool () const noexcept
0180 {
0181 return px != 0;
0182 }
0183
0184 bool unique() const noexcept
0185 {
0186 return pn.unique();
0187 }
0188
0189 long use_count() const noexcept
0190 {
0191 return pn.use_count();
0192 }
0193
0194 void swap(shared_array<T> & other) noexcept
0195 {
0196 std::swap(px, other.px);
0197 pn.swap(other.pn);
0198 }
0199
0200 void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const noexcept
0201 {
0202 return pn.get_deleter( ti );
0203 }
0204
0205 private:
0206
0207 template<class Y> friend class shared_array;
0208
0209 T * px;
0210 detail::shared_count pn;
0211
0212 };
0213
0214 template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) noexcept
0215 {
0216 return a.get() == b.get();
0217 }
0218
0219 template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) noexcept
0220 {
0221 return a.get() != b.get();
0222 }
0223
0224 template<class T> inline bool operator==( shared_array<T> const & p, std::nullptr_t ) noexcept
0225 {
0226 return p.get() == 0;
0227 }
0228
0229 template<class T> inline bool operator==( std::nullptr_t, shared_array<T> const & p ) noexcept
0230 {
0231 return p.get() == 0;
0232 }
0233
0234 template<class T> inline bool operator!=( shared_array<T> const & p, std::nullptr_t ) noexcept
0235 {
0236 return p.get() != 0;
0237 }
0238
0239 template<class T> inline bool operator!=( std::nullptr_t, shared_array<T> const & p ) noexcept
0240 {
0241 return p.get() != 0;
0242 }
0243
0244 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) noexcept
0245 {
0246 return std::less<T*>()(a.get(), b.get());
0247 }
0248
0249 template<class T> void swap(shared_array<T> & a, shared_array<T> & b) noexcept
0250 {
0251 a.swap(b);
0252 }
0253
0254 template< class D, class T > D * get_deleter( shared_array<T> const & p ) noexcept
0255 {
0256 return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID_(D) ) );
0257 }
0258
0259 }
0260
0261 #endif