Added initial implementation of move_if_noexcept

This commit is contained in:
Antony Polukhin
2014-06-04 19:57:30 +04:00
parent 51c9e874a8
commit f02990aebc
2 changed files with 113 additions and 0 deletions

View File

@@ -18,6 +18,7 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.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>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -55,6 +56,15 @@ struct has_nothrow_move
namespace move_detail {
template <class T>
struct has_nothrow_move_or_uncopyable
: public ::boost::move_detail::integral_constant
< bool
, has_nothrow_move<T>::value ||
!boost::is_copy_constructible<T>::value
>
{};
// Code from Jeffrey Lee Hellrung, many thanks
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES

View File

@@ -17,6 +17,7 @@
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/core.hpp>
#include <boost/move/detail/meta_utils.hpp>
#include <boost/move/traits.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
@@ -80,6 +81,56 @@
return x;
}
//////////////////////////////////////////////////////////////////////////////
//
// move_if_noexcept()
//
//////////////////////////////////////////////////////////////////////////////
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_if_noexcept(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
&& ::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, rv<T>&>::type
move_if_noexcept(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
&& ::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, rv<T>&>::type
move_if_noexcept(rv<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
&& !::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, T&>::type
move_if_noexcept(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
&& !::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, T&>::type
move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
{
return x;
}
} //namespace boost
#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
@@ -91,6 +142,7 @@
using ::std::move;
using ::std::forward;
using ::std::move_if_noexcept;
} //namespace boost
@@ -183,6 +235,57 @@
#endif //BOOST_MOVE_DOXYGEN_INVOKED
//////////////////////////////////////////////////////////////////////////////
//
// move_if_noexcept()
//
//////////////////////////////////////////////////////////////////////////////
#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. Reference
//! would be converted to rvalue reference only if input type is nothrow move
//! constructible or if it has no copy constructor.
template <class T>
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::enable_if_c
< ::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, typename remove_reference<T>::type&&>::type
move_if_noexcept(T& x) BOOST_NOEXCEPT
{
return ::boost::move(x);
}
template <class T>
inline typename ::boost::move_detail::enable_if_c
< !::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, typename remove_reference<T>::type&>::type
move_if_noexcept(T& x) BOOST_NOEXCEPT
{
return x;
}
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
template <class T>
inline typename ::boost::move_detail::enable_if_c
< ::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, T&&>::type
move_if_noexcept(T& x) BOOST_NOEXCEPT
{
return ::boost::move(x);
}
template <class T>
inline typename ::boost::move_detail::enable_if_c
< !::boost::move_detail::has_nothrow_move_or_uncopyable<T>::value, T&>::type
move_if_noexcept(T& x) BOOST_NOEXCEPT
{
return x;
}
#endif //BOOST_MOVE_DOXYGEN_INVOKED
} //namespace boost {
#endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)