Edit: /usr/include/boost/move/unique_ptr.hpp (39216B)
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
#define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
#ifndef BOOST_CONFIG_HPP
# include
#endif
#
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include
#include //forceinline
#include
#include
#include
#include
#include
#include
#include //For std::nullptr_t and std::size_t
//!\file
//! Describes the smart pointer unique_ptr, a drop-in replacement for std::unique_ptr,
//! usable also from C++03 compilers.
//!
//! Main differences from std::unique_ptr to avoid heavy dependencies,
//! specially in C++03 compilers:
//! - operator < uses pointer operator < instead of std::less.
//! This avoids dependencies on std::common_type and std::less
//! (/ headers). In C++03 this avoid pulling Boost.Typeof and other
//! cascading dependencies. As in all Boost platforms operator < on raw pointers and
//! other smart pointers provides strict weak ordering in practice this should not be a problem for users.
//! - assignable from literal 0 for compilers without nullptr
//! - unique_ptr is constructible and assignable from unique_ptr if
//! cv-less T and cv-less U are the same type and T is more CV qualified than U.
namespace boost{
// @cond
namespace move_upd {
////////////////////////////////////////////
// deleter types
////////////////////////////////////////////
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template
class is_noncopyable
{
typedef char true_t;
class false_t { char dummy[2]; };
template static false_t dispatch(...);
template static true_t dispatch(typename U::boost_move_no_copy_constructor_or_assign*);
public:
static const bool value = sizeof(dispatch(0)) == sizeof(true_t);
};
#endif //defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template
struct deleter_types
{
typedef typename bmupmu::add_lvalue_reference::type del_ref;
typedef typename bmupmu::add_const_lvalue_reference::type del_cref;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef typename bmupmu::if_c
< bmupmu::is_lvalue_reference::value, D, del_cref >::type deleter_arg_type1;
typedef typename bmupmu::remove_reference::type && deleter_arg_type2;
#else
typedef typename bmupmu::if_c
< is_noncopyable::value, bmupmu::nat, del_cref>::type non_ref_deleter_arg1;
typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference::value
, D, non_ref_deleter_arg1 >::type deleter_arg_type1;
typedef ::boost::rv & deleter_arg_type2;
#endif
};
////////////////////////////////////////////
// unique_ptr_data
////////////////////////////////////////////
template ::value || bmupmu::is_reference::value >
struct unique_ptr_data
{
typedef typename deleter_types::deleter_arg_type1 deleter_arg_type1;
typedef typename deleter_types::del_ref del_ref;
typedef typename deleter_types::del_cref del_cref;
BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
: m_p(), d()
{}
BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
: m_p(p), d()
{}
BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
: m_p(p), d(d1)
{}
template
BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d1) BOOST_NOEXCEPT
: m_p(p), d(::boost::forward(d1))
{}
BOOST_MOVE_FORCEINLINE del_ref deleter() { return d; }
BOOST_MOVE_FORCEINLINE del_cref deleter() const{ return d; }
P m_p;
D d;
private:
unique_ptr_data& operator=(const unique_ptr_data&);
unique_ptr_data(const unique_ptr_data&);
};
template
struct unique_ptr_data
: private D
{
typedef typename deleter_types::deleter_arg_type1 deleter_arg_type1;
typedef typename deleter_types::del_ref del_ref;
typedef typename deleter_types::del_cref del_cref;
BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
: D(), m_p()
{}
BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
: D(), m_p(p)
{}
BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
: D(d1), m_p(p)
{}
template
BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
: D(::boost::forward(d)), m_p(p)
{}
BOOST_MOVE_FORCEINLINE del_ref deleter() BOOST_NOEXCEPT { return static_cast(*this); }
BOOST_MOVE_FORCEINLINE del_cref deleter() const BOOST_NOEXCEPT { return static_cast(*this); }
P m_p;
private:
unique_ptr_data& operator=(const unique_ptr_data&);
unique_ptr_data(const unique_ptr_data&);
};
////////////////////////////////////////////
// is_unique_ptr_convertible
////////////////////////////////////////////
//Although non-standard, we avoid using pointer_traits
//to avoid heavy dependencies
template
struct get_element_type
{
struct DefaultWrap { typedef bmupmu::natify element_type; };
template static char test(int, typename X::element_type*);
template static int test(...);
static const bool value = (1 == sizeof(test(0, 0)));
typedef typename bmupmu::if_c::type::element_type type;
};
template
struct get_element_type
{
typedef T type;
};
template
struct get_cvelement
: bmupmu::remove_cv::type>
{};
template
struct is_same_cvelement_and_convertible
{
typedef typename bmupmu::remove_reference::type arg1;
typedef typename bmupmu::remove_reference::type arg2;
static const bool same_cvless =
bmupmu::is_same::type,typename get_cvelement::type>::value;
static const bool value = same_cvless && bmupmu::is_convertible::value;
};
template
struct is_unique_ptr_convertible
: is_same_cvelement_and_convertible
{};
template
struct is_unique_ptr_convertible
: bmupmu::is_convertible
{};
////////////////////////////////////////
//// enable_up_moveconv_assign
////////////////////////////////////////
template
struct enable_up_ptr
: bmupmu::enable_if_c< is_unique_ptr_convertible
< bmupmu::is_array::value, FromPointer, ThisPointer>::value, Type>
{};
////////////////////////////////////////
//// enable_up_moveconv_assign
////////////////////////////////////////
template
struct unique_moveconvert_assignable
{
static const bool t_is_array = bmupmu::is_array::value;
static const bool value =
t_is_array == bmupmu::is_array::value &&
bmupmu::extent::value == bmupmu::extent::value &&
is_unique_ptr_convertible
< t_is_array
, typename bmupmu::pointer_type::type, typename bmupmu::pointer_type::type
>::value;
};
template
struct unique_moveconvert_assignable
: unique_moveconvert_assignable
{};
template
struct enable_up_moveconv_assign
: bmupmu::enable_if_c::value, Type>
{};
////////////////////////////////////////
//// enable_up_moveconv_constr
////////////////////////////////////////
template::value>
struct unique_deleter_is_initializable
: bmupmu::is_same
{};
template
class is_rvalue_convertible
{
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef typename bmupmu::remove_reference::type&& t_from;
#else
typedef typename bmupmu::if_c
< ::boost::has_move_emulation_enabled::value && !bmupmu::is_reference::value
, ::boost::rv&
, typename bmupmu::add_lvalue_reference::type
>::type t_from;
#endif
typedef char true_t;
class false_t { char dummy[2]; };
static false_t dispatch(...);
static true_t dispatch(U);
static t_from trigger();
public:
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
};
template
struct unique_deleter_is_initializable
{
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//Clang has some problems with is_rvalue_convertible with non-copyable types
//so use intrinsic if available
#if defined(BOOST_CLANG)
#if __has_feature(is_convertible_to)
static const bool value = __is_convertible_to(E, D);
#else
static const bool value = is_rvalue_convertible::value;
#endif
#else
static const bool value = is_rvalue_convertible::value;
#endif
#else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//No hope for compilers with move emulation for now. In several compilers is_convertible
// leads to errors, so just move the Deleter and see if the conversion works
static const bool value = true; /*is_rvalue_convertible::value*/
#endif
};
template
struct enable_up_moveconv_constr
: bmupmu::enable_if_c
< unique_moveconvert_assignable::value && unique_deleter_is_initializable::value
, Type>
{};
} //namespace move_upd {
// @endcond
namespace movelib {
//! A unique pointer is an object that owns another object and
//! manages that other object through a pointer.
//!
//! More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose
//! of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
//!
//! The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct
//! invocation results in p's appropriate disposition (typically its deletion).
//!
//! Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
//! u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned
//! object via the associated deleter before such replacement is considered completed.
//!
//! Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of
//! such a transfer, the following postconditions hold:
//! - u2.p is equal to the pre-transfer u.p,
//! - u.p is equal to nullptr, and
//! - if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
//!
//! As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer
//! associated deleter before the ownership transfer is considered complete.
//!
//! Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict
//! ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each
//! such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
//! The template parameter T of unique_ptr may be an incomplete type.
//!
//! The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing
//! ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
//! a function.
//!
//! If T is an array type (e.g. unique_ptr) the interface is slightly altered:
//! - Pointers to types derived from T are rejected by the constructors, and by reset.
//! - The observers operator* and operator-> are not provided.
//! - The indexing observer operator[] is provided.
//!
//! \tparam T Provides the type of the stored pointer.
//! \tparam D The deleter type:
//! - The default type for the template parameter D is default_delete. A client-supplied template argument
//! D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type
//! for which, given a value d of type D and a value ptr of type unique_ptr::pointer, the expression
//! d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
//! - If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
//! - If the type remove_reference::type::pointer exists, it shall satisfy the requirements of NullablePointer.
template >
class unique_ptr
{
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
public:
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
private:
#else
BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
typedef bmupmu::pointer_type pointer_type_obtainer;
typedef bmupd::unique_ptr_data
data_type;
typedef typename bmupd::deleter_types::deleter_arg_type1 deleter_arg_type1;
typedef typename bmupd::deleter_types::deleter_arg_type2 deleter_arg_type2;
data_type m_data;
#endif
public:
//! If the type remove_reference::type::pointer exists, then it shall be a
//! synonym for remove_reference::type::pointer. Otherwise it shall be a
//! synonym for T*.
typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer;
//! If T is an array type, then element_type is equal to T. Otherwise, if T is a type
//! in the form U[], element_type is equal to U.
typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent::type) element_type;
typedef D deleter_type;
//! Requires: D shall satisfy the requirements of DefaultConstructible, and
//! that construction shall not throw an exception.
//!
//! Effects: Constructs a unique_ptr object that owns nothing, value-initializing the
//! stored pointer and the stored deleter.
//!
//! Postconditions: get() == nullptr. get_deleter() returns a reference to the stored deleter.
//!
//! Remarks: If this constructor is instantiated with a pointer type or reference type
//! for the template argument D, the program is ill-formed.
BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr() BOOST_NOEXCEPT
: m_data()
{
//If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmupmu::is_pointer::value);
BOOST_STATIC_ASSERT(!bmupmu::is_reference::value);
}
//! Effects: Same as unique_ptr() (default constructor).
//!
BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
: m_data()
{
//If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmupmu::is_pointer::value);
BOOST_STATIC_ASSERT(!bmupmu::is_reference::value);
}
//! Requires: D shall satisfy the requirements of DefaultConstructible, and
//! that construction shall not throw an exception.
//!
//! Effects: Constructs a unique_ptr which owns p, initializing the stored pointer
//! with p and value initializing the stored deleter.
//!
//! Postconditions: get() == p. get_deleter() returns a reference to the stored deleter.
//!
//! Remarks: If this constructor is instantiated with a pointer type or reference type
//! for the template argument D, the program is ill-formed.
//! This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template
BOOST_MOVE_FORCEINLINE explicit unique_ptr(Pointer p
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr::type* =0)
) BOOST_NOEXCEPT
: m_data(p)
{
//If T is not an array type, element_type_t derives from T
//it uses the default deleter and T has no virtual destructor, then you have a problem
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
::type>::value ));
//If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmupmu::is_pointer::value);
BOOST_STATIC_ASSERT(!bmupmu::is_reference::value);
}
//!The signature of this constructor depends upon whether D is a reference type.
//! - If D is non-reference type A, then the signature is unique_ptr(pointer p, const A& d).
//! - If D is an lvalue-reference type A&, then the signature is unique_ptr(pointer p, A& d).
//! - If D is an lvalue-reference type const A&, then the signature is unique_ptr(pointer p, const A& d).
//!
//!
//! Requires: Either
//! - D is not an lvalue-reference type and d is an lvalue or const rvalue.
//! D shall satisfy the requirements of CopyConstructible, and the copy constructor of D
//! shall not throw an exception. This unique_ptr will hold a copy of d.
//! - D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor
//! MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d.
//!
//! Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
//! initializing the deleter as described above.
//!
//! Postconditions: get() == p. get_deleter() returns a reference to the stored deleter. If D is a
//! reference type then get_deleter() returns a reference to the lvalue d.
//!
//! Remarks: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template
BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr::type* =0)
) BOOST_NOEXCEPT
: m_data(p, d1)
{
//If T is not an array type, element_type_t derives from T
//it uses the default deleter and T has no virtual destructor, then you have a problem
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
::type>::value ));
}
//! Effects: Same effects as template unique_ptr(Pointer p, deleter_arg_type1 d1)
//! and additionally get() == nullptr
BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
: m_data(pointer(), d1)
{}
//! The signature of this constructor depends upon whether D is a reference type.
//! - If D is non-reference type A, then the signature is unique_ptr(pointer p, A&& d).
//! - If D is an lvalue-reference type A&, then the signature is unique_ptr(pointer p, A&& d).
//! - If D is an lvalue-reference type const A&, then the signature is unique_ptr(pointer p, const A&& d).
//!
//! Requires: Either
//! - D is not an lvalue-reference type and d is a non-const rvalue. D
//! shall satisfy the requirements of MoveConstructible, and the move constructor
//! of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
//! - D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
//!
//! Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
//! initializing the deleter as described above.
//!
//! Postconditions: get() == p. get_deleter() returns a reference to the stored deleter. If D is a
//! reference type then get_deleter() returns a reference to the lvalue d.
//!
//! Remarks: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template
BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr::type* =0)
) BOOST_NOEXCEPT
: m_data(p, ::boost::move(d2))
{
//If T is not an array type, element_type_t derives from T
//it uses the default deleter and T has no virtual destructor, then you have a problem
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
::type>::value ));
}
//! Effects: Same effects as template unique_ptr(Pointer p, deleter_arg_type2 d2)
//! and additionally get() == nullptr
BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
: m_data(pointer(), ::boost::move(d2))
{}
//! Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible.
//! Construction of the deleter from an rvalue of type D shall not throw an exception.
//!
//! Effects: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type,
//! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's
//! deleter.
//!
//! Postconditions: get() yields the value u.get() yielded before the construction. get_deleter()
//! returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a
//! reference type then get_deleter() and u.get_deleter() both reference the same lvalue deleter.
BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
: m_data(u.release(), ::boost::move_if_not_lvalue_reference(u.get_deleter()))
{}
//! Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be
//! well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the
//! deleter from an lvalue of type E shall be well formed and shall not throw an exception.
//!
//! Remarks: This constructor shall not participate in overload resolution unless:
//! - unique_ptr::pointer is implicitly convertible to pointer,
//! - U is not an array type, and
//! - either D is a reference type and E is the same type as D, or D is not a reference type and E is
//! implicitly convertible to D.
//!
//! Effects: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type,
//! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
//!
//! Postconditions: get() yields the value u.get() yielded before the construction. get_deleter()
//! returns a reference to the stored deleter that was constructed from u.get_deleter().
template
BOOST_MOVE_FORCEINLINE unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr BOOST_RV_REF_END_IF_CXX11 u
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr::type* =0)
) BOOST_NOEXCEPT
: m_data(u.release(), ::boost::move_if_not_lvalue_reference(u.get_deleter()))
{
//If T is not an array type, U derives from T
//it uses the default deleter and T has no virtual destructor, then you have a problem
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
::pointer>::value ));
}
//! Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior,
//! and shall not throw exceptions.
//!
//! Effects: If get() == nullpt1r there are no effects. Otherwise get_deleter()(get()).
//!
//! Note: The use of default_delete requires T to be a complete type
~unique_ptr()
{ if(m_data.m_p) m_data.deleter()(m_data.m_p); }
//! Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable
//! and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D
//! is a reference type; remove_reference::type shall satisfy the CopyAssignable requirements and
//! assignment of the deleter from an lvalue of type D shall not throw an exception.
//!
//! Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed
//! by get_deleter() = std::forward(u.get_deleter()).
//!
//! Returns: *this.
unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
{
this->reset(u.release());
m_data.deleter() = ::boost::move_if_not_lvalue_reference(u.get_deleter());
return *this;
}
//! Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be
//! well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the
//! deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
//!
//! Remarks: This operator shall not participate in overload resolution unless:
//! - unique_ptr::pointer is implicitly convertible to pointer and
//! - U is not an array type.
//!
//! Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by
//! get_deleter() = std::forward(u.get_deleter()).
//!
//! Returns: *this.
template
BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
::type)
operator=(BOOST_RV_REF_BEG unique_ptr BOOST_RV_REF_END u) BOOST_NOEXCEPT
{
this->reset(u.release());
m_data.deleter() = ::boost::move_if_not_lvalue_reference(u.get_deleter());
return *this;
}
//! Effects: reset().
//!
//! Postcondition: get() == nullptr
//!
//! Returns: *this.
unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ this->reset(); return *this; }
//! Requires: get() != nullptr.
//!
//! Returns: *get().
//!
//! Remarks::type)
operator*() const BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT((!bmupmu::is_array::value));
return *m_data.m_p;
}
//! Requires: i < the number of elements in the array to which the stored pointer points.
//!
//! Returns: get()[i].
//!
//! Remarks::type)
operator[](std::size_t i) const BOOST_NOEXCEPT
{
BOOST_ASSERT( bmupmu::extent::value == 0 || i < bmupmu::extent::value );
BOOST_ASSERT(m_data.m_p);
return m_data.m_p[i];
}
//! Requires: get() != nullptr.
//!
//! Returns: get().
//!
//! Note: use typically requires that T be a complete type.
//!
//! Remarks() const BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT((!bmupmu::is_array::value));
BOOST_ASSERT(m_data.m_p);
return m_data.m_p;
}
//! Returns: The stored pointer.
//!
BOOST_MOVE_FORCEINLINE pointer get() const BOOST_NOEXCEPT
{ return m_data.m_p; }
//! Returns: A reference to the stored deleter.
//!
BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference::type)
get_deleter() BOOST_NOEXCEPT
{ return m_data.deleter(); }
//! Returns: A reference to the stored deleter.
//!
BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference::type)
get_deleter() const BOOST_NOEXCEPT
{ return m_data.deleter(); }
#ifdef BOOST_MOVE_DOXYGEN_INVOKED
//! Returns: Returns: get() != nullptr.
//!
BOOST_MOVE_FORCEINLINE explicit operator bool
#else
BOOST_MOVE_FORCEINLINE operator bmupd::explicit_bool_arg
#endif
()const BOOST_NOEXCEPT
{
return m_data.m_p
? &bmupd::bool_conversion::for_bool
: bmupd::explicit_bool_arg(0);
}
//! Postcondition: get() == nullptr.
//!
//! Returns: The value get() had at the start of the call to release.
BOOST_MOVE_FORCEINLINE pointer release() BOOST_NOEXCEPT
{
const pointer tmp = m_data.m_p;
m_data.m_p = pointer();
return tmp;
}
//! Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior,
//! and shall not throw exceptions.
//!
//! Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not
//! equal to nullptr, calls get_deleter()(old_p). Note: The order of these operations is significant
//! because the call to get_deleter() may destroy *this.
//!
//! Postconditions: get() == p. Note: The postcondition does not hold if the call to get_deleter()
//! destroys *this since this->get() is no longer a valid expression.
//!
//! Remarks: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template
BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr::type)
reset(Pointer p) BOOST_NOEXCEPT
{
//If T is not an array type, element_type_t derives from T
//it uses the default deleter and T has no virtual destructor, then you have a problem
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
::type>::value ));
pointer tmp = m_data.m_p;
m_data.m_p = p;
if(tmp) m_data.deleter()(tmp);
}
//! Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior,
//! and shall not throw exceptions.
//!
//! Effects: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not
//! equal to nullptr, calls get_deleter()(old_p). Note: The order of these operations is significant
//! because the call to get_deleter() may destroy *this.
//!
//! Postconditions: get() == p. Note: The postcondition does not hold if the call to get_deleter()
//! destroys *this since this->get() is no longer a valid expression.
void reset() BOOST_NOEXCEPT
{ this->reset(pointer()); }
//! Effects: Same as reset()
//!
void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ this->reset(); }
//! Requires: get_deleter() shall be swappable and shall not throw an exception under swap.
//!
//! Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.
void swap(unique_ptr& u) BOOST_NOEXCEPT
{
::boost::adl_move_swap(m_data.m_p, u.m_data.m_p);
::boost::adl_move_swap(m_data.deleter(), u.m_data.deleter());
}
};
//! Effects: Calls x.swap(y).
//!
template
BOOST_MOVE_FORCEINLINE void swap(unique_ptr &x, unique_ptr &y) BOOST_NOEXCEPT
{ x.swap(y); }
//! Returns: x.get() == y.get().
//!
template
BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr &x, const unique_ptr &y)
{ return x.get() == y.get(); }
//! Returns: x.get() != y.get().
//!
template
BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr &x, const unique_ptr &y)
{ return x.get() != y.get(); }
//! Returns: x.get() < y.get().
//!
//! Remarks: This comparison shall induce a
//! strict weak ordering betwen pointers.
template
BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr &x, const unique_ptr &y)
{ return x.get() < y.get(); }
//! Returns: !(y < x).
//!
template
BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr &x, const unique_ptr &y)
{ return !(y < x); }
//! Returns: y < x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr &x, const unique_ptr &y)
{ return y < x; }
//! Returns:!(x < y).
//!
template
BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr &x, const unique_ptr &y)
{ return !(x < y); }
//! Returns:!x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ return !x; }
//! Returns:!x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x) BOOST_NOEXCEPT
{ return !x; }
//! Returns: (bool)x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ return !!x; }
//! Returns: (bool)x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x) BOOST_NOEXCEPT
{ return !!x; }
//! Requires: operator shall induce a strict weak ordering on unique_ptr::pointer values.
//!
//! Returns: Returns x.get() < pointer().
template
BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return x.get() < typename unique_ptr::pointer(); }
//! Requires: operator shall induce a strict weak ordering on unique_ptr::pointer values.
//!
//! Returns: Returns pointer() < x.get().
template
BOOST_MOVE_FORCEINLINE bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x)
{ return typename unique_ptr::pointer() < x.get(); }
//! Returns: nullptr < x.
//!
template
BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return x.get() > typename unique_ptr::pointer(); }
//! Returns: x < nullptr.
//!
template
BOOST_MOVE_FORCEINLINE bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x)
{ return typename unique_ptr::pointer() > x.get(); }
//! Returns: !(nullptr < x).
//!
template
BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return !(bmupd::nullptr_type() < x); }
//! Returns: !(x < nullptr).
//!
template
BOOST_MOVE_FORCEINLINE bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x)
{ return !(x < bmupd::nullptr_type()); }
//! Returns: !(x < nullptr).
//!
template
BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return !(x < bmupd::nullptr_type()); }
//! Returns: !(nullptr < x).
//!
template
BOOST_MOVE_FORCEINLINE bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr &x)
{ return !(bmupd::nullptr_type() < x); }
} //namespace movelib {
} //namespace boost{
#include
#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED