mirror of
https://github.com/boostorg/move.git
synced 2025-08-03 14:14:26 +02:00
Merge branch 'develop'
This commit is contained in:
30
doc/move.qbk
30
doc/move.qbk
@@ -532,19 +532,26 @@ care to achieve portable and efficient code when using the library with C++03 co
|
|||||||
[section:emulation_limitations_base Initializing base classes]
|
[section:emulation_limitations_base Initializing base classes]
|
||||||
|
|
||||||
When initializing base classes in move constructors, users must
|
When initializing base classes in move constructors, users must
|
||||||
cast the reference to a base class reference before moving it. Example:
|
cast the reference to a base class reference before moving it or just
|
||||||
|
use `BOOST_MOVE_BASE`. Example:
|
||||||
|
|
||||||
[c++]
|
[c++]
|
||||||
|
|
||||||
//Portable and efficient
|
|
||||||
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
||||||
: Base(boost::move(static_cast<Base&>(x))),
|
: Base(boost::move(static_cast<Base&>(x)))
|
||||||
mem_(boost::move(x.mem_)) { }
|
//...
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
[c++]
|
||||||
|
|
||||||
|
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
||||||
|
: Base(BOOST_MOVE_BASE(Base, x))
|
||||||
|
//...
|
||||||
|
|
||||||
If casting is not performed the emulation will not move construct
|
If casting is not performed the emulation will not move construct
|
||||||
the base class, because no conversion is available from `BOOST_RV_REF(Derived)`
|
the base class, because no conversion is available from `BOOST_RV_REF(Derived)` to
|
||||||
to `BOOST_RV_REF(Base)`. Without the cast we might obtain a compilation
|
`BOOST_RV_REF(Base)`. Without the cast or `BOOST_MOVE_BASE` we might obtain a compilation
|
||||||
error (for non-copyable types) or a less-efficient move constructor (for copyable types):
|
error (for non-copyable types) or a less-efficient move constructor (for copyable types):
|
||||||
|
|
||||||
[c++]
|
[c++]
|
||||||
@@ -552,8 +559,8 @@ error (for non-copyable types) or a less-efficient move constructor (for copyabl
|
|||||||
//If Derived is copyable, then Base is copy-constructed.
|
//If Derived is copyable, then Base is copy-constructed.
|
||||||
//If not, a compilation error is issued
|
//If not, a compilation error is issued
|
||||||
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
||||||
: Base(boost::move(x)),
|
: Base(boost::move(x))
|
||||||
mem_(boost::move(x.mem_)) { }
|
//...
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -755,6 +762,13 @@ 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_58_00 Boost 1.58 Release]
|
||||||
|
|
||||||
|
* Added [macroref BOOST_MOVE_BASE BOOST_MOVE_BASE] utility.
|
||||||
|
* Added [funcref boost::adl_move_swap adl_move_swap] utility.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
|
[section:release_notes_boost_1_57_00 Boost 1.57 Release]
|
||||||
|
|
||||||
* Added `unique_ptr` smart pointer. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite.
|
* Added `unique_ptr` smart pointer. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite.
|
||||||
|
@@ -64,19 +64,19 @@ class Derived : public Base
|
|||||||
// Compiler-generated copy constructor...
|
// Compiler-generated copy constructor...
|
||||||
|
|
||||||
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
Derived(BOOST_RV_REF(Derived) x) // Move ctor
|
||||||
: Base(boost::move(static_cast<Base&>(x))),
|
: Base(BOOST_MOVE_BASE(Base, x)),
|
||||||
mem_(boost::move(x.mem_)) { }
|
mem_(boost::move(x.mem_)) { }
|
||||||
|
|
||||||
Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign
|
Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign
|
||||||
{
|
{
|
||||||
Base::operator=(boost::move(static_cast<Base&>(x)));
|
Base::operator=(BOOST_MOVE_BASE(Base, x));
|
||||||
mem_ = boost::move(x.mem_);
|
mem_ = boost::move(x.mem_);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign
|
Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign
|
||||||
{
|
{
|
||||||
Base::operator=(static_cast<const Base&>(x));
|
Base::operator=(x);
|
||||||
mem_ = x.mem_;
|
mem_ = x.mem_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
225
include/boost/move/adl_move_swap.hpp
Normal file
225
include/boost/move/adl_move_swap.hpp
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
|
||||||
|
// (C) Copyright Ion Gaztanaga 2005-2013. 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/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
|
||||||
|
#define BOOST_MOVE_ADL_MOVE_SWAP_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Based on Boost.Core's swap.
|
||||||
|
//Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <cstddef> //for std::size_t
|
||||||
|
|
||||||
|
//Try to avoid including <algorithm>, as it's quite big
|
||||||
|
#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
|
||||||
|
#include <utility> //Dinkum libraries define std::swap in utility which is lighter than algorithm
|
||||||
|
#elif defined(BOOST_GCC) && defined(BOOST_GNU_STDLIB)
|
||||||
|
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
|
||||||
|
#include <bits/stl_algobase.h> //algobase is lighter than <algorithm>
|
||||||
|
#elif ((__GNUC__ == 4) && (__GNUC_MINOR__ == 3))
|
||||||
|
//In GCC 4.3 a tiny stl_move.h was created with swap and move utilities
|
||||||
|
#include <bits/stl_move.h>
|
||||||
|
#else
|
||||||
|
//In GCC 4.4 stl_move.h was renamed to move.h
|
||||||
|
#include <bits/move.h>
|
||||||
|
#endif
|
||||||
|
#elif defined(_LIBCPP_VERSION)
|
||||||
|
#include <type_traits> //The initial import of libc++ defines std::swap and still there
|
||||||
|
#else //Fallback
|
||||||
|
#include <algorithm>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/move/utility_core.hpp> //for boost::move
|
||||||
|
|
||||||
|
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
namespace boost_move_member_swap {
|
||||||
|
|
||||||
|
struct dont_care
|
||||||
|
{
|
||||||
|
dont_care(...);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct private_type
|
||||||
|
{
|
||||||
|
static private_type p;
|
||||||
|
private_type const &operator,(int) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef char yes_type;
|
||||||
|
struct no_type{ char dummy[2]; };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
no_type is_private_type(T const &);
|
||||||
|
|
||||||
|
yes_type is_private_type(private_type const &);
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class has_member_function_named_swap
|
||||||
|
{
|
||||||
|
struct BaseMixin
|
||||||
|
{
|
||||||
|
void swap();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base : public Type, public BaseMixin { Base(); };
|
||||||
|
template <typename T, T t> class Helper{};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
|
||||||
|
static yes_type deduce(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, bool HasFunc>
|
||||||
|
struct has_member_swap_impl
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_swap_impl<Fun, true>
|
||||||
|
{
|
||||||
|
struct FunWrap : Fun
|
||||||
|
{
|
||||||
|
FunWrap();
|
||||||
|
|
||||||
|
using Fun::swap;
|
||||||
|
private_type swap(dont_care) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Fun &declval_fun();
|
||||||
|
static FunWrap declval_wrap();
|
||||||
|
|
||||||
|
static bool const value =
|
||||||
|
sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_swap : public has_member_swap_impl
|
||||||
|
<Fun, has_member_function_named_swap<Fun>::value>
|
||||||
|
{};
|
||||||
|
|
||||||
|
} //namespace boost_move_member_swap
|
||||||
|
|
||||||
|
namespace boost_move_adl_swap{
|
||||||
|
|
||||||
|
template<class P1, class P2, bool = P1::value>
|
||||||
|
struct and_op_impl
|
||||||
|
{ static const bool value = false; };
|
||||||
|
|
||||||
|
template<class P1, class P2>
|
||||||
|
struct and_op_impl<P1, P2, true>
|
||||||
|
{ static const bool value = P2::value; };
|
||||||
|
|
||||||
|
template<class P1, class P2>
|
||||||
|
struct and_op
|
||||||
|
: and_op_impl<P1, P2>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//////
|
||||||
|
|
||||||
|
template<class P1, class P2, bool = P1::value>
|
||||||
|
struct and_op_not_impl
|
||||||
|
{ static const bool value = false; };
|
||||||
|
|
||||||
|
template<class P1, class P2>
|
||||||
|
struct and_op_not_impl<P1, P2, true>
|
||||||
|
{ static const bool value = !P2::value; };
|
||||||
|
|
||||||
|
template<class P1, class P2>
|
||||||
|
struct and_op_not
|
||||||
|
: and_op_not_impl<P1, P2>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0)
|
||||||
|
{
|
||||||
|
//use std::swap if argument dependent lookup fails
|
||||||
|
//Use using directive ("using namespace xxx;") instead as some older compilers
|
||||||
|
//don't do ADL with using declarations ("using ns::func;").
|
||||||
|
using namespace std;
|
||||||
|
swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void swap_proxy(T& x, T& y
|
||||||
|
, typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
|
||||||
|
, boost_move_member_swap::has_member_swap<T> >
|
||||||
|
>::type* = 0)
|
||||||
|
{ T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t); }
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void swap_proxy(T& x, T& y
|
||||||
|
, typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T>
|
||||||
|
, boost_move_member_swap::has_member_swap<T> >
|
||||||
|
>::type* = 0)
|
||||||
|
{ x.swap(y); }
|
||||||
|
|
||||||
|
} //namespace boost_move_adl_swap{
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace boost_move_adl_swap{
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void swap_proxy(T& x, T& y)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace boost_move_adl_swap{
|
||||||
|
|
||||||
|
#endif //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
|
||||||
|
namespace boost_move_adl_swap{
|
||||||
|
|
||||||
|
template<class T, std::size_t N>
|
||||||
|
void swap_proxy(T (& x)[N], T (& y)[N])
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < N; ++i){
|
||||||
|
::boost_move_adl_swap::swap_proxy(x[i], y[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace boost_move_adl_swap {
|
||||||
|
|
||||||
|
#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
|
||||||
|
//! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a
|
||||||
|
//! specialized swap function if available. If no specialized swap function is available,
|
||||||
|
//! std::swap is used.
|
||||||
|
//!
|
||||||
|
//! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has
|
||||||
|
//! no rvalue references then:
|
||||||
|
//!
|
||||||
|
//! - If T has a <code>T::swap(T&)</code> member, that member is called.
|
||||||
|
//! - Otherwise a move-based swap is called, equivalent to:
|
||||||
|
//! <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>.
|
||||||
|
template<class T>
|
||||||
|
void adl_move_swap(T& x, T& y)
|
||||||
|
{
|
||||||
|
::boost_move_adl_swap::swap_proxy(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace boost{
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef BOOST_MOVE_ALGORITHM_HPP
|
#ifndef BOOST_MOVE_ALGORITHM_HPP
|
||||||
#define BOOST_MOVE_ALGORITHM_HPP
|
#define BOOST_MOVE_ALGORITHM_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
|
@@ -16,6 +16,10 @@
|
|||||||
#ifndef BOOST_MOVE_CORE_HPP
|
#ifndef BOOST_MOVE_CORE_HPP
|
||||||
#define BOOST_MOVE_CORE_HPP
|
#define BOOST_MOVE_CORE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
|
|
||||||
//boost_move_no_copy_constructor_or_assign typedef
|
//boost_move_no_copy_constructor_or_assign typedef
|
||||||
@@ -194,6 +198,10 @@
|
|||||||
boost::move_detail::move_return< RET_TYPE >(REF)
|
boost::move_detail::move_return< RET_TYPE >(REF)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
|
||||||
|
::boost::move((BASE_TYPE&)(ARG))
|
||||||
|
//
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// BOOST_MOVABLE_BUT_NOT_COPYABLE
|
// BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||||
@@ -369,7 +377,6 @@
|
|||||||
const TYPE & \
|
const TYPE & \
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#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)
|
#if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
@@ -432,6 +439,17 @@
|
|||||||
|
|
||||||
#endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
#endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
|
//!This macro is used to achieve portable optimal move constructors.
|
||||||
|
//!
|
||||||
|
//!When implementing the move constructor, in C++03 compilers the moved-from argument must be
|
||||||
|
//!cast to the base type before calling `::boost::move()` due to rvalue reference limitations.
|
||||||
|
//!
|
||||||
|
//!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
|
||||||
|
//!a base type is implicit.
|
||||||
|
#define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
|
||||||
|
::boost::move((BASE_TYPE&)(ARG))
|
||||||
|
//
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace move_detail {
|
namespace move_detail {
|
||||||
|
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
||||||
#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/detail/workaround.hpp>
|
#include <boost/move/detail/workaround.hpp>
|
||||||
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
|
#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
|
||||||
#define BOOST_MOVE_DETAIL_META_UTILS_HPP
|
#define BOOST_MOVE_DETAIL_META_UTILS_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <cstddef> //for std::size_t
|
#include <cstddef> //for std::size_t
|
||||||
|
|
||||||
|
@@ -12,6 +12,10 @@
|
|||||||
#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
|
#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
|
||||||
#define BOOST_MOVE_MOVE_HELPERS_HPP
|
#define BOOST_MOVE_MOVE_HELPERS_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <boost/move/detail/meta_utils.hpp>
|
#include <boost/move/detail/meta_utils.hpp>
|
||||||
|
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
||||||
#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstddef> //for std::size_t
|
#include <cstddef> //for std::size_t
|
||||||
|
|
||||||
//Small meta-typetraits to support move
|
//Small meta-typetraits to support move
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
||||||
#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
#define BOOST_MOVE_PERFECT_FORWARDING
|
#define BOOST_MOVE_PERFECT_FORWARDING
|
||||||
#endif
|
#endif
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef BOOST_MOVE_ITERATOR_HPP
|
#ifndef BOOST_MOVE_ITERATOR_HPP
|
||||||
#define BOOST_MOVE_ITERATOR_HPP
|
#define BOOST_MOVE_ITERATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <iterator> //std::iterator
|
#include <iterator> //std::iterator
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
||||||
#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/detail/workaround.hpp>
|
#include <boost/move/detail/workaround.hpp>
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
|
@@ -17,6 +17,10 @@
|
|||||||
#ifndef BOOST_MOVE_MOVE_HPP
|
#ifndef BOOST_MOVE_MOVE_HPP
|
||||||
#define BOOST_MOVE_MOVE_HPP
|
#define BOOST_MOVE_MOVE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#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 <boost/move/iterator.hpp>
|
#include <boost/move/iterator.hpp>
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef BOOST_MOVE_MOVE_TRAITS_HPP
|
#ifndef BOOST_MOVE_MOVE_TRAITS_HPP
|
||||||
#define BOOST_MOVE_MOVE_TRAITS_HPP
|
#define BOOST_MOVE_MOVE_TRAITS_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#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_constructible.hpp>
|
||||||
|
@@ -11,11 +11,16 @@
|
|||||||
#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
||||||
#define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
#define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/detail/workaround.hpp>
|
#include <boost/move/detail/workaround.hpp>
|
||||||
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
||||||
#include <boost/move/default_delete.hpp>
|
#include <boost/move/default_delete.hpp>
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
|
#include <boost/move/adl_move_swap.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
@@ -723,9 +728,8 @@ class unique_ptr
|
|||||||
//! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
|
//! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
|
||||||
void swap(unique_ptr& u) BOOST_NOEXCEPT
|
void swap(unique_ptr& u) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
using ::boost::move_detail::swap;
|
::boost::adl_move_swap(m_data.m_p, u.m_data.m_p);
|
||||||
swap(m_data.m_p, u.m_data.m_p);
|
::boost::adl_move_swap(m_data.deleter(), u.m_data.deleter());
|
||||||
swap(m_data.deleter(), u.m_data.deleter());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -16,6 +16,10 @@
|
|||||||
#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
||||||
#define BOOST_MOVE_MOVE_UTILITY_HPP
|
#define BOOST_MOVE_MOVE_UTILITY_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <boost/move/traits.hpp>
|
#include <boost/move/traits.hpp>
|
||||||
|
@@ -17,6 +17,10 @@
|
|||||||
#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||||
#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/move/detail/config_begin.hpp>
|
#include <boost/move/detail/config_begin.hpp>
|
||||||
#include <boost/move/core.hpp>
|
#include <boost/move/core.hpp>
|
||||||
#include <boost/move/detail/meta_utils.hpp>
|
#include <boost/move/detail/meta_utils.hpp>
|
||||||
@@ -273,14 +277,6 @@
|
|||||||
namespace boost{
|
namespace boost{
|
||||||
namespace move_detail{
|
namespace move_detail{
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void swap(T &a, T &b)
|
|
||||||
{
|
|
||||||
T c((::boost::move(a)));
|
|
||||||
a = ::boost::move(b);
|
|
||||||
b = ::boost::move(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename boost::move_detail::add_rvalue_reference<T>::type declval();
|
typename boost::move_detail::add_rvalue_reference<T>::type declval();
|
||||||
|
|
||||||
|
@@ -103,6 +103,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_types_test", "un
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adl_move_swap", "adl_move_swap.vcproj", "{CD2617A8-79EB-6172-2CE4-26617AA3AC93}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@@ -215,8 +219,13 @@ Global
|
|||||||
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Debug.Build.0 = Debug|Win32
|
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Debug.Build.0 = Debug|Win32
|
||||||
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.ActiveCfg = Release|Win32
|
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.ActiveCfg = Release|Win32
|
||||||
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.Build.0 = Release|Win32
|
{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.Build.0 = Release|Win32
|
||||||
|
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.Build.0 = Debug|Win32
|
||||||
|
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.ActiveCfg = Release|Win32
|
||||||
|
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionItems) = postSolution
|
GlobalSection(SolutionItems) = postSolution
|
||||||
|
..\..\..\..\boost\move\adl_move_swap.hpp = ..\..\..\..\boost\move\adl_move_swap.hpp
|
||||||
..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp
|
..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp
|
||||||
..\..\..\..\boost\move\detail\config_begin.hpp = ..\..\..\..\boost\move\detail\config_begin.hpp
|
..\..\..\..\boost\move\detail\config_begin.hpp = ..\..\..\..\boost\move\detail\config_begin.hpp
|
||||||
..\..\..\..\boost\move\detail\config_end.hpp = ..\..\..\..\boost\move\detail\config_end.hpp
|
..\..\..\..\boost\move\detail\config_end.hpp = ..\..\..\..\boost\move\detail\config_end.hpp
|
||||||
|
134
proj/vc7ide/adl_move_swap.vcproj
Normal file
134
proj/vc7ide/adl_move_swap.vcproj
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="adl_move_swap"
|
||||||
|
ProjectGUID="{CD2617A8-79EB-6172-2CE4-26617AA3AC93}"
|
||||||
|
Keyword="Win32Proj">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="../../Bin/Win32/Debug"
|
||||||
|
IntermediateDirectory="Debug/move_adl_move_swap"
|
||||||
|
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)/move_iterator_test_d.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/move_adl_move_swap.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_adl_move_swap"
|
||||||
|
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_adl_move_swap.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="{163D8753-4026-0A65-5C56-2BA532AD7FEF}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\test\adl_move_swap.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
268
test/adl_move_swap.cpp
Normal file
268
test/adl_move_swap.cpp
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (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>
|
||||||
|
#include <boost/move/adl_move_swap.hpp>
|
||||||
|
#include <boost/move/core.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
class swap_stats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void reset_stats()
|
||||||
|
{
|
||||||
|
member_swap_calls = 0;
|
||||||
|
friend_swap_calls = 0;
|
||||||
|
move_cnstor_calls = 0;
|
||||||
|
move_assign_calls = 0;
|
||||||
|
copy_cnstor_calls = 0;
|
||||||
|
copy_assign_calls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int member_swap_calls;
|
||||||
|
static unsigned int friend_swap_calls;
|
||||||
|
static unsigned int move_cnstor_calls;
|
||||||
|
static unsigned int move_assign_calls;
|
||||||
|
static unsigned int copy_cnstor_calls;
|
||||||
|
static unsigned int copy_assign_calls;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int swap_stats::member_swap_calls = 0;
|
||||||
|
unsigned int swap_stats::friend_swap_calls = 0;
|
||||||
|
unsigned int swap_stats::move_cnstor_calls = 0;
|
||||||
|
unsigned int swap_stats::move_assign_calls = 0;
|
||||||
|
unsigned int swap_stats::copy_cnstor_calls = 0;
|
||||||
|
unsigned int swap_stats::copy_assign_calls = 0;
|
||||||
|
|
||||||
|
class movable : public swap_stats
|
||||||
|
{
|
||||||
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
|
||||||
|
public:
|
||||||
|
movable() {}
|
||||||
|
movable(BOOST_RV_REF(movable)) { ++move_cnstor_calls; }
|
||||||
|
movable & operator=(BOOST_RV_REF(movable)){ ++move_assign_calls; return *this; }
|
||||||
|
friend void swap(movable &, movable &) { ++friend_swap_calls; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class movable_swap_member : public swap_stats
|
||||||
|
{
|
||||||
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_swap_member)
|
||||||
|
public:
|
||||||
|
movable_swap_member() {}
|
||||||
|
movable_swap_member(BOOST_RV_REF(movable_swap_member)) { ++move_cnstor_calls; }
|
||||||
|
movable_swap_member & operator=(BOOST_RV_REF(movable_swap_member)){ ++move_assign_calls; return *this; }
|
||||||
|
void swap(movable_swap_member &) { ++member_swap_calls; }
|
||||||
|
friend void swap(movable_swap_member &, movable_swap_member &) { ++friend_swap_calls; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class copyable : public swap_stats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
copyable() {}
|
||||||
|
copyable(const copyable &) { ++copy_cnstor_calls; }
|
||||||
|
copyable & operator=(const copyable&) { ++copy_assign_calls; return *this; }
|
||||||
|
void swap(copyable &) { ++member_swap_calls; }
|
||||||
|
friend void swap(copyable &, copyable &) { ++friend_swap_calls; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class no_swap : public swap_stats
|
||||||
|
{
|
||||||
|
private: unsigned m_state;
|
||||||
|
public:
|
||||||
|
explicit no_swap(unsigned i): m_state(i){}
|
||||||
|
no_swap(const no_swap &x) { m_state = x.m_state; ++copy_cnstor_calls; }
|
||||||
|
no_swap & operator=(const no_swap& x) { m_state = x.m_state; ++copy_assign_calls; return *this; }
|
||||||
|
void swap(no_swap &) { ++member_swap_calls; }
|
||||||
|
friend bool operator==(const no_swap &x, const no_swap &y) { return x.m_state == y.m_state; }
|
||||||
|
friend bool operator!=(const no_swap &x, const no_swap &y) { return !(x==y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{ //movable
|
||||||
|
movable x, y;
|
||||||
|
swap_stats::reset_stats();
|
||||||
|
::boost::adl_move_swap(x, y);
|
||||||
|
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
|
//In non rvalue reference compilers,
|
||||||
|
//movable classes with no swap() member uses
|
||||||
|
//boost::move() to implement swap.
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 2);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 0);
|
||||||
|
#else
|
||||||
|
//In compilers with rvalue references, this should call friend swap via ADL
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{ //movable_swap_member
|
||||||
|
movable_swap_member x, y;
|
||||||
|
swap_stats::reset_stats();
|
||||||
|
::boost::adl_move_swap(x, y);
|
||||||
|
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
|
//In non rvalue reference compilers,
|
||||||
|
//movable classes with no swap() member uses
|
||||||
|
//boost::move() to implement swap.
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 0);
|
||||||
|
#else
|
||||||
|
//In compilers with rvalue references, this should call friend swap via ADL
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{ //copyable
|
||||||
|
copyable x, y;
|
||||||
|
swap_stats::reset_stats();
|
||||||
|
::boost::adl_move_swap(x, y);
|
||||||
|
//This should call friend swap via ADL
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 0);
|
||||||
|
}
|
||||||
|
{ //no_swap
|
||||||
|
no_swap x(1), y(2), x_back(x), y_back(y);
|
||||||
|
swap_stats::reset_stats();
|
||||||
|
::boost::adl_move_swap(x, y);
|
||||||
|
//This should call std::swap which uses copies
|
||||||
|
BOOST_TEST(swap_stats::friend_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::member_swap_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_cnstor_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::move_assign_calls == 0);
|
||||||
|
BOOST_TEST(swap_stats::copy_cnstor_calls == 1);
|
||||||
|
BOOST_TEST(swap_stats::copy_assign_calls == 2);
|
||||||
|
BOOST_TEST(x == y_back);
|
||||||
|
BOOST_TEST(y == x_back);
|
||||||
|
BOOST_TEST(x != y);
|
||||||
|
}
|
||||||
|
return ::boost::report_errors();
|
||||||
|
}
|
||||||
|
#include <boost/move/detail/config_end.hpp>
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
namespace boost_move_member_swap {
|
||||||
|
|
||||||
|
struct dont_care
|
||||||
|
{
|
||||||
|
dont_care(...);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct private_type
|
||||||
|
{
|
||||||
|
static private_type p;
|
||||||
|
private_type const &operator,(int) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef char yes_type;
|
||||||
|
struct no_type{ char dummy[2]; };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
no_type is_private_type(T const &);
|
||||||
|
|
||||||
|
yes_type is_private_type(private_type const &);
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class has_member_function_named_swap
|
||||||
|
{
|
||||||
|
struct BaseMixin
|
||||||
|
{
|
||||||
|
void swap();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base : public Type, public BaseMixin { Base(); };
|
||||||
|
template <typename T, T t> class Helper{};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
|
||||||
|
static yes_type deduce(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun, bool HasFunc>
|
||||||
|
struct has_member_swap_impl
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_swap_impl<Fun, true>
|
||||||
|
{
|
||||||
|
struct FunWrap : Fun
|
||||||
|
{
|
||||||
|
FunWrap();
|
||||||
|
|
||||||
|
using Fun::swap;
|
||||||
|
private_type swap(dont_care) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Fun &declval_fun();
|
||||||
|
static FunWrap declval_wrap();
|
||||||
|
|
||||||
|
static bool const value =
|
||||||
|
sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Fun>
|
||||||
|
struct has_member_swap : public has_member_swap_impl
|
||||||
|
<Fun, has_member_function_named_swap<Fun>::value>
|
||||||
|
{};
|
||||||
|
|
||||||
|
} //namespace boost_move_member_swap
|
||||||
|
|
||||||
|
class noswap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void swap();
|
||||||
|
};
|
||||||
|
|
||||||
|
class noneswap
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class yesswap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void swap(yesswap&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST(!boost_move_member_swap::has_member_swap<noswap>::value);
|
||||||
|
BOOST_TEST(boost_move_member_swap::has_member_swap<yesswap>::value);
|
||||||
|
BOOST_TEST(!boost_move_member_swap::has_member_swap<noneswap>::value);
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
*/
|
@@ -13,6 +13,7 @@
|
|||||||
#include <boost/move/utility_core.hpp>
|
#include <boost/move/utility_core.hpp>
|
||||||
#include <boost/move/unique_ptr.hpp>
|
#include <boost/move/unique_ptr.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/move/adl_move_swap.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
@@ -284,7 +285,7 @@ void test()
|
|||||||
BOOST_TEST(s2.get() == p2);
|
BOOST_TEST(s2.get() == p2);
|
||||||
BOOST_TEST(*s2 == A(2));
|
BOOST_TEST(*s2 == A(2));
|
||||||
BOOST_TEST(s2.get_deleter().state() == 2);
|
BOOST_TEST(s2.get_deleter().state() == 2);
|
||||||
swap(s1, s2);
|
boost::adl_move_swap(s1, s2);
|
||||||
BOOST_TEST(s1.get() == p2);
|
BOOST_TEST(s1.get() == p2);
|
||||||
BOOST_TEST(*s1 == A(2));
|
BOOST_TEST(*s1 == A(2));
|
||||||
BOOST_TEST(s1.get_deleter().state() == 2);
|
BOOST_TEST(s1.get_deleter().state() == 2);
|
||||||
|
Reference in New Issue
Block a user