1//// 2Copyright 2017 Peter Dimov 3 4Distributed under the Boost Software License, Version 1.0. 5 6See accompanying file LICENSE_1_0.txt or copy at 7http://www.boost.org/LICENSE_1_0.txt 8//// 9 10[[shared_array]] 11[appendix] 12# shared_array (deprecated) 13:toc: 14:toc-title: 15:idprefix: shared_array_ 16 17NOTE: This facility is deprecated because a `shared_ptr` to `T[]` or `T[N]` 18is now available, and is superior in every regard. 19 20## Description 21 22The `shared_array` class template stores a pointer to a dynamically allocated 23array. (Dynamically allocated array are allocated with the C++ `new[]` 24expression.) The object pointed to is guaranteed to be deleted when the last 25`shared_array` pointing to it is destroyed or reset. 26 27Every `shared_array` meets the _CopyConstructible_ and _Assignable_ 28requirements of the {cpp} Standard Library, and so can be used in standard 29library containers. Comparison operators are supplied so that shared_array 30works with the standard library's associative containers. 31 32Normally, a `shared_array` cannot correctly hold a pointer to an object that 33has been allocated with the non-array form of `new`. See `shared_ptr` for that 34usage. 35 36Because the implementation uses reference counting, cycles of `shared_array` 37instances will not be reclaimed. For example, if `main` holds a shared_array 38to `A`, which directly or indirectly holds a shared_array back to `A`, the use 39count of `A` will be 2. Destruction of the original `shared_array` will leave 40`A` dangling with a use count of 1. 41 42A `shared_ptr` to a `std::vector` is an alternative to a `shared_array` that 43is a bit heavier duty but far more flexible. 44 45The class template is parameterized on `T`, the type of the object pointed to. 46`shared_array` and most of its member functions place no requirements on `T`; 47it is allowed to be an incomplete type, or `void`. Member functions that do 48place additional requirements (constructors, reset) are explicitly documented 49below. 50 51## Synopsis 52 53``` 54namespace boost { 55 56 template<class T> class shared_array { 57 public: 58 typedef T element_type; 59 60 explicit shared_array(T* p = 0); 61 template<class D> shared_array(T* p, D d); 62 shared_array(const shared_array& v) noexcept; 63 64 ~shared_array() noexcept; 65 66 shared_array& operator=(const shared_array& v) noexcept; 67 68 void reset(T* p = 0); 69 template<class D> void reset(T* p, D d); 70 71 T& operator[](std::ptrdiff_t n) const noexcept; 72 T* get() const noexcept; 73 74 bool unique() const noexcept; 75 long use_count() const noexcept; 76 77 explicit operator bool() const noexcept; 78 79 void swap(shared_array<T>& v) noexcept; 80 }; 81 82 template<class T> bool 83 operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept; 84 template<class T> bool 85 operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept; 86 template<class T> bool 87 operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept; 88 89 template<class T> 90 void swap(shared_array<T>& a, shared_array<T>& b) noexcept; 91} 92``` 93 94## Members 95 96### element_type 97 98``` 99typedef T element_type; 100``` 101Type:: Provides the type of the stored pointer. 102 103### Constructors 104 105``` 106explicit shared_array(T* p = 0); 107``` 108[none] 109* {blank} 110+ 111Effects:: Constructs a `shared_array`, storing a copy of `p`, which must be a 112pointer to an array that was allocated via a C++ `new[]` expression or be 0. 113Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`). 114Requires:: `T` is a complete type. 115Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. 116 117``` 118template<class D> shared_array(T* p, D d); 119``` 120[none] 121* {blank} 122+ 123Effects:: Constructs a `shared_array`, storing a copy of `p` and of `d`. 124Afterwards, the use count is 1. When the the time comes to delete the array 125pointed to by `p`, the object `d` is used in the statement `d(p)`. 126Requires:: 127* `T` is a complete type. 128* The copy constructor and destructor of `D` must not throw. 129* Invoking the object `d` with parameter `p` must not throw. 130Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. 131 132``` 133shared_array(const shared_array& v) noexcept; 134``` 135[none] 136* {blank} 137+ 138Effects:: Constructs a `shared_array`, as if by storing a copy of the pointer 139stored in `v`. Afterwards, the use count for all copies is 1 more than the 140initial use count. 141Requires:: `T` is a complete type. 142 143### Destructor 144 145``` 146~shared_array() noexcept; 147``` 148[none] 149* {blank} 150+ 151Effects:: Decrements the use count. Then, if the use count is 0, deletes the 152array pointed to by the stored pointer. Note that `delete[]` on a pointer with 153a value of 0 is harmless. 154 155### Assignment 156 157``` 158shared_array& operator=(const shared_array& v) noexcept; 159``` 160[none] 161* {blank} 162+ 163Effects:: Constructs a new `shared_array` as described above, then replaces 164this `shared_array` with the new one, destroying the replaced object. 165Requires:: `T` is a complete type. 166Returns:: `*this`. 167 168### reset 169 170``` 171void reset(T* p = 0); 172``` 173[none] 174* {blank} 175+ 176Effects:: Constructs a new `shared_array` as described above, then replaces 177this `shared_array` with the new one, destroying the replaced object. 178Requires:: `T` is a complete type. 179Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. 180 181``` 182template<class D> void reset(T* p, D d); 183``` 184[none] 185* {blank} 186+ 187Effects:: Constructs a new `shared_array` as described above, then replaces 188this `shared_array` with the new one, destroying the replaced object. 189Requires:: 190* `T` is a complete type. 191* The copy constructor of `D` must not throw. 192Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. 193 194### Indexing 195 196``` 197T& operator[](std::ptrdiff_t n) const noexcept; 198``` 199Returns:: A reference to element `n` of the array pointed to by the stored 200pointer. Behavior is undefined and almost certainly undesirable if the stored 201pointer is 0, or if `n` is less than 0 or is greater than or equal to the 202number of elements in the array. 203Requires:: `T` is a complete type. 204 205### get 206 207``` 208T* get() const noexcept; 209``` 210[none] 211* {blank} 212+ 213Returns:: The stored pointer. 214 215### unique 216 217``` 218bool unique() const noexcept; 219``` 220[none] 221* {blank} 222+ 223Returns:: `true` if no other `shared_array` is sharing ownership of the 224stored pointer, `false` otherwise. 225 226### use_count 227 228``` 229long use_count() const noexcept; 230``` 231[none] 232* {blank} 233+ 234Returns:: The number of `shared_array` objects sharing ownership of the 235stored pointer. 236 237### Conversions 238 239``` 240explicit operator bool() const noexcept; 241``` 242[none] 243* {blank} 244+ 245Returns:: `get() != 0`. 246Requires:: `T` is a complete type. 247 248### swap 249 250``` 251void swap(shared_array<T>& b) noexcept; 252``` 253[none] 254* {blank} 255+ 256Effects:: Exchanges the contents of the two smart pointers. 257 258## Free Functions 259 260### Comparison 261 262``` 263template<class T> bool 264 operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept; 265``` 266``` 267template<class T> bool 268 operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept; 269``` 270``` 271template<class T> bool 272 operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept; 273``` 274[none] 275* {blank} 276+ 277Returns:: The result of comparing the stored pointers of the two smart 278pointers. 279 280NOTE: The `operator<` overload is provided to define an ordering so that 281`shared_array` objects can be used in associative containers such as 282`std::map`. The implementation uses `std::less<T*>` to perform the comparison. 283This ensures that the comparison is handled correctly, since the standard 284mandates that relational operations on pointers are unspecified (5.9 285[expr.rel] paragraph 2) but `std::less` on pointers is well-defined (20.3.3 286[lib.comparisons] paragraph 8). 287 288### swap 289 290``` 291template<class T> 292 void swap(shared_array<T>& a, shared_array<T>& b) noexcept; 293``` 294[none] 295* {blank} 296+ 297Returns:: `a.swap(b)`. 298Requires:: `T` is a complete type. 299