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