Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 08:54:27

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