Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:50

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/move for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
0012 #define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/move/detail/config_begin.hpp>
0023 #include <boost/move/detail/workaround.hpp>  //forceinline
0024 #include <boost/move/detail/unique_ptr_meta_utils.hpp>
0025 #include <boost/move/default_delete.hpp>
0026 #include <boost/move/utility_core.hpp>
0027 #include <boost/move/adl_move_swap.hpp>
0028 #include <cassert>
0029 
0030 #include <cstddef>   //For std::nullptr_t and std::size_t
0031 
0032 //!\file
0033 //! Describes the smart pointer unique_ptr, a drop-in replacement for std::unique_ptr,
0034 //! usable also from C++03 compilers.
0035 //!
0036 //! Main differences from std::unique_ptr to avoid heavy dependencies,
0037 //! specially in C++03 compilers:
0038 //!   - <tt>operator < </tt> uses pointer <tt>operator < </tt>instead of <tt>std::less<common_type></tt>. 
0039 //!      This avoids dependencies on <tt>std::common_type</tt> and <tt>std::less</tt>
0040 //!      (<tt><type_traits>/<functional></tt> headers). In C++03 this avoid pulling Boost.Typeof and other
0041 //!      cascading dependencies. As in all Boost platforms <tt>operator <</tt> on raw pointers and
0042 //!      other smart pointers provides strict weak ordering in practice this should not be a problem for users.
0043 //!   - assignable from literal 0 for compilers without nullptr
0044 //!   - <tt>unique_ptr<T[]></tt> is constructible and assignable from <tt>unique_ptr<U[]></tt> if
0045 //!      cv-less T and cv-less U are the same type and T is more CV qualified than U.
0046 
0047 namespace boost{
0048 // @cond
0049 namespace move_upd {
0050 
0051 ////////////////////////////////////////////
0052 //          deleter types
0053 ////////////////////////////////////////////
0054 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0055 template <class T>
0056 class is_noncopyable
0057 {
0058    typedef char true_t;
0059    class false_t { char dummy[2]; };
0060    template<class U> static false_t dispatch(...);
0061    template<class U> static true_t  dispatch(typename U::boost_move_no_copy_constructor_or_assign*);
0062    public:
0063    static const bool value = sizeof(dispatch<T>(0)) == sizeof(true_t);
0064 };
0065 #endif   //defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0066 
0067 template <class D>
0068 struct deleter_types
0069 {
0070    typedef typename bmupmu::add_lvalue_reference<D>::type            del_ref;
0071    typedef typename bmupmu::add_const_lvalue_reference<D>::type      del_cref;
0072    #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0073    typedef typename bmupmu::if_c
0074       < bmupmu::is_lvalue_reference<D>::value, D, del_cref >::type   deleter_arg_type1;
0075    typedef typename bmupmu::remove_reference<D>::type &&             deleter_arg_type2;
0076    #else
0077    typedef typename bmupmu::if_c
0078       < is_noncopyable<D>::value, bmupmu::nat, del_cref>::type       non_ref_deleter_arg1;
0079    typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference<D>::value
0080                        , D, non_ref_deleter_arg1 >::type          deleter_arg_type1;
0081    typedef ::boost::rv<D> &                                       deleter_arg_type2;
0082    #endif
0083 };
0084 
0085 ////////////////////////////////////////////
0086 //          unique_ptr_data
0087 ////////////////////////////////////////////
0088 template <class P, class D, bool = bmupmu::is_unary_function<D>::value || bmupmu::is_reference<D>::value >
0089 struct unique_ptr_data
0090 {
0091    typedef typename deleter_types<D>::deleter_arg_type1  deleter_arg_type1;
0092    typedef typename deleter_types<D>::del_ref            del_ref;
0093    typedef typename deleter_types<D>::del_cref           del_cref;
0094 
0095    BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
0096       : m_p(), d()
0097    {}
0098 
0099    BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
0100       : m_p(p), d()
0101    {}
0102 
0103    BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
0104       : m_p(p), d(d1)
0105    {}
0106 
0107    template <class U>
0108    BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d1) BOOST_NOEXCEPT
0109       : m_p(p), d(::boost::forward<U>(d1))
0110    {}
0111 
0112    BOOST_MOVE_FORCEINLINE del_ref deleter()       { return d; }
0113    BOOST_MOVE_FORCEINLINE del_cref deleter() const{ return d; }
0114 
0115    P m_p;
0116    D d;
0117 
0118    private:
0119    unique_ptr_data& operator=(const unique_ptr_data&);
0120    unique_ptr_data(const unique_ptr_data&);
0121 };
0122 
0123 template <class P, class D>
0124 struct unique_ptr_data<P, D, false>
0125    : private D
0126 {
0127    typedef typename deleter_types<D>::deleter_arg_type1  deleter_arg_type1;
0128    typedef typename deleter_types<D>::del_ref            del_ref;
0129    typedef typename deleter_types<D>::del_cref           del_cref;
0130 
0131    BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
0132       : D(), m_p()
0133    {}
0134 
0135    BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
0136       : D(), m_p(p)
0137    {}
0138 
0139    BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
0140       : D(d1), m_p(p)
0141    {}
0142 
0143    template <class U>
0144    BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
0145       : D(::boost::forward<U>(d)), m_p(p)
0146    {}
0147 
0148    BOOST_MOVE_FORCEINLINE del_ref deleter()        BOOST_NOEXCEPT   {  return static_cast<del_ref>(*this);   }
0149    BOOST_MOVE_FORCEINLINE del_cref deleter() const BOOST_NOEXCEPT   {  return static_cast<del_cref>(*this);  }
0150 
0151    P m_p;
0152 
0153    private:
0154    unique_ptr_data& operator=(const unique_ptr_data&);
0155    unique_ptr_data(const unique_ptr_data&);
0156 };
0157 
0158 ////////////////////////////////////////////
0159 //          is_unique_ptr_convertible
0160 ////////////////////////////////////////////
0161 
0162 //Although non-standard, we avoid using pointer_traits
0163 //to avoid heavy dependencies
0164 template <typename T>
0165 struct get_element_type
0166 {
0167    struct DefaultWrap { typedef bmupmu::natify<T> element_type; };
0168    template <typename X>   static char test(int, typename X::element_type*);
0169    template <typename X>   static int test(...);
0170    static const bool value = (1 == sizeof(test<T>(0, 0)));
0171    typedef typename bmupmu::if_c<value, T, DefaultWrap>::type::element_type type;
0172 };
0173 
0174 template<class T>
0175 struct get_element_type<T*>
0176 {
0177    typedef T type;
0178 };
0179 
0180 template<class T>
0181 struct get_cvelement
0182    : bmupmu::remove_cv<typename get_element_type<T>::type>
0183 {};
0184 
0185 template <class P1, class P2>
0186 struct is_same_cvelement_and_convertible
0187 {
0188    typedef typename bmupmu::remove_reference<P1>::type arg1;
0189    typedef typename bmupmu::remove_reference<P2>::type arg2;
0190    static const bool same_cvless =
0191       bmupmu::is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value;
0192    static const bool value = same_cvless && bmupmu::is_convertible<arg1, arg2>::value;
0193 };
0194 
0195 template<bool IsArray, class FromPointer, class ThisPointer>
0196 struct is_unique_ptr_convertible
0197    : is_same_cvelement_and_convertible<FromPointer, ThisPointer>
0198 {};
0199 
0200 template<class FromPointer, class ThisPointer>
0201 struct is_unique_ptr_convertible<false, FromPointer, ThisPointer>
0202    : bmupmu::is_convertible<FromPointer, ThisPointer>
0203 {};
0204 
0205 ////////////////////////////////////////
0206 ////     enable_up_moveconv_assign
0207 ////////////////////////////////////////
0208 
0209 template<class T, class FromPointer, class ThisPointer, class Type = bmupmu::nat>
0210 struct enable_up_ptr
0211    : bmupmu::enable_if_c< is_unique_ptr_convertible
0212       < bmupmu::is_array<T>::value, FromPointer, ThisPointer>::value, Type>
0213 {};
0214 
0215 ////////////////////////////////////////
0216 ////     enable_up_moveconv_assign
0217 ////////////////////////////////////////
0218 
0219 template<class T, class D, class U, class E>
0220 struct unique_moveconvert_assignable
0221 {
0222    static const bool t_is_array = bmupmu::is_array<T>::value;
0223    static const bool value =
0224       t_is_array == bmupmu::is_array<U>::value &&
0225       bmupmu::extent<T>::value == bmupmu::extent<U>::value &&
0226       is_unique_ptr_convertible
0227          < t_is_array
0228          , typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type
0229          >::value;
0230 };
0231 
0232 template<class T, class D, class U, class E, std::size_t N>
0233 struct unique_moveconvert_assignable<T[], D, U[N], E>
0234    : unique_moveconvert_assignable<T[], D, U[], E>
0235 {};
0236 
0237 template<class T, class D, class U, class E, class Type = bmupmu::nat>
0238 struct enable_up_moveconv_assign
0239    : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type>
0240 {};
0241 
0242 ////////////////////////////////////////
0243 ////     enable_up_moveconv_constr
0244 ////////////////////////////////////////
0245 
0246 template<class D, class E, bool IsReference = bmupmu::is_reference<D>::value>
0247 struct unique_deleter_is_initializable
0248    : bmupmu::is_same<D, E>
0249 {};
0250 
0251 template <class T, class U>
0252 class is_rvalue_convertible
0253 {
0254    #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0255    typedef typename bmupmu::remove_reference<T>::type&& t_from;
0256    #else
0257    typedef typename bmupmu::if_c
0258       < ::boost::has_move_emulation_enabled<T>::value && !bmupmu::is_reference<T>::value
0259       , ::boost::rv<T>&
0260       , typename bmupmu::add_lvalue_reference<T>::type
0261       >::type t_from;
0262    #endif
0263 
0264    typedef char true_t;
0265    class false_t { char dummy[2]; };
0266    static false_t dispatch(...);
0267    static true_t  dispatch(U);
0268    static t_from trigger();
0269    public:
0270    static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
0271 };
0272 
0273 template<class D, class E>
0274 struct unique_deleter_is_initializable<D, E, false>
0275 {
0276    #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0277    //Clang has some problems with is_rvalue_convertible with non-copyable types
0278    //so use intrinsic if available
0279    #if defined(BOOST_CLANG)
0280       #if __has_feature(is_convertible_to)
0281       static const bool value = __is_convertible_to(E, D);
0282       #else
0283       static const bool value = is_rvalue_convertible<E, D>::value;
0284       #endif
0285    #else
0286    static const bool value = is_rvalue_convertible<E, D>::value;
0287    #endif
0288 
0289    #else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0290    //No hope for compilers with move emulation for now. In several compilers is_convertible
0291    // leads to errors, so just move the Deleter and see if the conversion works
0292    static const bool value = true;  /*is_rvalue_convertible<E, D>::value*/
0293    #endif
0294 };
0295 
0296 template<class T, class D, class U, class E, class Type = bmupmu::nat>
0297 struct enable_up_moveconv_constr
0298    : bmupmu::enable_if_c
0299       < unique_moveconvert_assignable<T, D, U, E>::value && unique_deleter_is_initializable<D, E>::value
0300       , Type>
0301 {};
0302 
0303 }  //namespace move_upd {
0304 // @endcond
0305 
0306 namespace movelib {
0307 
0308 //! A unique pointer is an object that owns another object and
0309 //! manages that other object through a pointer.
0310 //! 
0311 //! More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose
0312 //! of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
0313 //! 
0314 //! The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct
0315 //! invocation results in p's appropriate disposition (typically its deletion).
0316 //! 
0317 //! Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
0318 //! u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned
0319 //! object via the associated deleter before such replacement is considered completed.
0320 //! 
0321 //! Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of
0322 //! such a transfer, the following postconditions hold:
0323 //!   - u2.p is equal to the pre-transfer u.p,
0324 //!   - u.p is equal to nullptr, and
0325 //!   - if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
0326 //! 
0327 //! As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer
0328 //! associated deleter before the ownership transfer is considered complete.
0329 //! 
0330 //! Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict
0331 //! ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each
0332 //! such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
0333 //! The template parameter T of unique_ptr may be an incomplete type.
0334 //! 
0335 //! The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing
0336 //! ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
0337 //! a function.
0338 //!
0339 //! If T is an array type (e.g. unique_ptr<MyType[]>) the interface is slightly altered:
0340 //!   - Pointers to types derived from T are rejected by the constructors, and by reset.
0341 //!   - The observers <tt>operator*</tt> and <tt>operator-></tt> are not provided.
0342 //!   - The indexing observer <tt>operator[]</tt> is provided.
0343 //!
0344 //! \tparam T Provides the type of the stored pointer.
0345 //! \tparam D The deleter type:
0346 //!   -  The default type for the template parameter D is default_delete. A client-supplied template argument
0347 //!      D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type
0348 //!      for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression
0349 //!      d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
0350 //!   -  If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
0351 //!   -  If the type <tt>remove_reference<D>::type::pointer</tt> exists, it shall satisfy the requirements of NullablePointer.
0352 template <class T, class D = default_delete<T> >
0353 class unique_ptr
0354 {
0355    #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
0356    public:
0357    unique_ptr(const unique_ptr&) = delete;
0358    unique_ptr& operator=(const unique_ptr&) = delete;
0359    private:
0360    #else
0361    BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
0362 
0363    typedef bmupmu::pointer_type<T, D >                            pointer_type_obtainer;
0364    typedef bmupd::unique_ptr_data
0365       <typename pointer_type_obtainer::type, D>                data_type;
0366    typedef typename bmupd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
0367    typedef typename bmupd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2;
0368    data_type m_data;
0369    #endif
0370 
0371    public:
0372    //! If the type <tt>remove_reference<D>::type::pointer</tt> exists, then it shall be a
0373    //! synonym for <tt>remove_reference<D>::type::pointer</tt>. Otherwise it shall be a
0374    //! synonym for T*.
0375    typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer;
0376    //! If T is an array type, then element_type is equal to T. Otherwise, if T is a type
0377    //! in the form U[], element_type is equal to U.
0378    typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent<T>::type) element_type;
0379    typedef D deleter_type;
0380 
0381    //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
0382    //!   that construction shall not throw an exception.
0383    //!
0384    //! <b>Effects</b>: Constructs a unique_ptr object that owns nothing, value-initializing the
0385    //!   stored pointer and the stored deleter.
0386    //!
0387    //! <b>Postconditions</b>: <tt>get() == nullptr</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
0388    //!
0389    //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
0390    //!   for the template argument D, the program is ill-formed.   
0391    BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr() BOOST_NOEXCEPT
0392       : m_data()
0393    {
0394       //If this constructor is instantiated with a pointer type or reference type
0395       //for the template argument D, the program is ill-formed.
0396       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
0397       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
0398    }
0399 
0400    //! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor).
0401    //! 
0402    BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
0403       : m_data()
0404    {
0405       //If this constructor is instantiated with a pointer type or reference type
0406       //for the template argument D, the program is ill-formed.
0407       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
0408       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
0409    }
0410 
0411    //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
0412    //!   that construction shall not throw an exception.
0413    //!
0414    //! <b>Effects</b>: Constructs a unique_ptr which owns p, initializing the stored pointer 
0415    //!   with p and value initializing the stored deleter.
0416    //!
0417    //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
0418    //!
0419    //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
0420    //!   for the template argument D, the program is ill-formed.
0421    //!   This constructor shall not participate in overload resolution unless:
0422    //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
0423    //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
0424    template<class Pointer>
0425    BOOST_MOVE_FORCEINLINE explicit unique_ptr(Pointer p
0426       BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
0427                  ) BOOST_NOEXCEPT
0428       : m_data(p)
0429    {
0430       //If T is not an array type, element_type_t<Pointer> derives from T
0431       //it uses the default deleter and T has no virtual destructor, then you have a problem
0432       BOOST_MOVE_STATIC_ASSERT(( !bmupd::missing_virtual_destructor
0433                             <D, typename bmupd::get_element_type<Pointer>::type>::value ));
0434       //If this constructor is instantiated with a pointer type or reference type
0435       //for the template argument D, the program is ill-formed.
0436       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
0437       BOOST_MOVE_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
0438    }
0439 
0440    //!The signature of this constructor depends upon whether D is a reference type.
0441    //!   - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
0442    //!   - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A& d)</tt>.
0443    //!   - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
0444    //!
0445    //!
0446    //! <b>Requires</b>: Either
0447    //!   - D is not an lvalue-reference type and d is an lvalue or const rvalue. 
0448    //!         D shall satisfy the requirements of CopyConstructible, and the copy constructor of D
0449    //!         shall not throw an exception. This unique_ptr will hold a copy of d.
0450    //!   - D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor
0451    //!      MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d.
0452    //!
0453    //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
0454    //!   initializing the deleter as described above.
0455    //! 
0456    //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
0457    //!   reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
0458    //!
0459    //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
0460    //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
0461    //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
0462    template<class Pointer>
0463    BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
0464       BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
0465               ) BOOST_NOEXCEPT
0466       : m_data(p, d1)
0467    {
0468       //If T is not an array type, element_type_t<Pointer> derives from T
0469       //it uses the default deleter and T has no virtual destructor, then you have a problem
0470       BOOST_MOVE_STATIC_ASSERT(( !bmupd::missing_virtual_destructor
0471                             <D, typename bmupd::get_element_type<Pointer>::type>::value ));
0472    }
0473 
0474    //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt>
0475    //!   and additionally <tt>get() == nullptr</tt>
0476    BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
0477       : m_data(pointer(), d1)
0478    {}
0479 
0480    //! The signature of this constructor depends upon whether D is a reference type.
0481    //!   - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
0482    //!   - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
0483    //!   - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A&& d)</tt>.
0484    //!
0485    //! <b>Requires</b>: Either
0486    //!   - D is not an lvalue-reference type and d is a non-const rvalue. D
0487    //!      shall satisfy the requirements of MoveConstructible, and the move constructor
0488    //!      of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
0489    //!   - D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
0490    //!
0491    //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
0492    //!   initializing the deleter as described above.
0493    //! 
0494    //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
0495    //!   reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
0496    //!
0497    //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
0498    //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
0499    //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
0500    template<class Pointer>
0501    BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
0502       BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
0503              ) BOOST_NOEXCEPT
0504       : m_data(p, ::boost::move(d2))
0505    {
0506       //If T is not an array type, element_type_t<Pointer> derives from T
0507       //it uses the default deleter and T has no virtual destructor, then you have a problem
0508       BOOST_MOVE_STATIC_ASSERT(( !bmupd::missing_virtual_destructor
0509                             <D, typename bmupd::get_element_type<Pointer>::type>::value ));
0510    }
0511 
0512    //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt>
0513    //!   and additionally <tt>get() == nullptr</tt>
0514    BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
0515       : m_data(pointer(), ::boost::move(d2))
0516    {}
0517 
0518    //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveConstructible.
0519    //! Construction of the deleter from an rvalue of type D shall not throw an exception.
0520    //! 
0521    //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type,
0522    //! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's
0523    //! deleter.
0524    //! 
0525    //! <b>Postconditions</b>: <tt>get()</tt> yields the value u.get() yielded before the construction. <tt>get_deleter()</tt>
0526    //! returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a
0527    //! reference type then <tt>get_deleter()</tt> and <tt>u.get_deleter()</tt> both reference the same lvalue deleter.
0528    BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
0529       : m_data(u.release(), ::boost::move_if_not_lvalue_reference<D>(u.get_deleter()))
0530    {}
0531 
0532    //! <b>Requires</b>: If E is not a reference type, construction of the deleter from an rvalue of type E shall be
0533    //!   well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the
0534    //!   deleter from an lvalue of type E shall be well formed and shall not throw an exception.
0535    //!
0536    //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
0537    //!   - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer,
0538    //!   - U is not an array type, and
0539    //!   - either D is a reference type and E is the same type as D, or D is not a reference type and E is
0540    //!      implicitly convertible to D.
0541    //!
0542    //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type,
0543    //!   this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
0544    //!
0545    //! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
0546    //!   returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
0547    template <class U, class E>
0548    BOOST_MOVE_FORCEINLINE unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr<U, E> BOOST_RV_REF_END_IF_CXX11 u
0549       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)
0550       ) BOOST_NOEXCEPT
0551       : m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
0552    {
0553       //If T is not an array type, U derives from T
0554       //it uses the default deleter and T has no virtual destructor, then you have a problem
0555       BOOST_MOVE_STATIC_ASSERT(( !bmupd::missing_virtual_destructor
0556                             <D, typename unique_ptr<U, E>::pointer>::value ));
0557    }
0558 
0559    //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
0560    //!   and shall not throw exceptions.
0561    //!
0562    //! <b>Effects</b>: If <tt>get() == nullpt1r</tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
0563    //!
0564    //! <b>Note</b>: The use of default_delete requires T to be a complete type
0565    ~unique_ptr()
0566    {  if(m_data.m_p) m_data.deleter()(m_data.m_p);   }
0567 
0568    //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveAssignable
0569    //!   and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D
0570    //!   is a reference type; <tt>remove_reference<D>::type</tt> shall satisfy the CopyAssignable requirements and
0571    //!   assignment of the deleter from an lvalue of type D shall not throw an exception.
0572    //!
0573    //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed
0574    //!   by <tt>get_deleter() = std::forward<D>(u.get_deleter())</tt>.
0575    //!
0576    //! <b>Returns</b>: *this.
0577    unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
0578    {
0579       this->reset(u.release());
0580       m_data.deleter() = ::boost::move_if_not_lvalue_reference<D>(u.get_deleter());
0581       return *this;
0582    }
0583 
0584    //! <b>Requires</b>: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be
0585    //!   well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the
0586    //!   deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
0587    //!
0588    //! <b>Remarks</b>: This operator shall not participate in overload resolution unless:
0589    //!   - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer and
0590    //!   - U is not an array type.
0591    //!
0592    //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed by
0593    //!   <tt>get_deleter() = std::forward<E>(u.get_deleter())</tt>.
0594    //!
0595    //! <b>Returns</b>: *this.
0596    template <class U, class E>
0597    BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
0598          <T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type)
0599       operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT
0600    {
0601       this->reset(u.release());
0602       m_data.deleter() = ::boost::move_if_not_lvalue_reference<E>(u.get_deleter());
0603       return *this;
0604    }
0605 
0606    //! <b>Effects</b>: <tt>reset()</tt>.
0607    //!
0608    //! <b>Postcondition</b>: <tt>get() == nullptr</tt>
0609    //!
0610    //! <b>Returns</b>: *this.
0611    unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
0612    {  this->reset(); return *this;  }
0613 
0614    //! <b>Requires</b>: <tt>get() != nullptr</tt>.
0615    //!
0616    //! <b>Returns</b>: <tt>*get()</tt>.
0617    //!
0618    //! <b>Remarks</b: If T is an array type, the program is ill-formed.
0619    BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
0620       operator*() const BOOST_NOEXCEPT
0621    {
0622       BOOST_MOVE_STATIC_ASSERT((!bmupmu::is_array<T>::value));
0623       return *m_data.m_p;
0624    }
0625 
0626    //! <b>Requires</b>: i < the number of elements in the array to which the stored pointer points.
0627    //!
0628    //! <b>Returns</b>: <tt>get()[i]</tt>.
0629    //!
0630    //! <b>Remarks</b: If T is not an array type, the program is ill-formed.
0631    BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
0632       operator[](std::size_t i) const BOOST_NOEXCEPT
0633    {
0634       assert( bmupmu::extent<T>::value == 0 || i < bmupmu::extent<T>::value );
0635       assert(m_data.m_p);
0636       return m_data.m_p[i];
0637    }
0638 
0639    //! <b>Requires</b>: <tt>get() != nullptr</tt>.
0640    //!
0641    //! <b>Returns</b>: <tt>get()</tt>.
0642    //!
0643    //! <b>Note</b>: use typically requires that T be a complete type.
0644    //!
0645    //! <b>Remarks</b: If T is an array type, the program is ill-formed.
0646    BOOST_MOVE_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT
0647    {
0648       BOOST_MOVE_STATIC_ASSERT((!bmupmu::is_array<T>::value));
0649       assert(m_data.m_p);
0650       return m_data.m_p;
0651    }
0652 
0653    //! <b>Returns</b>: The stored pointer.
0654    //!
0655    BOOST_MOVE_FORCEINLINE pointer get() const BOOST_NOEXCEPT
0656    {  return m_data.m_p;  }
0657 
0658    //! <b>Returns</b>: A reference to the stored deleter.
0659    //!
0660    BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference<D>::type)
0661       get_deleter() BOOST_NOEXCEPT
0662    {  return m_data.deleter();  }   
0663 
0664    //! <b>Returns</b>: A reference to the stored deleter.
0665    //!
0666    BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference<D>::type)
0667       get_deleter() const BOOST_NOEXCEPT
0668    {  return m_data.deleter();  }
0669 
0670    #ifdef BOOST_MOVE_DOXYGEN_INVOKED
0671    //! <b>Returns</b>: Returns: get() != nullptr.
0672    //!
0673    BOOST_MOVE_FORCEINLINE explicit operator bool
0674    #else
0675    BOOST_MOVE_FORCEINLINE operator bmupd::explicit_bool_arg
0676    #endif
0677       ()const BOOST_NOEXCEPT
0678    {
0679       return m_data.m_p
0680          ? &bmupd::bool_conversion::for_bool
0681          : bmupd::explicit_bool_arg(0);
0682    }
0683 
0684    //! <b>Postcondition</b>: <tt>get() == nullptr</tt>.
0685    //!
0686    //! <b>Returns</b>: The value <tt>get()</tt> had at the start of the call to release.   
0687    BOOST_MOVE_FORCEINLINE pointer release() BOOST_NOEXCEPT
0688    {
0689       const pointer tmp = m_data.m_p;
0690       m_data.m_p = pointer();
0691       return tmp;
0692    }
0693 
0694    //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
0695    //!   and shall not throw exceptions.
0696    //!
0697    //! <b>Effects</b>: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not
0698    //!   equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
0699    //!   because the call to <tt>get_deleter()</tt> may destroy *this.
0700    //!
0701    //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
0702    //!   destroys *this since <tt>this->get()</tt> is no longer a valid expression.
0703    //!
0704    //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
0705    //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
0706    //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
0707    template<class Pointer>
0708    BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type)
0709       reset(Pointer p) BOOST_NOEXCEPT
0710    {
0711       //If T is not an array type, element_type_t<Pointer> derives from T
0712       //it uses the default deleter and T has no virtual destructor, then you have a problem
0713       BOOST_MOVE_STATIC_ASSERT(( !bmupd::missing_virtual_destructor
0714                             <D, typename bmupd::get_element_type<Pointer>::type>::value ));
0715       pointer tmp = m_data.m_p;
0716       m_data.m_p = p;
0717       if(tmp) m_data.deleter()(tmp);
0718    }
0719 
0720    //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
0721    //!   and shall not throw exceptions.
0722    //!
0723    //! <b>Effects</b>: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not
0724    //!   equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
0725    //!   because the call to <tt>get_deleter()</tt> may destroy *this.
0726    //!
0727    //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
0728    //!   destroys *this since <tt>this->get()</tt> is no longer a valid expression.
0729    void reset() BOOST_NOEXCEPT
0730    {  this->reset(pointer());  }
0731 
0732    //! <b>Effects</b>: Same as <tt>reset()</tt>
0733    //! 
0734    void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
0735    {  this->reset(); }
0736 
0737    //! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap.
0738    //!
0739    //! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
0740    void swap(unique_ptr& u) BOOST_NOEXCEPT
0741    {
0742       ::boost::adl_move_swap(m_data.m_p, u.m_data.m_p);
0743       ::boost::adl_move_swap(m_data.deleter(), u.m_data.deleter());
0744    }
0745 };
0746 
0747 //! <b>Effects</b>: Calls <tt>x.swap(y)</tt>.
0748 //!
0749 template <class T, class D>
0750 BOOST_MOVE_FORCEINLINE void swap(unique_ptr<T, D> &x, unique_ptr<T, D> &y) BOOST_NOEXCEPT
0751 {  x.swap(y); }
0752 
0753 //! <b>Returns</b>: <tt>x.get() == y.get()</tt>.
0754 //!
0755 template <class T1, class D1, class T2, class D2>
0756 BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0757 {  return x.get() == y.get(); }
0758 
0759 //! <b>Returns</b>: <tt>x.get() != y.get()</tt>.
0760 //!
0761 template <class T1, class D1, class T2, class D2>
0762 BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0763 {  return x.get() != y.get(); }
0764 
0765 //! <b>Returns</b>: x.get() < y.get().
0766 //!
0767 //! <b>Remarks</b>: This comparison shall induce a
0768 //!   strict weak ordering betwen pointers.
0769 template <class T1, class D1, class T2, class D2>
0770 BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0771 {  return x.get() < y.get();  }
0772 
0773 //! <b>Returns</b>: !(y < x).
0774 //!
0775 template <class T1, class D1, class T2, class D2>
0776 BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0777 {  return !(y < x);  }
0778 
0779 //! <b>Returns</b>: y < x.
0780 //!
0781 template <class T1, class D1, class T2, class D2>
0782 BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0783 {  return y < x;  }
0784 
0785 //! <b>Returns</b>:!(x < y).
0786 //!
0787 template <class T1, class D1, class T2, class D2>
0788 BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
0789 {  return !(x < y);  }
0790 
0791 //! <b>Returns</b>:!x.
0792 //!
0793 template <class T, class D>
0794 BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
0795 {  return !x;  }
0796 
0797 //! <b>Returns</b>:!x.
0798 //!
0799 template <class T, class D>
0800 BOOST_MOVE_FORCEINLINE bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
0801 {  return !x;  }
0802 
0803 //! <b>Returns</b>: (bool)x.
0804 //!
0805 template <class T, class D>
0806 BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
0807 {  return !!x;  }
0808 
0809 //! <b>Returns</b>: (bool)x.
0810 //!
0811 template <class T, class D>
0812 BOOST_MOVE_FORCEINLINE bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
0813 {  return !!x;  }
0814 
0815 //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
0816 //!
0817 //! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>.
0818 template <class T, class D>
0819 BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
0820 {  return x.get() < typename unique_ptr<T, D>::pointer();  }
0821 
0822 //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
0823 //!
0824 //! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>.
0825 template <class T, class D>
0826 BOOST_MOVE_FORCEINLINE bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
0827 {  return typename unique_ptr<T, D>::pointer() < x.get();  }
0828 
0829 //! <b>Returns</b>: <tt>nullptr < x</tt>.
0830 //!
0831 template <class T, class D>
0832 BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
0833 {  return x.get() > typename unique_ptr<T, D>::pointer();  }
0834 
0835 //! <b>Returns</b>: <tt>x < nullptr</tt>.
0836 //!
0837 template <class T, class D>
0838 BOOST_MOVE_FORCEINLINE bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
0839 {  return typename unique_ptr<T, D>::pointer() > x.get();  }
0840 
0841 //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
0842 //!
0843 template <class T, class D>
0844 BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
0845 {  return !(bmupd::nullptr_type() < x);  }
0846 
0847 //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
0848 //!
0849 template <class T, class D>
0850 BOOST_MOVE_FORCEINLINE bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
0851 {  return !(x < bmupd::nullptr_type());  }
0852 
0853 //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
0854 //!
0855 template <class T, class D>
0856 BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
0857 {  return !(x < bmupd::nullptr_type());  }
0858 
0859 //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
0860 //!
0861 template <class T, class D>
0862 BOOST_MOVE_FORCEINLINE bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
0863 {  return !(bmupd::nullptr_type() < x);  }
0864 
0865 }  //namespace movelib {
0866 }  //namespace boost{
0867 
0868 #include <boost/move/detail/config_end.hpp>
0869 
0870 #endif   //#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED