mirror of
https://github.com/boostorg/move.git
synced 2025-08-02 13:44:28 +02:00
First Move merge for 1.55
[SVN r85442]
This commit is contained in:
27
doc/move.qbk
27
doc/move.qbk
@@ -129,9 +129,12 @@ Consider a simple handle class that owns a resource and also provides copy seman
|
|||||||
|
|
||||||
clone_ptr& operator=(clone_ptr&& p)
|
clone_ptr& operator=(clone_ptr&& p)
|
||||||
{
|
{
|
||||||
std::swap(ptr, p.ptr);
|
if(this != &p)
|
||||||
delete p.ptr;
|
{
|
||||||
p.ptr = 0;
|
std::swap(ptr, p.ptr);
|
||||||
|
delete p.ptr;
|
||||||
|
p.ptr = 0;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +174,7 @@ You just need to follow these simple steps:
|
|||||||
|
|
||||||
* Put the following macro in the [*private] section:
|
* Put the following macro in the [*private] section:
|
||||||
[macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE(classname)]
|
[macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE(classname)]
|
||||||
* Left copy constructor as is.
|
* Leave copy constructor as is.
|
||||||
* Write a copy assignment taking the parameter as
|
* Write a copy assignment taking the parameter as
|
||||||
[macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)]
|
[macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)]
|
||||||
* Write a move constructor and a move assignment taking the parameter as
|
* Write a move constructor and a move assignment taking the parameter as
|
||||||
@@ -787,10 +790,22 @@ 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_55_00 Boost 1.55 Release]
|
||||||
|
|
||||||
|
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7952 #7952],
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/8764 #8764],
|
||||||
|
[@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/8979 #8979].
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
[section:release_notes_boost_1_54_00 Boost 1.54 Release]
|
[section:release_notes_boost_1_54_00 Boost 1.54 Release]
|
||||||
|
|
||||||
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7969 #7969]),
|
|
||||||
[@https://svn.boost.org/trac/boost/ticket/8231 #8231]).
|
* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7969 #7969],
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/8231 #8231],
|
||||||
|
[@https://svn.boost.org/trac/boost/ticket/8765 #8765].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
//[file_descriptor_def
|
//[file_descriptor_def
|
||||||
|
|
||||||
@@ -24,8 +25,8 @@ class file_descriptor
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operating_system_close_file(int)
|
void operating_system_close_file(int fd)
|
||||||
{}
|
{ (void)fd; assert(fd != 0); }
|
||||||
//->
|
//->
|
||||||
int os_descr_;
|
int os_descr_;
|
||||||
|
|
||||||
@@ -33,12 +34,12 @@ class file_descriptor
|
|||||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit file_descriptor(const char *filename = 0) //Constructor
|
explicit file_descriptor(const char *filename) //Constructor
|
||||||
: os_descr_(filename ? operating_system_open_file(filename) : 0)
|
: os_descr_(operating_system_open_file(filename))
|
||||||
{ if(!os_descr_) throw std::runtime_error("file not found"); }
|
{ if(!os_descr_) throw std::runtime_error("file not found"); }
|
||||||
|
|
||||||
~file_descriptor() //Destructor
|
~file_descriptor() //Destructor
|
||||||
{ if(!os_descr_) operating_system_close_file(os_descr_); }
|
{ if(os_descr_) operating_system_close_file(os_descr_); }
|
||||||
|
|
||||||
file_descriptor(BOOST_RV_REF(file_descriptor) x) // Move ctor
|
file_descriptor(BOOST_RV_REF(file_descriptor) x) // Move ctor
|
||||||
: os_descr_(x.os_descr_)
|
: os_descr_(x.os_descr_)
|
||||||
@@ -46,7 +47,7 @@ class file_descriptor
|
|||||||
|
|
||||||
file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
|
file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
|
||||||
{
|
{
|
||||||
if(!os_descr_) operating_system_close_file(os_descr_);
|
if(os_descr_) operating_system_close_file(os_descr_);
|
||||||
os_descr_ = x.os_descr_;
|
os_descr_ = x.os_descr_;
|
||||||
x.os_descr_ = 0;
|
x.os_descr_ = 0;
|
||||||
return *this;
|
return *this;
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <boost/move/utility.hpp>
|
#include <boost/move/utility.hpp>
|
||||||
#include <boost/move/iterator.hpp>
|
#include <boost/move/iterator.hpp>
|
||||||
#include <boost/move/algorithm.hpp>
|
|
||||||
#include <boost/detail/no_exceptions_support.hpp>
|
#include <boost/detail/no_exceptions_support.hpp>
|
||||||
|
|
||||||
#include <algorithm> //copy, copy_backward
|
#include <algorithm> //copy, copy_backward
|
||||||
|
@@ -18,17 +18,24 @@
|
|||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
|
||||||
|
//boost_move_no_copy_constructor_or_assign typedef
|
||||||
|
//used to detect noncopyable types for other Boost libraries.
|
||||||
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
|
#ifdef 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 &);\
|
||||||
TYPE& operator=(TYPE &);\
|
TYPE& operator=(TYPE &);\
|
||||||
|
public:\
|
||||||
|
typedef int boost_move_no_copy_constructor_or_assign; \
|
||||||
|
private:\
|
||||||
//
|
//
|
||||||
#else
|
#else
|
||||||
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
||||||
public:\
|
public:\
|
||||||
TYPE(TYPE const &) = delete;\
|
TYPE(TYPE const &) = delete;\
|
||||||
TYPE& operator=(TYPE const &) = delete;\
|
TYPE& operator=(TYPE const &) = delete;\
|
||||||
|
public:\
|
||||||
|
typedef int boost_move_no_copy_constructor_or_assign; \
|
||||||
private:\
|
private:\
|
||||||
//
|
//
|
||||||
#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
|
#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#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_assignable.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
|
||||||
@@ -38,11 +40,17 @@ struct has_trivial_destructor_after_move
|
|||||||
: ::boost::has_trivial_destructor<T>
|
: ::boost::has_trivial_destructor<T>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
//! By default this traits returns false. Classes with non-throwing move constructor
|
//! By default this traits returns
|
||||||
|
//! <pre>boost::is_nothrow_move_constructible<T>::value && boost::is_nothrow_move_assignable<T>::value </pre>.
|
||||||
|
//! Classes with non-throwing move constructor
|
||||||
//! and assignment can specialize this trait to obtain some performance improvements.
|
//! and assignment can specialize this trait to obtain some performance improvements.
|
||||||
template <class T>
|
template <class T>
|
||||||
struct has_nothrow_move
|
struct has_nothrow_move
|
||||||
: public ::boost::move_detail::integral_constant<bool, false>
|
: public ::boost::move_detail::integral_constant
|
||||||
|
< bool
|
||||||
|
, boost::is_nothrow_move_constructible<T>::value &&
|
||||||
|
boost::is_nothrow_move_assignable<T>::value
|
||||||
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
namespace move_detail {
|
namespace move_detail {
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
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, T&>::type
|
||||||
move(T& x)
|
move(T& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
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, rv<T>&>::type
|
||||||
move(T& x)
|
move(T& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
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, rv<T>&>::type
|
||||||
move(rv<T>& x)
|
move(rv<T>& x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
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 && ::boost::move_detail::is_rv<T>::value, T &>::type
|
||||||
forward(const typename ::boost::move_detail::identity<T>::type &x)
|
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return const_cast<T&>(x);
|
return const_cast<T&>(x);
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
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 && !::boost::move_detail::is_rv<T>::value, const T &>::type
|
||||||
forward(const typename ::boost::move_detail::identity<T>::type &x)
|
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -123,19 +123,19 @@
|
|||||||
//! 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.
|
||||||
template <class T>
|
template <class T>
|
||||||
rvalue_reference move (input_reference);
|
rvalue_reference move(input_reference) noexcept;
|
||||||
|
|
||||||
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||||
|
|
||||||
//Old move approach, lvalues could bind to rvalue references
|
//Old move approach, lvalues could bind to rvalue references
|
||||||
template <class T>
|
template <class T>
|
||||||
inline typename remove_reference<T>::type && move(T&& t)
|
inline typename remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||||
{ return t; }
|
{ 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 remove_reference<T>::type && move(T&& t)
|
inline typename remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||||
{ return static_cast<typename remove_reference<T>::type &&>(t); }
|
{ return static_cast<typename remove_reference<T>::type &&>(t); }
|
||||||
|
|
||||||
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||||
@@ -159,13 +159,13 @@
|
|||||||
//! ::boost::rv<T> &
|
//! ::boost::rv<T> &
|
||||||
//!
|
//!
|
||||||
//! * Else, output_reference is equal to input_reference.
|
//! * Else, output_reference is equal to input_reference.
|
||||||
template <class T> output_reference forward(input_reference);
|
template <class T> output_reference forward(input_reference) noexcept;
|
||||||
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||||
|
|
||||||
//Old move approach, lvalues could bind to rvalue references
|
//Old move approach, lvalues could bind to rvalue references
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T&& forward (typename ::boost::move_detail::identity<T>::type&& t)
|
inline T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
|
||||||
{ return t; }
|
{ return t; }
|
||||||
|
|
||||||
#else //Old move
|
#else //Old move
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
move_detail::is_lvalue_reference<T>::value ? move_detail::is_lvalue_reference<U>::value : true>::type * = 0/*
|
move_detail::is_lvalue_reference<T>::value ? move_detail::is_lvalue_reference<U>::value : true>::type * = 0/*
|
||||||
, typename ::boost::move_detail::enable_if_c<
|
, typename ::boost::move_detail::enable_if_c<
|
||||||
move_detail::is_convertible
|
move_detail::is_convertible
|
||||||
<typename remove_reference<U>::type*, typename remove_reference<T>::type*>::value>::type * = 0*/)
|
<typename remove_reference<U>::type*, typename remove_reference<T>::type*>::value>::type * = 0*/) BOOST_NOEXCEPT
|
||||||
{ return static_cast<T&&>(t); }
|
{ return static_cast<T&&>(t); }
|
||||||
|
|
||||||
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
||||||
|
@@ -66,7 +66,6 @@ int main()
|
|||||||
{
|
{
|
||||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
BOOST_STATIC_ASSERT((boost::has_nothrow_move<movable>::value == true));
|
BOOST_STATIC_ASSERT((boost::has_nothrow_move<movable>::value == true));
|
||||||
BOOST_STATIC_ASSERT((boost::has_nothrow_move<copyable>::value == false));
|
|
||||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable>::value == false));
|
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable>::value == false));
|
||||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable*>::value == false));
|
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable*>::value == false));
|
||||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int>::value == false));
|
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int>::value == false));
|
||||||
|
Reference in New Issue
Block a user