Home | History | Annotate | Download | only in smart_ptr
      1 #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
      2 #define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
      3 
      4 //
      5 //  shared_array.hpp
      6 //
      7 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
      8 //  Copyright (c) 2001, 2002 Peter Dimov
      9 //
     10 //  Distributed under the Boost Software License, Version 1.0. (See
     11 //  accompanying file LICENSE_1_0.txt or copy at
     12 //  http://www.boost.org/LICENSE_1_0.txt)
     13 //
     14 //  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
     15 //
     16 
     17 #include <boost/config.hpp>   // for broken compiler workarounds
     18 
     19 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
     20 #include <boost/smart_ptr/detail/shared_array_nmt.hpp>
     21 #else
     22 
     23 #include <memory>             // TR1 cyclic inclusion fix
     24 
     25 #include <boost/assert.hpp>
     26 #include <boost/checked_delete.hpp>
     27 
     28 #include <boost/smart_ptr/detail/shared_count.hpp>
     29 #include <boost/detail/workaround.hpp>
     30 
     31 #include <cstddef>            // for std::ptrdiff_t
     32 #include <algorithm>          // for std::swap
     33 #include <functional>         // for std::less
     34 
     35 namespace boost
     36 {
     37 
     38 //
     39 //  shared_array
     40 //
     41 //  shared_array extends shared_ptr to arrays.
     42 //  The array pointed to is deleted when the last shared_array pointing to it
     43 //  is destroyed or reset.
     44 //
     45 
     46 template<class T> class shared_array
     47 {
     48 private:
     49 
     50     // Borland 5.5.1 specific workarounds
     51     typedef checked_array_deleter<T> deleter;
     52     typedef shared_array<T> this_type;
     53 
     54 public:
     55 
     56     typedef T element_type;
     57 
     58     explicit shared_array(T * p = 0): px(p), pn(p, deleter())
     59     {
     60     }
     61 
     62     //
     63     // Requirements: D's copy constructor must not throw
     64     //
     65     // shared_array will release p by calling d(p)
     66     //
     67 
     68     template<class D> shared_array(T * p, D d): px(p), pn(p, d)
     69     {
     70     }
     71 
     72 //  generated copy constructor, destructor are fine...
     73 
     74 #if defined( BOOST_HAS_RVALUE_REFS )
     75 
     76 // ... except in C++0x, move disables the implicit copy
     77 
     78     shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws
     79     {
     80     }
     81 
     82 #endif
     83 
     84     // assignment
     85 
     86     shared_array & operator=( shared_array const & r ) // never throws
     87     {
     88         this_type( r ).swap( *this );
     89         return *this;
     90     }
     91 
     92     void reset(T * p = 0)
     93     {
     94         BOOST_ASSERT(p == 0 || p != px);
     95         this_type(p).swap(*this);
     96     }
     97 
     98     template <class D> void reset(T * p, D d)
     99     {
    100         this_type(p, d).swap(*this);
    101     }
    102 
    103     T & operator[] (std::ptrdiff_t i) const // never throws
    104     {
    105         BOOST_ASSERT(px != 0);
    106         BOOST_ASSERT(i >= 0);
    107         return px[i];
    108     }
    109 
    110     T * get() const // never throws
    111     {
    112         return px;
    113     }
    114 
    115 // implicit conversion to "bool"
    116 #include <boost/smart_ptr/detail/operator_bool.hpp>
    117 
    118     bool unique() const // never throws
    119     {
    120         return pn.unique();
    121     }
    122 
    123     long use_count() const // never throws
    124     {
    125         return pn.use_count();
    126     }
    127 
    128     void swap(shared_array<T> & other) // never throws
    129     {
    130         std::swap(px, other.px);
    131         pn.swap(other.pn);
    132     }
    133 
    134     void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
    135     {
    136         return pn.get_deleter( ti );
    137     }
    138 
    139 private:
    140 
    141     T * px;                     // contained pointer
    142     detail::shared_count pn;    // reference counter
    143 
    144 };  // shared_array
    145 
    146 template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
    147 {
    148     return a.get() == b.get();
    149 }
    150 
    151 template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
    152 {
    153     return a.get() != b.get();
    154 }
    155 
    156 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
    157 {
    158     return std::less<T*>()(a.get(), b.get());
    159 }
    160 
    161 template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
    162 {
    163     a.swap(b);
    164 }
    165 
    166 template< class D, class T > D * get_deleter( shared_array<T> const & p )
    167 {
    168     return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
    169 }
    170 
    171 } // namespace boost
    172 
    173 #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
    174 
    175 #endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
    176