mirror of
https://github.com/boostorg/move.git
synced 2025-08-02 21:54:26 +02:00
Merge branch 'develop'
This commit is contained in:
216
doc/move.qbk
216
doc/move.qbk
@@ -7,7 +7,7 @@
|
|||||||
[library Boost.Move
|
[library Boost.Move
|
||||||
[quickbook 1.5]
|
[quickbook 1.5]
|
||||||
[authors [Gaztanaga, Ion]]
|
[authors [Gaztanaga, Ion]]
|
||||||
[copyright 2008-2012 Ion Gaztanaga]
|
[copyright 2008-2014 Ion Gaztanaga]
|
||||||
[id move]
|
[id move]
|
||||||
[dirname move]
|
[dirname move]
|
||||||
[purpose Move semantics]
|
[purpose Move semantics]
|
||||||
@@ -327,127 +327,92 @@ C++03 compilers. In compilers with rvalue references perfect forwarding is achie
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[/[section:perfect_forwarding Perfect Forwarding]
|
[section:move_return Implicit Move when returning a local object]
|
||||||
/
|
|
||||||
/Consider writing a generic factory function that returns a std::shared_ptr for a newly
|
The C++ standard specifies situations where an implicit move operation is safe and the
|
||||||
/constructed generic type. Factory functions such as this are valuable for encapsulating
|
compiler can use it in cases were the (Named) Return Value Optimization) can't be used.
|
||||||
/and localizing the allocation of resources. Obviously, the factory function must accept
|
The typical use case is when a function returns a named (non-temporary) object by value
|
||||||
/exactly the same sets of arguments as the constructors of the type of objects constructed.
|
and the following code will perfectly compile in C++11:
|
||||||
/Today this might be coded as:
|
|
||||||
/
|
[c++]
|
||||||
/[c++]
|
|
||||||
/
|
//Even if movable can't be copied
|
||||||
/ template <class T>
|
//the compiler will call the move-constructor
|
||||||
/ std::shared_ptr<T>
|
//to generate the return value
|
||||||
/ factory() // no argument version
|
//
|
||||||
/ {
|
//The compiler can also optimize out the move
|
||||||
/ return std::shared_ptr<T>(new T);
|
//and directly construct the object 'm'
|
||||||
/ }
|
movable factory()
|
||||||
/
|
{
|
||||||
/ template <class T, class A1>
|
movable tmp;
|
||||||
/ std::shared_ptr<T>
|
m = ...
|
||||||
/ factory(const A1& a1) // one argument version
|
//(1) moved instead of copied
|
||||||
/ {
|
return tmp;
|
||||||
/ return std::shared_ptr<T>(new T(a1));
|
};
|
||||||
/ }
|
|
||||||
/
|
//Initialize object
|
||||||
/ // all the other versions
|
movable m(factory());
|
||||||
/
|
|
||||||
/
|
|
||||||
/In the interest of brevity, we will focus on just the one-parameter version. For example:
|
In compilers without rvalue references and some non-conforming compilers (such as Visual C++ 2010/2012)
|
||||||
/
|
the line marked with `(1)` would trigger a compilation error because `movable` can't be copied. Using a explicit
|
||||||
/ [c++]
|
`::boost::move(tmp)` would workaround this limitation but it would code suboptimal in C++11 compilers
|
||||||
/
|
(as the compile could not use (N)RVO to optimize-away the copy/move).
|
||||||
/ std::shared_ptr<A> p = factory<A>(5);
|
|
||||||
/
|
[*Boost.Move] offers an additional macro called [macroref BOOST_MOVE_RET BOOST_MOVE_RET] that can be used to
|
||||||
/
|
alleviate this problem obtaining portable move-on-return semantics. Let's use the previously presented
|
||||||
/ [*Question]: What if T's constructor takes a parameter by non-const reference?
|
movable-only `movable` class with classes `copyable` (copy-only type), `copy_movable` (can be copied and moved) and
|
||||||
/
|
`non_copy_movable` (non-copyable and non-movable):
|
||||||
/ In that case, we get a compile-time error as the const-qualifed argument of the factory
|
|
||||||
/ function will not bind to the non-const parameter of T's constructor.
|
[import ../example/copymovable.hpp]
|
||||||
/
|
[copy_movable_definition]
|
||||||
/ To solve that problem, we could use non-const parameters in our factory functions:
|
|
||||||
/
|
and build a generic factory function that returns a newly constructed value or a reference to an already
|
||||||
/ [c++]
|
constructed object.
|
||||||
/
|
|
||||||
/ template <class T, class A1>
|
[import ../example/doc_move_return.cpp]
|
||||||
/ std::shared_ptr<T>
|
[move_return_example]
|
||||||
/ factory(A1& a1)
|
|
||||||
/ {
|
[*Caution]: When using this macro in a non-conforming or C++03
|
||||||
/ return std::shared_ptr<T>(new T(a1));
|
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. E.g.:
|
||||||
/
|
|
||||||
/ This is much better. If a const-qualified type is passed to the factory, the const will
|
[c++]
|
||||||
/ be deduced into the template parameter (A1 for example) and then properly forwarded to
|
|
||||||
/ T's constructor. Similarly, if a non-const argument is given to factory, it will be
|
struct foo
|
||||||
/ correctly forwarded to T's constructor as a non-const. Indeed, this is precisely how
|
{
|
||||||
/forwarding applications are coded today (e.g. `std::bind`).
|
copy_movable operator()() const
|
||||||
/
|
{
|
||||||
/However, consider:
|
//ERROR! The Standard does not allow implicit move returns when the object to be returned
|
||||||
/
|
//does not met the criteria for elision of a copy operation (such as returning a static member data)
|
||||||
/[c++]
|
//In C++03 compilers this will MOVE resources from cm
|
||||||
/
|
//In C++11 compilers this will COPY resources from cm
|
||||||
/ std::shared_ptr<A> p = factory<A>(5); // error
|
//so DON'T use use BOOST_MOVE_RET without care.
|
||||||
/ A* q = new A(5); // ok
|
return BOOST_MOVE_RET(copy_movable, cm);
|
||||||
/
|
}
|
||||||
/
|
|
||||||
/This example worked with our first version of factory, but now it's broken: The "5"
|
static copy_movable cm;
|
||||||
/causesthe factory template argument to be deduced as int& and subsequently will not
|
};
|
||||||
/bind to the rvalue "5". Neither solution so far is right. Each breaks reasonable and
|
|
||||||
/common code.
|
|
||||||
/
|
[*Note]: When returning a temporary object `BOOST_MOVE_REF` is not needed as copy ellision rules will work on
|
||||||
/[*Question]: What about overloading on every combination of AI& and const AI&?
|
both C++03 and C++11 compilers.
|
||||||
/
|
|
||||||
/This would allow use to handle all examples, but at a cost of an exponential explosion:
|
[c++]
|
||||||
/For our two-parameter case, this would require 4 overloads. For a three-parameter factory
|
|
||||||
/we would need 8 additional overloads. For a four-parameter factory we would need 16, and
|
//Note: no BOOST_MOVE_RET
|
||||||
/so on. This is not a scalable solution.
|
movable get_movable()
|
||||||
/
|
{ return movable(); }
|
||||||
/Rvalue references offer a simple, scalable solution to this problem:
|
|
||||||
/
|
copy_movable get_copy_movable()
|
||||||
/[c++]
|
{ return copy_movable(); }
|
||||||
/
|
|
||||||
/ template <class T, class A1>
|
copyable get_copyable()
|
||||||
/ std::shared_ptr<T>
|
{ return copyable(); }
|
||||||
/ factory(A1&& a1)
|
|
||||||
/ {
|
|
||||||
/ return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
|
[endsect]
|
||||||
/ }
|
|
||||||
/
|
|
||||||
/ Now rvalue arguments can bind to the factory parameters. If the argument is const, that
|
|
||||||
/ fact gets deduced into the factory template parameter type.
|
|
||||||
/
|
|
||||||
/ [*Question]: What is that forward function in our solution?
|
|
||||||
/
|
|
||||||
/ Like move, forward is a simple standard library function used to express our intent
|
|
||||||
/ directly and explicitly, rather than through potentially cryptic uses of references.
|
|
||||||
/ We want to forward the argument a1, so we simply say so.
|
|
||||||
/
|
|
||||||
/ Here, forward preserves the lvalue/rvalue-ness of the argument that was passed to factory.
|
|
||||||
/ If an rvalue is passed to factory, then an rvalue will be passed to T's constructor with
|
|
||||||
/ the help of the forward function. Similarly, if an lvalue is passed to factory, it is
|
|
||||||
/ forwarded to T's constructor as an lvalue.
|
|
||||||
/
|
|
||||||
/ The definition of forward looks like this:
|
|
||||||
/
|
|
||||||
/ [c++]
|
|
||||||
/
|
|
||||||
/ template <class T>
|
|
||||||
/ struct identity
|
|
||||||
/ {
|
|
||||||
/ typedef T type;
|
|
||||||
/ };
|
|
||||||
/
|
|
||||||
/ template <class T>
|
|
||||||
/ T&& forward(typename identity<T>::type&& a)
|
|
||||||
/ {
|
|
||||||
/ return a;
|
|
||||||
/ }
|
|
||||||
/
|
|
||||||
/[endsect]
|
|
||||||
/
|
|
||||||
/]
|
|
||||||
|
|
||||||
[section:move_iterator Move iterators]
|
[section:move_iterator Move iterators]
|
||||||
|
|
||||||
@@ -790,6 +755,12 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
|
|||||||
|
|
||||||
[section:release_notes Release Notes]
|
[section:release_notes Release Notes]
|
||||||
|
|
||||||
|
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
|
||||||
|
|
||||||
|
* Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET].
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
|
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
|
||||||
|
|
||||||
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7952 #7952],
|
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7952 #7952],
|
||||||
@@ -797,6 +768,7 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
|
|||||||
[@https://svn.boost.org/trac/boost/ticket/8765 #8765],
|
[@https://svn.boost.org/trac/boost/ticket/8765 #8765],
|
||||||
[@https://svn.boost.org/trac/boost/ticket/8842 #8842],
|
[@https://svn.boost.org/trac/boost/ticket/8842 #8842],
|
||||||
[@https://svn.boost.org/trac/boost/ticket/8979 #8979].
|
[@https://svn.boost.org/trac/boost/ticket/8979 #8979].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
@@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
|
||||||
//[movable_definition
|
//[copy_movable_definition
|
||||||
//header file "copy_movable.hpp"
|
//header file "copymovable.hpp"
|
||||||
#include <boost/move/core.hpp>
|
#include <boost/move/core.hpp>
|
||||||
|
|
||||||
//A copy_movable class
|
//A copy_movable class
|
||||||
@@ -43,6 +43,20 @@ class copy_movable
|
|||||||
{ return value_ == 0; }
|
{ return value_ == 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//A copyable-only class
|
||||||
|
class copyable
|
||||||
|
{};
|
||||||
|
|
||||||
|
//A copyable-only class
|
||||||
|
class non_copy_movable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
non_copy_movable(){}
|
||||||
|
private:
|
||||||
|
non_copy_movable(const non_copy_movable&);
|
||||||
|
non_copy_movable& operator=(const non_copy_movable&);
|
||||||
|
};
|
||||||
|
|
||||||
//]
|
//]
|
||||||
|
|
||||||
#include <boost/move/detail/config_end.hpp>
|
#include <boost/move/detail/config_end.hpp>
|
||||||
|
70
example/doc_move_return.cpp
Normal file
70
example/doc_move_return.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (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>
|
||||||
|
|
||||||
|
//[move_return_example
|
||||||
|
#include "movable.hpp"
|
||||||
|
#include "copymovable.hpp"
|
||||||
|
#include <boost/move/core.hpp>
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
struct factory_functor
|
||||||
|
{
|
||||||
|
typedef Type return_type;
|
||||||
|
|
||||||
|
Type operator()() const
|
||||||
|
{ Type t; return BOOST_MOVE_RET(Type, t); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct return_reference
|
||||||
|
{
|
||||||
|
typedef non_copy_movable &return_type;
|
||||||
|
|
||||||
|
non_copy_movable &operator()() const
|
||||||
|
{ return ncm; }
|
||||||
|
|
||||||
|
static non_copy_movable ncm;
|
||||||
|
};
|
||||||
|
|
||||||
|
non_copy_movable return_reference::ncm;
|
||||||
|
|
||||||
|
//A wrapper that locks a mutex while the
|
||||||
|
//factory creates a new value.
|
||||||
|
//It must generically move the return value
|
||||||
|
//if possible both in C++03 and C++11
|
||||||
|
template <class Factory>
|
||||||
|
typename Factory::return_type lock_wrapper(Factory f)
|
||||||
|
{
|
||||||
|
typedef typename Factory::return_type return_type;
|
||||||
|
//LOCK();
|
||||||
|
return_type r = f();
|
||||||
|
//UNLOCK();
|
||||||
|
|
||||||
|
//In C++03: boost::move() if R is not a reference and
|
||||||
|
//has move emulation enabled. In C++11: just return r.
|
||||||
|
return BOOST_MOVE_RET(return_type, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
movable m = lock_wrapper(factory_functor<movable> ());
|
||||||
|
copy_movable cm = lock_wrapper(factory_functor<copy_movable>());
|
||||||
|
copyable c = lock_wrapper(factory_functor<copyable> ());
|
||||||
|
non_copy_movable &mr = lock_wrapper(return_reference ());
|
||||||
|
//<-
|
||||||
|
(void)m; (void)cm; (void)c; (void)mr;
|
||||||
|
//->
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//]
|
||||||
|
|
||||||
|
#include <boost/move/detail/config_end.hpp>
|
@@ -168,6 +168,46 @@
|
|||||||
const ::boost::rv< TYPE >& \
|
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
|
// BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||||
@@ -220,9 +260,12 @@
|
|||||||
#elif defined(_MSC_VER) && (_MSC_VER == 1600)
|
#elif defined(_MSC_VER) && (_MSC_VER == 1600)
|
||||||
//Standard rvalue binding rules but with some bugs
|
//Standard rvalue binding rules but with some bugs
|
||||||
#define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
|
#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
|
//Use standard library for MSVC to avoid namespace issues as
|
||||||
//some move calls in the STL are not fully qualified.
|
//some move calls in the STL are not fully qualified.
|
||||||
//#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
//#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||||
|
#elif defined(_MSC_VER) && (_MSC_VER == 1700)
|
||||||
|
#define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -298,7 +341,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
/// @cond
|
|
||||||
|
|
||||||
#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||||
TYPE<ARG1, ARG2> && \
|
TYPE<ARG1, ARG2> && \
|
||||||
@@ -328,10 +370,69 @@
|
|||||||
const TYPE & \
|
const TYPE & \
|
||||||
//
|
//
|
||||||
|
|
||||||
/// @endcond
|
|
||||||
|
|
||||||
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
#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
|
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
|
||||||
#include <boost/move/detail/config_end.hpp>
|
#include <boost/move/detail/config_end.hpp>
|
||||||
|
@@ -59,6 +59,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_test", "move_test.vcpr
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_return", "doc_move_return.vcproj", "{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@@ -127,6 +131,10 @@ Global
|
|||||||
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = 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.ActiveCfg = Release|Win32
|
||||||
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
|
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
|
||||||
|
{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Debug.ActiveCfg = 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.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
|
||||||
|
134
proj/vc7ide/doc_move_return.vcproj
Normal file
134
proj/vc7ide/doc_move_return.vcproj
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="doc_move_return"
|
||||||
|
ProjectGUID="{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}"
|
||||||
|
Keyword="Win32Proj">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="../../Bin/Win32/Debug"
|
||||||
|
IntermediateDirectory="Debug/doc_move_return"
|
||||||
|
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)/doc_move_return_d.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/doc_move_return.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/doc_move_return"
|
||||||
|
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)/doc_move_return.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="{475F3C87-6465-7BC5-05A6-2454C0A2A2CF}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\example\doc_move_return.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
@@ -11,6 +11,7 @@
|
|||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/utility.hpp>
|
#include <boost/move/utility.hpp>
|
||||||
#include "../example/movable.hpp"
|
#include "../example/movable.hpp"
|
||||||
|
#include "../example/copymovable.hpp"
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
movable function(movable m)
|
movable function(movable m)
|
||||||
@@ -57,11 +58,41 @@ void function_ref(const movable &)
|
|||||||
void function_ref(BOOST_RV_REF(movable))
|
void function_ref(BOOST_RV_REF(movable))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
struct copyable
|
|
||||||
{};
|
|
||||||
|
|
||||||
movable create_movable()
|
movable create_movable()
|
||||||
{ return movable(); }
|
{ return movable(); }
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
struct factory
|
||||||
|
{
|
||||||
|
Type operator()() const
|
||||||
|
{
|
||||||
|
Type t;
|
||||||
|
return BOOST_MOVE_RET(Type, t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
struct factory<Type &>
|
||||||
|
{
|
||||||
|
static Type t;
|
||||||
|
Type &operator()() const
|
||||||
|
{
|
||||||
|
return BOOST_MOVE_RET(Type&, t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Type factory<Type&>::t;
|
||||||
|
|
||||||
|
template <class R, class F>
|
||||||
|
R factory_wrapper(F f)
|
||||||
|
{
|
||||||
|
// lock();
|
||||||
|
R r = f();
|
||||||
|
// unlock();
|
||||||
|
return BOOST_MOVE_RET(R, r);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
@@ -78,35 +109,72 @@ int main()
|
|||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(function(movable(boost::move(m2))));
|
movable m3(function(movable(boost::move(m2))));
|
||||||
movable m4(function(boost::move(m3)));
|
movable m4(function(boost::move(m3)));
|
||||||
|
(void)m;(void)m2;(void)m3;(void)m4;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
movable m;
|
movable m;
|
||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(functionr(movable(boost::move(m2))));
|
movable m3(functionr(movable(boost::move(m2))));
|
||||||
movable m4(functionr(boost::move(m3)));
|
movable m4(functionr(boost::move(m3)));
|
||||||
|
(void)m;(void)m2;(void)m3;(void)m4;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
movable m;
|
movable m;
|
||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(function2(movable(boost::move(m2))));
|
movable m3(function2(movable(boost::move(m2))));
|
||||||
movable m4(function2(boost::move(m3)));
|
movable m4(function2(boost::move(m3)));
|
||||||
|
(void)m;(void)m2;(void)m3;(void)m4;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
movable m;
|
movable m;
|
||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(function2r(movable(boost::move(m2))));
|
movable m3(function2r(movable(boost::move(m2))));
|
||||||
movable m4(function2r(boost::move(m3)));
|
movable m4(function2r(boost::move(m3)));
|
||||||
|
(void)m;(void)m2;(void)m3;(void)m4;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
movable m;
|
movable m;
|
||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(move_return_function());
|
movable m3(move_return_function());
|
||||||
|
(void)m;(void)m2;(void)m3;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
movable m;
|
movable m;
|
||||||
movable m2(boost::move(m));
|
movable m2(boost::move(m));
|
||||||
movable m3(move_return_function2());
|
movable m3(move_return_function2());
|
||||||
|
(void)m;(void)m2;(void)m3;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
//movable
|
||||||
|
movable m (factory_wrapper<movable>(factory<movable>()));
|
||||||
|
m = factory_wrapper<movable>(factory<movable>());
|
||||||
|
movable&mr(factory_wrapper<movable&>(factory<movable&>()));
|
||||||
|
movable&mr2 = factory_wrapper<movable&>(factory<movable&>());
|
||||||
|
(void)mr;
|
||||||
|
(void)mr2;
|
||||||
|
(void)m;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
//copyable
|
||||||
|
copyable c (factory_wrapper<copyable>(factory<copyable>()));
|
||||||
|
c = factory_wrapper<copyable>(factory<copyable>());
|
||||||
|
copyable&cr(factory_wrapper<copyable&>(factory<copyable&>()));
|
||||||
|
copyable&cr2 = factory_wrapper<copyable&>(factory<copyable&>());
|
||||||
|
(void)cr;
|
||||||
|
(void)cr2;
|
||||||
|
(void)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//copy_movable
|
||||||
|
copy_movable c (factory_wrapper<copy_movable>(factory<copy_movable>()));
|
||||||
|
c = factory_wrapper<copy_movable>(factory<copy_movable>());
|
||||||
|
copy_movable&cr(factory_wrapper<copy_movable&>(factory<copy_movable&>()));
|
||||||
|
copy_movable&cr2 = factory_wrapper<copy_movable&>(factory<copy_movable&>());
|
||||||
|
(void)cr;
|
||||||
|
(void)cr2;
|
||||||
|
(void)c;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user