1
0
forked from boostorg/move

Extracted default_delete into its own header.

Extracted meta utilities used only by unique_ptr and friends to its own "unique_ptr_meta_utils.hpp" header.
This commit is contained in:
Ion Gaztañaga
2014-09-02 16:28:17 +02:00
parent 19d35253cf
commit 90be9ebe22
8 changed files with 815 additions and 263 deletions

View File

@@ -0,0 +1,173 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_DEFAULT_DELETE_HPP_INCLUDED
#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/detail/workaround.hpp>
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#include <cstddef> //For std::size_t
//!\file
//! Describes the default deleter (destruction policy) of <tt>unique_ptr</tt>: <tt>default_delete</tt>.
namespace boost{
namespace move_upd {
namespace bmupmu = ::boost::move_upmu;
////////////////////////////////////////
//// enable_def_del
////////////////////////////////////////
//compatible with a pointer type T*:
//When either Y* is convertible to T*
//Y is U[N] and T is U cv []
template<class U, class T>
struct def_del_compatible_cond
: bmupmu::is_convertible<U*, T*>
{};
template<class U, class T, std::size_t N>
struct def_del_compatible_cond<U[N], T[]>
: def_del_compatible_cond<U[], T[]>
{};
template<class U, class T, class Type = bmupmu::nat>
struct enable_def_del
: bmupmu::enable_if_c<def_del_compatible_cond<U, T>::value, Type>
{};
////////////////////////////////////////
//// enable_defdel_call
////////////////////////////////////////
//When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N];
//When 2nd is T[], 1st(*)[] shall be convertible to T(*)[];
//Otherwise, 1st* shall be convertible to 2nd*.
template<class U, class T, class Type = bmupmu::nat>
struct enable_defdel_call
: public enable_def_del<U, T, Type>
{};
template<class U, class T, class Type>
struct enable_defdel_call<U, T[], Type>
: public enable_def_del<U[], T[], Type>
{};
template<class U, class T, class Type, std::size_t N>
struct enable_defdel_call<U, T[N], Type>
: public enable_def_del<U[N], T[N], Type>
{};
////////////////////////////////////////
//// Some bool literal zero conversion utilities
////////////////////////////////////////
struct bool_conversion {int for_bool; int for_arg(); };
typedef int bool_conversion::* explicit_bool_arg;
#if !defined(BOOST_NO_CXX11_NULLPTR)
typedef std::nullptr_t nullptr_type;
#else
typedef int (bool_conversion::*nullptr_type)();
#endif
} //namespace move_upd {
namespace movelib {
namespace bmupd = boost::move_upd;
namespace bmupmu = boost::move_detail;
//!The class template <tt>default_delete</tt> serves as the default deleter
//!(destruction policy) for the class template <tt>unique_ptr</tt>.
//!
//! \tparam T The type to be deleted. It may be an incomplete type
template <class T>
struct default_delete
{
//! Default constructor.
//!
BOOST_CONSTEXPR default_delete()
//Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
#if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
BOOST_NOEXCEPT
#endif
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
= default;
#else
{};
#endif
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
default_delete(const default_delete&) BOOST_NOEXCEPT = default;
default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
#else
typedef typename bmupmu::remove_extent<T>::type element_type;
#endif
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
//!
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and U* is implicitly convertible to T*.
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
template <class U>
default_delete(const default_delete<U>&
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
) BOOST_NOEXCEPT
{}
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
//!
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and U* is implicitly convertible to T*.
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
template <class U>
BOOST_MOVE_DOC1ST(default_delete&,
typename bmupd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
operator=(const default_delete<U>&) BOOST_NOEXCEPT
{ return *this; }
//! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
//! otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
//!
//! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
//! This operator shall not participate in overload resolution unless:
//! - T is not an array type and U* is convertible to T*, OR
//! - T is an array type, and remove_cv<U>::type is the same type as
//! remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
template <class U>
BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
operator()(U* ptr) const BOOST_NOEXCEPT
{
//U must be a complete type
BOOST_STATIC_ASSERT(sizeof(U) > 0);
element_type * const p = static_cast<element_type*>(ptr);
bmupmu::is_array<T>::value ? delete [] p : delete p;
}
//! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
//!
void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT
{ BOOST_STATIC_ASSERT(sizeof(element_type) > 0); }
};
} //namespace movelib {
} //namespace boost{
#include <boost/move/detail/config_end.hpp>
#endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED

View File

@@ -0,0 +1,523 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2012-2012.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//! \file
#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
#include <cstddef> //for std::size_t
//Small meta-typetraits to support move
namespace boost {
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
//Forward declare boost::rv
template <class T> class rv;
#endif
namespace move_upmu {
//////////////////////////////////////
// nat
//////////////////////////////////////
struct nat{};
//////////////////////////////////////
// natify
//////////////////////////////////////
template <class T> struct natify{};
//////////////////////////////////////
// if_c
//////////////////////////////////////
template<bool C, typename T1, typename T2>
struct if_c
{
typedef T1 type;
};
template<typename T1, typename T2>
struct if_c<false,T1,T2>
{
typedef T2 type;
};
//////////////////////////////////////
// if_
//////////////////////////////////////
template<typename T1, typename T2, typename T3>
struct if_ : if_c<0 != T1::value, T2, T3>
{};
//enable_if_
template <bool B, class T = nat>
struct enable_if_c
{
typedef T type;
};
//////////////////////////////////////
// enable_if_c
//////////////////////////////////////
template <class T>
struct enable_if_c<false, T> {};
//////////////////////////////////////
// enable_if
//////////////////////////////////////
template <class Cond, class T = nat>
struct enable_if : public enable_if_c<Cond::value, T> {};
//////////////////////////////////////
// remove_reference
//////////////////////////////////////
template<class T>
struct remove_reference
{
typedef T type;
};
template<class T>
struct remove_reference<T&>
{
typedef T type;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T>
struct remove_reference<T&&>
{
typedef T type;
};
#else
template<class T>
struct remove_reference< rv<T> >
{
typedef T type;
};
template<class T>
struct remove_reference< rv<T> &>
{
typedef T type;
};
template<class T>
struct remove_reference< const rv<T> &>
{
typedef T type;
};
#endif
//////////////////////////////////////
// remove_const
//////////////////////////////////////
template< class T >
struct remove_const
{
typedef T type;
};
template< class T >
struct remove_const<const T>
{
typedef T type;
};
//////////////////////////////////////
// remove_volatile
//////////////////////////////////////
template< class T >
struct remove_volatile
{
typedef T type;
};
template< class T >
struct remove_volatile<volatile T>
{
typedef T type;
};
//////////////////////////////////////
// remove_cv
//////////////////////////////////////
template< class T >
struct remove_cv
{
typedef typename remove_volatile
<typename remove_const<T>::type>::type type;
};
//////////////////////////////////////
// remove_extent
//////////////////////////////////////
template<class T>
struct remove_extent
{
typedef T type;
};
template<class T>
struct remove_extent<T[]>
{
typedef T type;
};
template<class T, std::size_t N>
struct remove_extent<T[N]>
{
typedef T type;
};
//////////////////////////////////////
// extent
//////////////////////////////////////
template<class T, unsigned N = 0>
struct extent
{
static const std::size_t value = 0;
};
template<class T>
struct extent<T[], 0>
{
static const std::size_t value = 0;
};
template<class T, unsigned N>
struct extent<T[], N>
{
static const std::size_t value = extent<T, N-1>::value;
};
template<class T, std::size_t N>
struct extent<T[N], 0>
{
static const std::size_t value = N;
};
template<class T, std::size_t I, unsigned N>
struct extent<T[I], N>
{
static const std::size_t value = extent<T, N-1>::value;
};
//////////////////////////////////////
// add_lvalue_reference
//////////////////////////////////////
template<class T>
struct add_lvalue_reference
{
typedef T& type;
};
template<class T>
struct add_lvalue_reference<T&>
{
typedef T& type;
};
template<>
struct add_lvalue_reference<void>
{
typedef void type;
};
template<>
struct add_lvalue_reference<const void>
{
typedef const void type;
};
template<>
struct add_lvalue_reference<volatile void>
{
typedef volatile void type;
};
template<>
struct add_lvalue_reference<const volatile void>
{
typedef const volatile void type;
};
template<class T>
struct add_const_lvalue_reference
{
typedef typename remove_reference<T>::type t_unreferenced;
typedef const t_unreferenced t_unreferenced_const;
typedef typename add_lvalue_reference
<t_unreferenced_const>::type type;
};
//////////////////////////////////////
// is_same
//////////////////////////////////////
template<class T, class U>
struct is_same
{
static const bool value = false;
};
template<class T>
struct is_same<T, T>
{
static const bool value = true;
};
//////////////////////////////////////
// is_pointer
//////////////////////////////////////
template< class T >
struct is_pointer
{
static const bool value = false;
};
template< class T >
struct is_pointer<T*>
{
static const bool value = true;
};
//////////////////////////////////////
// is_reference
//////////////////////////////////////
template< class T >
struct is_reference
{
static const bool value = false;
};
template< class T >
struct is_reference<T&>
{
static const bool value = true;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template< class T >
struct is_reference<T&&>
{
static const bool value = true;
};
#endif
//////////////////////////////////////
// is_lvalue_reference
//////////////////////////////////////
template<class T>
struct is_lvalue_reference
{
static const bool value = false;
};
template<class T>
struct is_lvalue_reference<T&>
{
static const bool value = true;
};
//////////////////////////////////////
// is_array
//////////////////////////////////////
template<class T>
struct is_array
{
static const bool value = false;
};
template<class T>
struct is_array<T[]>
{
static const bool value = true;
};
template<class T, std::size_t N>
struct is_array<T[N]>
{
static const bool value = true;
};
//////////////////////////////////////
// has_pointer_type
//////////////////////////////////////
template <class T>
struct has_pointer_type
{
struct two { char c[2]; };
template <class U> static two test(...);
template <class U> static char test(typename U::pointer* = 0);
static const bool value = sizeof(test<T>(0)) == 1;
};
//////////////////////////////////////
// pointer_type
//////////////////////////////////////
template <class T, class D, bool = has_pointer_type<D>::value>
struct pointer_type_imp
{
typedef typename D::pointer type;
};
template <class T, class D>
struct pointer_type_imp<T, D, false>
{
typedef typename remove_extent<T>::type* type;
};
template <class T, class D>
struct pointer_type
{
typedef typename pointer_type_imp
<typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
};
//////////////////////////////////////
// is_convertible
//////////////////////////////////////
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
//use intrinsic since in MSVC
//overaligned types can't go through ellipsis
template <class T, class U>
struct is_convertible
{
static const bool value = __is_convertible_to(T, U);
};
#else
template <class T, class U>
class is_convertible
{
typedef typename add_lvalue_reference<T>::type t_reference;
typedef char true_t;
class false_t { char dummy[2]; };
static false_t dispatch(...);
static true_t dispatch(U);
static t_reference trigger();
public:
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
};
#endif
//////////////////////////////////////
// is_unary_function
//////////////////////////////////////
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
#define BOOST_MOVE_TT_DECL __cdecl
#else
#define BOOST_MOVE_TT_DECL
#endif
#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE)
#define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
#endif
template <typename T>
struct is_unary_function_impl
{ static const bool value = false; };
// avoid duplicate definitions of is_unary_function_impl
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_function_impl<R (*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_function_impl<R (*)(...)>
{ static const bool value = true; };
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_function_impl<R (__stdcall*)()>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R>
struct is_unary_function_impl<R (__fastcall*)()>
{ static const bool value = true; };
#endif
template <typename R>
struct is_unary_function_impl<R (__cdecl*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_function_impl<R (__cdecl*)(...)>
{ static const bool value = true; };
#endif
// avoid duplicate definitions of is_unary_function_impl
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0>
struct is_unary_function_impl<R (*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_function_impl<R (*)(T0...)>
{ static const bool value = true; };
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0>
struct is_unary_function_impl<R (__stdcall*)(T0)>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R, class T0>
struct is_unary_function_impl<R (__fastcall*)(T0)>
{ static const bool value = true; };
#endif
template <typename R, class T0>
struct is_unary_function_impl<R (__cdecl*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_function_impl<R (__cdecl*)(T0...)>
{ static const bool value = true; };
#endif
template <typename T>
struct is_unary_function_impl<T&>
{ static const bool value = false; };
template<typename T>
struct is_unary_function
{ static const bool value = is_unary_function_impl<T>::value; };
} //namespace move_upmu {
} //namespace boost {
#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP

View File

@@ -13,8 +13,9 @@
#include <boost/move/detail/config_begin.hpp> #include <boost/move/detail/config_begin.hpp>
#include <boost/move/detail/workaround.hpp> #include <boost/move/detail/workaround.hpp>
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
#include <boost/move/default_delete.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/detail/meta_utils.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
@@ -36,8 +37,7 @@
//! cv-less T and cv-less U are the same type and T is more CV qualified than U. //! cv-less T and cv-less U are the same type and T is more CV qualified than U.
namespace boost{ namespace boost{
namespace move_upd {
namespace move_detail {
//////////////////////////////////////////// ////////////////////////////////////////////
// deleter types // deleter types
@@ -58,25 +58,25 @@ class is_noncopyable
template <class D> template <class D>
struct deleter_types struct deleter_types
{ {
typedef typename add_lvalue_reference<D>::type del_ref; typedef typename bmupmu::add_lvalue_reference<D>::type del_ref;
typedef typename add_const_lvalue_reference<D>::type del_cref; typedef typename bmupmu::add_const_lvalue_reference<D>::type del_cref;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef typename if_c typedef typename bmupmu::if_c
< is_lvalue_reference<D>::value, D, del_cref >::type deleter_arg_type1; < bmupmu::is_lvalue_reference<D>::value, D, del_cref >::type deleter_arg_type1;
typedef typename remove_reference<D>::type && deleter_arg_type2; typedef typename bmupmu::remove_reference<D>::type && deleter_arg_type2;
#else #else
typedef typename if_c typedef typename bmupmu::if_c
< is_noncopyable<D>::value, nat, del_cref>::type non_ref_deleter_arg1; < is_noncopyable<D>::value, bmupmu::nat, del_cref>::type non_ref_deleter_arg1;
typedef typename if_c< is_lvalue_reference<D>::value typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference<D>::value
, D, non_ref_deleter_arg1 >::type deleter_arg_type1; , D, non_ref_deleter_arg1 >::type deleter_arg_type1;
typedef ::boost::rv<D> & deleter_arg_type2; typedef ::boost::rv<D> & deleter_arg_type2;
#endif #endif
}; };
//////////////////////////////////////////// ////////////////////////////////////////////
// unique_ptr_data // unique_ptr_data
//////////////////////////////////////////// ////////////////////////////////////////////
template <class P, class D, bool = is_unary_function<D>::value || is_reference<D>::value > template <class P, class D, bool = bmupmu::is_unary_function<D>::value || bmupmu::is_reference<D>::value >
struct unique_ptr_data struct unique_ptr_data
{ {
typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1; typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
@@ -155,11 +155,11 @@ struct unique_ptr_data<P, D, false>
template <typename T> template <typename T>
struct get_element_type struct get_element_type
{ {
struct DefaultWrap { typedef natify<T> element_type; }; struct DefaultWrap { typedef bmupmu::natify<T> element_type; };
template <typename X> static char test(int, typename X::element_type*); template <typename X> static char test(int, typename X::element_type*);
template <typename X> static int test(...); template <typename X> static int test(...);
static const bool value = (1 == sizeof(test<T>(0, 0))); static const bool value = (1 == sizeof(test<T>(0, 0)));
typedef typename if_c<value, T, DefaultWrap>::type::element_type type; typedef typename bmupmu::if_c<value, T, DefaultWrap>::type::element_type type;
}; };
template<class T> template<class T>
@@ -170,18 +170,17 @@ struct get_element_type<T*>
template<class T> template<class T>
struct get_cvelement struct get_cvelement
{ : bmupmu::remove_cv<typename get_element_type<T>::type>
typedef typename remove_cv<typename get_element_type<T>::type>::type type; {};
};
template <class P1, class P2> template <class P1, class P2>
struct is_same_cvelement_and_convertible struct is_same_cvelement_and_convertible
{ {
typedef typename remove_reference<P1>::type arg1; typedef typename bmupmu::remove_reference<P1>::type arg1;
typedef typename remove_reference<P2>::type arg2; typedef typename bmupmu::remove_reference<P2>::type arg2;
static const bool same_cvless = static const bool same_cvless =
is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value; bmupmu::is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value;
static const bool value = same_cvless && is_convertible<arg1, arg2>::value; static const bool value = same_cvless && bmupmu::is_convertible<arg1, arg2>::value;
}; };
template<bool IsArray, class FromPointer, class ThisPointer> template<bool IsArray, class FromPointer, class ThisPointer>
@@ -191,63 +190,17 @@ struct is_unique_ptr_convertible
template<class FromPointer, class ThisPointer> template<class FromPointer, class ThisPointer>
struct is_unique_ptr_convertible<false, FromPointer, ThisPointer> struct is_unique_ptr_convertible<false, FromPointer, ThisPointer>
: is_convertible<FromPointer, ThisPointer> : bmupmu::is_convertible<FromPointer, ThisPointer>
{};
////////////////////////////////////////
//// enable_def_del
////////////////////////////////////////
//compatible with a pointer type T*:
//When either Y* is convertible to T*
//Y is U[N] and T is U cv []
template<class U, class T>
struct def_del_compatible_cond
{
static const bool value = is_convertible<U*, T*>::value;
};
template<class U, class T, std::size_t N>
struct def_del_compatible_cond<U[N], T[]>
{
static const bool value = def_del_compatible_cond<U[], T[]>::value;
};
template<class U, class T, class Type = nat>
struct enable_def_del
: enable_if_c<def_del_compatible_cond<U, T>::value, Type>
{};
////////////////////////////////////////
//// enable_defdel_call
////////////////////////////////////////
//When 2nd is T[N], 1st(*)[N] shall be convertible to T[N]*;
//When 2nd is T[], 1st(*)[] shall be convertible to T[]*;
//Otherwise, 1st* shall be convertible to 2nd*.
template<class U, class T, class Type = nat>
struct enable_defdel_call
: public enable_def_del<U, T, Type>
{};
template<class U, class T, class Type>
struct enable_defdel_call<U, T[], Type>
: public enable_def_del<U[], T[], Type>
{};
template<class U, class T, class Type, std::size_t N>
struct enable_defdel_call<U, T[N], Type>
: public enable_def_del<U[N], T[N], Type>
{}; {};
//////////////////////////////////////// ////////////////////////////////////////
//// enable_up_moveconv_assign //// enable_up_moveconv_assign
//////////////////////////////////////// ////////////////////////////////////////
template<class T, class FromPointer, class ThisPointer, class Type = nat> template<class T, class FromPointer, class ThisPointer, class Type = bmupmu::nat>
struct enable_up_ptr struct enable_up_ptr
: enable_if_c< is_unique_ptr_convertible < is_array<T>::value, FromPointer, ThisPointer>::value, Type> : bmupmu::enable_if_c< is_unique_ptr_convertible
< bmupmu::is_array<T>::value, FromPointer, ThisPointer>::value, Type>
{}; {};
//////////////////////////////////////// ////////////////////////////////////////
@@ -257,53 +210,40 @@ struct enable_up_ptr
template<class T, class D, class U, class E> template<class T, class D, class U, class E>
struct unique_moveconvert_assignable struct unique_moveconvert_assignable
{ {
static const bool value = (extent<T>::value == extent<U>::value)&& is_unique_ptr_convertible static const bool value = (bmupmu::extent<T>::value == bmupmu::extent<U>::value) && is_unique_ptr_convertible
<is_array<T>::value, typename pointer_type<U, E>::type, typename pointer_type<T, D>::type>::value; < bmupmu::is_array<T>::value
, typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type>::value;
}; };
template<class T, class D, class U, class E, std::size_t N> template<class T, class D, class U, class E, std::size_t N>
struct unique_moveconvert_assignable<T[], D, U[N], E> struct unique_moveconvert_assignable<T[], D, U[N], E>
{ : unique_moveconvert_assignable<T[], D, U[], E>
static const bool value = unique_moveconvert_assignable<T[], D, U[], E>::value; {};
};
/*
template<class T, class D, class U, class E, std::size_t N>
struct unique_moveconvert_assignable<T[N], D, U[], E>
{
static const bool value = unique_moveconvert_assignable<nat[], D, U[], E>::value;
};
template<class T, class D, class U, class E, std::size_t N, std::size_t M> template<class T, class D, class U, class E, class Type = bmupmu::nat>
struct unique_moveconvert_assignable<T[N], D, U[M], E>
{
static const bool value = (M == N) && unique_moveconvert_assignable<T[], D, U[], E>::value;
};
*/
template<class T, class D, class U, class E, class Type = nat>
struct enable_up_moveconv_assign struct enable_up_moveconv_assign
: enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type> : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type>
{}; {};
//////////////////////////////////////// ////////////////////////////////////////
//// enable_up_moveconv_constr //// enable_up_moveconv_constr
//////////////////////////////////////// ////////////////////////////////////////
template<class D, class E, bool IsReference = is_reference<D>::value> template<class D, class E, bool IsReference = bmupmu::is_reference<D>::value>
struct unique_deleter_is_initializable struct unique_deleter_is_initializable
{ : bmupmu::is_same<D, E>
static const bool value = is_same<D, E>::value; {};
};
template <class T, class U> template <class T, class U>
class is_rvalue_convertible class is_rvalue_convertible
{ {
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef typename remove_reference<T>::type&& t_from; typedef typename bmupmu::remove_reference<T>::type&& t_from;
#else #else
typedef typename if_c typedef typename bmupmu::if_c
< has_move_emulation_enabled<T>::value && !is_reference<T>::value < ::boost::has_move_emulation_enabled<T>::value && !bmupmu::is_reference<T>::value
, boost::rv<T>& , ::boost::rv<T>&
, typename add_lvalue_reference<T>::type , typename bmupmu::add_lvalue_reference<T>::type
>::type t_from; >::type t_from;
#endif #endif
@@ -339,103 +279,16 @@ struct unique_deleter_is_initializable<D, E, false>
#endif #endif
}; };
template<class T, class D, class U, class E, class Type = nat> template<class T, class D, class U, class E, class Type = bmupmu::nat>
struct enable_up_moveconv_constr struct enable_up_moveconv_constr
: enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value && : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value &&
unique_deleter_is_initializable<D, E>::value, Type> unique_deleter_is_initializable<D, E>::value, Type>
{}; {};
//////////////////////////////////////// } //namespace move_upd {
//// Some bool literal zero conversion utilities
////////////////////////////////////////
struct bool_conversion {int for_bool; int for_arg(); };
typedef int bool_conversion::* explicit_bool_arg;
#if !defined(BOOST_NO_CXX11_NULLPTR)
typedef std::nullptr_t nullptr_type;
#else
typedef int (bool_conversion::*nullptr_type)();
#endif
} //namespace move_detail {
namespace movelib { namespace movelib {
namespace bmd = boost::move_detail;
//!The class template <tt>default_delete</tt> serves as the default deleter
//!(destruction policy) for the class template <tt>unique_ptr</tt>.
template <class T>
struct default_delete
{
//! Default constructor.
//!
BOOST_CONSTEXPR default_delete()
//Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
#if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
BOOST_NOEXCEPT
#endif
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
= default;
#else
{};
#endif
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
default_delete(const default_delete&) BOOST_NOEXCEPT = default;
default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
#else
typedef typename bmd::remove_extent<T>::type element_type;
#endif
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
//!
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and U* is implicitly convertible to T*.
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
template <class U>
default_delete(const default_delete<U>&
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
) BOOST_NOEXCEPT
{}
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
//!
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
//! - If T is not an array type and U* is implicitly convertible to T*.
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
template <class U>
BOOST_MOVE_DOC1ST(default_delete&,
typename bmd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
operator=(const default_delete<U>&) BOOST_NOEXCEPT
{ return *this; }
//! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
//! otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
//!
//! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
//! This operator shall not participate in overload resolution unless:
//! - T is not an array type and U* is convertible to T*, OR
//! - T is an array type, and remove_cv<U>::type is the same type as
//! remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
template <class U>
BOOST_MOVE_DOC1ST(void, typename bmd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
operator()(U* ptr) const BOOST_NOEXCEPT
{
//U must be a complete type
BOOST_STATIC_ASSERT(sizeof(U) > 0);
element_type * const p = static_cast<element_type*>(ptr);
bmd::is_array<T>::value ? delete [] p : delete p;
}
//! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
//!
void operator()(BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) const BOOST_NOEXCEPT
{ BOOST_STATIC_ASSERT(sizeof(element_type) > 0); }
};
//! A unique pointer is an object that owns another object and //! A unique pointer is an object that owns another object and
//! manages that other object through a pointer. //! manages that other object through a pointer.
//! //!
@@ -491,11 +344,11 @@ class unique_ptr
#else #else
BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr) BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
typedef move_detail::pointer_type<T, D > pointer_type_obtainer; typedef bmupmu::pointer_type<T, D > pointer_type_obtainer;
typedef bmd::unique_ptr_data typedef bmupd::unique_ptr_data
<typename pointer_type_obtainer::type, D> data_type; <typename pointer_type_obtainer::type, D> data_type;
typedef typename bmd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1; typedef typename bmupd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
typedef typename bmd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2; typedef typename bmupd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2;
data_type m_data; data_type m_data;
#endif #endif
@@ -506,7 +359,7 @@ class unique_ptr
typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer; 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 //! 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. //! in the form U[], element_type is equal to U.
typedef typename BOOST_MOVE_SEEDOC(bmd::remove_extent<T>::type) element_type; typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent<T>::type) element_type;
typedef D deleter_type; typedef D deleter_type;
//! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
@@ -524,19 +377,19 @@ class unique_ptr
{ {
//If this constructor is instantiated with a pointer type or reference type //If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed. //for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmd::is_pointer<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
BOOST_STATIC_ASSERT(!bmd::is_reference<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
} }
//! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor). //! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor).
//! //!
BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) BOOST_NOEXCEPT BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
: m_data() : m_data()
{ {
//If this constructor is instantiated with a pointer type or reference type //If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed. //for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmd::is_pointer<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
BOOST_STATIC_ASSERT(!bmd::is_reference<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
} }
//! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
@@ -554,14 +407,14 @@ class unique_ptr
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type. //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template<class Pointer> template<class Pointer>
explicit unique_ptr(Pointer p explicit unique_ptr(Pointer p
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0) BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
) BOOST_NOEXCEPT ) BOOST_NOEXCEPT
: m_data(p) : m_data(p)
{ {
//If this constructor is instantiated with a pointer type or reference type //If this constructor is instantiated with a pointer type or reference type
//for the template argument D, the program is ill-formed. //for the template argument D, the program is ill-formed.
BOOST_STATIC_ASSERT(!bmd::is_pointer<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
BOOST_STATIC_ASSERT(!bmd::is_reference<D>::value); BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
} }
//!The signature of this constructor depends upon whether D is a reference type. //!The signature of this constructor depends upon whether D is a reference type.
@@ -588,14 +441,14 @@ class unique_ptr
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type. //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template<class Pointer> template<class Pointer>
unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1 unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0) BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
) BOOST_NOEXCEPT ) BOOST_NOEXCEPT
: m_data(p, d1) : m_data(p, d1)
{} {}
//! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt> //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt>
//! and additionally <tt>get() == nullptr</tt> //! and additionally <tt>get() == nullptr</tt>
unique_ptr(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
: m_data(pointer(), d1) : m_data(pointer(), d1)
{} {}
@@ -621,14 +474,14 @@ class unique_ptr
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type. //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template<class Pointer> template<class Pointer>
unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2 unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0) BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
) BOOST_NOEXCEPT ) BOOST_NOEXCEPT
: m_data(p, ::boost::move(d2)) : m_data(p, ::boost::move(d2))
{} {}
//! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt> //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt>
//! and additionally <tt>get() == nullptr</tt> //! and additionally <tt>get() == nullptr</tt>
unique_ptr(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
: m_data(pointer(), ::boost::move(d2)) : m_data(pointer(), ::boost::move(d2))
{} {}
@@ -663,7 +516,7 @@ class unique_ptr
//! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>. //! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
template <class U, class E> template <class U, class E>
unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0) 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)
) BOOST_NOEXCEPT ) BOOST_NOEXCEPT
: m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter())) : m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
{} {}
@@ -706,7 +559,7 @@ class unique_ptr
//! //!
//! <b>Returns</b>: *this. //! <b>Returns</b>: *this.
template <class U, class E> template <class U, class E>
BOOST_MOVE_DOC1ST(unique_ptr&, typename bmd::enable_up_moveconv_assign BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type) <T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type)
operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT
{ {
@@ -720,7 +573,7 @@ class unique_ptr
//! <b>Postcondition</b>: <tt>get() == nullptr</tt> //! <b>Postcondition</b>: <tt>get() == nullptr</tt>
//! //!
//! <b>Returns</b>: *this. //! <b>Returns</b>: *this.
unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) BOOST_NOEXCEPT unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ this->reset(); return *this; } { this->reset(); return *this; }
//! <b>Requires</b>: <tt>get() != nullptr</tt>. //! <b>Requires</b>: <tt>get() != nullptr</tt>.
@@ -728,10 +581,10 @@ class unique_ptr
//! <b>Returns</b>: <tt>*get()</tt>. //! <b>Returns</b>: <tt>*get()</tt>.
//! //!
//! <b>Remarks</b: If T is an array type, the program is ill-formed. //! <b>Remarks</b: If T is an array type, the program is ill-formed.
BOOST_MOVE_DOC1ST(element_type&, typename bmd::add_lvalue_reference<element_type>::type) BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
operator*() const BOOST_NOEXCEPT operator*() const BOOST_NOEXCEPT
{ {
BOOST_STATIC_ASSERT((!bmd::is_array<T>::value)); BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
return *m_data.m_p; return *m_data.m_p;
} }
@@ -740,10 +593,10 @@ class unique_ptr
//! <b>Returns</b>: <tt>get()[i]</tt>. //! <b>Returns</b>: <tt>get()[i]</tt>.
//! //!
//! <b>Remarks</b: If T is not an array type, the program is ill-formed. //! <b>Remarks</b: If T is not an array type, the program is ill-formed.
BOOST_MOVE_DOC1ST(element_type&, typename bmd::add_lvalue_reference<element_type>::type) BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
operator[](std::size_t i) const BOOST_NOEXCEPT operator[](std::size_t i) const BOOST_NOEXCEPT
{ {
BOOST_ASSERT( bmd::extent<T>::value == 0 || i < bmd::extent<T>::value ); BOOST_ASSERT( bmupmu::extent<T>::value == 0 || i < bmupmu::extent<T>::value );
BOOST_ASSERT(m_data.m_p); BOOST_ASSERT(m_data.m_p);
return m_data.m_p[i]; return m_data.m_p[i];
} }
@@ -757,7 +610,7 @@ class unique_ptr
//! <b>Remarks</b: If T is an array type, the program is ill-formed. //! <b>Remarks</b: If T is an array type, the program is ill-formed.
pointer operator->() const BOOST_NOEXCEPT pointer operator->() const BOOST_NOEXCEPT
{ {
BOOST_STATIC_ASSERT((!bmd::is_array<T>::value)); BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
BOOST_ASSERT(m_data.m_p); BOOST_ASSERT(m_data.m_p);
return m_data.m_p; return m_data.m_p;
} }
@@ -769,13 +622,13 @@ class unique_ptr
//! <b>Returns</b>: A reference to the stored deleter. //! <b>Returns</b>: A reference to the stored deleter.
//! //!
BOOST_MOVE_DOC1ST(D&, typename bmd::add_lvalue_reference<D>::type) BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference<D>::type)
get_deleter() BOOST_NOEXCEPT get_deleter() BOOST_NOEXCEPT
{ return m_data.deleter(); } { return m_data.deleter(); }
//! <b>Returns</b>: A reference to the stored deleter. //! <b>Returns</b>: A reference to the stored deleter.
//! //!
BOOST_MOVE_DOC1ST(const D&, typename bmd::add_const_lvalue_reference<D>::type) BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference<D>::type)
get_deleter() const BOOST_NOEXCEPT get_deleter() const BOOST_NOEXCEPT
{ return m_data.deleter(); } { return m_data.deleter(); }
@@ -784,13 +637,13 @@ class unique_ptr
//! //!
explicit operator bool explicit operator bool
#else #else
operator bmd::explicit_bool_arg operator bmupd::explicit_bool_arg
#endif #endif
()const BOOST_NOEXCEPT ()const BOOST_NOEXCEPT
{ {
return m_data.m_p return m_data.m_p
? &bmd::bool_conversion::for_bool ? &bmupd::bool_conversion::for_bool
: bmd::explicit_bool_arg(0); : bmupd::explicit_bool_arg(0);
} }
//! <b>Postcondition</b>: <tt>get() == nullptr</tt>. //! <b>Postcondition</b>: <tt>get() == nullptr</tt>.
@@ -817,7 +670,7 @@ class unique_ptr
//! - If T is not an array type and Pointer is implicitly convertible to pointer. //! - 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. //! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
template<class Pointer> template<class Pointer>
BOOST_MOVE_DOC1ST(void, typename bmd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type) BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type)
reset(Pointer p) BOOST_NOEXCEPT reset(Pointer p) BOOST_NOEXCEPT
{ {
pointer tmp = m_data.m_p; pointer tmp = m_data.m_p;
@@ -839,7 +692,7 @@ class unique_ptr
//! <b>Effects</b>: Same as <tt>reset()</tt> //! <b>Effects</b>: Same as <tt>reset()</tt>
//! //!
void reset(BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) BOOST_NOEXCEPT void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ this->reset(); } { this->reset(); }
//! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap. //! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap.
@@ -847,7 +700,7 @@ class unique_ptr
//! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u. //! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
void swap(unique_ptr& u) BOOST_NOEXCEPT void swap(unique_ptr& u) BOOST_NOEXCEPT
{ {
using bmd::swap; using bmupmu::swap;
swap(m_data.m_p, u.m_data.m_p); swap(m_data.m_p, u.m_data.m_p);
swap(m_data.deleter(), u.m_data.deleter()); swap(m_data.deleter(), u.m_data.deleter());
} }
@@ -900,76 +753,76 @@ inline bool operator>=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
//! <b>Returns</b>:!x. //! <b>Returns</b>:!x.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) BOOST_NOEXCEPT inline bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ return !x; } { return !x; }
//! <b>Returns</b>:!x. //! <b>Returns</b>:!x.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator==(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT inline bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
{ return !x; } { return !x; }
//! <b>Returns</b>: (bool)x. //! <b>Returns</b>: (bool)x.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) BOOST_NOEXCEPT inline bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
{ return !!x; } { return !!x; }
//! <b>Returns</b>: (bool)x. //! <b>Returns</b>: (bool)x.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator!=(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT inline bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
{ return !!x; } { return !!x; }
//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values. //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
//! //!
//! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>. //! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>.
template <class T, class D> template <class T, class D>
inline bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) inline bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return x.get() < typename unique_ptr<T, D>::pointer(); } { return x.get() < typename unique_ptr<T, D>::pointer(); }
//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values. //! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
//! //!
//! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>. //! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>.
template <class T, class D> template <class T, class D>
inline bool operator<(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) inline bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
{ return typename unique_ptr<T, D>::pointer() < x.get(); } { return typename unique_ptr<T, D>::pointer() < x.get(); }
//! <b>Returns</b>: <tt>nullptr < x</tt>. //! <b>Returns</b>: <tt>nullptr < x</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) inline bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return x.get() > typename unique_ptr<T, D>::pointer(); } { return x.get() > typename unique_ptr<T, D>::pointer(); }
//! <b>Returns</b>: <tt>x < nullptr</tt>. //! <b>Returns</b>: <tt>x < nullptr</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator>(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) inline bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
{ return typename unique_ptr<T, D>::pointer() > x.get(); } { return typename unique_ptr<T, D>::pointer() > x.get(); }
//! <b>Returns</b>: <tt>!(nullptr < x)</tt>. //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) inline bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return !(bmd::nullptr_type() < x); } { return !(bmupd::nullptr_type() < x); }
//! <b>Returns</b>: <tt>!(x < nullptr)</tt>. //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator<=(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) inline bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
{ return !(x < bmd::nullptr_type()); } { return !(x < bmupd::nullptr_type()); }
//! <b>Returns</b>: <tt>!(x < nullptr)</tt>. //! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmd::nullptr_type)) inline bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
{ return !(x < bmd::nullptr_type()); } { return !(x < bmupd::nullptr_type()); }
//! <b>Returns</b>: <tt>!(nullptr < x)</tt>. //! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
//! //!
template <class T, class D> template <class T, class D>
inline bool operator>=(BOOST_MOVE_DOC0PTR(bmd::nullptr_type), const unique_ptr<T, D> &x) inline bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
{ return !(bmd::nullptr_type() < x); } { return !(bmupd::nullptr_type() < x); }
} //namespace movelib { } //namespace movelib {
} //namespace boost{ } //namespace boost{

View File

@@ -95,7 +95,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_nullptr_test", "
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_ptr_observers_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_observers_test", "unique_ptr_observers_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
@@ -221,6 +221,7 @@ Global
..\..\..\..\boost\move\detail\config_begin.hpp = ..\..\..\..\boost\move\detail\config_begin.hpp ..\..\..\..\boost\move\detail\config_begin.hpp = ..\..\..\..\boost\move\detail\config_begin.hpp
..\..\..\..\boost\move\detail\config_end.hpp = ..\..\..\..\boost\move\detail\config_end.hpp ..\..\..\..\boost\move\detail\config_end.hpp = ..\..\..\..\boost\move\detail\config_end.hpp
..\..\..\..\boost\move\core.hpp = ..\..\..\..\boost\move\core.hpp ..\..\..\..\boost\move\core.hpp = ..\..\..\..\boost\move\core.hpp
..\..\..\..\boost\move\default_delete.hpp = ..\..\..\..\boost\move\default_delete.hpp
..\..\..\..\boost\move\iterator.hpp = ..\..\..\..\boost\move\iterator.hpp ..\..\..\..\boost\move\iterator.hpp = ..\..\..\..\boost\move\iterator.hpp
..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2 ..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2
..\..\..\..\boost\move\make_unique.hpp = ..\..\..\..\boost\move\make_unique.hpp ..\..\..\..\boost\move\make_unique.hpp = ..\..\..\..\boost\move\make_unique.hpp

View File

@@ -10,7 +10,7 @@
// See http://www.boost.org/libs/move for documentation. // See http://www.boost.org/libs/move for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <boost/move/unique_ptr.hpp> #include <boost/move/default_delete.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
////////////////////////////////////////////// //////////////////////////////////////////////

View File

@@ -32,6 +32,7 @@
#include "unique_ptr_test_utils_beg.hpp" #include "unique_ptr_test_utils_beg.hpp"
namespace bml = ::boost::movelib; namespace bml = ::boost::movelib;
namespace bmupmu = ::boost::move_upmu;
//////////////////////////////// ////////////////////////////////
// unique_ptr_ctor_move_defdel // unique_ptr_ctor_move_defdel
@@ -266,7 +267,7 @@ void test()
{ {
//Single unique_ptr //Single unique_ptr
reset_counters(); reset_counters();
BOOST_STATIC_ASSERT((boost::move_detail::is_convertible<B, A>::value)); BOOST_STATIC_ASSERT((bmupmu::is_convertible<B, A>::value));
{ {
bml::unique_ptr<B, move_constr_deleter<B> > s(new B); bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
A* p = s.get(); A* p = s.get();

View File

@@ -71,13 +71,13 @@ class copy_constr_deleter
template<class U> template<class U>
copy_constr_deleter(const copy_constr_deleter<U>& copy_constr_deleter(const copy_constr_deleter<U>&
, typename boost::move_detail::enable_def_del<U, T>::type* =0) , typename boost::move_upd::enable_def_del<U, T>::type* =0)
{ state_ = 5; } { state_ = 5; }
explicit copy_constr_deleter(int s) : state_(s) {} explicit copy_constr_deleter(int s) : state_(s) {}
template <class U> template <class U>
typename boost::move_detail::enable_def_del<U, T, copy_constr_deleter&>::type typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
operator=(const copy_constr_deleter<U> &d) operator=(const copy_constr_deleter<U> &d)
{ {
state_ = d.state(); state_ = d.state();
@@ -117,7 +117,7 @@ class move_constr_deleter
template <class U> template <class U>
move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
, typename boost::move_detail::enable_def_del<U, T>::type* =0) , typename boost::move_upd::enable_def_del<U, T>::type* =0)
: state_(d.state()) : state_(d.state())
{ d.set_state(0); } { d.set_state(0); }
@@ -129,7 +129,7 @@ class move_constr_deleter
} }
template <class U> template <class U>
typename boost::move_detail::enable_def_del<U, T, move_constr_deleter&>::type typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
operator=(BOOST_RV_REF(move_constr_deleter<U>) d) operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
{ {
state_ = d.state(); state_ = d.state();

View File

@@ -32,6 +32,7 @@
#include "unique_ptr_test_utils_beg.hpp" #include "unique_ptr_test_utils_beg.hpp"
namespace bml = ::boost::movelib; namespace bml = ::boost::movelib;
namespace bmupmu = ::boost::move_upmu;
//////////////////////////////// ////////////////////////////////
// unique_ptr_pointer_type // unique_ptr_pointer_type
@@ -49,29 +50,29 @@ void test()
//Single unique_ptr //Single unique_ptr
{ {
typedef bml::unique_ptr<int> P; typedef bml::unique_ptr<int> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, int*>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
} }
{ {
typedef bml::unique_ptr<int, Deleter> P; typedef bml::unique_ptr<int, Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, Deleter::pointer>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
} }
//Unbounded array unique_ptr //Unbounded array unique_ptr
{ {
typedef bml::unique_ptr<int[]> P; typedef bml::unique_ptr<int[]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, int*>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
} }
{ {
typedef bml::unique_ptr<int[], Deleter> P; typedef bml::unique_ptr<int[], Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, Deleter::pointer>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
} }
//Bounded array unique_ptr //Bounded array unique_ptr
{ {
typedef bml::unique_ptr<int[5]> P; typedef bml::unique_ptr<int[5]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, int*>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
} }
{ {
typedef bml::unique_ptr<int[5], Deleter> P; typedef bml::unique_ptr<int[5], Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::pointer, Deleter::pointer>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
} }
} }
@@ -91,29 +92,29 @@ void test()
//Single unique_ptr //Single unique_ptr
{ {
typedef bml::unique_ptr<int> P; typedef bml::unique_ptr<int> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, bml::default_delete<int> >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int> >::value));
} }
{ {
typedef bml::unique_ptr<int, Deleter> P; typedef bml::unique_ptr<int, Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, Deleter >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
} }
//Unbounded array unique_ptr //Unbounded array unique_ptr
{ {
typedef bml::unique_ptr<int[]> P; typedef bml::unique_ptr<int[]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, bml::default_delete<int[]> >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[]> >::value));
} }
{ {
typedef bml::unique_ptr<int[], Deleter> P; typedef bml::unique_ptr<int[], Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, Deleter >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
} }
//Bounded array unique_ptr //Bounded array unique_ptr
{ {
typedef bml::unique_ptr<int[2]> P; typedef bml::unique_ptr<int[2]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, bml::default_delete<int[2]> >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[2]> >::value));
} }
{ {
typedef bml::unique_ptr<int[2], Deleter> P; typedef bml::unique_ptr<int[2], Deleter> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::deleter_type, Deleter >::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
} }
} }
@@ -130,17 +131,17 @@ void test()
//Single unique_ptr //Single unique_ptr
{ {
typedef bml::unique_ptr<const int> P; typedef bml::unique_ptr<const int> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::element_type, const int>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
} }
//Unbounded array unique_ptr //Unbounded array unique_ptr
{ {
typedef bml::unique_ptr<const int[]> P; typedef bml::unique_ptr<const int[]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::element_type, const int>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
} }
//Bounded array unique_ptr //Bounded array unique_ptr
{ {
typedef bml::unique_ptr<const int[2]> P; typedef bml::unique_ptr<const int[2]> P;
BOOST_STATIC_ASSERT((boost::move_detail::is_same<P::element_type, const int>::value)); BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
} }
} }