Back to home page

EIC code displayed by LXR

 
 

    


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 //  shared_array.hpp
0006 //
0007 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
0008 //  Copyright (c) 2001, 2002, 2012 Peter Dimov
0009 //
0010 //  Distributed under the Boost Software License, Version 1.0. (See
0011 //  accompanying file LICENSE_1_0.txt or copy at
0012 //  http://www.boost.org/LICENSE_1_0.txt)
0013 //
0014 //  See http://www.boost.org/libs/smart_ptr/ for documentation.
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 //  shared_array
0034 //
0035 //  shared_array extends shared_ptr to arrays.
0036 //  The array pointed to is deleted when the last shared_array pointing to it
0037 //  is destroyed or reset.
0038 //
0039 
0040 template<class T> class shared_array
0041 {
0042 private:
0043 
0044     // Borland 5.5.1 specific workarounds
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     // Requirements: D's copy constructor must not throw
0068     //
0069     // shared_array will release p by calling d(p)
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     // As above, but with allocator. A's copy constructor shall not throw.
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 //  generated copy constructor, destructor are fine...
0085 // ... except in C++0x, move disables the implicit copy
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     // conversion
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     // aliasing
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     // assignment
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 ) // Y must be complete
0147     {
0148         BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
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;                     // contained pointer
0210     detail::shared_count pn;    // reference counter
0211 
0212 };  // shared_array
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 } // namespace boost
0260 
0261 #endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED