Brian Silverman | 1f5d398 | 2018-08-04 23:37:52 -0700 | [diff] [blame^] | 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 |