Chris@102
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
|
Chris@102
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@102
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //
|
Chris@102
|
7 // See http://www.boost.org/libs/move for documentation.
|
Chris@102
|
8 //
|
Chris@102
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
10
|
Chris@102
|
11 #ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
Chris@102
|
12 #define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
15 # include <boost/config.hpp>
|
Chris@102
|
16 #endif
|
Chris@102
|
17 #
|
Chris@102
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
19 # pragma once
|
Chris@102
|
20 #endif
|
Chris@102
|
21
|
Chris@102
|
22 #include <boost/move/detail/config_begin.hpp>
|
Chris@102
|
23 #include <boost/move/detail/workaround.hpp>
|
Chris@102
|
24 #include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
Chris@102
|
25 #include <boost/move/default_delete.hpp>
|
Chris@102
|
26 #include <boost/move/utility_core.hpp>
|
Chris@102
|
27 #include <boost/move/adl_move_swap.hpp>
|
Chris@102
|
28 #include <boost/static_assert.hpp>
|
Chris@102
|
29 #include <boost/assert.hpp>
|
Chris@102
|
30
|
Chris@102
|
31 #include <cstddef> //For std::nullptr_t and std::size_t
|
Chris@102
|
32
|
Chris@102
|
33 //!\file
|
Chris@102
|
34 //! Describes the smart pointer unique_ptr, a drop-in replacement for std::unique_ptr,
|
Chris@102
|
35 //! usable also from C++03 compilers.
|
Chris@102
|
36 //!
|
Chris@102
|
37 //! Main differences from std::unique_ptr to avoid heavy dependencies,
|
Chris@102
|
38 //! specially in C++03 compilers:
|
Chris@102
|
39 //! - <tt>operator < </tt> uses pointer <tt>operator < </tt>instead of <tt>std::less<common_type></tt>.
|
Chris@102
|
40 //! This avoids dependencies on <tt>std::common_type</tt> and <tt>std::less</tt>
|
Chris@102
|
41 //! (<tt><type_traits>/<functional></tt> headers. In C++03 this avoid pulling Boost.Typeof and other
|
Chris@102
|
42 //! cascading dependencies. As in all Boost platforms <tt>operator <</tt> on raw pointers and
|
Chris@102
|
43 //! other smart pointers provides strict weak ordering in practice this should not be a problem for users.
|
Chris@102
|
44 //! - assignable from literal 0 for compilers without nullptr
|
Chris@102
|
45 //! - <tt>unique_ptr<T[]></tt> is constructible and assignable from <tt>unique_ptr<U[]></tt> if
|
Chris@102
|
46 //! cv-less T and cv-less U are the same type and T is more CV qualified than U.
|
Chris@102
|
47
|
Chris@102
|
48 namespace boost{
|
Chris@102
|
49 namespace move_upd {
|
Chris@102
|
50
|
Chris@102
|
51 ////////////////////////////////////////////
|
Chris@102
|
52 // deleter types
|
Chris@102
|
53 ////////////////////////////////////////////
|
Chris@102
|
54 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
55 template <class T>
|
Chris@102
|
56 class is_noncopyable
|
Chris@102
|
57 {
|
Chris@102
|
58 typedef char true_t;
|
Chris@102
|
59 class false_t { char dummy[2]; };
|
Chris@102
|
60 template<class U> static false_t dispatch(...);
|
Chris@102
|
61 template<class U> static true_t dispatch(typename U::boost_move_no_copy_constructor_or_assign*);
|
Chris@102
|
62 public:
|
Chris@102
|
63 static const bool value = sizeof(dispatch<T>(0)) == sizeof(true_t);
|
Chris@102
|
64 };
|
Chris@102
|
65 #endif //defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
66
|
Chris@102
|
67 template <class D>
|
Chris@102
|
68 struct deleter_types
|
Chris@102
|
69 {
|
Chris@102
|
70 typedef typename bmupmu::add_lvalue_reference<D>::type del_ref;
|
Chris@102
|
71 typedef typename bmupmu::add_const_lvalue_reference<D>::type del_cref;
|
Chris@102
|
72 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
73 typedef typename bmupmu::if_c
|
Chris@102
|
74 < bmupmu::is_lvalue_reference<D>::value, D, del_cref >::type deleter_arg_type1;
|
Chris@102
|
75 typedef typename bmupmu::remove_reference<D>::type && deleter_arg_type2;
|
Chris@102
|
76 #else
|
Chris@102
|
77 typedef typename bmupmu::if_c
|
Chris@102
|
78 < is_noncopyable<D>::value, bmupmu::nat, del_cref>::type non_ref_deleter_arg1;
|
Chris@102
|
79 typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference<D>::value
|
Chris@102
|
80 , D, non_ref_deleter_arg1 >::type deleter_arg_type1;
|
Chris@102
|
81 typedef ::boost::rv<D> & deleter_arg_type2;
|
Chris@102
|
82 #endif
|
Chris@102
|
83 };
|
Chris@102
|
84
|
Chris@102
|
85 ////////////////////////////////////////////
|
Chris@102
|
86 // unique_ptr_data
|
Chris@102
|
87 ////////////////////////////////////////////
|
Chris@102
|
88 template <class P, class D, bool = bmupmu::is_unary_function<D>::value || bmupmu::is_reference<D>::value >
|
Chris@102
|
89 struct unique_ptr_data
|
Chris@102
|
90 {
|
Chris@102
|
91 typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
Chris@102
|
92 typedef typename deleter_types<D>::del_ref del_ref;
|
Chris@102
|
93 typedef typename deleter_types<D>::del_cref del_cref;
|
Chris@102
|
94
|
Chris@102
|
95 unique_ptr_data() BOOST_NOEXCEPT
|
Chris@102
|
96 : m_p(), d()
|
Chris@102
|
97 {}
|
Chris@102
|
98
|
Chris@102
|
99 explicit unique_ptr_data(P p) BOOST_NOEXCEPT
|
Chris@102
|
100 : m_p(p), d()
|
Chris@102
|
101 {}
|
Chris@102
|
102
|
Chris@102
|
103 unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
|
Chris@102
|
104 : m_p(p), d(d1)
|
Chris@102
|
105 {}
|
Chris@102
|
106
|
Chris@102
|
107 template <class U>
|
Chris@102
|
108 unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
|
Chris@102
|
109 : m_p(p), d(::boost::forward<U>(d))
|
Chris@102
|
110 {}
|
Chris@102
|
111
|
Chris@102
|
112 del_ref deleter() { return d; }
|
Chris@102
|
113 del_cref deleter() const{ return d; }
|
Chris@102
|
114
|
Chris@102
|
115 P m_p;
|
Chris@102
|
116 D d;
|
Chris@102
|
117
|
Chris@102
|
118 private:
|
Chris@102
|
119 unique_ptr_data& operator=(const unique_ptr_data&);
|
Chris@102
|
120 unique_ptr_data(const unique_ptr_data&);
|
Chris@102
|
121 };
|
Chris@102
|
122
|
Chris@102
|
123 template <class P, class D>
|
Chris@102
|
124 struct unique_ptr_data<P, D, false>
|
Chris@102
|
125 : private D
|
Chris@102
|
126 {
|
Chris@102
|
127 typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
Chris@102
|
128 typedef typename deleter_types<D>::del_ref del_ref;
|
Chris@102
|
129 typedef typename deleter_types<D>::del_cref del_cref;
|
Chris@102
|
130
|
Chris@102
|
131 unique_ptr_data() BOOST_NOEXCEPT
|
Chris@102
|
132 : D(), m_p()
|
Chris@102
|
133 {}
|
Chris@102
|
134
|
Chris@102
|
135 explicit unique_ptr_data(P p) BOOST_NOEXCEPT
|
Chris@102
|
136 : D(), m_p(p)
|
Chris@102
|
137 {}
|
Chris@102
|
138
|
Chris@102
|
139 unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
|
Chris@102
|
140 : D(d1), m_p(p)
|
Chris@102
|
141 {}
|
Chris@102
|
142
|
Chris@102
|
143 template <class U>
|
Chris@102
|
144 unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
|
Chris@102
|
145 : D(::boost::forward<U>(d)), m_p(p)
|
Chris@102
|
146 {}
|
Chris@102
|
147
|
Chris@102
|
148 del_ref deleter() BOOST_NOEXCEPT { return static_cast<del_ref>(*this); }
|
Chris@102
|
149 del_cref deleter() const BOOST_NOEXCEPT { return static_cast<del_cref>(*this); }
|
Chris@102
|
150
|
Chris@102
|
151 P m_p;
|
Chris@102
|
152
|
Chris@102
|
153 private:
|
Chris@102
|
154 unique_ptr_data& operator=(const unique_ptr_data&);
|
Chris@102
|
155 unique_ptr_data(const unique_ptr_data&);
|
Chris@102
|
156 };
|
Chris@102
|
157
|
Chris@102
|
158 ////////////////////////////////////////////
|
Chris@102
|
159 // is_unique_ptr_convertible
|
Chris@102
|
160 ////////////////////////////////////////////
|
Chris@102
|
161
|
Chris@102
|
162 //Although non-standard, we avoid using pointer_traits
|
Chris@102
|
163 //to avoid heavy dependencies
|
Chris@102
|
164 template <typename T>
|
Chris@102
|
165 struct get_element_type
|
Chris@102
|
166 {
|
Chris@102
|
167 struct DefaultWrap { typedef bmupmu::natify<T> element_type; };
|
Chris@102
|
168 template <typename X> static char test(int, typename X::element_type*);
|
Chris@102
|
169 template <typename X> static int test(...);
|
Chris@102
|
170 static const bool value = (1 == sizeof(test<T>(0, 0)));
|
Chris@102
|
171 typedef typename bmupmu::if_c<value, T, DefaultWrap>::type::element_type type;
|
Chris@102
|
172 };
|
Chris@102
|
173
|
Chris@102
|
174 template<class T>
|
Chris@102
|
175 struct get_element_type<T*>
|
Chris@102
|
176 {
|
Chris@102
|
177 typedef T type;
|
Chris@102
|
178 };
|
Chris@102
|
179
|
Chris@102
|
180 template<class T>
|
Chris@102
|
181 struct get_cvelement
|
Chris@102
|
182 : bmupmu::remove_cv<typename get_element_type<T>::type>
|
Chris@102
|
183 {};
|
Chris@102
|
184
|
Chris@102
|
185 template <class P1, class P2>
|
Chris@102
|
186 struct is_same_cvelement_and_convertible
|
Chris@102
|
187 {
|
Chris@102
|
188 typedef typename bmupmu::remove_reference<P1>::type arg1;
|
Chris@102
|
189 typedef typename bmupmu::remove_reference<P2>::type arg2;
|
Chris@102
|
190 static const bool same_cvless =
|
Chris@102
|
191 bmupmu::is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value;
|
Chris@102
|
192 static const bool value = same_cvless && bmupmu::is_convertible<arg1, arg2>::value;
|
Chris@102
|
193 };
|
Chris@102
|
194
|
Chris@102
|
195 template<bool IsArray, class FromPointer, class ThisPointer>
|
Chris@102
|
196 struct is_unique_ptr_convertible
|
Chris@102
|
197 : is_same_cvelement_and_convertible<FromPointer, ThisPointer>
|
Chris@102
|
198 {};
|
Chris@102
|
199
|
Chris@102
|
200 template<class FromPointer, class ThisPointer>
|
Chris@102
|
201 struct is_unique_ptr_convertible<false, FromPointer, ThisPointer>
|
Chris@102
|
202 : bmupmu::is_convertible<FromPointer, ThisPointer>
|
Chris@102
|
203 {};
|
Chris@102
|
204
|
Chris@102
|
205 ////////////////////////////////////////
|
Chris@102
|
206 //// enable_up_moveconv_assign
|
Chris@102
|
207 ////////////////////////////////////////
|
Chris@102
|
208
|
Chris@102
|
209 template<class T, class FromPointer, class ThisPointer, class Type = bmupmu::nat>
|
Chris@102
|
210 struct enable_up_ptr
|
Chris@102
|
211 : bmupmu::enable_if_c< is_unique_ptr_convertible
|
Chris@102
|
212 < bmupmu::is_array<T>::value, FromPointer, ThisPointer>::value, Type>
|
Chris@102
|
213 {};
|
Chris@102
|
214
|
Chris@102
|
215 ////////////////////////////////////////
|
Chris@102
|
216 //// enable_up_moveconv_assign
|
Chris@102
|
217 ////////////////////////////////////////
|
Chris@102
|
218
|
Chris@102
|
219 template<class T, class D, class U, class E>
|
Chris@102
|
220 struct unique_moveconvert_assignable
|
Chris@102
|
221 {
|
Chris@102
|
222 static const bool value = (bmupmu::extent<T>::value == bmupmu::extent<U>::value) && is_unique_ptr_convertible
|
Chris@102
|
223 < bmupmu::is_array<T>::value
|
Chris@102
|
224 , typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type>::value;
|
Chris@102
|
225 };
|
Chris@102
|
226
|
Chris@102
|
227 template<class T, class D, class U, class E, std::size_t N>
|
Chris@102
|
228 struct unique_moveconvert_assignable<T[], D, U[N], E>
|
Chris@102
|
229 : unique_moveconvert_assignable<T[], D, U[], E>
|
Chris@102
|
230 {};
|
Chris@102
|
231
|
Chris@102
|
232 template<class T, class D, class U, class E, class Type = bmupmu::nat>
|
Chris@102
|
233 struct enable_up_moveconv_assign
|
Chris@102
|
234 : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type>
|
Chris@102
|
235 {};
|
Chris@102
|
236
|
Chris@102
|
237 ////////////////////////////////////////
|
Chris@102
|
238 //// enable_up_moveconv_constr
|
Chris@102
|
239 ////////////////////////////////////////
|
Chris@102
|
240
|
Chris@102
|
241 template<class D, class E, bool IsReference = bmupmu::is_reference<D>::value>
|
Chris@102
|
242 struct unique_deleter_is_initializable
|
Chris@102
|
243 : bmupmu::is_same<D, E>
|
Chris@102
|
244 {};
|
Chris@102
|
245
|
Chris@102
|
246 template <class T, class U>
|
Chris@102
|
247 class is_rvalue_convertible
|
Chris@102
|
248 {
|
Chris@102
|
249 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@102
|
250 typedef typename bmupmu::remove_reference<T>::type&& t_from;
|
Chris@102
|
251 #else
|
Chris@102
|
252 typedef typename bmupmu::if_c
|
Chris@102
|
253 < ::boost::has_move_emulation_enabled<T>::value && !bmupmu::is_reference<T>::value
|
Chris@102
|
254 , ::boost::rv<T>&
|
Chris@102
|
255 , typename bmupmu::add_lvalue_reference<T>::type
|
Chris@102
|
256 >::type t_from;
|
Chris@102
|
257 #endif
|
Chris@102
|
258
|
Chris@102
|
259 typedef char true_t;
|
Chris@102
|
260 class false_t { char dummy[2]; };
|
Chris@102
|
261 static false_t dispatch(...);
|
Chris@102
|
262 static true_t dispatch(U);
|
Chris@102
|
263 static t_from trigger();
|
Chris@102
|
264 public:
|
Chris@102
|
265 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
Chris@102
|
266 };
|
Chris@102
|
267
|
Chris@102
|
268 template<class D, class E>
|
Chris@102
|
269 struct unique_deleter_is_initializable<D, E, false>
|
Chris@102
|
270 {
|
Chris@102
|
271 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
272 //Clang has some problems with is_rvalue_convertible with non-copyable types
|
Chris@102
|
273 //so use intrinsic if available
|
Chris@102
|
274 #if defined(BOOST_CLANG)
|
Chris@102
|
275 #if __has_feature(is_convertible_to)
|
Chris@102
|
276 static const bool value = __is_convertible_to(E, D);
|
Chris@102
|
277 #else
|
Chris@102
|
278 static const bool value = is_rvalue_convertible<E, D>::value;
|
Chris@102
|
279 #endif
|
Chris@102
|
280 #else
|
Chris@102
|
281 static const bool value = is_rvalue_convertible<E, D>::value;
|
Chris@102
|
282 #endif
|
Chris@102
|
283
|
Chris@102
|
284 #else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@102
|
285 //No hope for compilers with move emulation for now. In several compilers is_convertible
|
Chris@102
|
286 // leads to errors, so just move the Deleter and see if the conversion works
|
Chris@102
|
287 static const bool value = true; /*is_rvalue_convertible<E, D>::value*/
|
Chris@102
|
288 #endif
|
Chris@102
|
289 };
|
Chris@102
|
290
|
Chris@102
|
291 template<class T, class D, class U, class E, class Type = bmupmu::nat>
|
Chris@102
|
292 struct enable_up_moveconv_constr
|
Chris@102
|
293 : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value &&
|
Chris@102
|
294 unique_deleter_is_initializable<D, E>::value, Type>
|
Chris@102
|
295 {};
|
Chris@102
|
296
|
Chris@102
|
297 } //namespace move_upd {
|
Chris@102
|
298
|
Chris@102
|
299 namespace movelib {
|
Chris@102
|
300
|
Chris@102
|
301 //! A unique pointer is an object that owns another object and
|
Chris@102
|
302 //! manages that other object through a pointer.
|
Chris@102
|
303 //!
|
Chris@102
|
304 //! More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose
|
Chris@102
|
305 //! of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
|
Chris@102
|
306 //!
|
Chris@102
|
307 //! The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct
|
Chris@102
|
308 //! invocation results in p's appropriate disposition (typically its deletion).
|
Chris@102
|
309 //!
|
Chris@102
|
310 //! Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
|
Chris@102
|
311 //! u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned
|
Chris@102
|
312 //! object via the associated deleter before such replacement is considered completed.
|
Chris@102
|
313 //!
|
Chris@102
|
314 //! Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of
|
Chris@102
|
315 //! such a transfer, the following postconditions hold:
|
Chris@102
|
316 //! - u2.p is equal to the pre-transfer u.p,
|
Chris@102
|
317 //! - u.p is equal to nullptr, and
|
Chris@102
|
318 //! - if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
|
Chris@102
|
319 //!
|
Chris@102
|
320 //! As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer
|
Chris@102
|
321 //! associated deleter before the ownership transfer is considered complete.
|
Chris@102
|
322 //!
|
Chris@102
|
323 //! Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict
|
Chris@102
|
324 //! ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each
|
Chris@102
|
325 //! such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
|
Chris@102
|
326 //! The template parameter T of unique_ptr may be an incomplete type.
|
Chris@102
|
327 //!
|
Chris@102
|
328 //! The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing
|
Chris@102
|
329 //! ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
|
Chris@102
|
330 //! a function.
|
Chris@102
|
331 //!
|
Chris@102
|
332 //! If T is an array type (e.g. unique_ptr<MyType[]>) the interface is slightly altered:
|
Chris@102
|
333 //! - Pointers to types derived from T are rejected by the constructors, and by reset.
|
Chris@102
|
334 //! - The observers <tt>operator*</tt> and <tt>operator-></tt> are not provided.
|
Chris@102
|
335 //! - The indexing observer <tt>operator[]</tt> is provided.
|
Chris@102
|
336 //!
|
Chris@102
|
337 //! \tparam T Provides the type of the stored pointer.
|
Chris@102
|
338 //! \tparam D The deleter type:
|
Chris@102
|
339 //! - The default type for the template parameter D is default_delete. A client-supplied template argument
|
Chris@102
|
340 //! D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type
|
Chris@102
|
341 //! for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression
|
Chris@102
|
342 //! d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
|
Chris@102
|
343 //! - If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
|
Chris@102
|
344 //! - If the type <tt>remove_reference<D>::type::pointer</tt> exists, it shall satisfy the requirements of NullablePointer.
|
Chris@102
|
345 template <class T, class D = default_delete<T> >
|
Chris@102
|
346 class unique_ptr
|
Chris@102
|
347 {
|
Chris@102
|
348 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
Chris@102
|
349 public:
|
Chris@102
|
350 unique_ptr(const unique_ptr&) = delete;
|
Chris@102
|
351 unique_ptr& operator=(const unique_ptr&) = delete;
|
Chris@102
|
352 private:
|
Chris@102
|
353 #else
|
Chris@102
|
354 BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
|
Chris@102
|
355
|
Chris@102
|
356 typedef bmupmu::pointer_type<T, D > pointer_type_obtainer;
|
Chris@102
|
357 typedef bmupd::unique_ptr_data
|
Chris@102
|
358 <typename pointer_type_obtainer::type, D> data_type;
|
Chris@102
|
359 typedef typename bmupd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
Chris@102
|
360 typedef typename bmupd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2;
|
Chris@102
|
361 data_type m_data;
|
Chris@102
|
362 #endif
|
Chris@102
|
363
|
Chris@102
|
364 public:
|
Chris@102
|
365 //! If the type <tt>remove_reference<D>::type::pointer</tt> exists, then it shall be a
|
Chris@102
|
366 //! synonym for <tt>remove_reference<D>::type::pointer</tt>. Otherwise it shall be a
|
Chris@102
|
367 //! synonym for T*.
|
Chris@102
|
368 typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer;
|
Chris@102
|
369 //! If T is an array type, then element_type is equal to T. Otherwise, if T is a type
|
Chris@102
|
370 //! in the form U[], element_type is equal to U.
|
Chris@102
|
371 typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent<T>::type) element_type;
|
Chris@102
|
372 typedef D deleter_type;
|
Chris@102
|
373
|
Chris@102
|
374 //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
|
Chris@102
|
375 //! that construction shall not throw an exception.
|
Chris@102
|
376 //!
|
Chris@102
|
377 //! <b>Effects</b>: Constructs a unique_ptr object that owns nothing, value-initializing the
|
Chris@102
|
378 //! stored pointer and the stored deleter.
|
Chris@102
|
379 //!
|
Chris@102
|
380 //! <b>Postconditions</b>: <tt>get() == nullptr</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
|
Chris@102
|
381 //!
|
Chris@102
|
382 //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
|
Chris@102
|
383 //! for the template argument D, the program is ill-formed.
|
Chris@102
|
384 BOOST_CONSTEXPR unique_ptr() BOOST_NOEXCEPT
|
Chris@102
|
385 : m_data()
|
Chris@102
|
386 {
|
Chris@102
|
387 //If this constructor is instantiated with a pointer type or reference type
|
Chris@102
|
388 //for the template argument D, the program is ill-formed.
|
Chris@102
|
389 BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
Chris@102
|
390 BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
Chris@102
|
391 }
|
Chris@102
|
392
|
Chris@102
|
393 //! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor).
|
Chris@102
|
394 //!
|
Chris@102
|
395 BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
Chris@102
|
396 : m_data()
|
Chris@102
|
397 {
|
Chris@102
|
398 //If this constructor is instantiated with a pointer type or reference type
|
Chris@102
|
399 //for the template argument D, the program is ill-formed.
|
Chris@102
|
400 BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
Chris@102
|
401 BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
Chris@102
|
402 }
|
Chris@102
|
403
|
Chris@102
|
404 //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
|
Chris@102
|
405 //! that construction shall not throw an exception.
|
Chris@102
|
406 //!
|
Chris@102
|
407 //! <b>Effects</b>: Constructs a unique_ptr which owns p, initializing the stored pointer
|
Chris@102
|
408 //! with p and value initializing the stored deleter.
|
Chris@102
|
409 //!
|
Chris@102
|
410 //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
|
Chris@102
|
411 //!
|
Chris@102
|
412 //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
|
Chris@102
|
413 //! for the template argument D, the program is ill-formed.
|
Chris@102
|
414 //! This constructor shall not participate in overload resolution unless:
|
Chris@102
|
415 //! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
Chris@102
|
416 //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
Chris@102
|
417 template<class Pointer>
|
Chris@102
|
418 explicit unique_ptr(Pointer p
|
Chris@102
|
419 BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
Chris@102
|
420 ) BOOST_NOEXCEPT
|
Chris@102
|
421 : m_data(p)
|
Chris@102
|
422 {
|
Chris@102
|
423 //If T is not an array type, element_type_t<Pointer> derives from T
|
Chris@102
|
424 //it uses the default deleter and T has no virtual destructor, then you have a problem
|
Chris@102
|
425 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
Chris@102
|
426 <D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
Chris@102
|
427 //If this constructor is instantiated with a pointer type or reference type
|
Chris@102
|
428 //for the template argument D, the program is ill-formed.
|
Chris@102
|
429 BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
Chris@102
|
430 BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
Chris@102
|
431 }
|
Chris@102
|
432
|
Chris@102
|
433 //!The signature of this constructor depends upon whether D is a reference type.
|
Chris@102
|
434 //! - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
|
Chris@102
|
435 //! - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A& d)</tt>.
|
Chris@102
|
436 //! - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
|
Chris@102
|
437 //!
|
Chris@102
|
438 //!
|
Chris@102
|
439 //! <b>Requires</b>: Either
|
Chris@102
|
440 //! - D is not an lvalue-reference type and d is an lvalue or const rvalue.
|
Chris@102
|
441 //! D shall satisfy the requirements of CopyConstructible, and the copy constructor of D
|
Chris@102
|
442 //! shall not throw an exception. This unique_ptr will hold a copy of d.
|
Chris@102
|
443 //! - D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor
|
Chris@102
|
444 //! MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d.
|
Chris@102
|
445 //!
|
Chris@102
|
446 //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
|
Chris@102
|
447 //! initializing the deleter as described above.
|
Chris@102
|
448 //!
|
Chris@102
|
449 //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
|
Chris@102
|
450 //! reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
|
Chris@102
|
451 //!
|
Chris@102
|
452 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
453 //! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
Chris@102
|
454 //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
Chris@102
|
455 template<class Pointer>
|
Chris@102
|
456 unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
|
Chris@102
|
457 BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
Chris@102
|
458 ) BOOST_NOEXCEPT
|
Chris@102
|
459 : m_data(p, d1)
|
Chris@102
|
460 {
|
Chris@102
|
461 //If T is not an array type, element_type_t<Pointer> derives from T
|
Chris@102
|
462 //it uses the default deleter and T has no virtual destructor, then you have a problem
|
Chris@102
|
463 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
Chris@102
|
464 <D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
Chris@102
|
465 }
|
Chris@102
|
466
|
Chris@102
|
467 //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt>
|
Chris@102
|
468 //! and additionally <tt>get() == nullptr</tt>
|
Chris@102
|
469 unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
|
Chris@102
|
470 : m_data(pointer(), d1)
|
Chris@102
|
471 {}
|
Chris@102
|
472
|
Chris@102
|
473 //! The signature of this constructor depends upon whether D is a reference type.
|
Chris@102
|
474 //! - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
|
Chris@102
|
475 //! - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
|
Chris@102
|
476 //! - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A&& d)</tt>.
|
Chris@102
|
477 //!
|
Chris@102
|
478 //! <b>Requires</b>: Either
|
Chris@102
|
479 //! - D is not an lvalue-reference type and d is a non-const rvalue. D
|
Chris@102
|
480 //! shall satisfy the requirements of MoveConstructible, and the move constructor
|
Chris@102
|
481 //! of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
|
Chris@102
|
482 //! - D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
|
Chris@102
|
483 //!
|
Chris@102
|
484 //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
|
Chris@102
|
485 //! initializing the deleter as described above.
|
Chris@102
|
486 //!
|
Chris@102
|
487 //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
|
Chris@102
|
488 //! reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
|
Chris@102
|
489 //!
|
Chris@102
|
490 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
491 //! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
Chris@102
|
492 //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
Chris@102
|
493 template<class Pointer>
|
Chris@102
|
494 unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
|
Chris@102
|
495 BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
Chris@102
|
496 ) BOOST_NOEXCEPT
|
Chris@102
|
497 : m_data(p, ::boost::move(d2))
|
Chris@102
|
498 {
|
Chris@102
|
499 //If T is not an array type, element_type_t<Pointer> derives from T
|
Chris@102
|
500 //it uses the default deleter and T has no virtual destructor, then you have a problem
|
Chris@102
|
501 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
Chris@102
|
502 <D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
Chris@102
|
503 }
|
Chris@102
|
504
|
Chris@102
|
505 //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt>
|
Chris@102
|
506 //! and additionally <tt>get() == nullptr</tt>
|
Chris@102
|
507 unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
|
Chris@102
|
508 : m_data(pointer(), ::boost::move(d2))
|
Chris@102
|
509 {}
|
Chris@102
|
510
|
Chris@102
|
511 //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveConstructible.
|
Chris@102
|
512 //! Construction of the deleter from an rvalue of type D shall not throw an exception.
|
Chris@102
|
513 //!
|
Chris@102
|
514 //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type,
|
Chris@102
|
515 //! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's
|
Chris@102
|
516 //! deleter.
|
Chris@102
|
517 //!
|
Chris@102
|
518 //! <b>Postconditions</b>: <tt>get()</tt> yields the value u.get() yielded before the construction. <tt>get_deleter()</tt>
|
Chris@102
|
519 //! returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a
|
Chris@102
|
520 //! reference type then <tt>get_deleter()</tt> and <tt>u.get_deleter()</tt> both reference the same lvalue deleter.
|
Chris@102
|
521 unique_ptr(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
|
Chris@102
|
522 : m_data(u.release(), ::boost::move_if_not_lvalue_reference<D>(u.get_deleter()))
|
Chris@102
|
523 {}
|
Chris@102
|
524
|
Chris@102
|
525 //! <b>Requires</b>: If E is not a reference type, construction of the deleter from an rvalue of type E shall be
|
Chris@102
|
526 //! well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the
|
Chris@102
|
527 //! deleter from an lvalue of type E shall be well formed and shall not throw an exception.
|
Chris@102
|
528 //!
|
Chris@102
|
529 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
530 //! - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer,
|
Chris@102
|
531 //! - U is not an array type, and
|
Chris@102
|
532 //! - either D is a reference type and E is the same type as D, or D is not a reference type and E is
|
Chris@102
|
533 //! implicitly convertible to D.
|
Chris@102
|
534 //!
|
Chris@102
|
535 //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type,
|
Chris@102
|
536 //! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
|
Chris@102
|
537 //!
|
Chris@102
|
538 //! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
|
Chris@102
|
539 //! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
|
Chris@102
|
540 template <class U, class E>
|
Chris@102
|
541 unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u
|
Chris@102
|
542 BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0)
|
Chris@102
|
543 ) BOOST_NOEXCEPT
|
Chris@102
|
544 : m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
|
Chris@102
|
545 {
|
Chris@102
|
546 //If T is not an array type, U derives from T
|
Chris@102
|
547 //it uses the default deleter and T has no virtual destructor, then you have a problem
|
Chris@102
|
548 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
Chris@102
|
549 <D, typename unique_ptr<U, E>::pointer>::value ));
|
Chris@102
|
550 }
|
Chris@102
|
551
|
Chris@102
|
552 //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
Chris@102
|
553 //! and shall not throw exceptions.
|
Chris@102
|
554 //!
|
Chris@102
|
555 //! <b>Effects</b>: If <tt>get() == nullpt1r</tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
|
Chris@102
|
556 //!
|
Chris@102
|
557 //! <b>Note</b>: The use of default_delete requires T to be a complete type
|
Chris@102
|
558 ~unique_ptr()
|
Chris@102
|
559 { if(m_data.m_p) m_data.deleter()(m_data.m_p); }
|
Chris@102
|
560
|
Chris@102
|
561 //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveAssignable
|
Chris@102
|
562 //! and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D
|
Chris@102
|
563 //! is a reference type; <tt>remove_reference<D>::type</tt> shall satisfy the CopyAssignable requirements and
|
Chris@102
|
564 //! assignment of the deleter from an lvalue of type D shall not throw an exception.
|
Chris@102
|
565 //!
|
Chris@102
|
566 //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed
|
Chris@102
|
567 //! by <tt>get_deleter() = std::forward<D>(u.get_deleter())</tt>.
|
Chris@102
|
568 //!
|
Chris@102
|
569 //! <b>Returns</b>: *this.
|
Chris@102
|
570 unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
|
Chris@102
|
571 {
|
Chris@102
|
572 this->reset(u.release());
|
Chris@102
|
573 m_data.deleter() = ::boost::move_if_not_lvalue_reference<D>(u.get_deleter());
|
Chris@102
|
574 return *this;
|
Chris@102
|
575 }
|
Chris@102
|
576
|
Chris@102
|
577 //! <b>Requires</b>: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be
|
Chris@102
|
578 //! well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the
|
Chris@102
|
579 //! deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
|
Chris@102
|
580 //!
|
Chris@102
|
581 //! <b>Remarks</b>: This operator shall not participate in overload resolution unless:
|
Chris@102
|
582 //! - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer and
|
Chris@102
|
583 //! - U is not an array type.
|
Chris@102
|
584 //!
|
Chris@102
|
585 //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed by
|
Chris@102
|
586 //! <tt>get_deleter() = std::forward<E>(u.get_deleter())</tt>.
|
Chris@102
|
587 //!
|
Chris@102
|
588 //! <b>Returns</b>: *this.
|
Chris@102
|
589 template <class U, class E>
|
Chris@102
|
590 BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
|
Chris@102
|
591 <T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type)
|
Chris@102
|
592 operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT
|
Chris@102
|
593 {
|
Chris@102
|
594 this->reset(u.release());
|
Chris@102
|
595 m_data.deleter() = ::boost::move_if_not_lvalue_reference<E>(u.get_deleter());
|
Chris@102
|
596 return *this;
|
Chris@102
|
597 }
|
Chris@102
|
598
|
Chris@102
|
599 //! <b>Effects</b>: <tt>reset()</tt>.
|
Chris@102
|
600 //!
|
Chris@102
|
601 //! <b>Postcondition</b>: <tt>get() == nullptr</tt>
|
Chris@102
|
602 //!
|
Chris@102
|
603 //! <b>Returns</b>: *this.
|
Chris@102
|
604 unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
Chris@102
|
605 { this->reset(); return *this; }
|
Chris@102
|
606
|
Chris@102
|
607 //! <b>Requires</b>: <tt>get() != nullptr</tt>.
|
Chris@102
|
608 //!
|
Chris@102
|
609 //! <b>Returns</b>: <tt>*get()</tt>.
|
Chris@102
|
610 //!
|
Chris@102
|
611 //! <b>Remarks</b: If T is an array type, the program is ill-formed.
|
Chris@102
|
612 BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
|
Chris@102
|
613 operator*() const BOOST_NOEXCEPT
|
Chris@102
|
614 {
|
Chris@102
|
615 BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
|
Chris@102
|
616 return *m_data.m_p;
|
Chris@102
|
617 }
|
Chris@102
|
618
|
Chris@102
|
619 //! <b>Requires</b>: i < the number of elements in the array to which the stored pointer points.
|
Chris@102
|
620 //!
|
Chris@102
|
621 //! <b>Returns</b>: <tt>get()[i]</tt>.
|
Chris@102
|
622 //!
|
Chris@102
|
623 //! <b>Remarks</b: If T is not an array type, the program is ill-formed.
|
Chris@102
|
624 BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
|
Chris@102
|
625 operator[](std::size_t i) const BOOST_NOEXCEPT
|
Chris@102
|
626 {
|
Chris@102
|
627 BOOST_ASSERT( bmupmu::extent<T>::value == 0 || i < bmupmu::extent<T>::value );
|
Chris@102
|
628 BOOST_ASSERT(m_data.m_p);
|
Chris@102
|
629 return m_data.m_p[i];
|
Chris@102
|
630 }
|
Chris@102
|
631
|
Chris@102
|
632 //! <b>Requires</b>: <tt>get() != nullptr</tt>.
|
Chris@102
|
633 //!
|
Chris@102
|
634 //! <b>Returns</b>: <tt>get()</tt>.
|
Chris@102
|
635 //!
|
Chris@102
|
636 //! <b>Note</b>: use typically requires that T be a complete type.
|
Chris@102
|
637 //!
|
Chris@102
|
638 //! <b>Remarks</b: If T is an array type, the program is ill-formed.
|
Chris@102
|
639 pointer operator->() const BOOST_NOEXCEPT
|
Chris@102
|
640 {
|
Chris@102
|
641 BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
|
Chris@102
|
642 BOOST_ASSERT(m_data.m_p);
|
Chris@102
|
643 return m_data.m_p;
|
Chris@102
|
644 }
|
Chris@102
|
645
|
Chris@102
|
646 //! <b>Returns</b>: The stored pointer.
|
Chris@102
|
647 //!
|
Chris@102
|
648 pointer get() const BOOST_NOEXCEPT
|
Chris@102
|
649 { return m_data.m_p; }
|
Chris@102
|
650
|
Chris@102
|
651 //! <b>Returns</b>: A reference to the stored deleter.
|
Chris@102
|
652 //!
|
Chris@102
|
653 BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference<D>::type)
|
Chris@102
|
654 get_deleter() BOOST_NOEXCEPT
|
Chris@102
|
655 { return m_data.deleter(); }
|
Chris@102
|
656
|
Chris@102
|
657 //! <b>Returns</b>: A reference to the stored deleter.
|
Chris@102
|
658 //!
|
Chris@102
|
659 BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference<D>::type)
|
Chris@102
|
660 get_deleter() const BOOST_NOEXCEPT
|
Chris@102
|
661 { return m_data.deleter(); }
|
Chris@102
|
662
|
Chris@102
|
663 #ifdef BOOST_MOVE_DOXYGEN_INVOKED
|
Chris@102
|
664 //! <b>Returns</b>: Returns: get() != nullptr.
|
Chris@102
|
665 //!
|
Chris@102
|
666 explicit operator bool
|
Chris@102
|
667 #else
|
Chris@102
|
668 operator bmupd::explicit_bool_arg
|
Chris@102
|
669 #endif
|
Chris@102
|
670 ()const BOOST_NOEXCEPT
|
Chris@102
|
671 {
|
Chris@102
|
672 return m_data.m_p
|
Chris@102
|
673 ? &bmupd::bool_conversion::for_bool
|
Chris@102
|
674 : bmupd::explicit_bool_arg(0);
|
Chris@102
|
675 }
|
Chris@102
|
676
|
Chris@102
|
677 //! <b>Postcondition</b>: <tt>get() == nullptr</tt>.
|
Chris@102
|
678 //!
|
Chris@102
|
679 //! <b>Returns</b>: The value <tt>get()</tt> had at the start of the call to release.
|
Chris@102
|
680 pointer release() BOOST_NOEXCEPT
|
Chris@102
|
681 {
|
Chris@102
|
682 const pointer tmp = m_data.m_p;
|
Chris@102
|
683 m_data.m_p = pointer();
|
Chris@102
|
684 return tmp;
|
Chris@102
|
685 }
|
Chris@102
|
686
|
Chris@102
|
687 //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
Chris@102
|
688 //! and shall not throw exceptions.
|
Chris@102
|
689 //!
|
Chris@102
|
690 //! <b>Effects</b>: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not
|
Chris@102
|
691 //! equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
|
Chris@102
|
692 //! because the call to <tt>get_deleter()</tt> may destroy *this.
|
Chris@102
|
693 //!
|
Chris@102
|
694 //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
|
Chris@102
|
695 //! destroys *this since <tt>this->get()</tt> is no longer a valid expression.
|
Chris@102
|
696 //!
|
Chris@102
|
697 //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
Chris@102
|
698 //! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
Chris@102
|
699 //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
Chris@102
|
700 template<class Pointer>
|
Chris@102
|
701 BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type)
|
Chris@102
|
702 reset(Pointer p) BOOST_NOEXCEPT
|
Chris@102
|
703 {
|
Chris@102
|
704 //If T is not an array type, element_type_t<Pointer> derives from T
|
Chris@102
|
705 //it uses the default deleter and T has no virtual destructor, then you have a problem
|
Chris@102
|
706 BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
Chris@102
|
707 <D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
Chris@102
|
708 pointer tmp = m_data.m_p;
|
Chris@102
|
709 m_data.m_p = p;
|
Chris@102
|
710 if(tmp) m_data.deleter()(tmp);
|
Chris@102
|
711 }
|
Chris@102
|
712
|
Chris@102
|
713 //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
Chris@102
|
714 //! and shall not throw exceptions.
|
Chris@102
|
715 //!
|
Chris@102
|
716 //! <b>Effects</b>: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not
|
Chris@102
|
717 //! equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
|
Chris@102
|
718 //! because the call to <tt>get_deleter()</tt> may destroy *this.
|
Chris@102
|
719 //!
|
Chris@102
|
720 //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
|
Chris@102
|
721 //! destroys *this since <tt>this->get()</tt> is no longer a valid expression.
|
Chris@102
|
722 void reset() BOOST_NOEXCEPT
|
Chris@102
|
723 { this->reset(pointer()); }
|
Chris@102
|
724
|
Chris@102
|
725 //! <b>Effects</b>: Same as <tt>reset()</tt>
|
Chris@102
|
726 //!
|
Chris@102
|
727 void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
Chris@102
|
728 { this->reset(); }
|
Chris@102
|
729
|
Chris@102
|
730 //! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap.
|
Chris@102
|
731 //!
|
Chris@102
|
732 //! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
|
Chris@102
|
733 void swap(unique_ptr& u) BOOST_NOEXCEPT
|
Chris@102
|
734 {
|
Chris@102
|
735 ::boost::adl_move_swap(m_data.m_p, u.m_data.m_p);
|
Chris@102
|
736 ::boost::adl_move_swap(m_data.deleter(), u.m_data.deleter());
|
Chris@102
|
737 }
|
Chris@102
|
738 };
|
Chris@102
|
739
|
Chris@102
|
740 //! <b>Effects</b>: Calls <tt>x.swap(y)</tt>.
|
Chris@102
|
741 //!
|
Chris@102
|
742 template <class T, class D>
|
Chris@102
|
743 inline void swap(unique_ptr<T, D> &x, unique_ptr<T, D> &y) BOOST_NOEXCEPT
|
Chris@102
|
744 { x.swap(y); }
|
Chris@102
|
745
|
Chris@102
|
746 //! <b>Returns</b>: <tt>x.get() == y.get()</tt>.
|
Chris@102
|
747 //!
|
Chris@102
|
748 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
749 inline bool operator==(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
750 { return x.get() == y.get(); }
|
Chris@102
|
751
|
Chris@102
|
752 //! <b>Returns</b>: <tt>x.get() != y.get()</tt>.
|
Chris@102
|
753 //!
|
Chris@102
|
754 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
755 inline bool operator!=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
756 { return x.get() != y.get(); }
|
Chris@102
|
757
|
Chris@102
|
758 //! <b>Returns</b>: x.get() < y.get().
|
Chris@102
|
759 //!
|
Chris@102
|
760 //! <b>Remarks</b>: This comparison shall induce a
|
Chris@102
|
761 //! strict weak ordering betwen pointers.
|
Chris@102
|
762 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
763 inline bool operator<(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
764 { return x.get() < y.get(); }
|
Chris@102
|
765
|
Chris@102
|
766 //! <b>Returns</b>: !(y < x).
|
Chris@102
|
767 //!
|
Chris@102
|
768 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
769 inline bool operator<=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
770 { return !(y < x); }
|
Chris@102
|
771
|
Chris@102
|
772 //! <b>Returns</b>: y < x.
|
Chris@102
|
773 //!
|
Chris@102
|
774 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
775 inline bool operator>(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
776 { return y < x; }
|
Chris@102
|
777
|
Chris@102
|
778 //! <b>Returns</b>:!(x < y).
|
Chris@102
|
779 //!
|
Chris@102
|
780 template <class T1, class D1, class T2, class D2>
|
Chris@102
|
781 inline bool operator>=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
Chris@102
|
782 { return !(x < y); }
|
Chris@102
|
783
|
Chris@102
|
784 //! <b>Returns</b>:!x.
|
Chris@102
|
785 //!
|
Chris@102
|
786 template <class T, class D>
|
Chris@102
|
787 inline bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
Chris@102
|
788 { return !x; }
|
Chris@102
|
789
|
Chris@102
|
790 //! <b>Returns</b>:!x.
|
Chris@102
|
791 //!
|
Chris@102
|
792 template <class T, class D>
|
Chris@102
|
793 inline bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
|
Chris@102
|
794 { return !x; }
|
Chris@102
|
795
|
Chris@102
|
796 //! <b>Returns</b>: (bool)x.
|
Chris@102
|
797 //!
|
Chris@102
|
798 template <class T, class D>
|
Chris@102
|
799 inline bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
Chris@102
|
800 { return !!x; }
|
Chris@102
|
801
|
Chris@102
|
802 //! <b>Returns</b>: (bool)x.
|
Chris@102
|
803 //!
|
Chris@102
|
804 template <class T, class D>
|
Chris@102
|
805 inline bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
|
Chris@102
|
806 { return !!x; }
|
Chris@102
|
807
|
Chris@102
|
808 //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
|
Chris@102
|
809 //!
|
Chris@102
|
810 //! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>.
|
Chris@102
|
811 template <class T, class D>
|
Chris@102
|
812 inline bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
Chris@102
|
813 { return x.get() < typename unique_ptr<T, D>::pointer(); }
|
Chris@102
|
814
|
Chris@102
|
815 //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
|
Chris@102
|
816 //!
|
Chris@102
|
817 //! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>.
|
Chris@102
|
818 template <class T, class D>
|
Chris@102
|
819 inline bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
Chris@102
|
820 { return typename unique_ptr<T, D>::pointer() < x.get(); }
|
Chris@102
|
821
|
Chris@102
|
822 //! <b>Returns</b>: <tt>nullptr < x</tt>.
|
Chris@102
|
823 //!
|
Chris@102
|
824 template <class T, class D>
|
Chris@102
|
825 inline bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
Chris@102
|
826 { return x.get() > typename unique_ptr<T, D>::pointer(); }
|
Chris@102
|
827
|
Chris@102
|
828 //! <b>Returns</b>: <tt>x < nullptr</tt>.
|
Chris@102
|
829 //!
|
Chris@102
|
830 template <class T, class D>
|
Chris@102
|
831 inline bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
Chris@102
|
832 { return typename unique_ptr<T, D>::pointer() > x.get(); }
|
Chris@102
|
833
|
Chris@102
|
834 //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
|
Chris@102
|
835 //!
|
Chris@102
|
836 template <class T, class D>
|
Chris@102
|
837 inline bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
Chris@102
|
838 { return !(bmupd::nullptr_type() < x); }
|
Chris@102
|
839
|
Chris@102
|
840 //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
|
Chris@102
|
841 //!
|
Chris@102
|
842 template <class T, class D>
|
Chris@102
|
843 inline bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
Chris@102
|
844 { return !(x < bmupd::nullptr_type()); }
|
Chris@102
|
845
|
Chris@102
|
846 //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
|
Chris@102
|
847 //!
|
Chris@102
|
848 template <class T, class D>
|
Chris@102
|
849 inline bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
Chris@102
|
850 { return !(x < bmupd::nullptr_type()); }
|
Chris@102
|
851
|
Chris@102
|
852 //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
|
Chris@102
|
853 //!
|
Chris@102
|
854 template <class T, class D>
|
Chris@102
|
855 inline bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
Chris@102
|
856 { return !(bmupd::nullptr_type() < x); }
|
Chris@102
|
857
|
Chris@102
|
858 } //namespace movelib {
|
Chris@102
|
859 } //namespace boost{
|
Chris@102
|
860
|
Chris@102
|
861 #include <boost/move/detail/config_end.hpp>
|
Chris@102
|
862
|
Chris@102
|
863 #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|