]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/shared_array.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / smart_ptr / shared_array.hpp
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, 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/ for documentation.
15 //
16
17 #include <boost/config.hpp> // for broken compiler workarounds
18
19 #include <memory> // TR1 cyclic inclusion fix
20
21 #include <boost/assert.hpp>
22 #include <boost/checked_delete.hpp>
23
24 #include <boost/smart_ptr/shared_ptr.hpp>
25 #include <boost/smart_ptr/detail/shared_count.hpp>
26 #include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
27 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
28 #include <boost/detail/workaround.hpp>
29
30 #include <cstddef> // for std::ptrdiff_t
31 #include <algorithm> // for std::swap
32 #include <functional> // for std::less
33
34 namespace boost
35 {
36
37 //
38 // shared_array
39 //
40 // shared_array extends shared_ptr to arrays.
41 // The array pointed to is deleted when the last shared_array pointing to it
42 // is destroyed or reset.
43 //
44
45 template<class T> class shared_array
46 {
47 private:
48
49 // Borland 5.5.1 specific workarounds
50 typedef checked_array_deleter<T> deleter;
51 typedef shared_array<T> this_type;
52
53 public:
54
55 typedef T element_type;
56
57 shared_array() BOOST_SP_NOEXCEPT : px( 0 ), pn()
58 {
59 }
60
61 #if !defined( BOOST_NO_CXX11_NULLPTR )
62
63 shared_array( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn()
64 {
65 }
66
67 #endif
68
69 template<class Y>
70 explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
71 {
72 boost::detail::sp_assert_convertible< Y[], T[] >();
73 }
74
75 //
76 // Requirements: D's copy constructor must not throw
77 //
78 // shared_array will release p by calling d(p)
79 //
80
81 template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
82 {
83 boost::detail::sp_assert_convertible< Y[], T[] >();
84 }
85
86 // As above, but with allocator. A's copy constructor shall not throw.
87
88 template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
89 {
90 boost::detail::sp_assert_convertible< Y[], T[] >();
91 }
92
93 // generated copy constructor, destructor are fine...
94
95 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
96
97 // ... except in C++0x, move disables the implicit copy
98
99 shared_array( shared_array const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
100 {
101 }
102
103 shared_array( shared_array && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn()
104 {
105 pn.swap( r.pn );
106 r.px = 0;
107 }
108
109 #endif
110
111 // conversion
112
113 template<class Y>
114 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
115
116 shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
117
118 #else
119
120 shared_array( shared_array<Y> const & r )
121
122 #endif
123 BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
124 {
125 boost::detail::sp_assert_convertible< Y[], T[] >();
126 }
127
128 // aliasing
129
130 template< class Y >
131 shared_array( shared_array<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT : px( p ), pn( r.pn )
132 {
133 }
134
135 // assignment
136
137 shared_array & operator=( shared_array const & r ) BOOST_SP_NOEXCEPT
138 {
139 this_type( r ).swap( *this );
140 return *this;
141 }
142
143 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
144
145 template<class Y>
146 shared_array & operator=( shared_array<Y> const & r ) BOOST_SP_NOEXCEPT
147 {
148 this_type( r ).swap( *this );
149 return *this;
150 }
151
152 #endif
153
154 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
155
156 shared_array & operator=( shared_array && r ) BOOST_SP_NOEXCEPT
157 {
158 this_type( static_cast< shared_array && >( r ) ).swap( *this );
159 return *this;
160 }
161
162 template<class Y>
163 shared_array & operator=( shared_array<Y> && r ) BOOST_SP_NOEXCEPT
164 {
165 this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
166 return *this;
167 }
168
169 #endif
170
171 void reset() BOOST_SP_NOEXCEPT
172 {
173 this_type().swap( *this );
174 }
175
176 template<class Y> void reset( Y * p ) // Y must be complete
177 {
178 BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
179 this_type( p ).swap( *this );
180 }
181
182 template<class Y, class D> void reset( Y * p, D d )
183 {
184 this_type( p, d ).swap( *this );
185 }
186
187 template<class Y, class D, class A> void reset( Y * p, D d, A a )
188 {
189 this_type( p, d, a ).swap( *this );
190 }
191
192 template<class Y> void reset( shared_array<Y> const & r, element_type * p ) BOOST_SP_NOEXCEPT
193 {
194 this_type( r, p ).swap( *this );
195 }
196
197 T & operator[] (std::ptrdiff_t i) const BOOST_SP_NOEXCEPT_WITH_ASSERT
198 {
199 BOOST_ASSERT(px != 0);
200 BOOST_ASSERT(i >= 0);
201 return px[i];
202 }
203
204 T * get() const BOOST_SP_NOEXCEPT
205 {
206 return px;
207 }
208
209 // implicit conversion to "bool"
210 #include <boost/smart_ptr/detail/operator_bool.hpp>
211
212 bool unique() const BOOST_SP_NOEXCEPT
213 {
214 return pn.unique();
215 }
216
217 long use_count() const BOOST_SP_NOEXCEPT
218 {
219 return pn.use_count();
220 }
221
222 void swap(shared_array<T> & other) BOOST_SP_NOEXCEPT
223 {
224 std::swap(px, other.px);
225 pn.swap(other.pn);
226 }
227
228 void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
229 {
230 return pn.get_deleter( ti );
231 }
232
233 private:
234
235 template<class Y> friend class shared_array;
236
237 T * px; // contained pointer
238 detail::shared_count pn; // reference counter
239
240 }; // shared_array
241
242 template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
243 {
244 return a.get() == b.get();
245 }
246
247 template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
248 {
249 return a.get() != b.get();
250 }
251
252 #if !defined( BOOST_NO_CXX11_NULLPTR )
253
254 template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
255 {
256 return p.get() == 0;
257 }
258
259 template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_SP_NOEXCEPT
260 {
261 return p.get() == 0;
262 }
263
264 template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
265 {
266 return p.get() != 0;
267 }
268
269 template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_SP_NOEXCEPT
270 {
271 return p.get() != 0;
272 }
273
274 #endif
275
276 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_SP_NOEXCEPT
277 {
278 return std::less<T*>()(a.get(), b.get());
279 }
280
281 template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_SP_NOEXCEPT
282 {
283 a.swap(b);
284 }
285
286 template< class D, class T > D * get_deleter( shared_array<T> const & p ) BOOST_SP_NOEXCEPT
287 {
288 return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
289 }
290
291 } // namespace boost
292
293 #endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED