mirror of
https://github.com/boostorg/move.git
synced 2025-08-02 13:44:28 +02:00
Merge branch 'apolukhin-develop' into develop
This commit is contained in:
11
doc/move.qbk
11
doc/move.qbk
@@ -757,16 +757,19 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
|
|||||||
|
|
||||||
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
|
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
|
||||||
|
|
||||||
* Fixed bug [@https://svn.boost.org/trac/boost/ticket/9785 Trac #9785: ['"Compiler warning with intel icc in boost/move/core.hpp"]],
|
* 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"]],
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
|
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
|
||||||
|
|
||||||
* Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET].
|
* Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET].
|
||||||
* Fixed bug [@https://svn.boost.org/trac/boost/ticket/9482 #9482: ['"MSVC macros not undefined in boost/move/detail/config_end.hpp"]],
|
* Fixed bugs:
|
||||||
[@https://svn.boost.org/trac/boost/ticket/9045 #9045: ['"Wrong macro name on docs"]],
|
* [@https://svn.boost.org/trac/boost/ticket/9482 #9482: ['"MSVC macros not undefined in boost/move/detail/config_end.hpp"]],
|
||||||
[@https://svn.boost.org/trac/boost/ticket/8420 #8420: ['"move's is_convertible does not compile with aligned data"]].
|
* [@https://svn.boost.org/trac/boost/ticket/9045 #9045: ['"Wrong macro name on docs"]],
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/8420 #8420: ['"move's is_convertible does not compile with aligned data"]].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//! \file core.hpp
|
//! \file
|
||||||
//! This header implements macros to define movable classes and
|
//! This header implements macros to define movable classes and
|
||||||
//! move-aware functions
|
//! move-aware functions
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
//boost_move_no_copy_constructor_or_assign typedef
|
//boost_move_no_copy_constructor_or_assign typedef
|
||||||
//used to detect noncopyable types for other Boost libraries.
|
//used to detect noncopyable types for other Boost libraries.
|
||||||
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
|
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||||
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
||||||
private:\
|
private:\
|
||||||
TYPE(TYPE &);\
|
TYPE(TYPE &);\
|
||||||
|
@@ -133,6 +133,7 @@ struct remove_reference<T&>
|
|||||||
typedef T type;
|
typedef T type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -143,6 +144,30 @@ struct remove_reference<T&&>
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//add_const
|
||||||
|
template<class T>
|
||||||
|
struct add_const
|
||||||
|
{
|
||||||
|
typedef const T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct add_const<T&>
|
||||||
|
{
|
||||||
|
typedef T& type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct add_const<T&&>
|
||||||
|
{
|
||||||
|
typedef T&& type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_class_or_union
|
struct is_class_or_union
|
||||||
{
|
{
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//! \file move.hpp
|
//! \file
|
||||||
//! A general library header that includes
|
//! A general library header that includes
|
||||||
//! the rest of top-level headers.
|
//! the rest of top-level headers.
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||||
|
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||||
#include <boost/move/detail/meta_utils.hpp>
|
#include <boost/move/detail/meta_utils.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
@@ -55,6 +56,18 @@ struct has_nothrow_move
|
|||||||
|
|
||||||
namespace move_detail {
|
namespace move_detail {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct is_nothrow_move_constructible_or_uncopyable
|
||||||
|
: public ::boost::move_detail::integral_constant
|
||||||
|
< bool
|
||||||
|
//The standard requires is_nothrow_move_constructible for move_if_noexcept
|
||||||
|
//but a user (usually in C++03) might specialize has_nothrow_move which includes it
|
||||||
|
, boost::is_nothrow_move_constructible<T>::value ||
|
||||||
|
has_nothrow_move<T>::value ||
|
||||||
|
!boost::is_copy_constructible<T>::value
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
// Code from Jeffrey Lee Hellrung, many thanks
|
// Code from Jeffrey Lee Hellrung, many thanks
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
@@ -10,73 +10,74 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//! \file
|
//! \file
|
||||||
|
//! This header includes core utilities from <tt><boost/move/utility_core.hpp></tt> and defines
|
||||||
|
//! some more advanced utilities such as:
|
||||||
|
|
||||||
#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
||||||
#define BOOST_MOVE_MOVE_UTILITY_HPP
|
#define BOOST_MOVE_MOVE_UTILITY_HPP
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <boost/move/detail/meta_utils.hpp>
|
#include <boost/move/traits.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct enable_move_utility_emulation
|
|
||||||
{
|
|
||||||
static const bool value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// move()
|
// move_if_noexcept()
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::enable_if_c
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
< enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value, T&>::type
|
< enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value
|
||||||
move(T& x) BOOST_NOEXCEPT
|
, typename ::boost::move_detail::add_const<T>::type &
|
||||||
|
>::type
|
||||||
|
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::enable_if_c
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||||
move(T& x) BOOST_NOEXCEPT
|
&& ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, rv<T>&>::type
|
||||||
|
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::enable_if_c
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||||
move(rv<T>& x) BOOST_NOEXCEPT
|
&& ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||||
|
, rv<T>&
|
||||||
|
>::type
|
||||||
|
move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// forward()
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::enable_if_c
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
< enable_move_utility_emulation<T>::value && ::boost::move_detail::is_rv<T>::value, T &>::type
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
&& !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||||
|
, typename ::boost::move_detail::add_const<T>::type &
|
||||||
|
>::type
|
||||||
|
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return const_cast<T&>(x);
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::enable_if_c
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
< enable_move_utility_emulation<T>::value && !::boost::move_detail::is_rv<T>::value, const T &>::type
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
&& !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||||
|
, typename ::boost::move_detail::add_const<T>::type &
|
||||||
|
>::type
|
||||||
|
move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -90,8 +91,7 @@
|
|||||||
|
|
||||||
namespace boost{
|
namespace boost{
|
||||||
|
|
||||||
using ::std::move;
|
using ::std::move_if_noexcept;
|
||||||
using ::std::forward;
|
|
||||||
|
|
||||||
} //namespace boost
|
} //namespace boost
|
||||||
|
|
||||||
@@ -99,89 +99,35 @@
|
|||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
//! This trait's internal boolean `value` is false in compilers with rvalue references
|
|
||||||
//! and true in compilers without rvalue references.
|
|
||||||
//!
|
|
||||||
//! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
|
|
||||||
//! so that the user can define a different move emulation for that type in namespace boost
|
|
||||||
//! (e.g. another Boost library for its types) and avoid any overload ambiguity.
|
|
||||||
template<class T>
|
|
||||||
struct enable_move_utility_emulation
|
|
||||||
{
|
|
||||||
static const bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// move
|
// move_if_noexcept()
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
//! This function provides a way to convert a reference into a rvalue reference
|
//! This function provides a way to convert a reference into a rvalue reference
|
||||||
//! in compilers with rvalue references. For other compilers converts T & into
|
//! in compilers with rvalue references. For other compilers converts T & into
|
||||||
//! <i>::boost::rv<T> &</i> so that move emulation is activated.
|
//! <i>::boost::rv<T> &</i> so that move emulation is activated. Reference
|
||||||
|
//! would be converted to rvalue reference only if input type is nothrow move
|
||||||
|
//! constructible or if it has no copy constructor. In all other cases const
|
||||||
|
//! reference would be returned
|
||||||
template <class T>
|
template <class T>
|
||||||
rvalue_reference move(input_reference) noexcept;
|
rvalue_reference move_if_noexcept(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 typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
|
||||||
{ return t; }
|
|
||||||
|
|
||||||
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
inline typename ::boost::move_detail::if_c
|
||||||
{ return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
|
< ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||||
|
, T&&
|
||||||
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
, const T&
|
||||||
|
>::type
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||||
//
|
|
||||||
// forward
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
|
||||||
//! This function provides limited form of forwarding that is usually enough for
|
|
||||||
//! in-place construction and avoids the exponential overloading for
|
|
||||||
//! achieve the limited forwarding in C++03.
|
|
||||||
//!
|
|
||||||
//! For compilers with rvalue references this function provides perfect forwarding.
|
|
||||||
//!
|
|
||||||
//! Otherwise:
|
|
||||||
//! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
|
|
||||||
//! ::boost::rv<T> &
|
|
||||||
//!
|
|
||||||
//! * Else, output_reference is equal to input_reference.
|
|
||||||
template <class T> output_reference forward(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&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
|
|
||||||
{ return t; }
|
|
||||||
|
|
||||||
#else //Old move
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
|
|
||||||
{ return static_cast<T&&>(t); }
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T&& forward(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.";
|
return ::boost::move(x);
|
||||||
BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
|
|
||||||
return static_cast<T&&>(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
} //namespace boost {
|
} //namespace boost {
|
||||||
|
|
||||||
|
197
include/boost/move/utility_core.hpp
Normal file
197
include/boost/move/utility_core.hpp
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (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
|
||||||
|
//! This header defines core utilities to ease the development
|
||||||
|
//! of move-aware functions. This header minimizes dependencies
|
||||||
|
//! from other libraries.
|
||||||
|
|
||||||
|
#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||||
|
#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||||
|
|
||||||
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
#include <boost/move/core.hpp>
|
||||||
|
#include <boost/move/detail/meta_utils.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct enable_move_utility_emulation
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// move()
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
|
< enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value, T&>::type
|
||||||
|
move(T& x) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
||||||
|
move(T& x) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline typename ::boost::move_detail::enable_if_c
|
||||||
|
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
||||||
|
move(rv<T>& x) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// forward()
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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
|
||||||
|
forward(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, const T &>::type
|
||||||
|
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace boost
|
||||||
|
|
||||||
|
#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
|
#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
|
||||||
|
using ::std::move;
|
||||||
|
using ::std::forward;
|
||||||
|
|
||||||
|
} //namespace boost
|
||||||
|
|
||||||
|
#else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
//! This trait's internal boolean `value` is false in compilers with rvalue references
|
||||||
|
//! and true in compilers without rvalue references.
|
||||||
|
//!
|
||||||
|
//! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
|
||||||
|
//! so that the user can define a different move emulation for that type in namespace boost
|
||||||
|
//! (e.g. another Boost library for its types) and avoid any overload ambiguity.
|
||||||
|
template<class T>
|
||||||
|
struct enable_move_utility_emulation
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// move
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
//! This function provides a way to convert a reference into a rvalue reference
|
||||||
|
//! in compilers with rvalue references. For other compilers converts T & into
|
||||||
|
//! <i>::boost::rv<T> &</i> so that move emulation is activated.
|
||||||
|
template <class T>
|
||||||
|
rvalue_reference move(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 typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||||
|
{ return t; }
|
||||||
|
|
||||||
|
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||||
|
{ return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
|
||||||
|
|
||||||
|
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// forward
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
//! This function provides limited form of forwarding that is usually enough for
|
||||||
|
//! in-place construction and avoids the exponential overloading for
|
||||||
|
//! achieve the limited forwarding in C++03.
|
||||||
|
//!
|
||||||
|
//! For compilers with rvalue references this function provides perfect forwarding.
|
||||||
|
//!
|
||||||
|
//! Otherwise:
|
||||||
|
//! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
|
||||||
|
//! ::boost::rv<T> &
|
||||||
|
//!
|
||||||
|
//! * Else, output_reference is equal to input_reference.
|
||||||
|
template <class T> output_reference forward(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&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
|
||||||
|
{ return t; }
|
||||||
|
|
||||||
|
#else //Old move
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
|
||||||
|
{ return static_cast<T&&>(t); }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T&& forward(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
|
||||||
|
|
||||||
|
#include <boost/move/detail/config_end.hpp>
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
@@ -63,6 +63,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_return", "doc_move
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_if_noexcept_test", "move_if_noexcept_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@@ -135,6 +139,10 @@ Global
|
|||||||
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Debug.Build.0 = Debug|Win32
|
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Debug.Build.0 = Debug|Win32
|
||||||
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.ActiveCfg = Release|Win32
|
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.ActiveCfg = Release|Win32
|
||||||
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.Build.0 = Release|Win32
|
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.Build.0 = Release|Win32
|
||||||
|
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{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
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionItems) = postSolution
|
GlobalSection(SolutionItems) = postSolution
|
||||||
..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp
|
..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp
|
||||||
@@ -149,6 +157,7 @@ Global
|
|||||||
..\..\..\..\boost\move\detail\move_helpers.hpp = ..\..\..\..\boost\move\detail\move_helpers.hpp
|
..\..\..\..\boost\move\detail\move_helpers.hpp = ..\..\..\..\boost\move\detail\move_helpers.hpp
|
||||||
..\..\..\..\boost\move\traits.hpp = ..\..\..\..\boost\move\traits.hpp
|
..\..\..\..\boost\move\traits.hpp = ..\..\..\..\boost\move\traits.hpp
|
||||||
..\..\..\..\boost\move\utility.hpp = ..\..\..\..\boost\move\utility.hpp
|
..\..\..\..\boost\move\utility.hpp = ..\..\..\..\boost\move\utility.hpp
|
||||||
|
..\..\..\..\boost\move\utility_core.hpp = ..\..\..\..\boost\move\utility_core.hpp
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
135
proj/vc7ide/move_if_noexcept_test.vcproj
Normal file
135
proj/vc7ide/move_if_noexcept_test.vcproj
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="move_if_noexcept_test"
|
||||||
|
ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
|
||||||
|
Keyword="Win32Proj">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="../../Bin/Win32/Debug"
|
||||||
|
IntermediateDirectory="Debug/move_if_noexcept_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="TRUE"
|
||||||
|
TreatWChar_tAsBuiltInType="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
DebugInformationFormat="3"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="winmm.lib"
|
||||||
|
OutputFile="$(OutDir)/move_if_noexcept_test_d.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/move_if_noexcept_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/move_if_noexcept_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)/move_if_noexcept_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="{7EA34951-57AC-6216-05A6-20A754202AFF}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\test\move_if_noexcept.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
229
test/move_if_noexcept.cpp
Normal file
229
test/move_if_noexcept.cpp
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Antony Polukhin 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/utility.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include "../example/movable.hpp"
|
||||||
|
#include "../example/copymovable.hpp"
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//A copy_movable_noexcept class
|
||||||
|
class copy_movable_noexcept
|
||||||
|
{
|
||||||
|
BOOST_COPYABLE_AND_MOVABLE(copy_movable_noexcept)
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
copy_movable_noexcept() : value_(1){}
|
||||||
|
|
||||||
|
//Move constructor and assignment
|
||||||
|
copy_movable_noexcept(BOOST_RV_REF(copy_movable_noexcept) m)
|
||||||
|
{ value_ = m.value_; m.value_ = 0; }
|
||||||
|
|
||||||
|
copy_movable_noexcept(const copy_movable_noexcept &m)
|
||||||
|
{ value_ = m.value_; }
|
||||||
|
|
||||||
|
copy_movable_noexcept & operator=(BOOST_RV_REF(copy_movable_noexcept) m)
|
||||||
|
{ value_ = m.value_; m.value_ = 0; return *this; }
|
||||||
|
|
||||||
|
copy_movable_noexcept & operator=(BOOST_COPY_ASSIGN_REF(copy_movable_noexcept) m)
|
||||||
|
{ value_ = m.value_; return *this; }
|
||||||
|
|
||||||
|
bool moved() const //Observer
|
||||||
|
{ return value_ == 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct has_nothrow_move<copy_movable_noexcept>
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace boost{
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//A movable_throwable class
|
||||||
|
class movable_throwable
|
||||||
|
{
|
||||||
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_throwable)
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
movable_throwable() : value_(1){}
|
||||||
|
|
||||||
|
//Move constructor and assignment
|
||||||
|
movable_throwable(BOOST_RV_REF(movable_throwable) m)
|
||||||
|
{ value_ = m.value_; m.value_ = 0; }
|
||||||
|
|
||||||
|
movable_throwable & operator=(BOOST_RV_REF(movable_throwable) m)
|
||||||
|
{ value_ = m.value_; m.value_ = 0; return *this; }
|
||||||
|
|
||||||
|
bool moved() const //Observer
|
||||||
|
{ return !value_; }
|
||||||
|
|
||||||
|
int value() const //Observer
|
||||||
|
{ return value_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper functions
|
||||||
|
movable function(movable m)
|
||||||
|
{
|
||||||
|
return movable(boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_movable function(copy_movable m)
|
||||||
|
{
|
||||||
|
return copy_movable(boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_movable_noexcept function(copy_movable_noexcept m)
|
||||||
|
{
|
||||||
|
return copy_movable_noexcept(boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
movable_throwable function(movable_throwable m)
|
||||||
|
{
|
||||||
|
return movable_throwable(boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
movable functionr(BOOST_RV_REF(movable) m)
|
||||||
|
{
|
||||||
|
return movable(boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
movable function2(movable m)
|
||||||
|
{
|
||||||
|
return boost::move_if_noexcept(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
|
||||||
|
{
|
||||||
|
return boost::move_if_noexcept(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
movable move_return_function2 ()
|
||||||
|
{
|
||||||
|
return movable();
|
||||||
|
}
|
||||||
|
|
||||||
|
movable move_return_function ()
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
return (boost::move_if_noexcept(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_CHECK(x) if (!(x)) { return __LINE__; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
movable m3(function(movable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
movable m4(function(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
movable m3(functionr(movable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
movable m4(functionr(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
movable m3(function2(movable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
movable m4(function2(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
movable m3(function2r(movable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
movable m4(function2r(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
BOOST_CHECK(!m2.moved());
|
||||||
|
movable m3(move_return_function());
|
||||||
|
BOOST_CHECK(!m3.moved());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
movable m;
|
||||||
|
movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
BOOST_CHECK(!m2.moved());
|
||||||
|
movable m3(move_return_function2());
|
||||||
|
BOOST_CHECK(!m3.moved());
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy_movable may throw during move, so it must be copied
|
||||||
|
{
|
||||||
|
copy_movable m;
|
||||||
|
copy_movable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(!m.moved());
|
||||||
|
copy_movable m3(function(copy_movable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(!m2.moved());
|
||||||
|
copy_movable m4(function(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(!m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// copy_movable_noexcept can not throw during move
|
||||||
|
{
|
||||||
|
copy_movable_noexcept m;
|
||||||
|
copy_movable_noexcept m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
copy_movable_noexcept m3(function(copy_movable_noexcept(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
copy_movable_noexcept m4(function(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
|
||||||
|
// movable_throwable can not throw during move but it has no copy constructor
|
||||||
|
{
|
||||||
|
movable_throwable m;
|
||||||
|
movable_throwable m2(boost::move_if_noexcept(m));
|
||||||
|
BOOST_CHECK(m.moved());
|
||||||
|
movable_throwable m3(function(movable_throwable(boost::move_if_noexcept(m2))));
|
||||||
|
BOOST_CHECK(m2.moved());
|
||||||
|
movable_throwable m4(function(boost::move_if_noexcept(m3)));
|
||||||
|
BOOST_CHECK(m3.moved());
|
||||||
|
BOOST_CHECK(!m4.moved());
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/move/detail/config_end.hpp>
|
Reference in New Issue
Block a user