]> git.lyx.org Git - lyx.git/blob - boost/boost/smart_ptr/shared_array.hpp
Fix HTML output of \gg and \ll
[lyx.git] / 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/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/shared_ptr.hpp>
29 #include <boost/smart_ptr/detail/shared_count.hpp>
30 #include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
31 #include <boost/detail/workaround.hpp>
32
33 #include <cstddef>            // for std::ptrdiff_t
34 #include <algorithm>          // for std::swap
35 #include <functional>         // for std::less
36
37 namespace boost
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
48 template<class T> class shared_array
49 {
50 private:
51
52     // Borland 5.5.1 specific workarounds
53     typedef checked_array_deleter<T> deleter;
54     typedef shared_array<T> this_type;
55
56 public:
57
58     typedef T element_type;
59
60     shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
61     {
62     }
63
64     template<class Y>
65     explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
66     {
67         boost::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         boost::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         boost::detail::sp_assert_convertible< Y[], T[] >();
86     }
87
88 //  generated copy constructor, destructor are fine...
89
90 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
91
92 // ... except in C++0x, move disables the implicit copy
93
94     shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
95     {
96     }
97
98     shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
99     {
100         pn.swap( r.pn );
101         r.px = 0;
102     }
103
104 #endif
105
106     // conversion
107
108     template<class Y>
109 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
110
111     shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
112
113 #else
114
115     shared_array( shared_array<Y> const & r )
116
117 #endif
118     BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
119     {
120         boost::detail::sp_assert_convertible< Y[], T[] >();
121     }
122
123     // aliasing
124
125     template< class Y >
126     shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
127     {
128     }
129
130     // assignment
131
132     shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
133     {
134         this_type( r ).swap( *this );
135         return *this;
136     }
137
138 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
139
140     template<class Y>
141     shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
142     {
143         this_type( r ).swap( *this );
144         return *this;
145     }
146
147 #endif
148
149 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
150
151     shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
152     {
153         this_type( static_cast< shared_array && >( r ) ).swap( *this );
154         return *this;
155     }
156
157     template<class Y>
158     shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
159     {
160         this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
161         return *this;
162     }
163
164 #endif
165
166     void reset() BOOST_NOEXCEPT
167     {
168         this_type().swap( *this );
169     }
170
171     template<class Y> void reset( Y * p ) // Y must be complete
172     {
173         BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
174         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
192     T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
193     {
194         BOOST_ASSERT(px != 0);
195         BOOST_ASSERT(i >= 0);
196         return px[i];
197     }
198     
199     T * get() const BOOST_NOEXCEPT
200     {
201         return px;
202     }
203
204 // implicit conversion to "bool"
205 #include <boost/smart_ptr/detail/operator_bool.hpp>
206
207     bool unique() const BOOST_NOEXCEPT
208     {
209         return pn.unique();
210     }
211
212     long use_count() const BOOST_NOEXCEPT
213     {
214         return pn.use_count();
215     }
216
217     void swap(shared_array<T> & other) BOOST_NOEXCEPT
218     {
219         std::swap(px, other.px);
220         pn.swap(other.pn);
221     }
222
223     void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
224     {
225         return pn.get_deleter( ti );
226     }
227
228 private:
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
237 template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
238 {
239     return a.get() == b.get();
240 }
241
242 template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
243 {
244     return a.get() != b.get();
245 }
246
247 #if !defined( BOOST_NO_CXX11_NULLPTR )
248
249 template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
250 {
251     return p.get() == 0;
252 }
253
254 template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
255 {
256     return p.get() == 0;
257 }
258
259 template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
260 {
261     return p.get() != 0;
262 }
263
264 template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
265 {
266     return p.get() != 0;
267 }
268
269 #endif
270
271 template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
272 {
273     return std::less<T*>()(a.get(), b.get());
274 }
275
276 template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
277 {
278     a.swap(b);
279 }
280
281 template< class D, class T > D * get_deleter( shared_array<T> const & p )
282 {
283     return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
284 }
285
286 } // namespace boost
287
288 #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
289
290 #endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED