# shared_array class template

The shared_array class template stores a pointer to a dynamically allocated array. (Dynamically allocated array are allocated with the C++ new[] expression.) The object pointed to is guaranteed to be deleted when the last shared_array pointing to it is destroyed or reset.

Every shared_array meets the CopyConstructible and Assignable requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that shared_array works with the standard library's associative containers.

Normally, a shared_array cannot correctly hold a pointer to an object that has been allocated with the non-array form of new. See shared_ptr for that usage.

Because the implementation uses reference counting, cycles of shared_array instances will not be reclaimed. For example, if main() holds a shared_array to A, which directly or indirectly holds a shared_array back to A, A's use count will be 2. Destruction of the original shared_array will leave A dangling with a use count of 1.

A shared_ptr to a std::vector is an alternative to a shared_array that is a bit heavier duty but far more flexible.

The class template is parameterized on T, the type of the object pointed to. T must meet the smart pointer common requirements.

## Synopsis

    namespace boost {

      template<typename T> class shared_array {

        public:
          typedef T element_type;

          explicit shared_array(T * p = 0);
          template<typename D> shared_array(T * p, D d);
          ~shared_array(); // never throws

          shared_array(shared_array const & r); // never throws

          shared_array & operator=(shared_array const & r); // never throws

          void reset(T * p = 0);
          template<typename D> void reset(T * p, D d);

          T & operator[](std::ptrdiff_t i) const() const; // never throws
          T * get() const; // never throws

          bool unique() const; // never throws
          long use_count() const; // never throws

          void swap(shared_array<T> & b); // never throws
      };

      template<typename T>
        bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws
      template<typename T>
        bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws
      template<typename T>
        bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws

      template<typename T> void swap(shared_array<T> & a, shared_array<T> & b); // never throws

    }

## Members

### element_type

    typedef T element_type;

Provides the type of the stored pointer.

### constructors

    explicit shared_array(T * p = 0);

Constructs a shared_array, storing a copy of p, which must be a pointer to an array that was allocated via a C++ new[] expression or be 0. Afterwards, the use count is 1 (even if p == 0; see ~shared_array). The only exception which may be thrown by this constructor is std::bad_alloc. If an exception is thrown, delete[] p is called.

    template<typename D> shared_array(T * p, D d);

Constructs a shared_array, storing a copy of p and of d. Afterwards, the use count is 1. D's copy constructor and destructor must not throw. When the the time comes to delete the array pointed to by p, the object d is used in the statement d(p). Invoking the object d with parameter p in this way must not throw. The only exception which may be thrown by this constructor is std::bad_alloc. If an exception is thrown, d(p) is called.

    shared_array(shared_array const & r); // never throws

Constructs a shared_array, as if by storing a copy of the pointer stored in r. Afterwards, the use count for all copies is 1 more than the initial use count.

### destructor

    ~shared_array(); // never throws

Decrements the use count. Then, if the use count is 0, deletes the array pointed to by the stored pointer. Note that delete[] on a pointer with a value of 0 is harmless. T need not be a complete type. The guarantee that this does not throw exceptions depends on the requirement that the deleted object's destructor does not throw exceptions. See the smart pointer common requirements.

### assignment

    shared_array & operator=(shared_array const & r); // never throws

Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object.

### reset

    void reset(T * p = 0);

Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object. The only exception which may be thrown is std::bad_alloc. If an exception is thrown, delete[] p is called.

    template<typename D> void reset(T * p, D d);

Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object. D's copy constructor must not throw. The only exception which may be thrown is std::bad_alloc. If an exception is thrown, d(p) is called.

### indexing

    T & operator[](std::ptrdiff_t i) const; // never throws

Returns a reference to element i of the array pointed to by the stored pointer. Behavior is undefined and almost certainly undesirable if the stored pointer is 0, or if i is less than 0 or is greater than or equal to the number of elements in the array.

### get

    T * get() const; // never throws

Returns the stored pointer. T need not be a complete type. See the smart pointer common requirements.

### unique

    bool unique() const; // never throws

Returns true if no other shared_array is sharing ownership of the stored pointer, false otherwise. T need not be a complete type. See the smart pointer common requirements.

### use_count

    long use_count() const; // never throws

Returns the number of shared_array objects sharing ownership of the stored pointer. T need not be a complete type. See the smart pointer common requirements.

Because use_count is not necessarily efficient to implement for implementations of shared_array that do not use an explicit reference count, it might be removed from some future version. Thus it should be used for debugging purposes only, and not production code.

### swap

    void swap(shared_ptr & b); // never throws

Exchanges the contents of the two smart pointers. T need not be a complete type. See the smart pointer common requirements.

## Free Functions

### comparison

    template<typename T>
      bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws
    template<typename T>
      bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws
    template<typename T>
      bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws

Compares the stored pointers of the two smart pointers. T need not be a complete type. See the smart pointer common requirements.

The operator< overload is provided to define an ordering so that shared_array objects can be used in associative containers such as std::map. The implementation uses std::less<T *> to perform the comparison. This ensures that the comparison is handled correctly, since the standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel] paragraph 2) but std::less<> on pointers is well-defined (20.3.3 [lib.comparisons] paragraph 8).

### swap

    template<typename T>
      void swap(shared_array<T> & a, shared_array<T> & b) // never throws

Equivalent to a.swap(b). Matches the interface of std::swap. Provided as an aid to generic programming.

Revised 8 February 2002

Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.