annotate DEPENDENCIES/generic/include/boost/move/unique_ptr.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
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