Added class unique_ptr under boost::movelib namespace. This could be lifted to ::boost namespace if the community agrees.

This unique_ptr implementation is based on C++14, including make_unique functions. Large parte of the testsuite is based on Howard Hinnant's unique_ptr emulation testsuite.
This commit is contained in:
Ion Gaztañaga
2014-08-22 18:34:34 +02:00
parent cb06d13448
commit e1da7c5ca1
15 changed files with 4657 additions and 54 deletions

View File

@@ -21,7 +21,11 @@ doxygen autodoc
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"BOOST_MOVE_DOXYGEN_INVOKED\""
<doxygen:param>"PREDEFINED=\"BOOST_MOVE_DOXYGEN_INVOKED\" \\
\"BOOST_MOVE_SEEDOC(T)=see_documentation\" \\
\"BOOST_RV_REF(T)=T&&\" \\
\"BOOST_FWD_REF(T)=T&&\" \\
"
;
xml move : move.qbk ;

View File

@@ -757,6 +757,7 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
* Added `unique_ptr` utility. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite.
* Added `move_if_noexcept` utility. Thanks to Antony Polukhin for the implementation.
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/9785 Trac #9785: ['"Compiler warning with intel icc in boost/move/core.hpp"]],

View File

@@ -20,4 +20,5 @@
#endif
#pragma warning (push)
#pragma warning (disable : 4996) // "function": was declared deprecated
#pragma warning (disable : 4675) // "function": resolved overload was found by argument-dependent lookup
#endif

View File

@@ -19,9 +19,32 @@
//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_detail {
//if_
//////////////////////////////////////
// empty
//////////////////////////////////////
struct empty{};
//////////////////////////////////////
// nat
//////////////////////////////////////
struct nat{};
//////////////////////////////////////
// natify
//////////////////////////////////////
template <class T> struct natify{};
//////////////////////////////////////
// if_c
//////////////////////////////////////
template<bool C, typename T1, typename T2>
struct if_c
{
@@ -34,6 +57,9 @@ struct if_c<false,T1,T2>
typedef T2 type;
};
//////////////////////////////////////
// if_
//////////////////////////////////////
template<typename T1, typename T2, typename T3>
struct if_
{
@@ -41,22 +67,33 @@ struct if_
};
//enable_if_
template <bool B, class T = void>
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> {};
template <class Cond, class T = void>
//////////////////////////////////////
// enable_if
//////////////////////////////////////
template <class Cond, class T = nat>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <class Cond, class T = void>
//////////////////////////////////////
// disable_if
//////////////////////////////////////
template <class Cond, class T = nat>
struct disable_if : public enable_if_c<!Cond::value, T> {};
//integral_constant
//////////////////////////////////////
// integral_constant
//////////////////////////////////////
template<class T, T v>
struct integral_constant
{
@@ -65,62 +102,37 @@ struct integral_constant
typedef integral_constant<T, v> type;
};
//identity
typedef integral_constant<bool, true > true_type;
typedef integral_constant<bool, false > false_type;
//////////////////////////////////////
// identity
//////////////////////////////////////
template <class T>
struct identity
{
typedef T type;
};
#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 char true_t;
class false_t { char dummy[2]; };
static false_t dispatch(...);
static true_t dispatch(U);
static T &trigger();
public:
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
};
#endif
//and_ not_
//////////////////////////////////////
// and_
//////////////////////////////////////
template <typename Condition1, typename Condition2, typename Condition3 = integral_constant<bool, true> >
struct and_
: public integral_constant<bool, Condition1::value && Condition2::value && Condition3::value>
{};
//////////////////////////////////////
// not_
//////////////////////////////////////
template <typename Boolean>
struct not_
: public integral_constant<bool, !Boolean::value>
{};
//is_lvalue_reference
template<class T>
struct is_lvalue_reference
: public integral_constant<bool, false>
{};
template<class T>
struct is_lvalue_reference<T&>
: public integral_constant<bool, true>
{};
//remove_reference
//////////////////////////////////////
// remove_reference
//////////////////////////////////////
template<class T>
struct remove_reference
{
@@ -133,7 +145,6 @@ struct remove_reference<T&>
typedef T type;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T>
@@ -142,9 +153,73 @@ 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
//add_const
//////////////////////////////////////
// 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;
};
//////////////////////////////////////
// add_const
//////////////////////////////////////
template<class T>
struct add_const
{
@@ -154,7 +229,7 @@ struct add_const
template<class T>
struct add_const<T&>
{
typedef T& type;
typedef const T& type;
};
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -167,7 +242,171 @@ struct add_const<T&&>
#endif
//////////////////////////////////////
// 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;
};
//////////////////////////////////////
// element_pointer
//////////////////////////////////////
template<class T>
struct element_pointer
{
typedef typename remove_extent<T>::type element_type;
typedef element_type* type;
};
//////////////////////////////////////
// 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;
};
//////////////////////////////////////
// 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;
};
//////////////////////////////////////
// is_class_or_union
//////////////////////////////////////
template<class T>
struct is_class_or_union
{
@@ -179,10 +418,11 @@ struct is_class_or_union
static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
};
struct empty{};
//addressof
template<class T> struct addr_impl_ref
//////////////////////////////////////
// addressof
//////////////////////////////////////
template<class T>
struct addr_impl_ref
{
T & v_;
inline addr_impl_ref( T & v ): v_( v ) {}
@@ -192,7 +432,8 @@ template<class T> struct addr_impl_ref
addr_impl_ref & operator=(const addr_impl_ref &);
};
template<class T> struct addressof_impl
template<class T>
struct addressof_impl
{
static inline T * f( T & v, long )
{
@@ -211,6 +452,198 @@ inline T * addressof( T & v )
( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
}
//////////////////////////////////////
// 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<T, 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_or_binary_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_or_binary_function_impl
{ static const bool value = false; };
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_or_binary_function_impl<R (*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_or_binary_function_impl<R (*)(...)>
{ static const bool value = true; };
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R>
struct is_unary_or_binary_function_impl<R (__stdcall*)()>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R>
struct is_unary_or_binary_function_impl<R (__fastcall*)()>
{ static const bool value = true; };
#endif
template <typename R>
struct is_unary_or_binary_function_impl<R (__cdecl*)()>
{ static const bool value = true; };
template <typename R>
struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
{ static const bool value = true; };
#endif
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_or_binary_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_or_binary_function_impl<R (__stdcall*)(T0)>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
{ static const bool value = true; };
#endif
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
{ static const bool value = true; };
template <typename R, class T0>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
{ static const bool value = true; };
#endif
// avoid duplicate definitions of is_unary_or_binary_function_impl
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
{ static const bool value = true; };
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
{ static const bool value = true; };
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
{ static const bool value = true; };
#ifndef _MANAGED
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
{ static const bool value = true; };
#endif
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
{ static const bool value = true; };
template <typename R, class T0, class T1>
struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
{ static const bool value = true; };
#endif
template <typename T>
struct is_unary_or_binary_function_impl<T&>
{ static const bool value = false; };
template<typename T>
struct is_unary_or_binary_function
{ static const bool value = is_unary_or_binary_function_impl<T>::value; };
} //namespace move_detail {
} //namespace boost {

View File

@@ -0,0 +1,26 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_MOVE_PERFECT_FORWARDING
#endif
//Macros for documentation purposes. For code, expands to the argument
#define BOOST_MOVE_IMPDEF(TYPE) TYPE
#define BOOST_MOVE_SEEDOC(TYPE) TYPE
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP

View File

@@ -0,0 +1,148 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-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_MAKE_UNIQUE_HPP_INCLUDED
#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/detail/workaround.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/move/detail/meta_utils.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/cat.hpp>
#endif
//!\file
//! Defines "make_unique" functions, which are factories to create instances
//! of unique_ptr depending on the passed arguments.
//!
//! This header can be a bit heavyweight in C++03 compilers due to the use of the
//! preprocessor library, that's why it's a a separate header from <tt>unique_ptr.hpp</tt>
namespace boost{
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
namespace move_detail {
//Compile time switch between
//single element, unknown bound array
//and known bound array
template<class T>
struct unique_ptr_if
{
typedef ::boost::movelib::unique_ptr<T> t_is_not_array;
};
template<class T>
struct unique_ptr_if<T[]>
{
typedef ::boost::movelib::unique_ptr<T[]> t_is_array_of_unknown_bound;
};
template<class T, size_t N>
struct unique_ptr_if<T[N]>
{
typedef void t_is_array_of_known_bound;
};
} //namespace move_detail {
#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
namespace movelib {
#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
//!
//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::forward<Args>(args)...))</tt>.
template<class T, class... Args>
inline
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
unique_ptr<T>
#else
typename ::boost::move_detail::unique_ptr_if<T>::t_is_not_array
#endif
make_unique(BOOST_FWD_REF(Args)... args)
{ return unique_ptr<T>(new T(::boost::forward<Args>(args)...)); }
#else
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_MOVE_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
#else
#define BOOST_MOVE_PP_PARAM_LIST(z, n, data) \
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
//!
#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_MOVE_PP_PARAM_FORWARD(z, n, data) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_MOVE_MAX_CONSTRUCTOR_PARAMETERS 10
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
typename ::boost::move_detail::unique_ptr_if<T>::t_is_not_array \
make_unique(BOOST_PP_ENUM(n, BOOST_MOVE_PP_PARAM_LIST, _)) \
{ return unique_ptr<T>(new T(BOOST_PP_ENUM(n, BOOST_MOVE_PP_PARAM_FORWARD, _))); } \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_MOVE_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
//! unknown bound.
//!
//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n]())</tt>.
template<class T>
inline
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
unique_ptr<T>
#else
typename ::boost::move_detail::unique_ptr_if<T>::t_is_array_of_unknown_bound
#endif
make_unique(size_t n)
{
typedef typename ::boost::move_detail::remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
//! an array of known bound.
template<class T, class... Args>
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
unspecified
#else
typename ::boost::move_detail::unique_ptr_if<T>::t_is_array_of_known_bound
#endif
make_unique(BOOST_FWD_REF(Args) ...) = delete;
#endif
} //namespace movelib {
} //namespace boost{
#include <boost/move/detail/config_end.hpp>
#endif //#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@@ -84,6 +84,48 @@
return x;
}
//////////////////////////////////////////////////////////////////////////////
//
// move_if_not_lvalue_reference()
//
//////////////////////////////////////////////////////////////////////////////
template <class T>
inline typename ::boost::move_detail::enable_if_c
< enable_move_utility_emulation<T>::value &&
::boost::move_detail::is_rv<T>::value
, T &>::type
move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
{
return const_cast<T&>(x);
}
template <class T>
inline typename ::boost::move_detail::enable_if_c
< enable_move_utility_emulation<T>::value &&
!::boost::move_detail::is_rv<T>::value &&
(::boost::move_detail::is_lvalue_reference<T>::value ||
!has_move_emulation_enabled<T>::value)
, typename ::boost::move_detail::add_lvalue_reference<T>::type
>::type
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
{
return x;
}
template <class T>
inline typename ::boost::move_detail::enable_if_c
< enable_move_utility_emulation<T>::value &&
!::boost::move_detail::is_rv<T>::value &&
(!::boost::move_detail::is_lvalue_reference<T>::value &&
has_move_emulation_enabled<T>::value)
, rv<T>&
>::type
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
{
return move(x);
}
} //namespace boost
#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
@@ -186,12 +228,64 @@
#endif //BOOST_MOVE_DOXYGEN_INVOKED
//////////////////////////////////////////////////////////////////////////////
//
// move_if_not_lvalue_reference
//
//////////////////////////////////////////////////////////////////////////////
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
//Old move approach, lvalues could bind to rvalue references
template <class T>
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
{ return t; }
#else //Old move
template <class T>
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
{ return static_cast<T&&>(t); }
template <class T>
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
{
//"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
return static_cast<T&&>(t);
}
#endif //BOOST_MOVE_DOXYGEN_INVOKED
} //namespace boost {
#endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
namespace boost{
namespace move_detail{
template<class T>
void swap(T &a, T &b)
{
T c((::boost::move(a)));
a = ::boost::move(b);
b = ::boost::move(c);
}
} //namespace move_detail{
} //namespace boost{
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
#include <boost/move/detail/config_end.hpp>
#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP

View File

@@ -67,6 +67,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_if_noexcept_test", "mo
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_default_deleter_test", "unique_ptr_default_deleter.vcproj", "{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_ptr_test.vcproj", "{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_functions_test", "unique_ptr_functions.vcproj", "{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -143,6 +155,18 @@ Global
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.ActiveCfg = Debug|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.Build.0 = Debug|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.ActiveCfg = Release|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.Build.0 = Release|Win32
{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}.Debug.ActiveCfg = Debug|Win32
{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}.Debug.Build.0 = Debug|Win32
{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}.Release.ActiveCfg = Release|Win32
{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}.Release.Build.0 = Release|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.ActiveCfg = Debug|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.Build.0 = Debug|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.ActiveCfg = Release|Win32
{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionItems) = postSolution
..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp
@@ -151,11 +175,13 @@ Global
..\..\..\..\boost\move\core.hpp = ..\..\..\..\boost\move\core.hpp
..\..\..\..\boost\move\iterator.hpp = ..\..\..\..\boost\move\iterator.hpp
..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2
..\..\..\..\boost\move\make_unique.hpp = ..\..\..\..\boost\move\make_unique.hpp
..\..\..\..\boost\move\detail\meta_utils.hpp = ..\..\..\..\boost\move\detail\meta_utils.hpp
..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp
..\..\doc\move.qbk = ..\..\doc\move.qbk
..\..\..\..\boost\move\detail\move_helpers.hpp = ..\..\..\..\boost\move\detail\move_helpers.hpp
..\..\..\..\boost\move\traits.hpp = ..\..\..\..\boost\move\traits.hpp
..\..\..\..\boost\move\unique_ptr.hpp = ..\..\..\..\boost\move\unique_ptr.hpp
..\..\..\..\boost\move\utility.hpp = ..\..\..\..\boost\move\utility.hpp
..\..\..\..\boost\move\utility_core.hpp = ..\..\..\..\boost\move\utility_core.hpp
EndGlobalSection

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unique_ptr_default_deleter_test"
ProjectGUID="{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/unique_ptr_default_deleter_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_default_deleter_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unique_ptr_default_deleter_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/unique_ptr_default_deleter_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_default_deleter_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{73495AA1-5A6C-3E57-16AC-542F7F2242B9}">
<File
RelativePath="..\..\test\unique_ptr_default_deleter.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unique_ptr_functions_test"
ProjectGUID="{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/unique_ptr_functions_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_functions_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unique_ptr_functions_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/unique_ptr_functions_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_functions_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{73495AA1-5A6C-3E57-16AC-542F7F2242B9}">
<File
RelativePath="..\..\test\unique_ptr_functions.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unique_ptr_test"
ProjectGUID="{C57C28A3-4FE0-6208-BF87-A2B61D3A7671}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/unique_ptr_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unique_ptr_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/unique_ptr_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-2A2754202BFA}">
<File
RelativePath="..\..\test\unique_ptr.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

1907
test/unique_ptr.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Howard Hinnant 2009
// (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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
//////////////////////////////////////////////
//
// The initial implementation of these tests
// was written by Howard Hinnant.
//
// These test were later refactored grouping
// and porting them to Boost.Move.
//
// Many thanks to Howard for releasing his C++03
// unique_ptr implementation with such detailed
// test cases.
//
//////////////////////////////////////////////
////////////////////////////////
// unique_ptr_dltr_dflt_convert_ctor
////////////////////////////////
namespace bml = ::boost::movelib;
struct A
{
static int count;
A() {++count;}
A(const A&) {++count;}
virtual ~A() {--count;}
};
int A::count = 0;
struct B
: public A
{
static int count;
B() {++count;}
B(const B&) {++count;}
virtual ~B() {--count;}
};
int B::count = 0;
void reset_counters()
{ A::count = B::count = 0; }
namespace unique_ptr_dltr_dflt_convert_ctor{
void test()
{
//Single element deleter
{
reset_counters();
bml::default_delete<B> d2;
bml::default_delete<A> d1 = d2;
A* p = new B;
BOOST_TEST(A::count == 1);
BOOST_TEST(B::count == 1);
d1(p);
BOOST_TEST(A::count == 0);
BOOST_TEST(B::count == 0);
}
//Array element deleter
{
reset_counters();
bml::default_delete<A[]> d2;
bml::default_delete<const A[]> d1 = d2;
const A* p = new const A[2];
BOOST_TEST(A::count == 2);
d1(p);
BOOST_TEST(A::count == 0);
}
}
} //namespace unique_ptr_dltr_dflt_convert_ctor{
////////////////////////////////
// unique_ptr_dltr_dflt_default
////////////////////////////////
namespace unique_ptr_dltr_dflt_default{
void test()
{
{
//Single element deleter
reset_counters();
bml::default_delete<A> d;
A* p = new A;
BOOST_TEST(A::count == 1);
d(p);
BOOST_TEST(A::count == 0);
}
{
//Array element deleter
reset_counters();
bml::default_delete<A[]> d;
A* p = new A[2];
BOOST_TEST(A::count == 2);
d(p);
BOOST_TEST(A::count == 0);
}
}
} //namespace unique_ptr_dltr_dflt_default{
////////////////////////////////
// main
////////////////////////////////
int main()
{
unique_ptr_dltr_dflt_convert_ctor::test();
unique_ptr_dltr_dflt_default::test();
//Test results
return boost::report_errors();
}
#include <boost/move/detail/config_end.hpp>

View File

@@ -0,0 +1,174 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/make_unique.hpp>
#include <boost/core/lightweight_test.hpp>
struct A
{
int a, b, c;
static int count;
A() : a (999), b(1000), c(1001) {++count;}
A(int a) : a (a), b(1000), c(1001) {++count;}
A(int a, int b) : a (a), b(b), c(1001) {++count;}
A(int a, int b, int c) : a (a), b(b), c(c) {++count;}
A(const A&) {++count;}
virtual ~A() {--count;}
};
int A::count = 0;
struct B
: public A
{
static int count;
B() {++count;}
B(const B&) {++count;}
virtual ~B() {--count;}
};
int B::count = 0;
void reset_counters()
{ A::count = B::count = 0; }
namespace bml = ::boost::movelib;
////////////////////////////////
// make_unique_single
////////////////////////////////
namespace make_unique_single{
void test()
{
//Single element deleter
reset_counters();
{
bml::unique_ptr<A> p(bml::make_unique<A>());
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 999);
BOOST_TEST(p->b == 1000);
BOOST_TEST(p->c == 1001);
}
{
bml::unique_ptr<A> p(bml::make_unique<A>(0));
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 0);
BOOST_TEST(p->b == 1000);
BOOST_TEST(p->c == 1001);
}
BOOST_TEST(A::count == 0);
{
bml::unique_ptr<A> p(bml::make_unique<A>(0, 1));
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 0);
BOOST_TEST(p->b == 1);
BOOST_TEST(p->c == 1001);
}
BOOST_TEST(A::count == 0);
{
bml::unique_ptr<A> p(bml::make_unique<A>(0, 1, 2));
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 0);
BOOST_TEST(p->b == 1);
BOOST_TEST(p->c == 2);
}
BOOST_TEST(A::count == 0);
}
} //namespace make_unique_single{
////////////////////////////////
// make_unique_single
////////////////////////////////
namespace make_unique_array{
void test()
{
//Single element deleter
reset_counters();
{
bml::unique_ptr<A[]> p(bml::make_unique<A[]>(10));
BOOST_TEST(A::count == 10);
for(int i = 0; i != 10; ++i){
BOOST_TEST(p[i].a == 999);
BOOST_TEST(p[i].b == 1000);
BOOST_TEST(p[i].c == 1001);
}
}
BOOST_TEST(A::count == 0);
}
} //namespace make_unique_array{
////////////////////////////////
// unique_compare
////////////////////////////////
namespace unique_compare{
void test()
{
//Single element deleter
reset_counters();
{
bml::unique_ptr<A> pa(bml::make_unique<A>());
bml::unique_ptr<A> pb(bml::make_unique<A>());
BOOST_TEST(A::count == 2);
//Take references to less and greater
bml::unique_ptr<A> &rpl = pa < pb ? pa : pb;
bml::unique_ptr<A> &rpg = pa < pb ? pb : pa;
//Now test operations with .get()
//Equal
BOOST_TEST(rpl == rpl && rpl.get() == rpl.get());
BOOST_TEST(!(rpl == rpg) && !(rpl.get() != rpg.get()));
//Unequal
BOOST_TEST(rpl != rpg && rpl.get() != rpg.get());
BOOST_TEST(!(rpl != rpl) && !(rpl.get() != rpl.get()));
//Less
BOOST_TEST(rpl < rpg && rpl.get() < rpg.get());
BOOST_TEST(!(rpl < rpg) && !(rpl.get() < rpg.get()));
//Greater
BOOST_TEST(rpg > rpl && rpg.get() > rpl.get());
BOOST_TEST(!(rpg > rpg) && !(rpg.get() > rpl.get()));
//Less or equal
BOOST_TEST(rpl <= rpg && rpl.get() <= rpg.get());
BOOST_TEST(rpl <= rpl && rpl.get() <= rpl.get());
BOOST_TEST(!(rpg <= rpl) && !(rpg.get() < rpl.get()));
//Greater or equal
BOOST_TEST(rpg >= rpl && rpg.get() >= rpl.get());
BOOST_TEST(rpg >= rpg && rpg.get() >= rpg.get());
BOOST_TEST(!(rpl >= rpg) && !(rpl.get() < rpg.get()));
}
BOOST_TEST(A::count == 0);
}
} //namespace unique_compare{
////////////////////////////////
// main
////////////////////////////////
int main()
{
make_unique_single::test();
make_unique_array::test();
//Test results
return boost::report_errors();
}
#include <boost/move/detail/config_end.hpp>