blob: dedef12fda5b59f9aa06a06030f52f3eeec4a87c [file] [log] [blame]
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001#ifndef NDNBOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
2#define NDNBOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
Jeff Thompsonef2d5a42013-08-22 19:09:24 -07003
4//
5// shared_array.hpp
6//
7// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
8// Copyright (c) 2001, 2002, 2012 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 <ndnboost/config.hpp> // for broken compiler workarounds
18
Jeff Thompson3d613fd2013-10-15 15:39:04 -070019#if defined(NDNBOOST_NO_MEMBER_TEMPLATES) && !defined(NDNBOOST_MSVC6_MEMBER_TEMPLATES)
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070020#include <ndnboost/smart_ptr/detail/shared_array_nmt.hpp>
21#else
22
23#include <memory> // TR1 cyclic inclusion fix
24
25#include <ndnboost/assert.hpp>
26#include <ndnboost/checked_delete.hpp>
27
28#include <ndnboost/smart_ptr/shared_ptr.hpp>
29#include <ndnboost/smart_ptr/detail/shared_count.hpp>
30#include <ndnboost/smart_ptr/detail/sp_nullptr_t.hpp>
31#include <ndnboost/detail/workaround.hpp>
32
33#include <cstddef> // for std::ptrdiff_t
34#include <algorithm> // for std::swap
35#include <functional> // for std::less
36
37namespace ndnboost
38{
39
40//
41// shared_array
42//
43// shared_array extends shared_ptr to arrays.
44// The array pointed to is deleted when the last shared_array pointing to it
45// is destroyed or reset.
46//
47
48template<class T> class shared_array
49{
50private:
51
52 // Borland 5.5.1 specific workarounds
53 typedef checked_array_deleter<T> deleter;
54 typedef shared_array<T> this_type;
55
56public:
57
58 typedef T element_type;
59
Jeff Thompson3d613fd2013-10-15 15:39:04 -070060 shared_array() NDNBOOST_NOEXCEPT : px( 0 ), pn()
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070061 {
62 }
63
64 template<class Y>
65 explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
66 {
67 ndnboost::detail::sp_assert_convertible< Y[], T[] >();
68 }
69
70 //
71 // Requirements: D's copy constructor must not throw
72 //
73 // shared_array will release p by calling d(p)
74 //
75
76 template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
77 {
78 ndnboost::detail::sp_assert_convertible< Y[], T[] >();
79 }
80
81 // As above, but with allocator. A's copy constructor shall not throw.
82
83 template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
84 {
85 ndnboost::detail::sp_assert_convertible< Y[], T[] >();
86 }
87
88// generated copy constructor, destructor are fine...
89
Jeff Thompson3d613fd2013-10-15 15:39:04 -070090#if !defined( NDNBOOST_NO_CXX11_RVALUE_REFERENCES )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070091
92// ... except in C++0x, move disables the implicit copy
93
Jeff Thompson3d613fd2013-10-15 15:39:04 -070094 shared_array( shared_array const & r ) NDNBOOST_NOEXCEPT : px( r.px ), pn( r.pn )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070095 {
96 }
97
Jeff Thompson3d613fd2013-10-15 15:39:04 -070098 shared_array( shared_array && r ) NDNBOOST_NOEXCEPT : px( r.px ), pn()
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070099 {
100 pn.swap( r.pn );
101 r.px = 0;
102 }
103
104#endif
105
106 // conversion
107
108 template<class Y>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700109#if !defined( NDNBOOST_SP_NO_SP_CONVERTIBLE )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700110
111 shared_array( shared_array<Y> const & r, typename ndnboost::detail::sp_enable_if_convertible< Y[], T[] >::type = ndnboost::detail::sp_empty() )
112
113#else
114
115 shared_array( shared_array<Y> const & r )
116
117#endif
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700118 NDNBOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700119 {
120 ndnboost::detail::sp_assert_convertible< Y[], T[] >();
121 }
122
123 // aliasing
124
125 template< class Y >
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700126 shared_array( shared_array<Y> const & r, element_type * p ) NDNBOOST_NOEXCEPT : px( p ), pn( r.pn )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700127 {
128 }
129
130 // assignment
131
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700132 shared_array & operator=( shared_array const & r ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700133 {
134 this_type( r ).swap( *this );
135 return *this;
136 }
137
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700138#if !defined(NDNBOOST_MSVC) || (NDNBOOST_MSVC >= 1400)
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700139
140 template<class Y>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700141 shared_array & operator=( shared_array<Y> const & r ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700142 {
143 this_type( r ).swap( *this );
144 return *this;
145 }
146
147#endif
148
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700149#if !defined( NDNBOOST_NO_CXX11_RVALUE_REFERENCES )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700150
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700151 shared_array & operator=( shared_array && r ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700152 {
153 this_type( static_cast< shared_array && >( r ) ).swap( *this );
154 return *this;
155 }
156
157 template<class Y>
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700158 shared_array & operator=( shared_array<Y> && r ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700159 {
160 this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
161 return *this;
162 }
163
164#endif
165
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700166 void reset() NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700167 {
168 this_type().swap( *this );
169 }
170
171 template<class Y> void reset( Y * p ) // Y must be complete
172 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700173 NDNBOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700174 this_type( p ).swap( *this );
175 }
176
177 template<class Y, class D> void reset( Y * p, D d )
178 {
179 this_type( p, d ).swap( *this );
180 }
181
182 template<class Y, class D, class A> void reset( Y * p, D d, A a )
183 {
184 this_type( p, d, a ).swap( *this );
185 }
186
187 template<class Y> void reset( shared_array<Y> const & r, element_type * p )
188 {
189 this_type( r, p ).swap( *this );
190 }
191
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700192 T & operator[] (std::ptrdiff_t i) const // never throws (but has a NDNBOOST_ASSERT in it, so not marked with NDNBOOST_NOEXCEPT)
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700193 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700194 NDNBOOST_ASSERT(px != 0);
195 NDNBOOST_ASSERT(i >= 0);
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700196 return px[i];
197 }
198
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700199 T * get() const NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700200 {
201 return px;
202 }
203
204// implicit conversion to "bool"
205#include <ndnboost/smart_ptr/detail/operator_bool.hpp>
206
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700207 bool unique() const NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700208 {
209 return pn.unique();
210 }
211
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700212 long use_count() const NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700213 {
214 return pn.use_count();
215 }
216
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700217 void swap(shared_array<T> & other) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700218 {
219 std::swap(px, other.px);
220 pn.swap(other.pn);
221 }
222
223 void * _internal_get_deleter( ndnboost::detail::sp_typeinfo const & ti ) const
224 {
225 return pn.get_deleter( ti );
226 }
227
228private:
229
230 template<class Y> friend class shared_array;
231
232 T * px; // contained pointer
233 detail::shared_count pn; // reference counter
234
235}; // shared_array
236
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700237template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700238{
239 return a.get() == b.get();
240}
241
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700242template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700243{
244 return a.get() != b.get();
245}
246
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700247#if !defined( NDNBOOST_NO_CXX11_NULLPTR )
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700248
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700249template<class T> inline bool operator==( shared_array<T> const & p, ndnboost::detail::sp_nullptr_t ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700250{
251 return p.get() == 0;
252}
253
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700254template<class T> inline bool operator==( ndnboost::detail::sp_nullptr_t, shared_array<T> const & p ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700255{
256 return p.get() == 0;
257}
258
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700259template<class T> inline bool operator!=( shared_array<T> const & p, ndnboost::detail::sp_nullptr_t ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700260{
261 return p.get() != 0;
262}
263
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700264template<class T> inline bool operator!=( ndnboost::detail::sp_nullptr_t, shared_array<T> const & p ) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700265{
266 return p.get() != 0;
267}
268
269#endif
270
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700271template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700272{
273 return std::less<T*>()(a.get(), b.get());
274}
275
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700276template<class T> void swap(shared_array<T> & a, shared_array<T> & b) NDNBOOST_NOEXCEPT
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700277{
278 a.swap(b);
279}
280
281template< class D, class T > D * get_deleter( shared_array<T> const & p )
282{
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700283 return static_cast< D * >( p._internal_get_deleter( NDNBOOST_SP_TYPEID(D) ) );
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700284}
285
286} // namespace ndnboost
287
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700288#endif // #if defined(NDNBOOST_NO_MEMBER_TEMPLATES) && !defined(NDNBOOST_MSVC6_MEMBER_TEMPLATES)
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700289
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700290#endif // #ifndef NDNBOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED