forked from boostorg/move
Added BOOST_MOVE_RET
This commit is contained in:
+103
-2
@@ -168,6 +168,46 @@
|
||||
const ::boost::rv< TYPE >& \
|
||||
//
|
||||
|
||||
namespace boost {
|
||||
namespace move_detail {
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< ::boost::move_detail::is_lvalue_reference<Ret>::value ||
|
||||
!::boost::has_move_emulation_enabled<T>::value
|
||||
, T&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
||||
::boost::has_move_emulation_enabled<T>::value
|
||||
, ::boost::rv<T>&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return *static_cast< ::boost::rv<T>* >(::boost::move_detail::addressof(x));
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
||||
::boost::has_move_emulation_enabled<T>::value
|
||||
, ::boost::rv<T>&>::type
|
||||
move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
boost::move_detail::move_return< RET_TYPE >(REF)
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||
@@ -220,9 +260,12 @@
|
||||
#elif defined(_MSC_VER) && (_MSC_VER == 1600)
|
||||
//Standard rvalue binding rules but with some bugs
|
||||
#define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
|
||||
#define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
|
||||
//Use standard library for MSVC to avoid namespace issues as
|
||||
//some move calls in the STL are not fully qualified.
|
||||
//#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||
#elif defined(_MSC_VER) && (_MSC_VER == 1700)
|
||||
#define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -298,7 +341,6 @@
|
||||
//
|
||||
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
/// @cond
|
||||
|
||||
#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||
TYPE<ARG1, ARG2> && \
|
||||
@@ -328,10 +370,69 @@
|
||||
const TYPE & \
|
||||
//
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
//!This macro is used to achieve portable move return semantics.
|
||||
//!The Standard allows implicit move returns when the object to be returned
|
||||
//!is designated by an lvalue and:
|
||||
//! - The criteria for elision of a copy operation are met OR
|
||||
//! - The criteria would be met save for the fact that the source object is a function parameter
|
||||
//!
|
||||
//!For C++11 conforming compilers this macros only yields to REF:
|
||||
//! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
|
||||
//!
|
||||
//!For compilers without rvalue references
|
||||
//!this macro does an explicit move if the move emulation is activated
|
||||
//!and the return type (RET_TYPE) is not a reference.
|
||||
//!
|
||||
//!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
|
||||
//!an explicit move is performed if RET_TYPE is not a reference.
|
||||
//!
|
||||
//! <b>Caution</b>: When using this macro in a non-conforming or C++03
|
||||
//!compilers, a move will be performed even if the C++11 standard does not allow it
|
||||
//!(e.g. returning a static variable). The user is responsible for using this macro
|
||||
//!only used to return local objects that met C++11 criteria.
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
(REF)
|
||||
//
|
||||
|
||||
#else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace move_detail {
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< ::boost::move_detail::is_lvalue_reference<Ret>::value
|
||||
, T&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value
|
||||
, Ret && >::type
|
||||
move_return(T&& t) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< Ret&& >(t);
|
||||
}
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
boost::move_detail::move_return< RET_TYPE >(REF)
|
||||
//
|
||||
|
||||
#endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
Reference in New Issue
Block a user