From 4358c27ef8a0e6786e8c819038c2382c8fc1d2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 21 Jul 2011 17:47:15 +0000 Subject: [PATCH 01/30] Added Move to the release branch [SVN r73281] --- .gitattributes | 96 +++ include/boost/move/move.hpp | 1101 +++++++++++++++++++++++++++ include/boost/move/move_helpers.hpp | 173 +++++ 3 files changed, 1370 insertions(+) create mode 100644 .gitattributes create mode 100644 include/boost/move/move.hpp create mode 100644 include/boost/move/move_helpers.hpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3e84d7c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp new file mode 100644 index 0000000..1d6b3d5 --- /dev/null +++ b/include/boost/move/move.hpp @@ -0,0 +1,1101 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet 2009. +// (C) Copyright Ion Gaztanaga 2009-2010. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_MOVE_HPP +#define BOOST_MOVE_MOVE_HPP + +#include +#include //copy, copy_backward +#include //uninitialized_copy +#include //std::iterator + +#define BOOST_MOVE_AVOID_BOOST_DEPENDENCIES + +#ifndef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif //#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES +/// @cond + +#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES +#define BOOST_MOVE_MPL_NS ::boost::move_detail +#define BOOST_MOVE_BOOST_NS ::boost::move_detail +#else +#define BOOST_MOVE_MPL_NS ::boost::mpl +#define BOOST_MOVE_BOOST_NS ::boost +#endif + +#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES + +namespace boost { +namespace move_detail { + +//if_ +template +struct if_c +{ + typedef T1 type; +}; + +template +struct if_c +{ + typedef T2 type; +}; + +template +struct if_ +{ + typedef typename if_c<0 != T1::value, T2, T3>::type type; +}; + +//enable_if_ +template +struct enable_if_c +{ + typedef T type; +}; + +template +struct enable_if_c {}; + +template +struct enable_if : public enable_if_c {}; + +template +struct disable_if : public enable_if_c {}; + +//integral_constant +template +struct integral_constant +{ + static const T value = v; + typedef T value_type; + typedef integral_constant type; +}; + +//identity +template +struct identity +{ + typedef T type; +}; + +//is_convertible +template +class is_convertible +{ + typedef char true_t; + class false_t { char dummy[2]; }; + static true_t dispatch(U); + static false_t dispatch(...); + static T trigger(); + public: + enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; +}; + +//and_ not_ +template > + struct and_ + : public integral_constant +{}; + +template + struct not_ + : public integral_constant +{}; + +//is_lvalue_reference +template +struct is_lvalue_reference + : public integral_constant +{}; + +template +struct is_lvalue_reference + : public integral_constant +{}; + +//has_trivial_destructor +template +struct has_trivial_destructor + : public integral_constant +{}; + +//addressof +template struct addr_impl_ref +{ + T & v_; + inline addr_impl_ref( T & v ): v_( v ) {} + inline operator T& () const { return v_; } + + private: + addr_impl_ref & operator=(const addr_impl_ref &); +}; + +template struct addressof_impl +{ + static inline T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + static inline T * f( T * v, int ) + { return v; } +}; + +template T * addressof( T & v ) +{ + return ::boost::move_detail::addressof_impl::f + ( ::boost::move_detail::addr_impl_ref( v ), 0 ); +} + +/* +typedef char one; +struct two {one _[2];}; + +template +struct is_base_of_host +{ + operator B*() const; + operator D*(); +}; + +template +struct is_base_of +{ + typedef char yes; + class no { char dummy[2]; }; + + template + static yes check(D*, T); + static no check(B*, int); + + static const bool value = sizeof(check(is_base_of_host(), int())) == sizeof(yes); +}; +*/ + +} //namespace move_detail { +} //namespace boost { + +#endif //BOOST_MOVE_AVOID_BOOST_DEPENDENCIES + +/// @endcond + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) + +#ifndef BOOST_CLANG +#define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES +#endif + +#else + +#if defined(_MSC_VER) && (_MSC_VER == 1600) +#define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG +#endif + +#endif + +#endif + + +#if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) + +#ifdef __GNUC__ +# define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) +#else +# define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS +#endif + +namespace boost { + +////////////////////////////////////////////////////////////////////////////// +// +// struct rv +// +////////////////////////////////////////////////////////////////////////////// +template +class rv : public T +{ + rv(); + ~rv(); + rv(rv const&); + void operator=(rv const&); +} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS; + +////////////////////////////////////////////////////////////////////////////// +// +// move_detail::is_rv +// +////////////////////////////////////////////////////////////////////////////// + +namespace move_detail { + +template +struct is_rv + : BOOST_MOVE_BOOST_NS::integral_constant +{}; + +template +struct is_rv< rv > + : BOOST_MOVE_BOOST_NS::integral_constant +{}; + +template +struct is_rv< const rv > + : BOOST_MOVE_BOOST_NS::integral_constant +{}; + +} //namespace move_detail { + +////////////////////////////////////////////////////////////////////////////// +// +// has_move_emulation_enabled +// +////////////////////////////////////////////////////////////////////////////// +template +struct has_move_emulation_enabled + : BOOST_MOVE_BOOST_NS::is_convertible< T, ::boost::rv& > +{}; + +template +struct has_move_emulation_enabled + : BOOST_MOVE_BOOST_NS::integral_constant +{}; + +template +struct has_move_emulation_enabled< ::boost::rv > + : BOOST_MOVE_BOOST_NS::integral_constant +{}; + +template +struct has_nothrow_move + : public BOOST_MOVE_BOOST_NS::integral_constant +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// move() +// +////////////////////////////////////////////////////////////////////////////// +template +typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) +{ + return x; +} + +template +typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(T& x) +{ + return *static_cast* >(BOOST_MOVE_BOOST_NS::addressof(x)); +} + +template +typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(rv& x) +{ + return x; +} + +#define BOOST_RV_REF(TYPE)\ + ::boost::rv< TYPE >& \ +// + +#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + ::boost::rv< TYPE >& \ +// + +#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + ::boost::rv< TYPE >& \ +// + + +#define BOOST_FWD_REF(TYPE)\ + const TYPE & \ +// + +#define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const ::boost::rv< TYPE >& \ +// + +#define BOOST_COPY_ASSIGN_REF(TYPE)\ + const ::boost::rv< TYPE >& \ +// + +#define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const ::boost::rv< TYPE >& \ +// + +#define BOOST_MOVE_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + const ::boost::rv< TYPE >& \ +// + +////////////////////////////////////////////////////////////////////////////// +// +// forward() +// +////////////////////////////////////////////////////////////////////////////// + +template +typename BOOST_MOVE_BOOST_NS::enable_if< ::boost::move_detail::is_rv, T &>::type + forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) +{ + return const_cast(x); +} + +template +typename BOOST_MOVE_BOOST_NS::disable_if< ::boost::move_detail::is_rv, const T &>::type + forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) +{ + return x; +} + +////////////////////////////////////////////////////////////////////////////// +// +// BOOST_MOVABLE_BUT_NOT_COPYABLE +// +////////////////////////////////////////////////////////////////////////////// +#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + private:\ + TYPE(TYPE &);\ + TYPE& operator=(TYPE &);\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ +// + +////////////////////////////////////////////////////////////////////////////// +// +// BOOST_COPYABLE_AND_MOVABLE +// +////////////////////////////////////////////////////////////////////////////// + +#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + public:\ + TYPE& operator=(TYPE &t)\ + { this->operator=(static_cast &>(const_cast(t))); return *this;}\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ +// + +#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ +// + +} //namespace boost + +#else //BOOST_NO_RVALUE_REFERENCES + +#include + +namespace boost { + +//! By default this traits returns false. Classes with non-thworing move construction +//! and assignment should specialize this trait to obtain some performance improvements. +template +struct has_nothrow_move + : public BOOST_MOVE_MPL_NS::integral_constant +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// move +// +////////////////////////////////////////////////////////////////////////////// + + +#if defined(BOOST_MOVE_DOXYGEN_INVOKED) +//! This function provides a way to convert a reference into a rvalue reference +//! in compilers with rvalue references. For other compilers converts T & into +//! ::boost::rv & so that move emulation is activated. +template inline +rvalue_reference move (input_reference); + +#else //BOOST_MOVE_DOXYGEN_INVOKED + +#if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + +//Old move approach, lvalues could bind to rvalue references +template inline +typename remove_reference::type && move(T&& t) +{ return t; } + +#else //Old move + +template inline +typename remove_reference::type && move(T&& t) +{ return static_cast::type &&>(t); } + +#endif //Old move + +#endif //BOOST_MOVE_DOXYGEN_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// forward +// +////////////////////////////////////////////////////////////////////////////// + + +#if defined(BOOST_MOVE_DOXYGEN_INVOKED) +//! This function provides limited form of forwarding that is usually enough for +//! in-place construction and avoids the exponential overloading necessary for +//! perfect forwarding in C++03. +//! +//! For compilers with rvalue references this function provides perfect forwarding. +//! +//! Otherwise: +//! * If input_reference binds to const ::boost::rv & then it output_reference is +//! ::boost::rev & +//! +//! * Else, input_reference is equal to output_reference is equal to input_reference. +template inline output_reference forward(input_reference); + +#else + +#if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + +//Old move approach, lvalues could bind to rvalue references + +template inline +T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) +{ return t; } + +#else //Old move + +//Implementation #5 from N2951, thanks to Howard Hinnant + +template +inline T&& forward(U&& t + , typename BOOST_MOVE_BOOST_NS::enable_if_c< + move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* + , typename BOOST_MOVE_BOOST_NS::enable_if_c< + move_detail::is_convertible + ::type*, typename remove_reference::type*>::value>::type * = 0*/) +{ return static_cast(t); } + +#endif //Old move + +#endif //BOOST_MOVE_DOXYGEN_INVOKED + +////////////////////////////////////////////////////////////////////////////// +// +// BOOST_ENABLE_MOVE_EMULATION +// +////////////////////////////////////////////////////////////////////////////// + +///@cond + +#define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ + typedef int boost_move_emulation_t; +\ +// + +/// @endcond + +//! This macro marks a type as movable but not copyable, disabling copy construction +//! and assignment. The user will need to write a move constructor/assignment as explained +//! in the documentation to fully write a movable but not copyable class. +#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + public:\ + typedef int boost_move_emulation_t;\ + private:\ + TYPE(const TYPE &);\ + TYPE& operator=(const TYPE &);\ +// + +//! This macro marks a type as copyable and movable. +//! The user will need to write a move constructor/assignment and a copy assignment +//! as explained in the documentation to fully write a copyable and movable class. +#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ +// + +/// @cond + +#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + TYPE && \ +// + +#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE && \ +// + +/// @endcond + +//!This macro is used to achieve portable syntax in move +//!constructors and assignments for classes marked as +//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE +#define BOOST_RV_REF(TYPE)\ + TYPE && \ +// + +//!This macro is used to achieve portable syntax in copy +//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. +#define BOOST_COPY_ASSIGN_REF(TYPE)\ + const TYPE & \ +// + +/// @cond + +#define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const TYPE & \ +// + +#define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE& \ +// + +/// @endcond + +//! This macro is used to implement portable perfect forwarding +//! as explained in the documentation. +#define BOOST_FWD_REF(TYPE)\ + TYPE && \ +// + +/// @cond + +#define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const TYPE & \ +// + +/// @endcond + +} //namespace boost { + +#endif //BOOST_NO_RVALUE_REFERENCES + +namespace boost { + +////////////////////////////////////////////////////////////////////////////// +// +// move_iterator +// +////////////////////////////////////////////////////////////////////////////// + +//! Class template move_iterator is an iterator adaptor with the same behavior +//! as the underlying iterator except that its dereference operator implicitly +//! converts the value returned by the underlying iterator's dereference operator +//! to an rvalue reference. Some generic algorithms can be called with move +//! iterators to replace copying with moving. +template +class move_iterator +{ + public: + typedef It iterator_type; + typedef typename std::iterator_traits::value_type value_type; + #if !defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + typedef value_type && reference; + #else + typedef typename BOOST_MOVE_MPL_NS::if_ + < ::boost::has_move_emulation_enabled + , ::boost::rv& + , value_type & >::type reference; + #endif + typedef It pointer; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + + move_iterator() + {} + + explicit move_iterator(It i) + : m_it(i) + {} + + template + move_iterator(const move_iterator& u) + : m_it(u.base()) + {} + + iterator_type base() const + { return m_it; } + + reference operator*() const + { + #if defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + return *m_it; + #else + return ::boost::move(*m_it); + #endif + } + + pointer operator->() const + { return m_it; } + + move_iterator& operator++() + { ++m_it; return *this; } + + move_iterator operator++(int) + { move_iterator tmp(*this); ++(*this); return tmp; } + + move_iterator& operator--() + { --m_it; return *this; } + + move_iterator operator--(int) + { move_iterator tmp(*this); --(*this); return tmp; } + + move_iterator operator+ (difference_type n) const + { return move_iterator(m_it + n); } + + move_iterator& operator+=(difference_type n) + { m_it += n; return *this; } + + move_iterator operator- (difference_type n) const + { return move_iterator(m_it - n); } + + move_iterator& operator-=(difference_type n) + { m_it -= n; return *this; } + + reference operator[](difference_type n) const + { + #if defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + return m_it[n]; + #else + return ::boost::move(m_it[n]); + #endif + } + + friend bool operator==(const move_iterator& x, const move_iterator& y) + { return x.base() == y.base(); } + + friend bool operator!=(const move_iterator& x, const move_iterator& y) + { return x.base() != y.base(); } + + friend bool operator< (const move_iterator& x, const move_iterator& y) + { return x.base() < y.base(); } + + friend bool operator<=(const move_iterator& x, const move_iterator& y) + { return x.base() <= y.base(); } + + friend bool operator> (const move_iterator& x, const move_iterator& y) + { return x.base() > y.base(); } + + friend bool operator>=(const move_iterator& x, const move_iterator& y) + { return x.base() >= y.base(); } + + friend difference_type operator-(const move_iterator& x, const move_iterator& y) + { return x.base() - y.base(); } + + friend move_iterator operator+(difference_type n, const move_iterator& x) + { return move_iterator(x.base() + n); } + + private: + It m_it; +}; + + +//is_move_iterator +namespace move_detail { + +template +struct is_move_iterator + : public BOOST_MOVE_MPL_NS::integral_constant +{ +}; + +template +struct is_move_iterator< ::boost::move_iterator > + : public BOOST_MOVE_MPL_NS::integral_constant +{ +}; + +} //namespace move_detail { + +////////////////////////////////////////////////////////////////////////////// +// +// move_iterator +// +////////////////////////////////////////////////////////////////////////////// + +//! +//! Returns: move_iterator(i). +template +move_iterator make_move_iterator(const It &it) +{ return move_iterator(it); } + +////////////////////////////////////////////////////////////////////////////// +// +// back_move_insert_iterator +// +////////////////////////////////////////////////////////////////////////////// + + +//! A move insert iterator that move constructs elements at the +//! back of a container +template // C models Container +class back_move_insert_iterator + : public std::iterator +{ + C* container_m; + + public: + typedef C container_type; + + explicit back_move_insert_iterator(C& x) : container_m(&x) { } + + back_move_insert_iterator& operator=(typename C::reference x) + { container_m->push_back(boost::move(x)); return *this; } + + back_move_insert_iterator& operator*() { return *this; } + back_move_insert_iterator& operator++() { return *this; } + back_move_insert_iterator& operator++(int) { return *this; } +}; + +//! +//! Returns: back_move_insert_iterator(x). +template // C models Container +inline back_move_insert_iterator back_move_inserter(C& x) +{ + return back_move_insert_iterator(x); +} + +////////////////////////////////////////////////////////////////////////////// +// +// front_move_insert_iterator +// +////////////////////////////////////////////////////////////////////////////// + +//! A move insert iterator that move constructs elements int the +//! front of a container +template // C models Container +class front_move_insert_iterator + : public std::iterator +{ + C* container_m; + +public: + typedef C container_type; + + explicit front_move_insert_iterator(C& x) : container_m(&x) { } + + front_move_insert_iterator& operator=(typename C::reference x) + { container_m->push_front(boost::move(x)); return *this; } + + front_move_insert_iterator& operator*() { return *this; } + front_move_insert_iterator& operator++() { return *this; } + front_move_insert_iterator& operator++(int) { return *this; } +}; + +//! +//! Returns: front_move_insert_iterator(x). +template // C models Container +inline front_move_insert_iterator front_move_inserter(C& x) +{ + return front_move_insert_iterator(x); +} + +////////////////////////////////////////////////////////////////////////////// +// +// insert_move_iterator +// +////////////////////////////////////////////////////////////////////////////// +template // C models Container +class move_insert_iterator + : public std::iterator +{ + C* container_m; + typename C::iterator pos_; + + public: + typedef C container_type; + + explicit move_insert_iterator(C& x, typename C::iterator pos) + : container_m(&x), pos_(pos) + {} + + move_insert_iterator& operator=(typename C::reference x) + { + pos_ = container_m->insert(pos_, ::boost::move(x)); + ++pos_; + return *this; + } + + move_insert_iterator& operator*() { return *this; } + move_insert_iterator& operator++() { return *this; } + move_insert_iterator& operator++(int) { return *this; } +}; + +//! +//! Returns: move_insert_iterator(x, it). +template // C models Container +inline move_insert_iterator move_inserter(C& x, typename C::iterator it) +{ + return move_insert_iterator(x, it); +} + +////////////////////////////////////////////////////////////////////////////// +// +// move +// +////////////////////////////////////////////////////////////////////////////// + + +//! Effects: Moves elements in the range [first,last) into the range [result,result + (last - +//! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first), +//! performs *(result + n) = ::boost::move (*(first + n)). +//! +//! Effects: result + (last - first). +//! +//! Requires: result shall not be in the range [first,last). +//! +//! Complexity: Exactly last - first move assignments. +template // O models OutputIterator +O move(I f, I l, O result) +{ + while (f != l) { + *result = ::boost::move(*f); + ++f; ++result; + } + return result; +} + +////////////////////////////////////////////////////////////////////////////// +// +// move_backward +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: Moves elements in the range [first,last) into the range +//! [result - (last-first),result) starting from last - 1 and proceeding to +//! first. For each positive integer n <= (last - first), +//! performs *(result - n) = ::boost::move(*(last - n)). +//! +//! Requires: result shall not be in the range [first,last). +//! +//! Returns: result - (last - first). +//! +//! Complexity: Exactly last - first assignments. +template // O models BidirectionalIterator +O move_backward(I f, I l, O result) +{ + while (f != l) { + --l; --result; + *result = ::boost::move(*l); + } + return result; +} + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! new (static_cast(&*result)) +//! typename iterator_traits::value_type(boost::move(*first)); +//! \endcode +//! +//! Returns: result +template + // F models ForwardIterator +F uninitialized_move(I f, I l, F r + /// @cond +// ,typename BOOST_MOVE_BOOST_NS::enable_if::value_type> >::type* = 0 + /// @endcond + ) +{ + typedef typename std::iterator_traits::value_type input_value_type; + while (f != l) { + ::new(static_cast(&*r)) input_value_type(boost::move(*f)); + ++f; ++r; + } + return r; +} + +/// @cond +/* +template + // F models ForwardIterator +F uninitialized_move(I f, I l, F r, + typename BOOST_MOVE_BOOST_NS::disable_if::value_type> >::type* = 0) +{ + return std::uninitialized_copy(f, l, r); +} +*/ +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_or_move +// +////////////////////////////////////////////////////////////////////////////// + +namespace move_detail { + +template + // F models ForwardIterator +F uninitialized_move_move_iterator(I f, I l, F r +// ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 +) +{ + return ::boost::uninitialized_move(f, l, r); +} +/* +template + // F models ForwardIterator +F uninitialized_move_move_iterator(I f, I l, F r, + typename BOOST_MOVE_BOOST_NS::disable_if< has_move_emulation_enabled >::type* = 0) +{ + return std::uninitialized_copy(f.base(), l.base(), r); +} +*/ +} //namespace move_detail { + +template + // F models ForwardIterator +F uninitialized_copy_or_move(I f, I l, F r, + typename BOOST_MOVE_BOOST_NS::enable_if< move_detail::is_move_iterator >::type* = 0) +{ + return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r); +} + +////////////////////////////////////////////////////////////////////////////// +// +// copy_or_move +// +////////////////////////////////////////////////////////////////////////////// + +namespace move_detail { + +template + // F models ForwardIterator +F move_move_iterator(I f, I l, F r +// ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 +) +{ + return ::boost::move(f, l, r); +} +/* +template + // F models ForwardIterator +F move_move_iterator(I f, I l, F r, + typename BOOST_MOVE_BOOST_NS::disable_if< has_move_emulation_enabled >::type* = 0) +{ + return std::copy(f.base(), l.base(), r); +} +*/ + +} //namespace move_detail { + +template + // F models ForwardIterator +F copy_or_move(I f, I l, F r, + typename BOOST_MOVE_BOOST_NS::enable_if< move_detail::is_move_iterator >::type* = 0) +{ + return ::boost::move_detail::move_move_iterator(f, l, r); +} + +/// @endcond + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! new (static_cast(&*result)) +//! typename iterator_traits::value_type(*first); +//! \endcode +//! +//! Returns: result +//! +//! Note: This function is provided because +//! std::uninitialized_copy from some STL implementations +//! is not compatible with move_iterator +template + // F models ForwardIterator +F uninitialized_copy_or_move(I f, I l, F r + /// @cond + ,typename BOOST_MOVE_BOOST_NS::disable_if< move_detail::is_move_iterator >::type* = 0 + /// @endcond + ) +{ + return std::uninitialized_copy(f, l, r); +} + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! *result = *first; +//! \endcode +//! +//! Returns: result +//! +//! Note: This function is provided because +//! std::uninitialized_copy from some STL implementations +//! is not compatible with move_iterator +template + // F models ForwardIterator +F copy_or_move(I f, I l, F r + /// @cond + ,typename BOOST_MOVE_BOOST_NS::disable_if< move_detail::is_move_iterator >::type* = 0 + /// @endcond + ) +{ + return std::copy(f, l, r); +} + +//! If this trait yields to true +//! (has_trivial_destructor_after_move <T>::value == true) +//! means that if T is used as argument of a move construction/assignment, +//! there is no need to call T's destructor. +//! This optimization tipically is used to improve containers' performance. +//! +//! By default this trait is true if the type has trivial destructor, +//! every class should specialize this trait if it wants to improve performance +//! when inserted in containers. +template +struct has_trivial_destructor_after_move + : BOOST_MOVE_BOOST_NS::has_trivial_destructor +{}; + +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_MOVE_HPP diff --git a/include/boost/move/move_helpers.hpp b/include/boost/move/move_helpers.hpp new file mode 100644 index 0000000..92e052e --- /dev/null +++ b/include/boost/move/move_helpers.hpp @@ -0,0 +1,173 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2010-2011. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_MOVE_HELPERS_HPP +#define BOOST_MOVE_MOVE_HELPERS_HPP + +#include +#include + +#if defined(BOOST_NO_RVALUE_REFERENCES) || (defined(_MSC_VER) && (_MSC_VER == 1600)) +#include +#include +#endif +#if defined(BOOST_NO_RVALUE_REFERENCES) +#include +#endif + + +#if defined(BOOST_NO_RVALUE_REFERENCES) +struct not_a_type; +#define BOOST_MOVE_CATCH_CONST(U) \ + typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type +#define BOOST_MOVE_CATCH_RVALUE(U)\ + typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(T), not_a_type>::type +#define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U) +#else +#define BOOST_MOVE_CATCH_CONST(U) const U & +#define BOOST_MOVE_CATCH_RVALUE(U) U && +#define BOOST_MOVE_CATCH_FWD(U) U && +#endif + +#ifdef BOOST_NO_RVALUE_REFERENCES + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(TYPE &x)\ + { return FWD_FUNCTION(const_cast(x)); }\ +\ + template\ + typename ::boost::enable_if_c\ + < ::boost::is_class::value &&\ + ::boost::is_same::value &&\ + !::boost::has_move_emulation_enabled::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + { return FWD_FUNCTION(u); }\ +\ + template\ + typename ::boost::enable_if_c\ + < ::boost::is_class::value &&\ + !::boost::is_same::value &&\ + !::boost::move_detail::is_rv::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t(u);\ + return FWD_FUNCTION(::boost::move(t));\ + }\ +// + +#elif (defined(_MSC_VER) && (_MSC_VER == 1600)) + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ +\ + template\ + typename ::boost::enable_if_c\ + < !::boost::is_same::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t(u);\ + return FWD_FUNCTION(::boost::move(t));\ + }\ +// + +#else + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ +// + +#endif + + +#ifdef BOOST_NO_RVALUE_REFERENCES + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\ + { return FWD_FUNCTION(arg1, const_cast(x)); }\ +\ + template\ + typename ::boost::enable_if_c\ + < ::boost::is_class::value &&\ + ::boost::is_same::value &&\ + !::boost::has_move_emulation_enabled::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + { return FWD_FUNCTION(arg1, u); }\ +\ + template\ + typename ::boost::enable_if_c\ + < ::boost::is_class::value &&\ + !::boost::is_same::value &&\ + !::boost::move_detail::is_rv::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t(u);\ + return FWD_FUNCTION(arg1, ::boost::move(t));\ + }\ +// + +#elif (defined(_MSC_VER) && (_MSC_VER == 1600)) + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ +\ + template\ + typename ::boost::enable_if_c\ + < !::boost::is_same::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t(u);\ + return FWD_FUNCTION(arg1, ::boost::move(t));\ + }\ +// + +#else + +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ +\ + RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ +// + +#endif + +#endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP From e363c0a73fe96d7873511ec284893cc16661c6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 21 Jul 2011 17:47:17 +0000 Subject: [PATCH 02/30] Added Move to the release branch [SVN r73282] --- doc/Jamfile.v2 | 38 + doc/html/boostbook.css | 538 ++++++++++++++ doc/html/images/blank.png | Bin 0 -> 392 bytes doc/html/images/caution.png | Bin 0 -> 1253 bytes doc/html/images/draft.png | Bin 0 -> 17539 bytes doc/html/images/home.png | Bin 0 -> 361 bytes doc/html/images/important.png | Bin 0 -> 726 bytes doc/html/images/next.png | Bin 0 -> 342 bytes doc/html/images/note.png | Bin 0 -> 495 bytes doc/html/images/prev.png | Bin 0 -> 338 bytes doc/html/images/tip.png | Bin 0 -> 456 bytes doc/html/images/toc-blank.png | Bin 0 -> 321 bytes doc/html/images/toc-minus.png | Bin 0 -> 262 bytes doc/html/images/toc-plus.png | Bin 0 -> 267 bytes doc/html/images/up.png | Bin 0 -> 370 bytes doc/html/images/warning.png | Bin 0 -> 1244 bytes doc/html/reference.css | 13 + doc/move.qbk | 789 +++++++++++++++++++++ example/Jamfile.v2 | 28 + example/copymovable.hpp | 46 ++ example/doc_clone_ptr.cpp | 152 ++++ example/doc_construct_forward.cpp | 105 +++ example/doc_file_descriptor.cpp | 87 +++ example/doc_how_works.cpp | 60 ++ example/doc_move_algorithms.cpp | 41 ++ example/doc_move_inserter.cpp | 48 ++ example/doc_move_iterator.cpp | 39 + example/movable.hpp | 49 ++ proj/vc7ide/Move.sln | 140 ++++ proj/vc7ide/back_move_inserter_test.vcproj | 134 ++++ proj/vc7ide/construct_forward_test.vcproj | 134 ++++ proj/vc7ide/conversion_test.vcproj | 134 ++++ proj/vc7ide/copy_elision_test.vcproj | 134 ++++ proj/vc7ide/copy_move_optimization.vcproj | 134 ++++ proj/vc7ide/doc_clone_ptr.vcproj | 139 ++++ proj/vc7ide/doc_construct_forward.vcproj | 139 ++++ proj/vc7ide/doc_file_descriptor.vcproj | 139 ++++ proj/vc7ide/doc_how_works.vcproj | 139 ++++ proj/vc7ide/doc_move_algorithms.vcproj | 139 ++++ proj/vc7ide/doc_move_inserter.vcproj | 139 ++++ proj/vc7ide/doc_move_iterator.vcproj | 139 ++++ proj/vc7ide/move_algorithm.vcproj | 134 ++++ proj/vc7ide/move_iterator_test.vcproj | 134 ++++ proj/vc7ide/move_test.vcproj | 139 ++++ test/Jamfile.v2 | 28 + test/back_move_inserter.cpp | 61 ++ test/construct_forward.cpp | 115 +++ test/conversion_test.cpp | 677 ++++++++++++++++++ test/copy_elision_test.cpp | 170 +++++ test/copy_move_optimization.cpp | 105 +++ test/move.cpp | 114 +++ test/move_algorithm.cpp | 55 ++ test/move_iterator.cpp | 104 +++ 53 files changed, 5652 insertions(+) create mode 100644 doc/Jamfile.v2 create mode 100644 doc/html/boostbook.css create mode 100644 doc/html/images/blank.png create mode 100644 doc/html/images/caution.png create mode 100644 doc/html/images/draft.png create mode 100644 doc/html/images/home.png create mode 100644 doc/html/images/important.png create mode 100644 doc/html/images/next.png create mode 100644 doc/html/images/note.png create mode 100644 doc/html/images/prev.png create mode 100644 doc/html/images/tip.png create mode 100644 doc/html/images/toc-blank.png create mode 100644 doc/html/images/toc-minus.png create mode 100644 doc/html/images/toc-plus.png create mode 100644 doc/html/images/up.png create mode 100644 doc/html/images/warning.png create mode 100644 doc/html/reference.css create mode 100644 doc/move.qbk create mode 100644 example/Jamfile.v2 create mode 100644 example/copymovable.hpp create mode 100644 example/doc_clone_ptr.cpp create mode 100644 example/doc_construct_forward.cpp create mode 100644 example/doc_file_descriptor.cpp create mode 100644 example/doc_how_works.cpp create mode 100644 example/doc_move_algorithms.cpp create mode 100644 example/doc_move_inserter.cpp create mode 100644 example/doc_move_iterator.cpp create mode 100644 example/movable.hpp create mode 100644 proj/vc7ide/Move.sln create mode 100644 proj/vc7ide/back_move_inserter_test.vcproj create mode 100644 proj/vc7ide/construct_forward_test.vcproj create mode 100644 proj/vc7ide/conversion_test.vcproj create mode 100644 proj/vc7ide/copy_elision_test.vcproj create mode 100644 proj/vc7ide/copy_move_optimization.vcproj create mode 100644 proj/vc7ide/doc_clone_ptr.vcproj create mode 100644 proj/vc7ide/doc_construct_forward.vcproj create mode 100644 proj/vc7ide/doc_file_descriptor.vcproj create mode 100644 proj/vc7ide/doc_how_works.vcproj create mode 100644 proj/vc7ide/doc_move_algorithms.vcproj create mode 100644 proj/vc7ide/doc_move_inserter.vcproj create mode 100644 proj/vc7ide/doc_move_iterator.vcproj create mode 100644 proj/vc7ide/move_algorithm.vcproj create mode 100644 proj/vc7ide/move_iterator_test.vcproj create mode 100644 proj/vc7ide/move_test.vcproj create mode 100644 test/Jamfile.v2 create mode 100644 test/back_move_inserter.cpp create mode 100644 test/construct_forward.cpp create mode 100644 test/conversion_test.cpp create mode 100644 test/copy_elision_test.cpp create mode 100644 test/copy_move_optimization.cpp create mode 100644 test/move.cpp create mode 100644 test/move_algorithm.cpp create mode 100644 test/move_iterator.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 0000000..f970d61 --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,38 @@ +# Boost.Move library documentation Jamfile +# +# Copyright Ion Gaztanaga 2009. +# 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. + + +import doxygen ; +import quickbook ; + +doxygen autodoc + : + [ glob ../../../boost/move/*.hpp ] + : + HIDE_UNDOC_MEMBERS=YES + HIDE_UNDOC_MEMBERS=YES + HIDE_UNDOC_CLASSES=YES + EXTRACT_PRIVATE=NO + ENABLE_PREPROCESSING=YES + MACRO_EXPANSION=YES + "PREDEFINED=\"BOOST_MOVE_DOXYGEN_INVOKED\"" + ; + +xml move : move.qbk ; + +boostbook standalone + : + move + : + boost.root=../../../.. + boost.libraries=../../../../libs/libraries.htm + generate.section.toc.level=3 + chunk.first.sections=1 + autodoc + ; diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css new file mode 100644 index 0000000..e816cce --- /dev/null +++ b/doc/html/boostbook.css @@ -0,0 +1,538 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 10pt; + } + + pre.synopsis + { + font-size: 10pt; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 10pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 10pt; + line-height: 1.15; + } + + .toc-main + { + width: 600; + text-align: center; + margin: 1pc 1pc 1pc 10%; + padding: 2pc 1pc 3pc 1pc; + line-height: 0.1; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 120%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + font-size: 10pt; + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + p.blurb img + { + padding: 1pt; + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p + { + margin: 0em 0em 0.5em 0em; + } + + /* Make the terms in definition lists bold */ + div.variablelist dl dt + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist dl dd + { + margin: 1em 0em 1em 2em; + font-size: 10pt; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + font-size: 8pt; + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #0C7445; + } + + a:visited + { + color: #663974; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #E8FBE9; } + .dk_grey_bkd { background-color: #A0DAAC; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + p.blurb + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #E3F9E4; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .informaltable table, + .table table + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + border-collapse: collapse; + background-color: #FAFFFB; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } diff --git a/doc/html/images/blank.png b/doc/html/images/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..c387d424b21d641808bf44ca19f001bb7fde5d78 GIT binary patch literal 392 zcmeAS@N?(o;*#QGU|`_o^7L>CVqjos0AUU$1_lP7m~V3!7#LX69eo`c7&i8E|4C$J zU|`hsba4!+nDh3cqacF<&jEu2`=9%|$(e9fUAHz?KX;jNe>TH4hBb^4%p2Gec)1Qp hHJCDtioilcEFq2gFB6|f8Uq6ZgQu&X%Q~loCIIhfY*qjO literal 0 HcmV?d00001 diff --git a/doc/html/images/caution.png b/doc/html/images/caution.png new file mode 100644 index 0000000000000000000000000000000000000000..b056bccddb7f56b998b401bde72c561f64e65b4b GIT binary patch literal 1253 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 QFfcH9y85}Sb4q9e08q9V)&Kwi literal 0 HcmV?d00001 diff --git a/doc/html/images/home.png b/doc/html/images/home.png new file mode 100644 index 0000000000000000000000000000000000000000..04cc7bd01324e7cb6b16e2d4364908f61afdccc7 GIT binary patch literal 361 zcmeAS@N?(o<&xs%Vqjq4_4IHFVqjnp24NOv1_p+PI_>`q3=GW0PM#qg92~bF`afV` zU{DG032_w{5$x{laCWdedgO3IT#TBs!pxa7FJHd2ZR?gmf8VsUwEzGAFZ#1Vnt_3V zrzFTP_&)+L2;Dz-j)8%Jv%n*=n1O*?2!t6g-L3n>z`&qd;u=vBoS#-wo>-L1;G39S zl%JcLl9{OBmRXcqo?nz*tl%4=U}Rum(q6XaJOcxR7)XP2QEFmIW`3SRNM>#-gQ0=G zfw8`U$?^3)oD2*Md7dtgAr*6yZ}76HUUf)fW}a|EPJk~tFDYSdn~|u5#398qzC1h% zi2}kJ971eHj!g=Q3c@-ZBKHn32(s{Ui5vJd7)dfoNQoD4>LrNGF)(aQ+|KwpkNMqQ wrc2Tv3>$Y{n3;2o(?IP=gurHoV=N4vB6d^t3vVeiFfcH9y85}Sb4q9e02p6(&Hw-a literal 0 HcmV?d00001 diff --git a/doc/html/images/important.png b/doc/html/images/important.png new file mode 100644 index 0000000000000000000000000000000000000000..e257957c007b0348b700371d1897b51e6312435b GIT binary patch literal 726 zcmeAS@N?(o<&xs%Vqjq4_4IHFVqjp90AUVh1_p-fE6<){U|@I>;1l91z`!6NARr+j zp{c29X=&-?WEd5tnVc-)(<9N-W4U)P$J(`u zYu8%NnG@C1Q$1%+@|-!ebH&%LC11Oi{rC%?9YkQV1ow9W4oV|Nn_U@gtbm`KyYnQHFyLRi=t$X+G zJ$CHaxpU{PUAuPg-o59~pTB?q{`>du|NsAAd+G2!1_lPkByV>Y=kyD_Nem2(;+`&! zAr-fBCvgWKGT=FG?E2Ag>cRt8PI})72oaewwbM;~?$+P`?jK**ANc;;{@1aS;^i}i zPIzy0TFS1r%dJU6?5Wv<`yY!W#D0B9-o@C%qCfHCmev?%zk7!>7H^oXrSQn8;PFn| zR;!gPU%cLaXDFL0%4W~BVd}pB91F~@yszQqauBZl&Xn*!?zUaC%=)dxyj%hMua-GA zER| zDNig)WpL0?*7VFxOi%SqOwUZtRxr^s(z8&owA44S&^IttNG{4OE~#|Ltt>9dOx8;+ z)=McZ$j>X$OU}=oxJz*d0|SE=*tpE}yu^~yqEv=tCVqjnp24NOv1_p+PI_>`q3=GW0PM#qg92~bF`afV` zU{DG032_w{5$x{lFg7;cwslLOzpt9I!iwcfA3b__`SPWNxEN;#yZ`_H>j~K>GB7ak zlmz(&|3?4@q5J2~F)%Q27I;J!Gca%qfiUBxyLEpU7#LJbTq8;n};e2?i~kV)qVAc*MlQ~iPEwq7*nr2ic3*3&H#ax4GdJ&l(GnKNKxaqiKu6hw+Ub)`a+jX$dHg)z z`@Y^|p819UrY0+}Ec)|>*Jbq;TctgWznJ(o74x&oD|8%JZF(ZllCtOc9FGNG4ChPD zez56(C7@zJhD-x|Vg%h-{YDN|SB1O_Vf$_<@oU1aJO11r zr(c-djm_tt_x5VlnRCm}Kbx8UT`q3=GW0PM#qg92~bF`afV` zU{DG032_w{5ll-UX-Pz&nV3!aV^Z)<QK$!8;-MT*v3=FCzt`Q}{`DrEPiAAXlzKO|2 z`MIennTZN+nMJAP`9;~q3ce8vMg|5Z?PY7uGcYiSfiyT5r6!hS=I1GdWag$a7#ips z80#CD9ADqV$-ux6=IP=XQZXm_1}{sTLJ~9cgd2wpq>q&(JZLf6ZeXy%aV8%R&r1O{ zj}20XT6npbW;!^sT@6q$NMPXQa&lm1W^U?K=~^Ook|m{hVvche^Q6-g?(V)Vn8U=t YoEqFEkjD9gfq{X+)78&qol`;+0Plow*Z=?k literal 0 HcmV?d00001 diff --git a/doc/html/images/tip.png b/doc/html/images/tip.png new file mode 100644 index 0000000000000000000000000000000000000000..07ef20f8566cffc1379593d257b70cd388b77eb3 GIT binary patch literal 456 zcmeAS@N?(o<&xs%Vqjq4_4IHFVqjp9WME*B;9y{2V9>h9DaF9Rz?9_e?!v&Zs#n>F zfq~(+r;B4q#jVmwy9Ey`@Hj{+YFG5EnPj%qd-|FOLE0HCUfZWgHBJ)@5lZyt<>KVD zyWcqPUr>QgF%ln1NMyHmmVvr>?nXee;PB&*%IS zrnzQL-@JsL6gu;Ay@^OEA`#GK)(p9dav+OEQ!7Qj7Ic zN(=JyO7xQRb0_Xn+yM$tuyL8`d5I;ZMX3y_sg@}g=H|whX342WX6A{hNd|`ImMO-j yX%>b_Mv2Kn#=q1V7#R3Kx&ji@QyGj*D~wFE4YUpRedJsZiXcx{KbLh*2~7ZGd!Z`; literal 0 HcmV?d00001 diff --git a/doc/html/images/toc-blank.png b/doc/html/images/toc-blank.png new file mode 100644 index 0000000000000000000000000000000000000000..75b24d6fc4aafdebbc3b9adfe816fbbc546ea3e9 GIT binary patch literal 321 zcmeAS@N?(o;*#QGU|`_o^7L>CVqjq4XJBC9WMO7tV31#!ox;GtU=ZLF;>y6l&;Z5_ zV5)(kfuW({z<~n|4GsSp7#RLD{0CG2!L0xP|N9H8c``6CFeZ7syD)UH%6c#`Fvxkj zIEGZ*O8)VG|9^XdnuH(xj0$XGf&v)|3)s#uFig4NbSXn_;{yf;2Imsjh?3y^w370~ zqErS44P{Nw+{E-$-^BFHCVqjq4XJBC9W2%2N;(A7e1fPz^EY4<9WS5%buZDw_sh==UuK03=GaCt`Q}{ z`DrEPiAAXl4jRgup1FzXslJKnnaSA-CVEDC77CV@`UV#I28IgBMVZAVl@7U;#U+`^ zda1>FDWwJZc_n(u`MDE!DehokV9){^mzkcISW;S)%8;6zW@2cZnr32dYGh(!V3KBO zkZfX-Vv%f~VrZ0TlzO-0-z>1VK-vNl(^DA?O)D(54YUo+%RYe2WAJqKb6Mw<&;$Tl C3r%AH literal 0 HcmV?d00001 diff --git a/doc/html/images/toc-plus.png b/doc/html/images/toc-plus.png new file mode 100644 index 0000000000000000000000000000000000000000..29fada25c1d6c039ab4ad5682d3a11bb80b56781 GIT binary patch literal 267 zcmeAS@N?(o;*#QGU|`_o^7L>CVqjq4XJBC9W2%2N;(ASN<&d;gh5T!wGh0r7MeP_Gj5M1bO9bN||Y8!oa}b zT;dv05}cn_Ql40p%HW`(tm&DXn4apJn4X!Otze>Oq-UXEX{m2up>JTQkX)2mTvF+f zTUlI^nXH#utd~++ke^qgmzR+Sn6#IzInThrAO_OlT$Gwvl9`{U5R#dj z%3x@qZ(yu%U~+tY4<`cyLy@P8V@SoEspmFwHW&!FJyeg_(XezvV9WvAI|r@_>dZZG zPW6aiOT!J--9O?NG0%AP;}ge|4lDQN4=-}8`?JGwx}?mMnO)OdyQdu$nQCjPRV}jm z$u!Qa8E-cQ-r3Nz>Y(YPTd#BPEH+&8GWqfD!}4*53%dA!%#3$cIv;a~fq{X+)78&q Iol`;+0POUaApigX literal 0 HcmV?d00001 diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..74fc1ba2b4a7693f381d09607b6c2aaca3c043f7 GIT binary patch literal 1244 zcmeAS@N?(o<&xs%Vqjq4_4IHFVqjp90AUVh1_p-fE6<){U|?nl@Ck9{U|ZJ?} zOD!#zdU-8vX<0gD%F?Av*D^4yH8fm1Wy)3thOL^KTYGx8&Y81y>C&xRx9(+N*t>S^ z-mP1YF)$nx5I80waqQT!a|{gU1O(1WNSxEuyvD$AO;hvQwQKhn81CJ>_nd*@xuW9p z=g;3WFudpBc>n(WcLs*<-@pH7VE8`@Mnix~Ay8obcnSjp17ni6y9+}HtE>kD1H%hX z7srr_Te*{J^P3C=j=i7ad*|7am&=$<`NUgQ_e@pI<-PyEc$_`T z-}ks+llM|~rIOr~k12h5MQt-@+ihAJ>T>9>ci#Q%XzNS6?G0G-6!*_zE@WU}a4vC; zC<)F_D=AMbN@Z}+P}cO!O-xVqO-#>B&Q>tdGt#qAu(Z@Su+TR!R7ft$EH0^Z$gM0c z$xPNuE!ImZEy&L+(M!(How!SJ2Ll6x7TCDV^t{B9(xOy`WD}z#^Aw{LQ!|sq#3WM- z3kyp_OLI$e1LHIUqa+hkf5H2c85kJ&K)M1F(^DCYOe%~_v< swap(T& a, T& b) + { + T tmp(a); // now we have two copies of a + a = b; // now we have two copies of b + b = tmp; // now we have two copies of tmp (aka a) + } + +But, we didn't want to have any copies of a or b, we just wanted to swap them. Let's try again: + +[c++] + + template swap(T& a, T& b) + { + T tmp(::boost::move(a)); + a = ::boost::move(b); + b = ::boost::move(tmp); + } + +This `move()` gives its target the value of its argument, but is not obliged to preserve the value +of its source. So, for a `vector`, `move()` could reasonably be expected to leave its argument as +a zero-capacity vector to avoid having to copy all the elements. In other words, [*move is a potentially +destructive copy]. + +In this particular case, we could have optimized swap by a specialization. However, we can't +specialize every function that copies a large object just before it deletes or overwrites it. That +would be unmanageable. + +In C++0x, move semantics are implemented with the introduction of rvalue references. They allow us to +implement `move()` without verbosity or runtime overhead. [*Boost.Move] is a library that offers tools +to implement those move semantics not only in compilers with `rvalue references` but also in compilers +conforming to C++03. + +[endsect] + +[section:implementing_movable_classes Implementing copyable and movable classes] + +[import ../example/doc_clone_ptr.cpp] + +[section:copyable_and_movable_cpp0x Copyable and movable classes in C++0x] + +Consider a simple handle class that owns a resource and also provides copy semantics +(copy constructor and assignment). For example a `clone_ptr` might own a pointer, and call +`clone()` on it for copying purposes: + +[c++] + + template + class clone_ptr + { + private: + T* ptr; + + public: + // construction + explicit clone_ptr(T* p = 0) : ptr(p) {} + + // destruction + ~clone_ptr() { delete ptr; } + + // copy semantics + clone_ptr(const clone_ptr& p) + : ptr(p.ptr ? p.ptr->clone() : 0) {} + + clone_ptr& operator=(const clone_ptr& p) + { + if (this != &p) + { + T *p = p.ptr ? p.ptr->clone() : 0; + delete ptr; + ptr = p; + } + return *this; + } + + // move semantics + clone_ptr(clone_ptr&& p) + : ptr(p.ptr) { p.ptr = 0; } + + clone_ptr& operator=(clone_ptr&& p) + { + std::swap(ptr, p.ptr); + delete p.ptr; + p.ptr = 0; + return *this; + } + + // Other operations... + }; + +`clone_ptr` has expected copy constructor and assignment semantics, duplicating resources when copying. +Note that copy constructing or assigning a `clone_ptr` is a relatively expensive operation: + +[copy_clone_ptr] + +`clone_ptr` is code that you might find in today's books on C++, except for the part marked as +`move semantics`. That part is implemented in terms of C++0x `rvalue references`. You can find +some good introduction and tutorials on rvalue references in these papers: + +* [@http://www.artima.com/cppsource/rvalue.html ['A Brief Introduction to Rvalue References]] +* [@http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx ['Rvalue References: C++0x Features in VC10, Part 2]] + +When the source of the copy is known to be an `rvalue` (e.g.: a temporary object), one can avoid the +potentially expensive `clone()` operation by pilfering source's pointer (no one will notice!). The move +constructor above does exactly that, leaving the rvalue in a default constructed state. The move assignment +operator simply does the same freeing old resources. + +Now when code tries to copy an rvalue `clone_ptr`, or if that code explicitly gives permission to +consider the source of the copy an rvalue (using `boost::move`), the operation will execute much faster. + +[move_clone_ptr] + +[endsect] + +[section:copyable_and_movable_cpp03 Copyable and movable classes in portable syntax for both C++03 and C++0x compilers] + +Many aspects of move semantics can be emulated for compilers not supporting `rvalue references` +and [*Boost.Move] offers tools for that purpose. With [*Boost.Move] we can write `clone_ptr` +so that it will work both in compilers with rvalue references and those who conform to C++03. +You just need to follow these simple steps: + +* Put the following macro in the [*private] section: + [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE(classname)] +* Left copy constructor as is. +* Write a copy assignment taking the parameter as + [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)] +* Write a move constructor and a move assignment taking the parameter as + [macroref BOOST_RV_REF BOOST_RV_REF(classname)] + +Let's see how are applied to `clone_ptr`: + +[clone_ptr_def] + +[endsect] + +[*Question]: What about types that don't own resources? (E.g. `std::complex`?) + +No work needs to be done in that case. The copy constructor is already optimal. + +[endsect] + +[section:composition_inheritance Composition or inheritance] + +For classes made up of other classes (via either composition or inheritance), the move constructor +and move assignment can be easily coded using the `boost::move` function: + +[clone_ptr_base_derived] + +[important Due to limitations in the emulation code, a cast to `Base &` is needed before moving the base part in the move +constructor and call Base's move constructor instead of the copy constructor.] + +Each subobject will now be treated individually, calling move to bind to the subobject's move +constructors and move assignment operators. `Member` has move operations coded (just like +our earlier `clone_ptr` example) which will completely avoid the tremendously more expensive +copy operations: + +[clone_ptr_move_derived] + +Note above that the argument x is treated as a lvalue reference. That's why it is necessary to +say `move(x)` instead of just x when passing down to the base class. This is a key safety feature of move +semantics designed to prevent accidently moving twice from some named variable. All moves from +lvalues occur explicitly. + +[endsect] + +[section:movable_only_classes Movable but Non-Copyable Types] + +Some types are not amenable to copy semantics but can still be made movable. For example: + +* `unique_ptr` (non-shared, non-copyable ownership) +* A type representing a thread of execution +* A type representing a file descriptor + +By making such types movable (though still non-copyable) their utility is tremendously +increased. Movable but non-copyable types can be returned by value from factory functions: + +[c++] + + file_descriptor create_file(/* ... */); + //... + file_descriptor data_file; + //... + data_file = create_file(/* ... */); // No copies! + +In the above example, the underlying file handle is passed from object to object, as long +as the source `file_descriptor` is an rvalue. At all times, there is still only one underlying file +handle, and only one `file_descriptor` owns it at a time. + +To write a movable but not copyable type in portable syntax, you need to follow these simple steps: + +* Put the following macro in the [*private] section: + [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE(classname)] +* Write a move constructor and a move assignment taking the parameter as + [macroref BOOST_RV_REF BOOST_RV_REF(classname)] + +Here's the definition of `file descriptor` using portable syntax: + +[import ../example/doc_file_descriptor.cpp] +[file_descriptor_def] + +[/ + /Many standard algorithms benefit from moving elements of the sequence as opposed to + /copying them. This not only provides better performance (like the improved `swap` + /implementation described above), but also allows these algorithms to operate on movable + /but non-copyable types. For example the following code sorts a `vector>` + /based on comparing the pointed-to types: + / + /[c++] + / + / struct indirect_less + / { + / template + / bool operator()(const T& x, const T& y) + / {return *x < *y;} + / }; + / ... + / std::vector> v; + / ... + / std::sort(v.begin(), v.end(), indirect_less()); + / + / + /As sort moves the unique_ptr's around, it will use swap (which no longer requires Copyability) + /or move construction / move assignment. Thus during the entire algorithm, the invariant that + /each item is owned and referenced by one and only one smart pointer is maintained. If the + /algorithm were to attempt a copy (say by programming mistake) a compile time error would result. + /] + +[endsect] + +[section:move_and_containers Containers and move semantics] + +Movable but non-copyable types can be safely inserted into containers and +movable and copyable types are more efficiently handled if those containers +internally use move semantics instead of copy semantics. +If the container needs to "change the location" of an element +internally (e.g. vector reallocation) it will move the element instead of copying it. +[*Boost.Interprocess] containers are move-aware so you can write the following: + +[file_descriptor_example] + +[endsect] + +[section:construct_forwarding Constructor Forwarding] + +Consider writing a generic factory function that returns an object for a newly +constructed generic type. Factory functions such as this are valuable for encapsulating +and localizing the allocation of resources. Obviously, the factory function must accept +exactly the same sets of arguments as the constructors of the type of objects constructed: + +[c++] + + template T* factory_new() + { return new T(); } + + template T* factory_new(a1) + { return new T(a1); } + + template T* factory_new(a1, a2) + { return new T(a1, a2); } + +Unfortunately, in C++03 the much bigger issue with this approach is that the N-argument case +would require 2^N overloads, immediately discounting this as a general solution. Fortunately, +most constructors take arguments by value, by const-reference or by rvalue reference. If these +limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. +This library makes this emulation easy with the help of `BOOST_FWD_REF` and +`boost::forward`: + +[import ../example/doc_construct_forward.cpp] +[construct_forward_example] + +Constructor forwarding comes handful to implement placement insertion in containers with +just N overloads if the implementor accepts the limitations of this type of forwarding for +C++03 compilers. In compilers with rvalue references perfect forwarding is achieved. + +[endsect] + +[/[section:perfect_forwarding Perfect Forwarding] + / + /Consider writing a generic factory function that returns a std::shared_ptr for a newly + /constructed generic type. Factory functions such as this are valuable for encapsulating + /and localizing the allocation of resources. Obviously, the factory function must accept + /exactly the same sets of arguments as the constructors of the type of objects constructed. + /Today this might be coded as: + / + /[c++] + / + / template + / std::shared_ptr + / factory() // no argument version + / { + / return std::shared_ptr(new T); + / } + / + / template + / std::shared_ptr + / factory(const A1& a1) // one argument version + / { + / return std::shared_ptr(new T(a1)); + / } + / + / // all the other versions + / + / + /In the interest of brevity, we will focus on just the one-parameter version. For example: + / + / [c++] + / + / std::shared_ptr p = factory(5); + / + / + / [*Question]: What if T's constructor takes a parameter by non-const reference? + / + / 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. + / + / To solve that problem, we could use non-const parameters in our factory functions: + / + / [c++] + / + / template + / std::shared_ptr + / factory(A1& a1) + / { + / return std::shared_ptr(new T(a1)); + / } + / + / + / This is much better. If a const-qualified type is passed to the factory, the const will + / 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 + / correctly forwarded to T's constructor as a non-const. Indeed, this is precisely how + /forwarding applications are coded today (e.g. `std::bind`). + / + /However, consider: + / + /[c++] + / + / std::shared_ptr p = factory(5); // error + / A* q = new A(5); // ok + / + / + /This example worked with our first version of factory, but now it's broken: The "5" + /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. + / + /[*Question]: What about overloading on every combination of AI& and const AI&? + / + /This would allow use to handle all examples, but at a cost of an exponential explosion: + /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 + /so on. This is not a scalable solution. + / + /Rvalue references offer a simple, scalable solution to this problem: + / + /[c++] + / + / template + / std::shared_ptr + / factory(A1&& a1) + / { + / return std::shared_ptr(new T(std::forward(a1))); + / } + / + / 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 + / struct identity + / { + / typedef T type; + / }; + / + / template + / T&& forward(typename identity::type&& a) + / { + / return a; + / } + / + /[endsect] + / + /] + +[section:move_iterator Move iterators] + +[c++] + + template + class move_iterator; + + template + move_iterator make_move_iterator(const It &it); + +[classref boost::move_iterator move_iterator] is an iterator adaptor with the +same behavior as the underlying iterator +except that its dereference operator implicitly converts the value returned by the +underlying iterator's dereference operator to an rvalue reference: `boost::move(*underlying_iterator)` +It is a read-once iterator, but can have up to random access traversal characteristics. + +`move_iterator` is very useful because some generic algorithms and container insertion functions +can be called with move iterators to replace copying with moving. For example: + +[import ../example/movable.hpp] +[movable_definition] + +`movable` objects can be moved from one container to another using move iterators and insertion +and assignment operations.w + +[import ../example/doc_move_iterator.cpp] +[move_iterator_example] + +[endsect] + +[section:move_inserters Move inserters] + +Similar to standard insert iterators, it's possible to deal with move insertion in the same way +as writing into an array. A special kind of iterator adaptors, called move insert iterators, are +provided with this library. With regular iterator classes, + +[c++] + + while (first != last) *result++ = *first++; + +causes a range [first,last) to be copied into a range starting with result. The same code with +result being an move insert iterator will move insert corresponding elements into the container. +This device allows all of the copying algorithms in the library to work in the move insert mode +instead of the regular overwrite mode. This library offers 3 move insert iterators and their +helper functions: + +[c++] + + // Note: C models Container + template + class back_move_insert_iterator; + + template + back_move_insert_iterator back_move_inserter(C& x); + + template + class front_move_insert_iterator; + + template + front_move_insert_iterator front_move_inserter(C& x); + + template + class move_insert_iterator; + + template + move_insert_iterator move_inserter(C& x, typename C::iterator it); + + +A move insert iterator is constructed from a container and possibly one of its iterators pointing +to where insertion takes place if it is neither at the beginning nor at the end of the container. +Insert iterators satisfy the requirements of output iterators. `operator*` returns the move insert +iterator itself. The assignment `operator=(T& x)` is defined on insert iterators to allow writing +into them, it inserts x right before where the insert iterator is pointing. In other words, an +`insert iterator` is like a cursor pointing into the container where the insertion takes place. +`back_move_iterator` move inserts elements at the end of a container, `front_insert_iterator` +move inserts elements at the beginning of a container, and `move_insert_iterator` move inserts +elements where the iterator points to in a container. `back_move_inserter`, `front_move_inserter`, +and `move_inserter` are three functions making the insert iterators out of a container. Here's +an example of how to use them: + +[import ../example/doc_move_inserter.cpp] +[move_inserter_example] + +[endsect] + +[section:move_algorithms Move algorithms] + +The standard library offers several copy-based algorithms. Some of them, like `std::copy` or +`std::uninitialized_copy` are basic building blocks for containers and other data structures. +This library offers move-based functions for those purposes: + +[c++] + + template O move(I, I, O); + template O move_backward(I, I, O); + template F uninitialized_move(I, I, F); + template F uninitialized_copy_or_move(I, I, F); + + +The first 3 are move variations of their equivalent copy algorithms, but copy assignment and +copy construction are replaced with move assignment and construction. The last one has the +same behaviour as `std::uninitialized_copy` but since several standand library implementations +don't play very well with `move_iterator`s, this version is a portable version for those +willing to use move iterators. + +[import ../example/doc_move_algorithms.cpp] +[move_algorithms_example] + +[endsect] + +[section:emulation_limitations Emulation limitations] + +Like any emulation effort, the library has some limitations users should take in +care to achieve portable and efficient code when using the library with C++03 conformant compilers: + +[section:emulation_limitations_base Initializing base classes] + +When initializing base classes in move constructors, users must +cast the reference to a base class reference before moving it. Example: + +[c++] + + //Portable and efficient + Derived(BOOST_RV_REF(Derived) x) // Move ctor + : Base(boost::move(static_cast(x))), + mem_(boost::move(x.mem_)) { } + + +If casting is not performed the emulation will not move construct +the base class, because no conversion is available from `BOOST_RV_REF(Derived)` +to `BOOST_RV_REF(Base)`. Without the cast we might obtain a compilation +error (for non-copyable types) or a less-efficient move constructor (for copyable types): + +[c++] + + //If Derived is copyable, then Base is copy-constructed. + //If not, a compilation error is issued + Derived(BOOST_RV_REF(Derived) x) // Move ctor + : Base(boost::move(x)), + mem_(boost::move(x.mem_)) { } + +[endsect] + +[section:template_parameters Template parameters for perfect forwarding] + +The emulation can't deal with C++0x reference collapsing rules that allow perfect forwarding: + +[c++] + + //C++0x + template + void forward_function(T &&t) + { inner_function(std::forward(t); } + + //Wrong C++03 emulation + template + void forward_function(BOOST_RV_REF t) + { inner_function(boost::forward(t); } + +In C++03 emulation BOOST_RV_REF doesn't catch any const rlvalues. For more details on +forwarding see [link move.construct_forwarding Constructor Forwarding] chapter. + +[endsect] + +[section:emulation_limitations_binding Binding of rvalue references to lvalues] + +The +[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html first rvalue reference] +proposal allowed the binding of rvalue references to lvalues: + +[c++] + + func(Type &&t); + //.... + + Type t; //Allowed + func(t) + + +Later, as explained in +[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html ['Fixing a Safety Problem with Rvalue References]] +this behaviour was considered dangerous and eliminated this binding so that rvalue references adhere to the +principle of type-safe overloading: ['Every function must be type-safe in isolation, without regard to how it has been overloaded] + +[*Boost.Move] can't emulate this type-safe overloading principle for C++03 compilers: + +[c++] + + //Allowed by move emulation + movable m; + BOOST_RV_REF(movable) r = m; + +[endsect] + +[section:assignment_operator Assignment operator in classes derived from or holding copyable and movable types] + +The macro [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE] needs to +define a copy constructor for `copyable_and_movable` taking a non-const parameter in C++03 compilers: + +[c++] + + //Generated by BOOST_COPYABLE_AND_MOVABLE + copyable_and_movable &operator=(copyable_and_movable&){/**/} + +Since the non-const overload of the copy constructor is generated, compiler-generated +assignment operators for classes containing `copyable_and_movable` +will get the non-const copy constructor overload, which will surely surprise users: + +[c++] + + class holder + { + copyable_and_movable c; + }; + + void func(const holder& h) + { + holder copy_h(h); //<--- ERROR: can't convert 'const holder&' to 'holder&' + //Compiler-generated copy constructor is non-const: + // holder& operator(holder &) + //!!! + } + +This limitation forces the user to define a const version of the copy assignment, +in all classes holding copyable and movable classes which might annoying in some cases. + +An alternative is to implement a single `operator =()` for copyable and movable classes +[@http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ using "pass by value" semantics]: + +[c++] + + T& operator=(T x) // x is a copy of the source; hard work already done + { + swap(*this, x); // trade our resources for x's + return *this; // our (old) resources get destroyed with x + } + +However, "pass by value" is not optimal for classes (like containers, strings, etc.) that reuse resources +(like previously allocated memory) when x is assigned from a lvalue. + +[endsect] + +[endsect] + +[section:how_the_library_works How the library works] + +[*Boost.Move] is based on macros that are expanded to true rvalue references in C++0x compilers +and emulated rvalue reference classes and conversion operators in C++03 compilers. + +In C++03 compilers [*Boost.Move] defines a class named `::boost::rv`: + +[c++] + + template + class rv : public T + { + rv(); + ~rv(); + rv(rv const&); + void operator=(rv const&); + }; + +which is convertible to the movable base class (usual C++ derived to base conversion). When users mark +their classes as [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] or +[macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE], these macros define conversion +operators to references to `::boost::rv`: + +[c++] + + #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + public:\ + operator ::BOOST_MOVE_NAMESPACE::rv&() \ + { return *reinterpret_cast< ::BOOST_MOVE_NAMESPACE::rv* >(this); }\ + operator const ::BOOST_MOVE_NAMESPACE::rv&() const \ + { return *reinterpret_cast* >(this); }\ + private:\ + //More stuff... + +[macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] also declares a +private copy constructor and assignment. [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE] +defines a non-const copy constructor `TYPE &operator=(TYPE&)` that forwards to a const version: + + #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + public:\ + TYPE& operator=(TYPE &t)\ + { this->operator=(static_cast &>(const_cast(t))); return *this;}\ + //More stuff... + +In C++0x compilers `BOOST_COPYABLE_AND_MOVABLE` expands to nothing and `BOOST_MOVABLE_BUT_NOT_COPYABLE` +declares copy constructor and assigment operator private. + +When users define the [macroref BOOST_RV_REF BOOST_RV_REF] overload of a copy constructor/assignment, in +C++0x compilers it is expanded to a rvalue reference (`T&&`) overload and in C++03 compilers it is expanded +to a `::boost::rv &` overload: + +[c++] + + #define BOOST_RV_REF(TYPE) ::boost::rv< TYPE >& \ + +When users define the [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] overload, +it is expanded to a usual copy assignment (`const T &`) overload in C++0x compilers and +to a `const ::boost::rv &` overload in C++03 compilers: + +[c++] + + #define BOOST_COPY_ASSIGN_REF(TYPE) const ::boost::rv< TYPE >& + +As seen, in [*Boost.Move] generates efficient and clean code for C++0x move +semantics, without modifying any resolution overload. For C++03 compilers +when overload resolution is performed these are the bindings: + +* a) non-const rvalues (e.g.: temporaries), bind to `::boost::rv< TYPE >&` +* b) const rvalue and lvalues, bind to `const ::boost::rv< TYPE >&` +* c) non-const lvalues (e.g. non-const references) bind to `TYPE&` + +The library does not define the equivalent of +[macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] for copy construction (say, `BOOST_COPY_CTOR_REF`) +because nearly all modern compilers implement RVO and this is much more efficient than any move emulation. +[funcref boost::move move] just casts `TYPE &` into `::boost::rv &`. + +Here's an example that demostrates how different rlvalue objects bind to `::boost::rv` references in the +presence of three overloads and the conversion operators in C++03 compilers: + +[import ../example/doc_how_works.cpp] +[how_works_example] + +[endsect] + + +[section:thanks_to Thanks and credits] + +Thanks to all that developed ideas for move emulation: the first emulation was based on Howard Hinnant +emulation code for `unique_ptr`, David Abrahams suggested the use of `class rv` class, +and Klaus Triendl discovered how to bind const rlvalues using `class rv`. + +Many thanks to all boosters that have tested, reviewed and improved the library. + +[endsect] + +[xinclude autodoc.xml] diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 new file mode 100644 index 0000000..d7de3e6 --- /dev/null +++ b/example/Jamfile.v2 @@ -0,0 +1,28 @@ +############################################################################## +## +## (C) Copyright Ion Gaztanaga 2008-2009 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) +## +## +############################################################################## +rule test_all +{ + local all_rules = ; + + for local fileb in [ glob *.cpp ] + { + all_rules += [ run $(fileb) + : # additional args + : # test-files + : # requirements + ] ; + } + + return $(all_rules) ; +} + +test-suite move_example : [ test_all r ] +: static +; + diff --git a/example/copymovable.hpp b/example/copymovable.hpp new file mode 100644 index 0000000..c3b4793 --- /dev/null +++ b/example/copymovable.hpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_TEST_COPYMOVABLE_HPP +#define BOOST_MOVE_TEST_COPYMOVABLE_HPP + +//[movable_definition +//header file "copy_movable.hpp" +#include + +//A copy_movable class +class copy_movable +{ + BOOST_COPYABLE_AND_MOVABLE(copy_movable) + int value_; + + public: + copy_movable() : value_(1){} + + //Move constructor and assignment + copy_movable(BOOST_RV_REF(copy_movable) m) + { value_ = m.value_; m.value_ = 0; } + + copy_movable(const copy_movable &m) + { value_ = m.value_; } + + copy_movable & operator=(BOOST_RV_REF(copy_movable) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m) + { value_ = m.value_; return *this; } + + bool moved() const //Observer + { return value_ == 0; } +}; + +//] + +#endif //BOOST_MOVE_TEST_COPYMOVABLE_HPP diff --git a/example/doc_clone_ptr.cpp b/example/doc_clone_ptr.cpp new file mode 100644 index 0000000..e86e64b --- /dev/null +++ b/example/doc_clone_ptr.cpp @@ -0,0 +1,152 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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 + +//[clone_ptr_base_derived +class Base +{ + BOOST_COPYABLE_AND_MOVABLE(Base) + + public: + Base(){} + + // Compiler-generated copy constructor... + + Base(BOOST_RV_REF(Base) x) {/**/} // Move ctor + + Base& operator=(BOOST_RV_REF(Base) x) + {/**/ return *this;} // Move assign + + Base& operator=(BOOST_COPY_ASSIGN_REF(Base) x) + {/**/ return *this;} // Copy assign + + virtual Base *clone() const + { return new Base(*this); } +}; + +class Member +{ + BOOST_COPYABLE_AND_MOVABLE(Member) + + public: + Member(){} + + // Compiler-generated copy constructor... + + Member(BOOST_RV_REF(Member)) {/**/} // Move ctor + + Member &operator=(BOOST_RV_REF(Member)) // Move assign + {/**/ return *this; } + + Member &operator=(BOOST_COPY_ASSIGN_REF(Member)) // Copy assign + {/**/ return *this; } +}; + +class Derived : public Base +{ + BOOST_COPYABLE_AND_MOVABLE(Derived) + Member mem_; + + public: + Derived(){} + + // Compiler-generated copy constructor... + + Derived(BOOST_RV_REF(Derived) x) // Move ctor + : Base(boost::move(static_cast(x))), + mem_(boost::move(x.mem_)) { } + + Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign + { + Base::operator=(boost::move(static_cast(x))); + mem_ = boost::move(x.mem_); + return *this; + } + + Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign + { + Base::operator=(static_cast(x)); + mem_ = x.mem_; + return *this; + } + // ... +}; +//] + +//[clone_ptr_def +template +class clone_ptr +{ + private: + // Mark this class copyable and movable + BOOST_COPYABLE_AND_MOVABLE(clone_ptr) + T* ptr; + + public: + // Construction + explicit clone_ptr(T* p = 0) : ptr(p) {} + + // Destruction + ~clone_ptr() { delete ptr; } + + clone_ptr(const clone_ptr& p) // Copy constructor (as usual) + : ptr(p.ptr ? p.ptr->clone() : 0) {} + + clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment + { + if (this != &p){ + T *tmp_p = p.ptr ? p.ptr->clone() : 0; + delete ptr; + ptr = tmp_p; + } + return *this; + } + + //Move semantics... + clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor + : ptr(p.ptr) { p.ptr = 0; } + + clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment + { + if (this != &p){ + delete ptr; + ptr = p.ptr; + p.ptr = 0; + } + return *this; + } +}; +//] + +int main() +{ + { + //[copy_clone_ptr + clone_ptr p1(new Derived()); + // ... + clone_ptr p2 = p1; // p2 and p1 each own their own pointer + //] + } + { + //[move_clone_ptr + clone_ptr p1(new Derived()); + // ... + clone_ptr p2 = boost::move(p1); // p2 now owns the pointer instead of p1 + p2 = clone_ptr(new Derived()); // temporary is moved to p2 + } + //] + //[clone_ptr_move_derived + Derived d; + Derived d2(boost::move(d)); + d2 = boost::move(d); + //] + return 0; +} diff --git a/example/doc_construct_forward.cpp b/example/doc_construct_forward.cpp new file mode 100644 index 0000000..07be958 --- /dev/null +++ b/example/doc_construct_forward.cpp @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//[construct_forward_example +#include +#include + +class copyable_only_tester +{ + public: + copyable_only_tester() + { std::cout << "copyable_only_tester()" << std::endl; } + + copyable_only_tester(const copyable_only_tester&) + { std::cout << "copyable_only_tester(const copyable_only_tester&)" << std::endl; } + + copyable_only_tester(int) + { std::cout << "copyable_only_tester(int)" << std::endl; } + + copyable_only_tester(int, double) + { std::cout << "copyable_only_tester(int, double)" << std::endl; } +}; + +class copyable_movable_tester +{ + // move semantics + BOOST_COPYABLE_AND_MOVABLE(copyable_movable_tester) + public: + + copyable_movable_tester() + { std::cout << "copyable_movable_tester()" << std::endl; } + + copyable_movable_tester(int) + { std::cout << "copyable_movable_tester(int)" << std::endl; } + + copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester)) + { std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))" << std::endl; } + + copyable_movable_tester(const copyable_movable_tester &) + { std::cout << "copyable_movable_tester(const copyable_movable_tester &)" << std::endl; } + + copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester)) + { std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))" << std::endl; } + + copyable_movable_tester &operator=(BOOST_RV_REF(copyable_movable_tester)) + { std::cout << "copyable_movable_tester & operator=(BOOST_RV_REF(copyable_movable_tester))" << std::endl; + return *this; } + + copyable_movable_tester &operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester)) + { std::cout << "copyable_movable_tester & operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))" << std::endl; + return *this; } +}; + +//1 argument +template +void function_construct(BOOST_FWD_REF(MaybeRv) x) +{ MaybeMovable m(boost::forward(x)); } + +//2 argument +template +void function_construct(BOOST_FWD_REF(MaybeRv) x, BOOST_FWD_REF(MaybeRv2) x2) +{ MaybeMovable m(boost::forward(x), boost::forward(x2)); } + +int main() +{ + copyable_movable_tester m; + //move constructor + function_construct(boost::move(m)); + //copy constructor + function_construct(copyable_movable_tester()); + //two rvalue constructor + function_construct(boost::move(m), boost::move(m)); + + copyable_only_tester nm; + //copy constructor (copyable_only_tester has no move ctor.) + function_construct(boost::move(nm)); + //copy constructor + function_construct(nm); + //int constructor + function_construct(int(0)); + //int, double constructor + function_construct(int(0), double(0.0)); + + //Output is: + //copyable_movable_tester() + //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester)) + //copyable_movable_tester() + //copyable_movable_tester(const copyable_movable_tester &) + //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester)) + //copyable_only_tester() + //copyable_only_tester(const copyable_only_tester&) + //copyable_only_tester(const copyable_only_tester&) + //copyable_only_tester(int) + //copyable_only_tester(int, double) + return 0; +} +//] diff --git a/example/doc_file_descriptor.cpp b/example/doc_file_descriptor.cpp new file mode 100644 index 0000000..0691ebb --- /dev/null +++ b/example/doc_file_descriptor.cpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//[file_descriptor_def + +#include +#include + +class file_descriptor +{ + //<- + int operating_system_open_file(const char *) + { + return 1; + } + + void operating_system_close_file(int) + {} + //-> + int os_descr_; + + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor) + + public: + explicit file_descriptor(const char *filename = 0) //Constructor + : os_descr_(filename ? operating_system_open_file(filename) : 0) + { if(!os_descr_) throw std::runtime_error("file not found"); } + + ~file_descriptor() //Destructor + { if(!os_descr_) operating_system_close_file(os_descr_); } + + file_descriptor(BOOST_RV_REF(file_descriptor) x) // Move ctor + : os_descr_(x.os_descr_) + { x.os_descr_ = 0; } + + file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign + { + if(!os_descr_) operating_system_close_file(os_descr_); + os_descr_ = x.os_descr_; + x.os_descr_ = 0; + return *this; + } + + bool empty() const { return os_descr_ == 0; } +}; + +//] + +//[file_descriptor_example +#include +#include + +//Remember: 'file_descriptor' is NOT copyable, but it +//can be returned from functions thanks to move semantics +file_descriptor create_file_descriptor(const char *filename) +{ return file_descriptor(filename); } + +int main() +{ + //Open a file obtaining its descriptor, the temporary + //returned from 'create_file_descriptor' is moved to 'fd'. + file_descriptor fd = create_file_descriptor("filename"); + assert(!fd.empty()); + + //Now move fd into a vector + boost::interprocess::vector v; + v.push_back(boost::move(fd)); + + //Check ownership has been transferred + assert(fd.empty()); + assert(!v[0].empty()); + + //Compilation error if uncommented since file_descriptor is not copyable + //and vector copy construction requires value_type's copy constructor: + //boost::interprocess::vector v2(v); + return 0; +} +//] diff --git a/example/doc_how_works.cpp b/example/doc_how_works.cpp new file mode 100644 index 0000000..e2116c5 --- /dev/null +++ b/example/doc_how_works.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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 + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + +int main() +{ + return 0; +} + +#else + +//[how_works_example +#include +#include + +class sink_tester +{ + public: //conversions provided by BOOST_COPYABLE_AND_MOVABLE + operator ::boost::rv&() + { return *static_cast< ::boost::rv* >(this); } + operator const ::boost::rv&() const + { return *static_cast* >(this); } +}; + +//Functions returning different r/lvalue types + sink_tester rvalue() { return sink_tester(); } +const sink_tester const_rvalue() { return sink_tester(); } + sink_tester & lvalue() { static sink_tester lv; return lv; } +const sink_tester & const_lvalue() { static const sink_tester clv = sink_tester(); return clv; } + +//BOOST_RV_REF overload +void sink(::boost::rv &) { std::cout << "non-const rvalue catched" << std::endl; } +//BOOST_COPY_ASSIGN_REF overload +void sink(const ::boost::rv &){ std::cout << "const (r-l)value catched" << std::endl; } +//Overload provided by BOOST_COPYABLE_AND_MOVABLE +void sink(sink_tester &) { std::cout << "non-const lvalue catched" << std::endl; } + +int main() +{ + sink(const_rvalue()); //"const (r-l)value catched" + sink(const_lvalue()); //"const (r-l)value catched" + sink(lvalue()); //"non-const lvalue catched" + sink(rvalue()); //"non-const rvalue catched" + return 0; +} +//] + +#endif + diff --git a/example/doc_move_algorithms.cpp b/example/doc_move_algorithms.cpp new file mode 100644 index 0000000..c9ca065 --- /dev/null +++ b/example/doc_move_algorithms.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//[move_algorithms_example +#include "movable.hpp" +#include +#include + +int main() +{ + const std::size_t ArraySize = 10; + movable movable_array[ArraySize]; + movable movable_array2[ArraySize]; + //move + boost::move(&movable_array2[0], &movable_array2[ArraySize], &movable_array[0]); + assert(movable_array2[0].moved()); + assert(!movable_array[0].moved()); + + //move backward + boost::move_backward(&movable_array[0], &movable_array[ArraySize], &movable_array2[ArraySize]); + assert(movable_array[0].moved()); + assert(!movable_array2[0].moved()); + + //uninitialized_move + boost::aligned_storage< sizeof(movable)*ArraySize + , boost::alignment_of::value>::type storage; + movable *raw_movable = static_cast(static_cast(&storage)); + boost::uninitialized_move(&movable_array2[0], &movable_array2[ArraySize], raw_movable); + assert(movable_array2[0].moved()); + assert(!raw_movable[0].moved()); + return 0; +} +//] diff --git a/example/doc_move_inserter.cpp b/example/doc_move_inserter.cpp new file mode 100644 index 0000000..547cc82 --- /dev/null +++ b/example/doc_move_inserter.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//[move_inserter_example +#include +#include "movable.hpp" +#include + +using namespace ::boost::interprocess; + +typedef list list_t; +typedef list_t::iterator l_iterator; + +template +void test_move_inserter(list_t &l2, MoveInsertIterator mit) +{ + //Create a list with 10 default constructed objects + list l(10); + assert(!l.begin()->moved()); + l2.clear(); + + //Move construct + for(l_iterator itbeg = l.begin(), itend = l.end(); itbeg != itend; ++itbeg){ + *mit = *itbeg; + } + //Check size and status + assert(l2.size() == l.size()); + assert(l.begin()->moved()); + assert(!l2.begin()->moved()); +} + +int main() +{ + list_t l2; + test_move_inserter(l2, boost::back_move_inserter(l2)); + test_move_inserter(l2, boost::front_move_inserter(l2)); + test_move_inserter(l2, boost::move_inserter(l2, l2.end())); + return 0; +} +//] diff --git a/example/doc_move_iterator.cpp b/example/doc_move_iterator.cpp new file mode 100644 index 0000000..d48b93f --- /dev/null +++ b/example/doc_move_iterator.cpp @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// + +//[move_iterator_example +#include +#include "movable.hpp" +#include + +int main() +{ + using namespace ::boost::interprocess; + + //Create a vector with 10 default constructed objects + vector v(10); + assert(!v[0].moved()); + + //Move construct all elements in v into v2 + vector v2( boost::make_move_iterator(v.begin()) + , boost::make_move_iterator(v.end())); + assert(v[0].moved()); + assert(!v2[0].moved()); + + //Now move assign all elements from in v2 back into v + v.assign( boost::make_move_iterator(v2.begin()) + , boost::make_move_iterator(v2.end())); + assert(v2[0].moved()); + assert(!v[0].moved()); + + return 0; +} +//] diff --git a/example/movable.hpp b/example/movable.hpp new file mode 100644 index 0000000..89b4397 --- /dev/null +++ b/example/movable.hpp @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009. +// 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. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_TEST_MOVABLE_HPP +#define BOOST_MOVE_TEST_MOVABLE_HPP + +//[movable_definition +//header file "movable.hpp" +#include + +//A movable class +class movable +{ + BOOST_MOVABLE_BUT_NOT_COPYABLE(movable) + int value_; + + public: + movable() : value_(1){} + + //Move constructor and assignment + movable(BOOST_RV_REF(movable) m) + { value_ = m.value_; m.value_ = 0; } + + movable & operator=(BOOST_RV_REF(movable) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return value_ == 0; } +}; + +namespace boost{ + +template<> +struct has_nothrow_move +{ + static const bool value = true; +}; + +} //namespace boost{ +//] + +#endif //BOOST_MOVE_TEST_MOVABLE_HPP diff --git a/proj/vc7ide/Move.sln b/proj/vc7ide/Move.sln new file mode 100644 index 0000000..68e086e --- /dev/null +++ b/proj/vc7ide/Move.sln @@ -0,0 +1,140 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "construct_forward_test", "construct_forward_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_iterator_test", "move_iterator_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_test", "move_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_algorithm_test", "move_algorithm.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_clone_ptr", "doc_clone_ptr.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_descriptor", "doc_file_descriptor.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_iterator", "doc_move_iterator.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_inserter", "doc_move_inserter.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_algorithms", "doc_move_algorithms.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_construct_forward", "doc_construct_forward.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "back_move_inserter_test", "back_move_inserter_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_move_optimization_test", "copy_move_optimization.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_elision_test_test", "copy_elision_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_how_works", "doc_how_works.vcproj", "{C7C2F583-4FE2-1862-BF87-BA26D31A7995}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_test", "conversion_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Debug.ActiveCfg = Debug|Win32 + {C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Debug.Build.0 = Debug|Win32 + {C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Release.ActiveCfg = Release|Win32 + {C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Release.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionItems) = postSolution + ..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2 + ..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp + ..\..\doc\move.qbk = ..\..\doc\move.qbk + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/proj/vc7ide/back_move_inserter_test.vcproj b/proj/vc7ide/back_move_inserter_test.vcproj new file mode 100644 index 0000000..17a751f --- /dev/null +++ b/proj/vc7ide/back_move_inserter_test.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/construct_forward_test.vcproj b/proj/vc7ide/construct_forward_test.vcproj new file mode 100644 index 0000000..be11eec --- /dev/null +++ b/proj/vc7ide/construct_forward_test.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/conversion_test.vcproj b/proj/vc7ide/conversion_test.vcproj new file mode 100644 index 0000000..1321c21 --- /dev/null +++ b/proj/vc7ide/conversion_test.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/copy_elision_test.vcproj b/proj/vc7ide/copy_elision_test.vcproj new file mode 100644 index 0000000..9a31cd7 --- /dev/null +++ b/proj/vc7ide/copy_elision_test.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/copy_move_optimization.vcproj b/proj/vc7ide/copy_move_optimization.vcproj new file mode 100644 index 0000000..13ef1a4 --- /dev/null +++ b/proj/vc7ide/copy_move_optimization.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_clone_ptr.vcproj b/proj/vc7ide/doc_clone_ptr.vcproj new file mode 100644 index 0000000..e87a8b8 --- /dev/null +++ b/proj/vc7ide/doc_clone_ptr.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_construct_forward.vcproj b/proj/vc7ide/doc_construct_forward.vcproj new file mode 100644 index 0000000..5afea83 --- /dev/null +++ b/proj/vc7ide/doc_construct_forward.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_file_descriptor.vcproj b/proj/vc7ide/doc_file_descriptor.vcproj new file mode 100644 index 0000000..2ea9a34 --- /dev/null +++ b/proj/vc7ide/doc_file_descriptor.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_how_works.vcproj b/proj/vc7ide/doc_how_works.vcproj new file mode 100644 index 0000000..62363e8 --- /dev/null +++ b/proj/vc7ide/doc_how_works.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_move_algorithms.vcproj b/proj/vc7ide/doc_move_algorithms.vcproj new file mode 100644 index 0000000..62e3595 --- /dev/null +++ b/proj/vc7ide/doc_move_algorithms.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_move_inserter.vcproj b/proj/vc7ide/doc_move_inserter.vcproj new file mode 100644 index 0000000..8bf944b --- /dev/null +++ b/proj/vc7ide/doc_move_inserter.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/doc_move_iterator.vcproj b/proj/vc7ide/doc_move_iterator.vcproj new file mode 100644 index 0000000..1e1370a --- /dev/null +++ b/proj/vc7ide/doc_move_iterator.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/move_algorithm.vcproj b/proj/vc7ide/move_algorithm.vcproj new file mode 100644 index 0000000..33d4e5e --- /dev/null +++ b/proj/vc7ide/move_algorithm.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/move_iterator_test.vcproj b/proj/vc7ide/move_iterator_test.vcproj new file mode 100644 index 0000000..49355ee --- /dev/null +++ b/proj/vc7ide/move_iterator_test.vcproj @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/move_test.vcproj b/proj/vc7ide/move_test.vcproj new file mode 100644 index 0000000..a95ac52 --- /dev/null +++ b/proj/vc7ide/move_test.vcproj @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 new file mode 100644 index 0000000..22b904b --- /dev/null +++ b/test/Jamfile.v2 @@ -0,0 +1,28 @@ +############################################################################## +## +## (C) Copyright Ion Gaztanaga 2008-2009 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) +## +## +############################################################################## +rule test_all +{ + local all_rules = ; + + for local fileb in [ glob *.cpp ] + { + all_rules += [ run $(fileb) + : # additional args + : # test-files + : # requirements + ] ; + } + + return $(all_rules) ; +} + +test-suite move_test : [ test_all r ] +: static +; + diff --git a/test/back_move_inserter.cpp b/test/back_move_inserter.cpp new file mode 100644 index 0000000..27d28f4 --- /dev/null +++ b/test/back_move_inserter.cpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009. +// 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 +#include +#include +#include +#include "../example/movable.hpp" + +template +int move_test() +{ + //Default construct 10 movable objects + Container v(10); + + //Test default constructed value + if(v.begin()->moved()){ + return 1; + } + + //Move values + Container v2; + std::copy(v.begin(), v.end(), boost::back_move_inserter(v2)); + + //Test values have been moved + if(!v.begin()->moved()){ + return 1; + } + + if(v2.size() != 10){ + return 1; + } + + if(v2.begin()->moved()){ + return 1; + } + return 0; +} + +int main() +{ + namespace bi = ::boost::interprocess; + + if(move_test< bi::vector >()){ + return 1; + } + if(move_test< bi::list >()){ + return 1; + } + if(move_test< bi::stable_vector >()){ + return 1; + } + return 0; +} diff --git a/test/construct_forward.cpp b/test/construct_forward.cpp new file mode 100644 index 0000000..bf4c526 --- /dev/null +++ b/test/construct_forward.cpp @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009-2011. +// 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 +#include +#include "../example/movable.hpp" +#include "../example/copymovable.hpp" +#include + +class non_movable +{ + public: + non_movable() + {} +}; + +template +void catch_test(BOOST_RV_REF(MaybeRvalue) x + #ifdef BOOST_NO_RVALUE_REFERENCES + ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 + #endif //BOOST_NO_RVALUE_REFERENCES + ) +{ (void)x;} + +template +void catch_test(BOOST_COPY_ASSIGN_REF(MaybeRvalue) x + #ifdef BOOST_NO_RVALUE_REFERENCES + ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 + #endif //BOOST_NO_RVALUE_REFERENCES + ) + +{ (void)x;} + +template +void catch_test(MaybeRvalue &x + #ifdef BOOST_NO_RVALUE_REFERENCES + ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 + #endif //BOOST_NO_RVALUE_REFERENCES + ) +{ (void)x;} + + #ifdef BOOST_NO_RVALUE_REFERENCES +template +void catch_test(const MaybeRvalue& x + ,typename ::boost::disable_if< ::boost::has_move_emulation_enabled >::type* = 0 + ) +{ (void)x;} + #endif //BOOST_NO_RVALUE_REFERENCES + +movable create_movable() +{ return movable(); } + +copy_movable create_copy_movable() +{ return copy_movable(); } + +non_movable create_non_movable() +{ return non_movable(); } + + +void catch_test() +{ + movable m; + const movable constm; + catch_test(boost::move(m)); + #ifdef BOOST_CATCH_CONST_RLVALUE + catch_test(create_movable()); + #endif + catch_test(m); + catch_test(constm); + copy_movable cm; + const copy_movable constcm; + catch_test(boost::move(cm)); + catch_test(create_copy_movable()); + catch_test(cm); + catch_test(constcm); + non_movable nm; + const non_movable constnm; + catch_test(boost::move(nm)); + catch_test(create_non_movable()); + catch_test(nm); + catch_test(constnm); +} + +template +void function_construct(BOOST_FWD_REF(MaybeRvalue) x) +{ + //Moves in case Convertible is boost::rv copies otherwise + //For C++0x perfect forwarding + MaybeMovableOnly m(boost::forward(x)); +} + +void forward_test() +{ + movable m; + function_construct(boost::move(m)); +// non_movable nm; +// function_construct(boost::move(nm)); +// const non_movable cnm; +// function_construct(cnm); +} + +int main() +{ + catch_test(); + forward_test(); + return 0; +} diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp new file mode 100644 index 0000000..99157c1 --- /dev/null +++ b/test/conversion_test.cpp @@ -0,0 +1,677 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2010-2011. +// 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 + +#include +#include +#include +#include + + +enum ConstructionType { Copied, Moved, Other }; + +class conversion_source +{ + public: + conversion_source(){} + operator int() const { return 0; } +}; + +class conversion_target +{ + ConstructionType c_type_; + public: + conversion_target(conversion_source) + { c_type_ = Other; } + conversion_target() + { c_type_ = Other; } + conversion_target(const conversion_target &) + { c_type_ = Copied; } + ConstructionType construction_type() const + { return c_type_; } +}; + + +class conversion_target_copymovable +{ + ConstructionType c_type_; + BOOST_COPYABLE_AND_MOVABLE(conversion_target_copymovable) + public: + conversion_target_copymovable() + { c_type_ = Other; } + conversion_target_copymovable(conversion_source) + { c_type_ = Other; } + conversion_target_copymovable(const conversion_target_copymovable &) + { c_type_ = Copied; } + conversion_target_copymovable(BOOST_RV_REF(conversion_target_copymovable) ) + { c_type_ = Moved; } + conversion_target_copymovable &operator=(BOOST_RV_REF(conversion_target_copymovable) ) + { c_type_ = Moved; return *this; } + conversion_target_copymovable &operator=(BOOST_COPY_ASSIGN_REF(conversion_target_copymovable) ) + { c_type_ = Copied; return *this; } + ConstructionType construction_type() const + { return c_type_; } +}; + +class conversion_target_movable +{ + ConstructionType c_type_; + BOOST_MOVABLE_BUT_NOT_COPYABLE(conversion_target_movable) + public: + conversion_target_movable() + { c_type_ = Other; } + conversion_target_movable(conversion_source) + { c_type_ = Other; } + conversion_target_movable(BOOST_RV_REF(conversion_target_movable) ) + { c_type_ = Moved; } + conversion_target_movable &operator=(BOOST_RV_REF(conversion_target_movable) ) + { c_type_ = Moved; return *this; } + ConstructionType construction_type() const + { return c_type_; } +}; + + +template +class container +{ + typename ::boost::aligned_storage::value>::type storage_; + public: + + typedef T * iterator; + typedef const T * const_iterator; + + BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) + + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator) + + ConstructionType construction_type() const + { return construction_type_impl(typename ::boost::is_class::type()); } + ConstructionType construction_type_impl(::boost::true_type) const + { return reinterpret_cast(storage_).construction_type(); } + ConstructionType construction_type_impl(::boost::false_type) const + { return Copied; } + + iterator begin() { return iterator(0); } + + private: + + template + void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x) + { new (&storage_) T(::boost::forward(x)); } + + template + iterator priv_insert(const_iterator, BOOST_MOVE_CATCH_FWD(U) x) + { new (&storage_) T(::boost::forward(x)); return 0; } +}; + + +int main() +{ + conversion_target_movable a; + conversion_target_movable b(::boost::move(a)); + { + container c; + { + conversion_target x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + const conversion_target x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_target()); + assert(c.construction_type() == Copied); + c.insert(c.begin(), conversion_target()); + assert(c.construction_type() == Copied); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Copied); + c.insert(c.begin(), conversion_source()); + assert(c.construction_type() == Copied); + } + } + + { + container c; + { + conversion_target_copymovable x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + const conversion_target_copymovable x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_target_copymovable()); + assert(c.construction_type() == Moved); + c.insert(c.begin(), conversion_target_copymovable()); + assert(c.construction_type() == Moved); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Moved); + c.insert(c.begin(), x); + assert(c.construction_type() == Moved); + } + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Moved); + c.insert(c.begin(), x); + assert(c.construction_type() == Moved); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Moved); + c.insert(c.begin(), conversion_source()); + assert(c.construction_type() == Moved); + } + } + { + container c; + //This should not compile + //{ + // conversion_target_movable x; + // c.push_back(x); + // assert(c.construction_type() == Copied); + //} + //{ + // const conversion_target_movable x; + // c.push_back(x); + // assert(c.construction_type() == Copied); + //} + { + c.push_back(conversion_target_movable()); + assert(c.construction_type() == Moved); + c.insert(c.begin(), conversion_target_movable()); + assert(c.construction_type() == Moved); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Moved); + c.insert(c.begin(), x); + assert(c.construction_type() == Moved); + } + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Moved); + c.insert(c.begin(), x); + assert(c.construction_type() == Moved); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Moved); + c.insert(c.begin(), conversion_source()); + assert(c.construction_type() == Moved); + } + } + { + container c; + { + int x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), c.construction_type()); + assert(c.construction_type() == Copied); + } + { + const int x = 0; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(int(0)); + assert(c.construction_type() == Copied); + c.insert(c.begin(), int(0)); + assert(c.construction_type() == Copied); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Copied); + c.insert(c.begin(), conversion_source()); + assert(c.construction_type() == Copied); + } + } + + return 0; +} + +/* +#include +#include +#include +#include +#include +#include +#include + + +enum ConstructionType { Default, Copied, Moved, Other }; + +class conversion_source +{ + public: + conversion_source(){} + operator int() const { return 0; } +}; + +class conversion_target +{ + ConstructionType c_type_; + public: + conversion_target(conversion_source) + { c_type_ = Other; } + conversion_target() + { c_type_ = Default; } + conversion_target(const conversion_target &) + { c_type_ = Copied; } + ConstructionType construction_type() const + { return c_type_; } +}; + + +class conversion_target_copymovable +{ + ConstructionType c_type_; + BOOST_COPYABLE_AND_MOVABLE(conversion_target_copymovable) + public: + conversion_target_copymovable() + { c_type_ = Default; } + conversion_target_copymovable(conversion_source) + { c_type_ = Other; } + conversion_target_copymovable(const conversion_target_copymovable &) + { c_type_ = Copied; } + conversion_target_copymovable(BOOST_RV_REF(conversion_target_copymovable) ) + { c_type_ = Moved; } + conversion_target_copymovable &operator=(BOOST_RV_REF(conversion_target_copymovable) ) + { c_type_ = Moved; return *this; } + conversion_target_copymovable &operator=(BOOST_COPY_ASSIGN_REF(conversion_target_copymovable) ) + { c_type_ = Copied; return *this; } + ConstructionType construction_type() const + { return c_type_; } +}; + +class conversion_target_movable +{ + ConstructionType c_type_; + BOOST_MOVABLE_BUT_NOT_COPYABLE(conversion_target_movable) + public: + conversion_target_movable() + { c_type_ = Default; } + conversion_target_movable(conversion_source) + { c_type_ = Other; } + conversion_target_movable(BOOST_RV_REF(conversion_target_movable) ) + { c_type_ = Moved; } + conversion_target_movable &operator=(BOOST_RV_REF(conversion_target_movable) ) + { c_type_ = Moved; return *this; } + ConstructionType construction_type() const + { return c_type_; } +}; + +struct not_a_type; + +#if defined(BOOST_NO_RVALUE_REFERENCES) +#define BOOST_MOVE_CATCH_CONST(U) \ + typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type +#define BOOST_MOVE_CATCH_RVALUE(U)\ + typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(T), not_a_type>::type +#else +#define BOOST_MOVE_CATCH_CONST(U) BOOST_CATCH_CONST_RLVALUE(U) +#define BOOST_MOVE_CATCH_RVALUE(U) BOOST_RV_REF(U) +#endif + +// BEGIN JLH additional definitions... + +template< class T > struct remove_const_remove_reference { typedef T type; }; +template< class T > struct remove_const_remove_reference< const T > : remove_const_remove_reference { }; +template< class T > struct remove_const_remove_reference< volatile T > : remove_const_remove_reference { }; +template< class T > struct remove_const_remove_reference< const volatile T > : remove_const_remove_reference { }; +template< class T > struct remove_const_remove_reference< T& > : remove_const_remove_reference { }; +template< class T > struct remove_const_remove_reference< boost::rv > : remove_const_remove_reference { }; + +template< class T > struct add_reference_add_const { typedef T const & type; }; +template< class T > struct add_reference_add_const< T& > { typedef T& type; }; + +template< class T, class U > +struct is_same_sans_const_sans_reference + : boost::is_same< + typename remove_const_remove_reference::type, + typename remove_const_remove_reference::type + > +{ }; + +template< class T > struct add_lvalue_reference { typedef T& type; }; +template<> struct add_lvalue_reference< void > { typedef void type; }; +template<> struct add_lvalue_reference< const void > { typedef const void type; }; +template<> struct add_lvalue_reference< volatile void > { typedef volatile void type; }; +template<> struct add_lvalue_reference< const volatile void > { typedef const volatile void type; }; +template< class T > struct add_lvalue_reference< T& > { typedef T& type; }; +template< class T > struct add_lvalue_reference< boost::rv > { typedef T& type; }; +template< class T > struct add_lvalue_reference< const boost::rv > { typedef const T& type; }; +template< class T > struct add_lvalue_reference< volatile boost::rv > { typedef volatile T& type; }; +template< class T > struct add_lvalue_reference< const volatile boost::rv > { typedef const volatile T& type; }; +template< class T > struct add_lvalue_reference< boost::rv& > { typedef T& type; }; +template< class T > struct add_lvalue_reference< const boost::rv& > { typedef const T& type; }; +template< class T > struct add_lvalue_reference< volatile boost::rv& > { typedef volatile T& type; }; +template< class T > struct add_lvalue_reference< const volatile boost::rv& > { typedef const volatile T& type; }; + +template< class T > struct remove_rvalue_reference { typedef T type; }; +template< class T > struct remove_rvalue_reference< boost::rv > { typedef T type; }; +template< class T > struct remove_rvalue_reference< const boost::rv > { typedef T type; }; +template< class T > struct remove_rvalue_reference< volatile boost::rv > { typedef T type; }; +template< class T > struct remove_rvalue_reference< const volatile boost::rv > { typedef T type; }; +template< class T > struct remove_rvalue_reference< boost::rv& > { typedef T type; }; +template< class T > struct remove_rvalue_reference< const boost::rv& > { typedef T type; }; +template< class T > struct remove_rvalue_reference< volatile boost::rv& > { typedef T type; }; +template< class T > struct remove_rvalue_reference< const volatile boost::rv& > { typedef T type; }; + +template< class T > +struct add_rvalue_reference + : boost::mpl::if_< + boost::has_move_emulation_enabled, + boost::rv&, + T + > +{ }; + +template< class T > +struct remove_crv + : remove_rvalue_reference +{ }; +template< class T > +struct remove_crv< const T > + : remove_rvalue_reference +{ }; + +template< class T > +inline typename add_lvalue_reference::type +as_lvalue(T& x) +{ return x; } + +// END JLH additional definitions... + +template +class container +{ + typename ::boost::aligned_storage::value>::type storage_; + public: + + ConstructionType construction_type() const + { return construction_type_impl(typename ::boost::is_class::type()); } + ConstructionType construction_type_impl(::boost::true_type) const + { return reinterpret_cast(storage_).construction_type(); } + ConstructionType construction_type_impl(::boost::false_type) const + { return Copied; } + +#if 0 + + // Ion's original implementation + + void push_back(BOOST_MOVE_CATCH_CONST(T) x) + { return priv_push_back(static_cast(x)); } + + void push_back(BOOST_MOVE_CATCH_RVALUE(T) x) + { return priv_push_back(::boost::move(x)); } + + //Tricks for C++03 + #if defined(BOOST_NO_RVALUE_REFERENCES) + void push_back(T &x) + { priv_push_back(const_cast(x)); } + + template + typename ::boost::enable_if_c + < ::boost::is_class::value && + ::boost::is_same::value && + !::boost::has_move_emulation_enabled::value + >::type + push_back(const U &u) + { return priv_push_back(u); } + + template + typename ::boost::enable_if_c + < ::boost::is_class::value && + !::boost::is_same::value && + !::boost::move_detail::is_rv::value + >::type + push_back(const U &u) + { + T t(u); + priv_push_back(::boost::move(t)); + } + + #endif + + private: + template + void priv_push_back(BOOST_FWD_REF(U) x) + { new (&storage_) T(::boost::forward(x)); } + +#else // #if 0|1 + + // JLH's current implementation (roughly; only showing C++03 here) + + template< class U > + typename boost::disable_if< + is_same_sans_const_sans_reference + >::type + push_back(const U& x) { priv_push_back(as_lvalue(x)); } + template< class U > + void + push_back(U& x) { priv_push_back(x); } + + typedef typename add_reference_add_const< + typename add_rvalue_reference::type + >::type rv_param_type; + + void + push_back(rv_param_type x) { priv_push_back(x); } +private: + template< class U > + void + priv_push_back(U& x) { new (&storage_) T(x); } + +#endif // #if 0|1 +}; + + +int main() +{ + conversion_target_movable a; + conversion_target_movable b(::boost::move(a)); + { + container c; + { + conversion_target x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + const conversion_target x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_target()); + assert(c.construction_type() == Copied); + } + { + conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Copied); + assert(c.construction_type() == Other); + } + { + const conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Copied); + assert(c.construction_type() == Other); + } + { + c.push_back(conversion_source()); + //assert(c.construction_type() == Copied); + assert(c.construction_type() == Other); + } + } + + { + container c; + { + conversion_target_copymovable x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + const conversion_target_copymovable x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_target_copymovable()); + assert(c.construction_type() == Moved); + } + { + conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + { + const conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + { + c.push_back(conversion_source()); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + } + { + container c; + //This should not compile + //{ + // conversion_target_movable x; + // c.push_back(x); + // assert(c.construction_type() == Copied); + //} + //{ + // const conversion_target_movable x; + // c.push_back(x); + // assert(c.construction_type() == Copied); + //} + { + c.push_back(conversion_target_movable()); + assert(c.construction_type() == Moved); + } + { + conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + { + const conversion_source x; + c.push_back(x); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + { + c.push_back(conversion_source()); + //assert(c.construction_type() == Moved); + assert(c.construction_type() == Other); + } + } + { + container c; + { + int x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + const int x = 0; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + c.push_back(int(0)); + assert(c.construction_type() == Copied); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Copied); + } + } + + return 0; +} + +*/ \ No newline at end of file diff --git a/test/copy_elision_test.cpp b/test/copy_elision_test.cpp new file mode 100644 index 0000000..01bf212 --- /dev/null +++ b/test/copy_elision_test.cpp @@ -0,0 +1,170 @@ +// Copyright David Abrahams 2009. 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) + +#include + +#ifdef NO_MOVE +# undef BOOST_COPY_ASSIGN_REF +# define BOOST_COPY_ASSIGN_REF(X) X const& +# undef BOOST_COPYABLE_AND_MOVABLE +# define BOOST_COPYABLE_AND_MOVABLE(X) +# define MOVE(x) (x) +#else +#include +# define MOVE(x) boost::move(x) +#endif + +struct X +{ + X() : id(instances++) + { + std::cout << "X" << id << ": construct\n"; + } + + X(X const& rhs) : id(instances++) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n"; + ++copies; + } + + // This particular test doesn't exercise assignment, but for + // completeness: + X& operator=(BOOST_COPY_ASSIGN_REF(X) rhs) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": assign\n"; + return *this; + } + +#ifndef NO_MOVE + X& operator=(BOOST_RV_REF(X) rhs) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": move assign\n"; + return *this; + } + + X(BOOST_RV_REF(X) rhs) : id(instances++) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": ..move construct..\n"; + ++copies; + } +#endif + + ~X() { std::cout << "X" << id << ": destroy\n"; } + + unsigned id; + + static unsigned copies; + static unsigned instances; + + BOOST_COPYABLE_AND_MOVABLE(X) +}; + +unsigned X::copies = 0; +unsigned X::instances = 0; + +#define CHECK_COPIES( stmt, min, max, comment ) \ +{ \ + unsigned const old_copies = X::copies; \ + \ + std::cout << "\n" comment "\n" #stmt "\n===========\n"; \ + { \ + stmt; \ + } \ + unsigned const n = X::copies - old_copies; \ + if (n > max) \ + std::cout << "*** max is too low or compiler is buggy ***\n"; \ + if (n < min) \ + std::cout << "*** min is too high or compiler is buggy ***\n"; \ + \ + std::cout << "-----------\n" \ + << n << "/" << max \ + << " possible copies/moves made\n" \ + << max - n << "/" << max - min \ + << " possible elisions performed\n\n"; \ + \ + if (n > min) \ + std::cout << "*** " << n - min \ + << " possible elisions missed! ***\n"; \ +} + +struct trace +{ + trace(char const* name) + : name(name) + { + std::cout << "->: " << name << "\n"; + } + + ~trace() + { + std::cout << "<-: " << name << "\n"; + } + + char const* name; +}; + +void sink(X a) +{ + trace t("sink"); +} + +X nrvo_source() +{ + trace t("nrvo_source"); + X a; + return a; +} + +X urvo_source() +{ + trace t("urvo_source"); + return X(); +} + +X identity(X a) +{ + trace t("identity"); + return a; +} + +X lvalue_; +X& lvalue() +{ + return lvalue_; +} +typedef X rvalue; + +X ternary( bool y ) +{ + X a, b; + return MOVE(y?a:b); +} + +int main(int argc, char* argv[]) +{ + (void)argv; + // Double parens prevent "most vexing parse" + CHECK_COPIES( X a(( lvalue() )), 1, 1, "Direct initialization from lvalue"); + CHECK_COPIES( X a(( rvalue() )), 0, 1, "Direct initialization from rvalue"); + + CHECK_COPIES( X a = lvalue(), 1, 1, "Copy initialization from lvalue" ); + CHECK_COPIES( X a = rvalue(), 0, 1, "Copy initialization from rvalue" ); + + CHECK_COPIES( sink( lvalue() ), 1, 1, "Pass lvalue by value" ); + CHECK_COPIES( sink( rvalue() ), 0, 1, "Pass rvalue by value" ); + + CHECK_COPIES( nrvo_source(), 0, 1, "Named return value optimization (NRVO)" ); + CHECK_COPIES( urvo_source(), 0, 1, "Unnamed return value optimization (URVO)" ); + + // Just to prove these things compose properly + CHECK_COPIES( X a(urvo_source()), 0, 2, "Return value used as ctor arg" ); + + // Expect to miss one possible elision here + CHECK_COPIES( identity( rvalue() ), 0, 2, "Return rvalue passed by value" ); + + // Expect to miss an elision in at least one of the following lines + CHECK_COPIES( X a = ternary( argc == 1000 ), 0, 2, "Return result of ternary operation" ); + CHECK_COPIES( X a = ternary( argc != 1000 ), 0, 2, "Return result of ternary operation again" ); + return 0; +} diff --git a/test/copy_move_optimization.cpp b/test/copy_move_optimization.cpp new file mode 100644 index 0000000..10a0f20 --- /dev/null +++ b/test/copy_move_optimization.cpp @@ -0,0 +1,105 @@ +//We need to declare: +// +//2 conversions: rv & and const rv & +//1 rv & constructor: move constructor +//1 const rv & constructor: copy constructor +//1 T & constructor: copy constructor +// +//Optimization: +//Since RVO is better than move-construction, +//avoid copy constructor overloading. +#include +#include + +bool moved = false; + +class obj +{ + BOOST_COPYABLE_AND_MOVABLE(obj) + public: + + obj() + { + std::cout << "constructing obj" << "\n"; + } + + ~obj() + {} + + obj(const obj &) + { + std::cout << "copy construct from const obj" << "\n"; + } + + // copy construct from movable object (non-const rvalue, explicitly moved lvalue) + obj(BOOST_RV_REF(obj)) + { + std::cout << "move construct from movable rvalue" << "\n"; + } + + obj& operator =(BOOST_COPY_ASSIGN_REF(obj)) + { + std::cout << "copy assign from const obj" << "\n"; + return *this; + } + + obj& operator =(BOOST_RV_REF(obj)) + { + std::cout << "move assign from movable rvalue" << "\n"; + return *this; + } +}; + + +obj rvalue_func() { return obj(); } +const obj const_rvalue_func() { return obj(); } +obj& lvalue_func() { static obj o; return o; } +const obj& const_lvalue_func() { static obj o; return o; } + +obj produce() { return obj(); } + +void consume(obj){} + +int main() +{ + { consume(produce()); } + { obj o = produce(); } + { obj o(produce()); } + { + obj o1(rvalue_func()); + obj o2 = const_rvalue_func(); + obj o3 = lvalue_func(); + obj o4 = const_lvalue_func(); + // can't explicitly move temporaries + //obj o5 = boost::move(rvalue_func()); + obj o5; + //Maybe missed optimization: copied + o5 = rvalue_func(); + //Explicit forward works OK and optimized + o5 = boost::forward(rvalue_func()); + + obj o7 = boost::move(lvalue_func()); + obj o8 = boost::move(const_lvalue_func()); + + obj o; + o = rvalue_func(); + o = const_rvalue_func(); + o = lvalue_func(); + o = const_lvalue_func(); + // can't explicitly move temporaries + //o = boost::move(rvalue_func()); + o = boost::forward(rvalue_func()); + o = boost::move(const_rvalue_func()); + o = boost::move(lvalue_func()); + o = boost::move(const_lvalue_func()); + } + return 0; +} + +//We need to declare: +// +//2 conversions: rv & and const rv & +//1 rv & constructor: move constructor +//1 const rv & constructor: copy constructor +//1 T & constructor: copy constructor + diff --git a/test/move.cpp b/test/move.cpp new file mode 100644 index 0000000..e3e3790 --- /dev/null +++ b/test/move.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009. +// 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 +#include "../example/movable.hpp" +#include + +movable function(movable m) +{ + return movable(boost::move(m)); +} + +movable functionr(BOOST_RV_REF(movable) m) +{ + return movable(boost::move(m)); +} + +movable function2(movable m) +{ + return boost::move(m); +} + +BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m) +{ + return boost::move(m); +} + +movable move_return_function2 () +{ + return movable(); +} + +movable move_return_function () +{ + movable m; + return (boost::move(m)); +} + + +//Catch by value +void function_value(movable) +{} + +//Catch by reference +void function_ref(const movable &) +{} + +//Catch by reference +void function_ref(BOOST_RV_REF(movable)) +{} + +struct copyable +{}; + +movable create_movable() +{ return movable(); } +int main() +{ + #if defined(BOOST_NO_RVALUE_REFERENCES) + BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == true)); + BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); + #endif + + { + movable m; + movable m2(boost::move(m)); + movable m3(function(movable(boost::move(m2)))); + movable m4(function(boost::move(m3))); + } + { + movable m; + movable m2(boost::move(m)); + movable m3(functionr(movable(boost::move(m2)))); + movable m4(functionr(boost::move(m3))); + } + { + movable m; + movable m2(boost::move(m)); + movable m3(function2(movable(boost::move(m2)))); + movable m4(function2(boost::move(m3))); + } + { + movable m; + movable m2(boost::move(m)); + movable m3(function2r(movable(boost::move(m2)))); + movable m4(function2r(boost::move(m3))); + } + { + movable m; + movable m2(boost::move(m)); + movable m3(move_return_function()); + } + { + movable m; + movable m2(boost::move(m)); + movable m3(move_return_function2()); + } + //limitations_test(); + + return 0; +} diff --git a/test/move_algorithm.cpp b/test/move_algorithm.cpp new file mode 100644 index 0000000..86db155 --- /dev/null +++ b/test/move_algorithm.cpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009. +// 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 +#include +#include "../example/movable.hpp" + +int main() +{ + namespace bi = ::boost::interprocess; + //Default construct 10 movable objects + bi::vector v(10); + bi::vector v2(10); + + //Move to v2 + boost::move(v.begin(), v.end(), v2.begin()); + + //Test values have been moved + if(!v[0].moved()){ + return 1; + } + + if(v2.size() != 10){ + return 1; + } + + if(v2[0].moved()){ + return 1; + } + + //Move to v again + boost::move_backward(v2.begin(), v2.end(), v.end()); + + //Test values have been moved + if(!v2[0].moved()){ + return 1; + } + + if(v.size() != 10){ + return 1; + } + + if(v[0].moved()){ + return 1; + } + + return 0; +} diff --git a/test/move_iterator.cpp b/test/move_iterator.cpp new file mode 100644 index 0000000..05a524b --- /dev/null +++ b/test/move_iterator.cpp @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009. +// 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 +#include +#include "../example/movable.hpp" + +int main() +{ + namespace bi = ::boost::interprocess; + //Default construct 10 movable objects + bi::vector v(10); + + //Test default constructed value + if(v[0].moved()){ + return 1; + } + + //Move values + bi::vector v2 + (boost::make_move_iterator(v.begin()), boost::make_move_iterator(v.end())); + + //Test values have been moved + if(!v[0].moved()){ + return 1; + } + + if(v2.size() != 10){ + return 1; + } + + //Move again + v.assign(boost::make_move_iterator(v2.begin()), boost::make_move_iterator(v2.end())); + + //Test values have been moved + if(!v2[0].moved()){ + return 1; + } + + if(v[0].moved()){ + return 1; + } + + return 0; +} + +/* +#include + + +class copy_movable +{ + BOOST_COPYABLE_AND_MOVABLE(copy_movable) + int value_; + + public: + copy_movable() : value_(1){} + + //Move constructor and assignment + copy_movable(BOOST_RV_REF(copy_movable) m) + { value_ = m.value_; m.value_ = 0; } + + copy_movable(const copy_movable &m) + { value_ = m.value_; } + + copy_movable & operator=(BOOST_RV_REF(copy_movable) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m) + { value_ = m.value_; return *this; } + + bool moved() const //Observer + { return value_ == 0; } +}; + +struct copy_movable_wrapper +{ + copy_movable cm; +}; + +copy_movable produce() +{ return copy_movable(); } + + +int main() +{ + copy_movable cm; + cm = produce(); + + const copy_movable_wrapper cmw; + copy_movable_wrapper cmw2; + cmw2 = cmw; + + return 0; +} +*/ \ No newline at end of file From adfd0c6cad1c6977825118a4c323adfb2c3d3eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 29 Aug 2011 11:21:16 +0000 Subject: [PATCH 03/30] Fixes for clang + cleanup [SVN r74123] --- include/boost/move/move.hpp | 1065 ++++++++++++++++++----------------- 1 file changed, 535 insertions(+), 530 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 1d6b3d5..86cd032 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -15,589 +15,581 @@ #ifndef BOOST_MOVE_MOVE_HPP #define BOOST_MOVE_MOVE_HPP +/// @cond + #include + +#ifdef BOOST_MSVC + #ifndef _CRT_SECURE_NO_DEPRECATE + #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #define _SCL_SECURE_NO_WARNINGS + #endif + #pragma warning (push) + #pragma warning(disable:4996) +#endif + #include //copy, copy_backward #include //uninitialized_copy #include //std::iterator #define BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -#ifndef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif //#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -/// @cond +//If boost dependencies are avoided include all machinery +#if !defined(BOOST_MOVE_AVOID_BOOST_DEPENDENCIES) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include -#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -#define BOOST_MOVE_MPL_NS ::boost::move_detail -#define BOOST_MOVE_BOOST_NS ::boost::move_detail + #define BOOST_MOVE_MPL_NS ::boost::mpl + #define BOOST_MOVE_BOOST_NS ::boost #else -#define BOOST_MOVE_MPL_NS ::boost::mpl -#define BOOST_MOVE_BOOST_NS ::boost -#endif + #define BOOST_MOVE_MPL_NS ::boost::move_detail + #define BOOST_MOVE_BOOST_NS ::boost::move_detail +#endif //#ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES +//Small meta-typetraits to support move #ifdef BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -namespace boost { -namespace move_detail { + namespace boost { + namespace move_detail { -//if_ -template -struct if_c -{ - typedef T1 type; -}; - -template -struct if_c -{ - typedef T2 type; -}; - -template -struct if_ -{ - typedef typename if_c<0 != T1::value, T2, T3>::type type; -}; - -//enable_if_ -template -struct enable_if_c -{ - typedef T type; -}; - -template -struct enable_if_c {}; - -template -struct enable_if : public enable_if_c {}; - -template -struct disable_if : public enable_if_c {}; - -//integral_constant -template -struct integral_constant -{ - static const T value = v; - typedef T value_type; - typedef integral_constant type; -}; - -//identity -template -struct identity -{ - typedef T type; -}; - -//is_convertible -template -class is_convertible -{ - typedef char true_t; - class false_t { char dummy[2]; }; - static true_t dispatch(U); - static false_t dispatch(...); - static T trigger(); - public: - enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; -}; - -//and_ not_ -template > - struct and_ - : public integral_constant -{}; - -template - struct not_ - : public integral_constant -{}; - -//is_lvalue_reference -template -struct is_lvalue_reference - : public integral_constant -{}; - -template -struct is_lvalue_reference - : public integral_constant -{}; - -//has_trivial_destructor -template -struct has_trivial_destructor - : public integral_constant -{}; - -//addressof -template struct addr_impl_ref -{ - T & v_; - inline addr_impl_ref( T & v ): v_( v ) {} - inline operator T& () const { return v_; } - - private: - addr_impl_ref & operator=(const addr_impl_ref &); -}; - -template struct addressof_impl -{ - static inline T * f( T & v, long ) + //if_ + template + struct if_c { - return reinterpret_cast( - &const_cast(reinterpret_cast(v))); + typedef T1 type; + }; + + template + struct if_c + { + typedef T2 type; + }; + + template + struct if_ + { + typedef typename if_c<0 != T1::value, T2, T3>::type type; + }; + + //enable_if_ + template + struct enable_if_c + { + typedef T type; + }; + + template + struct enable_if_c {}; + + template + struct enable_if : public enable_if_c {}; + + template + struct disable_if : public enable_if_c {}; + + //integral_constant + template + struct integral_constant + { + static const T value = v; + typedef T value_type; + typedef integral_constant type; + }; + + //identity + template + struct identity + { + typedef T type; + }; + + //is_convertible + template + class is_convertible + { + typedef char true_t; + class false_t { char dummy[2]; }; + static true_t dispatch(U); + static false_t dispatch(...); + static T trigger(); + public: + enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; + }; + + //and_ not_ + template > + struct and_ + : public integral_constant + {}; + + template + struct not_ + : public integral_constant + {}; + + //is_lvalue_reference + template + struct is_lvalue_reference + : public integral_constant + {}; + + template + struct is_lvalue_reference + : public integral_constant + {}; + + //has_trivial_destructor + template + struct has_trivial_destructor + : public integral_constant + {}; + + //addressof + template struct addr_impl_ref + { + T & v_; + inline addr_impl_ref( T & v ): v_( v ) {} + inline operator T& () const { return v_; } + + private: + addr_impl_ref & operator=(const addr_impl_ref &); + }; + + template struct addressof_impl + { + static inline T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + static inline T * f( T * v, int ) + { return v; } + }; + + template T * addressof( T & v ) + { + return ::boost::move_detail::addressof_impl::f + ( ::boost::move_detail::addr_impl_ref( v ), 0 ); } - static inline T * f( T * v, int ) - { return v; } -}; - -template T * addressof( T & v ) -{ - return ::boost::move_detail::addressof_impl::f - ( ::boost::move_detail::addr_impl_ref( v ), 0 ); -} - -/* -typedef char one; -struct two {one _[2];}; - -template -struct is_base_of_host -{ - operator B*() const; - operator D*(); -}; - -template -struct is_base_of -{ - typedef char yes; - class no { char dummy[2]; }; - - template - static yes check(D*, T); - static no check(B*, int); - - static const bool value = sizeof(check(is_base_of_host(), int())) == sizeof(yes); -}; -*/ - -} //namespace move_detail { -} //namespace boost { + } //namespace move_detail { + } //namespace boost { #endif //BOOST_MOVE_AVOID_BOOST_DEPENDENCIES -/// @endcond - +//Compiler workaround detection #if !defined(BOOST_NO_RVALUE_REFERENCES) -#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) - -#ifndef BOOST_CLANG -#define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES -#endif - -#else - -#if defined(_MSC_VER) && (_MSC_VER == 1600) -#define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG -#endif - -#endif + #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__) + //Pre-standard rvalue binding rules + #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES + #elif defined(_MSC_VER) && (_MSC_VER == 1600) + //Standard rvalue binding rules but with some bugs + #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_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 + #endif #endif +/// @endcond #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) -#ifdef __GNUC__ -# define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) -#else -# define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS -#endif + //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers + #ifdef __GNUC__ + #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) + #else + #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS + #endif -namespace boost { + namespace boost { -////////////////////////////////////////////////////////////////////////////// -// -// struct rv -// -////////////////////////////////////////////////////////////////////////////// -template -class rv : public T -{ - rv(); - ~rv(); - rv(rv const&); - void operator=(rv const&); -} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS; + ////////////////////////////////////////////////////////////////////////////// + // + // struct rv + // + ////////////////////////////////////////////////////////////////////////////// + template + class rv : public T + { + rv(); + ~rv(); + rv(rv const&); + void operator=(rv const&); + } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS; -////////////////////////////////////////////////////////////////////////////// -// -// move_detail::is_rv -// -////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // move_detail::is_rv + // + ////////////////////////////////////////////////////////////////////////////// -namespace move_detail { + namespace move_detail { -template -struct is_rv - : BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct is_rv + : BOOST_MOVE_BOOST_NS::integral_constant + {}; -template -struct is_rv< rv > - : BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct is_rv< rv > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; -template -struct is_rv< const rv > - : BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct is_rv< const rv > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; -} //namespace move_detail { + } //namespace move_detail { -////////////////////////////////////////////////////////////////////////////// -// -// has_move_emulation_enabled -// -////////////////////////////////////////////////////////////////////////////// -template -struct has_move_emulation_enabled - : BOOST_MOVE_BOOST_NS::is_convertible< T, ::boost::rv& > -{}; + ////////////////////////////////////////////////////////////////////////////// + // + // has_move_emulation_enabled + // + ////////////////////////////////////////////////////////////////////////////// + template + struct has_move_emulation_enabled + : BOOST_MOVE_BOOST_NS::is_convertible< T, ::boost::rv& > + {}; -template -struct has_move_emulation_enabled - : BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct has_move_emulation_enabled + : BOOST_MOVE_BOOST_NS::integral_constant + {}; -template -struct has_move_emulation_enabled< ::boost::rv > - : BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct has_move_emulation_enabled< ::boost::rv > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; -template -struct has_nothrow_move - : public BOOST_MOVE_BOOST_NS::integral_constant -{}; + template + struct has_nothrow_move + : public BOOST_MOVE_BOOST_NS::integral_constant + {}; -////////////////////////////////////////////////////////////////////////////// -// -// move() -// -////////////////////////////////////////////////////////////////////////////// -template -typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) -{ - return x; -} + ////////////////////////////////////////////////////////////////////////////// + // + // move() + // + ////////////////////////////////////////////////////////////////////////////// + template + typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) + { + return x; + } -template -typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(T& x) -{ - return *static_cast* >(BOOST_MOVE_BOOST_NS::addressof(x)); -} + template + typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(T& x) + { + return *static_cast* >(BOOST_MOVE_BOOST_NS::addressof(x)); + } -template -typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(rv& x) -{ - return x; -} + template + typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(rv& x) + { + return x; + } -#define BOOST_RV_REF(TYPE)\ - ::boost::rv< TYPE >& \ -// + #define BOOST_RV_REF(TYPE)\ + ::boost::rv< TYPE >& \ + // -#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ - ::boost::rv< TYPE >& \ -// + #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + ::boost::rv< TYPE >& \ + // -#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - ::boost::rv< TYPE >& \ -// + #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + ::boost::rv< TYPE >& \ + // -#define BOOST_FWD_REF(TYPE)\ - const TYPE & \ -// + #define BOOST_FWD_REF(TYPE)\ + const TYPE & \ + // -#define BOOST_CATCH_CONST_RLVALUE(TYPE)\ - const ::boost::rv< TYPE >& \ -// + #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const ::boost::rv< TYPE >& \ + // -#define BOOST_COPY_ASSIGN_REF(TYPE)\ - const ::boost::rv< TYPE >& \ -// + #define BOOST_COPY_ASSIGN_REF(TYPE)\ + const ::boost::rv< TYPE >& \ + // -#define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ - const ::boost::rv< TYPE >& \ -// + #define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const ::boost::rv< TYPE >& \ + // -#define BOOST_MOVE_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - const ::boost::rv< TYPE >& \ -// + #define BOOST_MOVE_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + const ::boost::rv< TYPE >& \ + // -////////////////////////////////////////////////////////////////////////////// -// -// forward() -// -////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // forward() + // + ////////////////////////////////////////////////////////////////////////////// -template -typename BOOST_MOVE_BOOST_NS::enable_if< ::boost::move_detail::is_rv, T &>::type - forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) -{ - return const_cast(x); -} + template + typename BOOST_MOVE_BOOST_NS::enable_if< ::boost::move_detail::is_rv, T &>::type + forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) + { + return const_cast(x); + } -template -typename BOOST_MOVE_BOOST_NS::disable_if< ::boost::move_detail::is_rv, const T &>::type - forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) -{ - return x; -} + template + typename BOOST_MOVE_BOOST_NS::disable_if< ::boost::move_detail::is_rv, const T &>::type + forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) + { + return x; + } -////////////////////////////////////////////////////////////////////////////// -// -// BOOST_MOVABLE_BUT_NOT_COPYABLE -// -////////////////////////////////////////////////////////////////////////////// -#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ - private:\ - TYPE(TYPE &);\ - TYPE& operator=(TYPE &);\ - public:\ - operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ - operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ - private:\ -// + ////////////////////////////////////////////////////////////////////////////// + // + // BOOST_MOVABLE_BUT_NOT_COPYABLE + // + ////////////////////////////////////////////////////////////////////////////// + #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + private:\ + TYPE(TYPE &);\ + TYPE& operator=(TYPE &);\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ + // -////////////////////////////////////////////////////////////////////////////// -// -// BOOST_COPYABLE_AND_MOVABLE -// -////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // BOOST_COPYABLE_AND_MOVABLE + // + ////////////////////////////////////////////////////////////////////////////// -#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ - public:\ - TYPE& operator=(TYPE &t)\ - { this->operator=(static_cast &>(const_cast(t))); return *this;}\ - public:\ - operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ - operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ - private:\ -// + #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + public:\ + TYPE& operator=(TYPE &t)\ + { this->operator=(static_cast &>(const_cast(t))); return *this;}\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ + // -#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ - public:\ - operator ::boost::rv&() \ - { return *static_cast< ::boost::rv* >(this); }\ - operator const ::boost::rv&() const \ - { return *static_cast* >(this); }\ - private:\ -// + #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ + public:\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return *static_cast* >(this); }\ + private:\ + // -} //namespace boost + } //namespace boost #else //BOOST_NO_RVALUE_REFERENCES -#include + namespace boost{ -namespace boost { + //! By default this traits returns false. Classes with non-throwing move constructor + //! and assignment should specialize this trait to obtain some performance improvements. + template + struct has_nothrow_move + : public BOOST_MOVE_MPL_NS::integral_constant + {}; -//! By default this traits returns false. Classes with non-thworing move construction -//! and assignment should specialize this trait to obtain some performance improvements. -template -struct has_nothrow_move - : public BOOST_MOVE_MPL_NS::integral_constant -{}; + } // namespace boost{ -////////////////////////////////////////////////////////////////////////////// -// -// move -// -////////////////////////////////////////////////////////////////////////////// + #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + #include + + namespace boost{ + + using ::std::move; + using ::std::forward; + using ::std::move_backward; + + } //namespace boost + + #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE + + #include + + namespace boost { + + ////////////////////////////////////////////////////////////////////////////// + // + // move + // + ////////////////////////////////////////////////////////////////////////////// + + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! This function provides a way to convert a reference into a rvalue reference + //! in compilers with rvalue references. For other compilers converts T & into + //! ::boost::rv & so that move emulation is activated. + template inline + rvalue_reference move (input_reference); + + #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + + //Old move approach, lvalues could bind to rvalue references + template inline + typename remove_reference::type && move(T&& t) + { return t; } + + #else //Old move + + template inline + typename remove_reference::type && move(T&& t) + { return static_cast::type &&>(t); } + + #endif //Old move + + ////////////////////////////////////////////////////////////////////////////// + // + // forward + // + ////////////////////////////////////////////////////////////////////////////// -#if defined(BOOST_MOVE_DOXYGEN_INVOKED) -//! This function provides a way to convert a reference into a rvalue reference -//! in compilers with rvalue references. For other compilers converts T & into -//! ::boost::rv & so that move emulation is activated. -template inline -rvalue_reference move (input_reference); + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! This function provides limited form of forwarding that is usually enough for + //! in-place construction and avoids the exponential overloading necessary for + //! perfect forwarding in C++03. + //! + //! For compilers with rvalue references this function provides perfect forwarding. + //! + //! Otherwise: + //! * If input_reference binds to const ::boost::rv & then it output_reference is + //! ::boost::rev & + //! + //! * Else, input_reference is equal to output_reference is equal to input_reference. + template inline output_reference forward(input_reference); + #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) -#else //BOOST_MOVE_DOXYGEN_INVOKED + //Old move approach, lvalues could bind to rvalue references -#if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + template inline + T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) + { return t; } -//Old move approach, lvalues could bind to rvalue references -template inline -typename remove_reference::type && move(T&& t) -{ return t; } + #else //Old move -#else //Old move + //Implementation #5 from N2951, thanks to Howard Hinnant -template inline -typename remove_reference::type && move(T&& t) -{ return static_cast::type &&>(t); } + template + inline T&& forward(U&& t + , typename BOOST_MOVE_BOOST_NS::enable_if_c< + move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* + , typename BOOST_MOVE_BOOST_NS::enable_if_c< + move_detail::is_convertible + ::type*, typename remove_reference::type*>::value>::type * = 0*/) + { return static_cast(t); } -#endif //Old move + #endif //BOOST_MOVE_DOXYGEN_INVOKED -#endif //BOOST_MOVE_DOXYGEN_INVOKED + } //namespace boost { + #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) -////////////////////////////////////////////////////////////////////////////// -// -// forward -// -////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // BOOST_ENABLE_MOVE_EMULATION + // + ////////////////////////////////////////////////////////////////////////////// + ///@cond -#if defined(BOOST_MOVE_DOXYGEN_INVOKED) -//! This function provides limited form of forwarding that is usually enough for -//! in-place construction and avoids the exponential overloading necessary for -//! perfect forwarding in C++03. -//! -//! For compilers with rvalue references this function provides perfect forwarding. -//! -//! Otherwise: -//! * If input_reference binds to const ::boost::rv & then it output_reference is -//! ::boost::rev & -//! -//! * Else, input_reference is equal to output_reference is equal to input_reference. -template inline output_reference forward(input_reference); + #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ + typedef int boost_move_emulation_t; + \ + // -#else + /// @endcond -#if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) + //! This macro marks a type as movable but not copyable, disabling copy construction + //! and assignment. The user will need to write a move constructor/assignment as explained + //! in the documentation to fully write a movable but not copyable class. + #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + public:\ + typedef int boost_move_emulation_t;\ + private:\ + TYPE(const TYPE &);\ + TYPE& operator=(const TYPE &);\ + // -//Old move approach, lvalues could bind to rvalue references + //! This macro marks a type as copyable and movable. + //! The user will need to write a move constructor/assignment and a copy assignment + //! as explained in the documentation to fully write a copyable and movable class. + #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + // -template inline -T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) -{ return t; } + /// @cond -#else //Old move + #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + TYPE && \ + // -//Implementation #5 from N2951, thanks to Howard Hinnant + #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE && \ + // -template -inline T&& forward(U&& t - , typename BOOST_MOVE_BOOST_NS::enable_if_c< - move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* - , typename BOOST_MOVE_BOOST_NS::enable_if_c< - move_detail::is_convertible - ::type*, typename remove_reference::type*>::value>::type * = 0*/) -{ return static_cast(t); } + /// @endcond -#endif //Old move + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE + #define BOOST_RV_REF(TYPE)\ + TYPE && \ + // -#endif //BOOST_MOVE_DOXYGEN_INVOKED + //!This macro is used to achieve portable syntax in copy + //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. + #define BOOST_COPY_ASSIGN_REF(TYPE)\ + const TYPE & \ + // -////////////////////////////////////////////////////////////////////////////// -// -// BOOST_ENABLE_MOVE_EMULATION -// -////////////////////////////////////////////////////////////////////////////// + /// @cond -///@cond + #define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const TYPE & \ + // -#define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ - typedef int boost_move_emulation_t; -\ -// + #define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE& \ + // -/// @endcond + /// @endcond -//! This macro marks a type as movable but not copyable, disabling copy construction -//! and assignment. The user will need to write a move constructor/assignment as explained -//! in the documentation to fully write a movable but not copyable class. -#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ - public:\ - typedef int boost_move_emulation_t;\ - private:\ - TYPE(const TYPE &);\ - TYPE& operator=(const TYPE &);\ -// + //! This macro is used to implement portable perfect forwarding + //! as explained in the documentation. + #define BOOST_FWD_REF(TYPE)\ + TYPE && \ + // -//! This macro marks a type as copyable and movable. -//! The user will need to write a move constructor/assignment and a copy assignment -//! as explained in the documentation to fully write a copyable and movable class. -#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ -// + /// @cond -/// @cond + #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const TYPE & \ + // -#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ - TYPE && \ -// - -#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - TYPE && \ -// - -/// @endcond - -//!This macro is used to achieve portable syntax in move -//!constructors and assignments for classes marked as -//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE -#define BOOST_RV_REF(TYPE)\ - TYPE && \ -// - -//!This macro is used to achieve portable syntax in copy -//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. -#define BOOST_COPY_ASSIGN_REF(TYPE)\ - const TYPE & \ -// - -/// @cond - -#define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ - const TYPE & \ -// - -#define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - TYPE& \ -// - -/// @endcond - -//! This macro is used to implement portable perfect forwarding -//! as explained in the documentation. -#define BOOST_FWD_REF(TYPE)\ - TYPE && \ -// - -/// @cond - -#define BOOST_CATCH_CONST_RLVALUE(TYPE)\ - const TYPE & \ -// - -/// @endcond - -} //namespace boost { + /// @endcond #endif //BOOST_NO_RVALUE_REFERENCES @@ -866,53 +858,56 @@ inline move_insert_iterator move_inserter(C& x, typename C::iterator it) // ////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) -//! Effects: Moves elements in the range [first,last) into the range [result,result + (last - -//! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first), -//! performs *(result + n) = ::boost::move (*(first + n)). -//! -//! Effects: result + (last - first). -//! -//! Requires: result shall not be in the range [first,last). -//! -//! Complexity: Exactly last - first move assignments. -template // O models OutputIterator -O move(I f, I l, O result) -{ - while (f != l) { - *result = ::boost::move(*f); - ++f; ++result; + //! Effects: Moves elements in the range [first,last) into the range [result,result + (last - + //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first), + //! performs *(result + n) = ::boost::move (*(first + n)). + //! + //! Effects: result + (last - first). + //! + //! Requires: result shall not be in the range [first,last). + //! + //! Complexity: Exactly last - first move assignments. + template // O models OutputIterator + O move(I f, I l, O result) + { + while (f != l) { + *result = ::boost::move(*f); + ++f; ++result; + } + return result; } - return result; -} -////////////////////////////////////////////////////////////////////////////// -// -// move_backward -// -////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // move_backward + // + ////////////////////////////////////////////////////////////////////////////// -//! Effects: Moves elements in the range [first,last) into the range -//! [result - (last-first),result) starting from last - 1 and proceeding to -//! first. For each positive integer n <= (last - first), -//! performs *(result - n) = ::boost::move(*(last - n)). -//! -//! Requires: result shall not be in the range [first,last). -//! -//! Returns: result - (last - first). -//! -//! Complexity: Exactly last - first assignments. -template // O models BidirectionalIterator -O move_backward(I f, I l, O result) -{ - while (f != l) { - --l; --result; - *result = ::boost::move(*l); + //! Effects: Moves elements in the range [first,last) into the range + //! [result - (last-first),result) starting from last - 1 and proceeding to + //! first. For each positive integer n <= (last - first), + //! performs *(result - n) = ::boost::move(*(last - n)). + //! + //! Requires: result shall not be in the range [first,last). + //! + //! Returns: result - (last - first). + //! + //! Complexity: Exactly last - first assignments. + template // O models BidirectionalIterator + O move_backward(I f, I l, O result) + { + while (f != l) { + --l; --result; + *result = ::boost::move(*l); + } + return result; } - return result; -} + +#endif //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) ////////////////////////////////////////////////////////////////////////////// // @@ -956,6 +951,7 @@ F uninitialized_move(I f, I l, F r, return std::uninitialized_copy(f, l, r); } */ + ////////////////////////////////////////////////////////////////////////////// // // uninitialized_copy_or_move @@ -1098,4 +1094,13 @@ struct has_trivial_destructor_after_move } //namespace boost { +#if defined BOOST_MSVC + #pragma warning (pop) + #ifdef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef _CRT_SECURE_NO_DEPRECATE + #undef _SCL_SECURE_NO_WARNINGS + #endif +#endif + #endif //#ifndef BOOST_MOVE_MOVE_HPP From 8424c90dd407800c8caf05bdf4d3cb6d54d1e049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 29 Aug 2011 11:21:26 +0000 Subject: [PATCH 04/30] Fixes for clang + cleanup [SVN r74124] --- proj/vc7ide/Move.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/proj/vc7ide/Move.sln b/proj/vc7ide/Move.sln index 68e086e..894918a 100644 --- a/proj/vc7ide/Move.sln +++ b/proj/vc7ide/Move.sln @@ -132,6 +132,7 @@ Global ..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2 ..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp ..\..\doc\move.qbk = ..\..\doc\move.qbk + ..\..\..\..\boost\move\move_helpers.hpp = ..\..\..\..\boost\move\move_helpers.hpp EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection From e165c644b4c845a8404b4cb06be9cefce21c5c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 16 Oct 2011 16:45:41 +0000 Subject: [PATCH 05/30] Minor bugfix in is_convertible [SVN r74973] --- include/boost/move/move.hpp | 6 +++--- include/boost/move/move_helpers.hpp | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 86cd032..0a289fc 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -121,7 +121,7 @@ class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); - static T trigger(); + static T &trigger(); public: enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; }; @@ -718,13 +718,13 @@ namespace move_detail { template struct is_move_iterator - : public BOOST_MOVE_MPL_NS::integral_constant + : public BOOST_MOVE_BOOST_NS::integral_constant { }; template struct is_move_iterator< ::boost::move_iterator > - : public BOOST_MOVE_MPL_NS::integral_constant + : public BOOST_MOVE_BOOST_NS::integral_constant { }; diff --git a/include/boost/move/move_helpers.hpp b/include/boost/move/move_helpers.hpp index 92e052e..eaf51d6 100644 --- a/include/boost/move/move_helpers.hpp +++ b/include/boost/move/move_helpers.hpp @@ -27,9 +27,9 @@ #if defined(BOOST_NO_RVALUE_REFERENCES) struct not_a_type; #define BOOST_MOVE_CATCH_CONST(U) \ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type + typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type #define BOOST_MOVE_CATCH_RVALUE(U)\ - typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(T), not_a_type>::type + typename ::boost::mpl::if_< ::boost::is_class, BOOST_RV_REF(U), not_a_type>::type #define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U) #else #define BOOST_MOVE_CATCH_CONST(U) const U & @@ -60,9 +60,9 @@ struct not_a_type; \ template\ typename ::boost::enable_if_c\ - < ::boost::is_class::value &&\ - !::boost::is_same::value &&\ - !::boost::move_detail::is_rv::value\ + < (!::boost::is_class::value || \ + !::boost::move_detail::is_rv::value) && \ + !::boost::is_same::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -127,9 +127,9 @@ struct not_a_type; \ template\ typename ::boost::enable_if_c\ - < ::boost::is_class::value &&\ - !::boost::is_same::value &&\ - !::boost::move_detail::is_rv::value\ + < (!::boost::is_class::value || \ + !::boost::move_detail::is_rv::value) && \ + !::boost::is_same::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ From 6f393bd4d6630b936a87555d9bad97ab5aead000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 16 Oct 2011 16:47:28 +0000 Subject: [PATCH 06/30] Doxygen documentation fixes [SVN r74974] --- include/boost/move/move.hpp | 58 +++++++++++++++---------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 0a289fc..87d63c6 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_MOVE_MOVE_HPP #define BOOST_MOVE_MOVE_HPP +#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + /// @cond #include @@ -206,6 +208,8 @@ /// @endcond +#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers @@ -508,21 +512,6 @@ #endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) - ////////////////////////////////////////////////////////////////////////////// - // - // BOOST_ENABLE_MOVE_EMULATION - // - ////////////////////////////////////////////////////////////////////////////// - - ///@cond - - #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ - typedef int boost_move_emulation_t; - \ - // - - /// @endcond - //! This macro marks a type as movable but not copyable, disabling copy construction //! and assignment. The user will need to write a move constructor/assignment as explained //! in the documentation to fully write a movable but not copyable class. @@ -540,18 +529,9 @@ #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ // - /// @cond - - #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ - TYPE && \ + #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ // - #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - TYPE && \ - // - - /// @endcond - //!This macro is used to achieve portable syntax in move //!constructors and assignments for classes marked as //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE @@ -565,8 +545,24 @@ const TYPE & \ // + //! This macro is used to implement portable perfect forwarding + //! as explained in the documentation. + #define BOOST_FWD_REF(TYPE)\ + TYPE && \ + // + + + #if !defined(BOOST_MOVE_DOXYGEN_INVOKED) /// @cond + #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + TYPE && \ + // + + #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE && \ + // + #define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ const TYPE & \ // @@ -575,22 +571,14 @@ TYPE& \ // - /// @endcond - - //! This macro is used to implement portable perfect forwarding - //! as explained in the documentation. - #define BOOST_FWD_REF(TYPE)\ - TYPE && \ - // - - /// @cond - #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ const TYPE & \ // /// @endcond + #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + #endif //BOOST_NO_RVALUE_REFERENCES namespace boost { From b42013fcb115ce2caadee42798299c178e3a8a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 16 Oct 2011 16:50:47 +0000 Subject: [PATCH 07/30] Doxygen documentation fixes [SVN r74977] --- doc/Jamfile.v2 | 2 +- doc/move.qbk | 8 ++++---- example/doc_clone_ptr.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index f970d61..55c1702 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -13,7 +13,7 @@ import quickbook ; doxygen autodoc : - [ glob ../../../boost/move/*.hpp ] + [ glob ../../../boost/move/move.hpp ] : HIDE_UNDOC_MEMBERS=YES HIDE_UNDOC_MEMBERS=YES diff --git a/doc/move.qbk b/doc/move.qbk index 1275a56..5cc8a99 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -717,10 +717,10 @@ operators to references to `::boost::rv`: #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ public:\ - operator ::BOOST_MOVE_NAMESPACE::rv&() \ - { return *reinterpret_cast< ::BOOST_MOVE_NAMESPACE::rv* >(this); }\ - operator const ::BOOST_MOVE_NAMESPACE::rv&() const \ - { return *reinterpret_cast* >(this); }\ + operator ::boost::rv&() \ + { return *static_cast< ::boost::rv* >(this); }\ + operator const ::boost::rv&() const \ + { return static_cast* >(this); }\ private:\ //More stuff... diff --git a/example/doc_clone_ptr.cpp b/example/doc_clone_ptr.cpp index e86e64b..280c94c 100644 --- a/example/doc_clone_ptr.cpp +++ b/example/doc_clone_ptr.cpp @@ -18,7 +18,7 @@ class Base public: Base(){} - // Compiler-generated copy constructor... + Base(const Base &x) {/**/} // Copy ctor Base(BOOST_RV_REF(Base) x) {/**/} // Move ctor From d15998c78ae62fc43fc7f9b509bb9f2d7ba462bc Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 4 Nov 2011 02:31:36 +0000 Subject: [PATCH 08/30] Merge to release several changes for 1.48. [SVN r75293] --- index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 0000000..2534bef --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + +Automatic redirection failed, please go to +../../doc/html/move.html + + From 2f04e9e5064a2b9cbb76ea1a889a5f5f7c38995d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 26 Dec 2011 17:10:27 +0000 Subject: [PATCH 09/30] Changes for 1.49 [SVN r76179] --- include/boost/move/move.hpp | 113 ++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 87d63c6..2330a5c 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -23,9 +23,12 @@ #ifdef BOOST_MSVC #ifndef _CRT_SECURE_NO_DEPRECATE - #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #define _CRT_SECURE_NO_DEPRECATE - #define _SCL_SECURE_NO_WARNINGS + #define BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #endif + #ifndef _SCL_SECURE_NO_WARNINGS + #define BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #define _SCL_SECURE_NO_WARNINGS #endif #pragma warning (push) #pragma warning(disable:4996) @@ -1080,14 +1083,112 @@ struct has_trivial_destructor_after_move : BOOST_MOVE_BOOST_NS::has_trivial_destructor {}; + + +namespace move_detail { + +// Code from Jeffrey Lee Hellrung, many thanks + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T> struct forward_type { typedef T type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T> + struct forward_type + { typedef const T &type; }; + + template< class T> + struct forward_type< boost::rv > + { typedef T type; }; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + + + +// Code from Jeffrey Lee Hellrung, many thanks + +template< class T > struct is_rvalue_reference : BOOST_MOVE_BOOST_NS::integral_constant { }; +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct is_rvalue_reference< T&& > : BOOST_MOVE_BOOST_NS::integral_constant { }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct is_rvalue_reference< boost::rv& > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; + + template< class T > struct is_rvalue_reference< const boost::rv& > + : BOOST_MOVE_BOOST_NS::integral_constant + {}; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct add_rvalue_reference { typedef T&& type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + namespace detail_add_rvalue_reference + { + template< class T + , bool emulation = ::boost::has_move_emulation_enabled::value + , bool rv = ::boost::move_detail::is_rv::value > + struct add_rvalue_reference_impl { typedef T type; }; + + template< class T, bool emulation> + struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; }; + + template< class T, bool rv > + struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv& type; }; + } // namespace detail_add_rvalue_reference + + template< class T > + struct add_rvalue_reference + : detail_add_rvalue_reference::add_rvalue_reference_impl + { }; + + template< class T > + struct add_rvalue_reference + { typedef T & type; }; + +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +template< class T > struct remove_rvalue_reference { typedef T type; }; + +#ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< T&& > { typedef T type; }; +#else // #ifndef BOOST_NO_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES + +template +typename boost::move_detail::add_rvalue_reference::type declval(); + +} +// Ideas from Boost.Move review, Jeffrey Lee Hellrung: +// +//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? +// Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue +// references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than +// rv& (since T&& & -> T&). +// +//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? +// +//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated +// rvalue references in C++03. This may be necessary to prevent "accidental moves". + } //namespace boost { #if defined BOOST_MSVC #pragma warning (pop) #ifdef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE - #undef _CRT_SECURE_NO_DEPRECATE - #undef _SCL_SECURE_NO_WARNINGS + #undef BOOST_INTERPROCESS_CRT_SECURE_NO_DEPRECATE + #undef _CRT_SECURE_NO_DEPRECATE + #endif + + #ifdef BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #undef BOOST_INTERPROCESS_SCL_SECURE_NO_WARNINGS + #undef _SCL_SECURE_NO_WARNINGS #endif #endif From bb3285fb053faca53421ee3fda77feabeda01e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 26 Dec 2011 17:25:27 +0000 Subject: [PATCH 10/30] Changes for 1.49 [SVN r76183] --- doc/move.qbk | 16 ++++++++++++++-- index.html | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/doc/move.qbk b/doc/move.qbk index 5cc8a99..b542d12 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -49,7 +49,7 @@ proceed to overwrite the old copy. Consider: [c++] - template swap(T& a, T& b) + template void swap(T& a, T& b) { T tmp(a); // now we have two copies of a a = b; // now we have two copies of b @@ -60,7 +60,7 @@ But, we didn't want to have any copies of a or b, we just wanted to swap them. L [c++] - template swap(T& a, T& b) + template void swap(T& a, T& b) { T tmp(::boost::move(a)); a = ::boost::move(b); @@ -785,4 +785,16 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [endsect] +[section:release_notes Release Notes] + +[section:release_notes_boost_1_49_00 Boost 1.49 Release] + +* Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/6185 #6185], + [@https://svn.boost.org/trac/boost/ticket/6183 #6183]. + +[endsect] + +[endsect] + [xinclude autodoc.xml] diff --git a/index.html b/index.html index 2534bef..cb02a37 100644 --- a/index.html +++ b/index.html @@ -5,10 +5,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> - + -Automatic redirection failed, please go to +Automatic redirection failed, please go to ../../doc/html/move.html From 61329a7c3870f3cf38f33bd47245dc62b17fc23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 3 Jan 2012 22:03:56 +0000 Subject: [PATCH 11/30] Merged changeset 76271 https://svn.boost.org/trac/boost/changeset/76271 [SVN r76299] --- include/boost/move/move.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 2330a5c..4a0f158 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -283,6 +283,10 @@ : BOOST_MOVE_BOOST_NS::integral_constant {}; + template + struct has_move_emulation_enabled_aux + : has_move_emulation_enabled {}; + template struct has_nothrow_move : public BOOST_MOVE_BOOST_NS::integral_constant @@ -293,8 +297,9 @@ // move() // ////////////////////////////////////////////////////////////////////////////// + template - typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) + typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) { return x; } From fcc47ebe1ec0450762d55b66f8fe3ef6cfc9fa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 15 Jan 2012 11:09:47 +0000 Subject: [PATCH 12/30] Bug #6395: Some trivial functions aren't declared inline [SVN r76506] --- include/boost/move/move.hpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 4a0f158..284c58e 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -182,7 +182,8 @@ { return v; } }; - template T * addressof( T & v ) + template + inline T * addressof( T & v ) { return ::boost::move_detail::addressof_impl::f ( ::boost::move_detail::addr_impl_ref( v ), 0 ); @@ -299,19 +300,19 @@ ////////////////////////////////////////////////////////////////////////////// template - typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) + inline typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) { return x; } template - typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(T& x) + inline typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(T& x) { return *static_cast* >(BOOST_MOVE_BOOST_NS::addressof(x)); } template - typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(rv& x) + inline typename BOOST_MOVE_BOOST_NS::enable_if, rv&>::type move(rv& x) { return x; } @@ -356,14 +357,14 @@ ////////////////////////////////////////////////////////////////////////////// template - typename BOOST_MOVE_BOOST_NS::enable_if< ::boost::move_detail::is_rv, T &>::type + inline typename BOOST_MOVE_BOOST_NS::enable_if< ::boost::move_detail::is_rv, T &>::type forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) { return const_cast(x); } template - typename BOOST_MOVE_BOOST_NS::disable_if< ::boost::move_detail::is_rv, const T &>::type + inline typename BOOST_MOVE_BOOST_NS::disable_if< ::boost::move_detail::is_rv, const T &>::type forward(const typename BOOST_MOVE_MPL_NS::identity::type &x) { return x; @@ -462,13 +463,13 @@ //Old move approach, lvalues could bind to rvalue references template inline - typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) { return t; } #else //Old move template inline - typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) { return static_cast::type &&>(t); } #endif //Old move @@ -498,7 +499,7 @@ //Old move approach, lvalues could bind to rvalue references template inline - T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) + inline T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) { return t; } #else //Old move @@ -735,7 +736,7 @@ struct is_move_iterator< ::boost::move_iterator > //! //! Returns: move_iterator(i). template -move_iterator make_move_iterator(const It &it) +inline move_iterator make_move_iterator(const It &it) { return move_iterator(it); } ////////////////////////////////////////////////////////////////////////////// @@ -959,7 +960,7 @@ namespace move_detail { template // F models ForwardIterator -F uninitialized_move_move_iterator(I f, I l, F r +inline F uninitialized_move_move_iterator(I f, I l, F r // ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 ) { @@ -980,7 +981,7 @@ F uninitialized_move_move_iterator(I f, I l, F r, template // F models ForwardIterator -F uninitialized_copy_or_move(I f, I l, F r, +inline F uninitialized_copy_or_move(I f, I l, F r, typename BOOST_MOVE_BOOST_NS::enable_if< move_detail::is_move_iterator >::type* = 0) { return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r); @@ -997,7 +998,7 @@ namespace move_detail { template // F models ForwardIterator -F move_move_iterator(I f, I l, F r +inline F move_move_iterator(I f, I l, F r // ,typename BOOST_MOVE_BOOST_NS::enable_if< has_move_emulation_enabled >::type* = 0 ) { @@ -1019,7 +1020,7 @@ F move_move_iterator(I f, I l, F r, template // F models ForwardIterator -F copy_or_move(I f, I l, F r, +inline F copy_or_move(I f, I l, F r, typename BOOST_MOVE_BOOST_NS::enable_if< move_detail::is_move_iterator >::type* = 0) { return ::boost::move_detail::move_move_iterator(f, l, r); @@ -1042,7 +1043,7 @@ F copy_or_move(I f, I l, F r, template // F models ForwardIterator -F uninitialized_copy_or_move(I f, I l, F r +inline F uninitialized_copy_or_move(I f, I l, F r /// @cond ,typename BOOST_MOVE_BOOST_NS::disable_if< move_detail::is_move_iterator >::type* = 0 /// @endcond @@ -1065,7 +1066,7 @@ F uninitialized_copy_or_move(I f, I l, F r template // F models ForwardIterator -F copy_or_move(I f, I l, F r +inline F copy_or_move(I f, I l, F r /// @cond ,typename BOOST_MOVE_BOOST_NS::disable_if< move_detail::is_move_iterator >::type* = 0 /// @endcond From 7c1dcd51f6c4931ac3f446cb50e9c6b84e47baa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 15 Jan 2012 12:25:12 +0000 Subject: [PATCH 13/30] Ticket #6396: Implicit instanciation of boost::rv for non-cass types generates an error [SVN r76509] --- include/boost/move/move.hpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 284c58e..4d510f4 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -225,13 +225,32 @@ namespace boost { + namespace move_detail { + template + struct is_class_or_union + { + struct twochar { char _[2]; }; + template + static char is_class_or_union_tester(void(U::*)(void)); + template + static twochar is_class_or_union_tester(...); + static const bool value = sizeof(is_class_or_union_tester(0)) == sizeof(char); + }; + struct empty{}; + } + ////////////////////////////////////////////////////////////////////////////// // // struct rv // ////////////////////////////////////////////////////////////////////////////// template - class rv : public T + class rv + : public BOOST_MOVE_MPL_NS::if_c + < ::boost::move_detail::is_class_or_union::value + , T + , ::boost::move_detail::empty + >::type { rv(); ~rv(); @@ -239,6 +258,8 @@ void operator=(rv const&); } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS; + + ////////////////////////////////////////////////////////////////////////////// // // move_detail::is_rv From cf7642a84ec0ddbd17e11ffa89546d0022dd4f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 15 Jan 2012 12:29:10 +0000 Subject: [PATCH 14/30] Updated changelog for 1.49 [SVN r76510] --- doc/move.qbk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/move.qbk b/doc/move.qbk index b542d12..b029ae0 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -790,8 +790,10 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes_boost_1_49_00 Boost 1.49 Release] * Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/6183 #6183], [@https://svn.boost.org/trac/boost/ticket/6185 #6185], - [@https://svn.boost.org/trac/boost/ticket/6183 #6183]. + [@https://svn.boost.org/trac/boost/ticket/6395 #6395], + [@https://svn.boost.org/trac/boost/ticket/6396 #6396], [endsect] From 2c4dbd10d22d79f9fc61b218519bb57376b7a671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 16 Jan 2012 21:24:46 +0000 Subject: [PATCH 15/30] Fixed double inline [SVN r76547] --- include/boost/move/move.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 4d510f4..1f89d03 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -477,19 +477,19 @@ //! This function provides a way to convert a reference into a rvalue reference //! in compilers with rvalue references. For other compilers converts T & into //! ::boost::rv & so that move emulation is activated. - template inline + template rvalue_reference move (input_reference); #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references - template inline + template inline typename remove_reference::type && move(T&& t) { return t; } #else //Old move - template inline + template inline typename remove_reference::type && move(T&& t) { return static_cast::type &&>(t); } @@ -514,12 +514,12 @@ //! ::boost::rev & //! //! * Else, input_reference is equal to output_reference is equal to input_reference. - template inline output_reference forward(input_reference); + template output_reference forward(input_reference); #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references - template inline + template inline T&& forward (typename BOOST_MOVE_MPL_NS::identity::type&& t) { return t; } From 8c694c23b9f0dfb3aefc255857af3540dea74968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Wed, 18 Jan 2012 20:49:00 +0000 Subject: [PATCH 16/30] Added fixed bugs to changeset in container/interprocess/intrusive/move [SVN r76579] --- doc/move.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/move.qbk b/doc/move.qbk index b029ae0..bd90baa 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -790,6 +790,7 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes_boost_1_49_00 Boost 1.49 Release] * Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/6417 #6417], [@https://svn.boost.org/trac/boost/ticket/6183 #6183], [@https://svn.boost.org/trac/boost/ticket/6185 #6185], [@https://svn.boost.org/trac/boost/ticket/6395 #6395], From 528233d0e96d387d5fdb8828eb4509a00a78842a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 11 Feb 2012 18:29:50 +0000 Subject: [PATCH 17/30] Ticket #6519: Image files corrupted due to some cr lf conversion. [SVN r76983] --- doc/html/images/blank.png | Bin 392 -> 374 bytes doc/html/images/caution.png | Bin 1253 -> 1250 bytes doc/html/images/draft.png | Bin 17539 -> 17454 bytes doc/html/images/home.png | Bin 361 -> 358 bytes doc/html/images/important.png | Bin 726 -> 722 bytes doc/html/images/next.png | Bin 342 -> 336 bytes doc/html/images/note.png | Bin 495 -> 490 bytes doc/html/images/prev.png | Bin 338 -> 334 bytes doc/html/images/tip.png | Bin 456 -> 449 bytes doc/html/images/toc-blank.png | Bin 321 -> 318 bytes doc/html/images/toc-minus.png | Bin 262 -> 259 bytes doc/html/images/toc-plus.png | Bin 267 -> 264 bytes doc/html/images/warning.png | Bin 1244 -> 1241 bytes 13 files changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/html/images/blank.png b/doc/html/images/blank.png index c387d424b21d641808bf44ca19f001bb7fde5d78..764bf4f0c3bb4a09960b04b6fa9c9024bca703bc 100644 GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4kiW$2A`O3a~K#HSkfJR9T^xl_H+M9WMyDr z)b(_645^s&_M)R8g96V1g9H1Y`?|@Qa8+HmHda4(nQ?zM!!?FAj1kNm*b;aTNHv%; cj9>w=gf!;AOne?`3=9kmp00i_>zopr0BeCVqjos0AUU$1_lP7m~V3!7#LX69eo`c7&i8E|4C$J zU|`hsba4!+nDh3cqacF<&jEu2`=9%|$(e9fUAHz?KX;jNe>TH4hBb^4%p2Gec)1Qp hHJCDtioilcEFq2gFB6|f8Uq6ZgQu&X%Q~loCIIhfY*qjO diff --git a/doc/html/images/caution.png b/doc/html/images/caution.png index b056bccddb7f56b998b401bde72c561f64e65b4b..5b7809ca4a9c8d778087522e5ce04b6e90099595 100644 GIT binary patch delta 26 hcmaFL`G}LJGr-TCmrII^fq{W{Bi{<<&D)vv7y)6f2BH7} delta 30 lcmaFF`IM8dGr-TCmy1h^i-CcGmun->3T8&G&0CoD7y)!h2EG6Q diff --git a/doc/html/images/draft.png b/doc/html/images/draft.png index c99e091f224c503389c27d468ac46a7cee87135c..0084708c9b8287c51efa6b40b8d492854191455e 100644 GIT binary patch delta 474 zcmZqfWL($5$kQ3%=g!L|#l^tDz&nv|=EM~f1sQG}NH+blRr!gDA}<3+t}pLoU&b4g z)tIhM{=@WzpF#6O`L?P2*P_my-o>iOJDHK?=H%NfUX#^WRW^IG3NcQOW9!}ghRvIC zvIWQL$xk>exE^SDWUScx)I^bYvIeKgj)#UA5 zJ0=%!UlcoF?ax`e!p~4%HGkf7*Fcs3Z11ELc_&Bm%%A*|$9A(hFB{`zJ3g_=p?u1d zEBW#!zu-%q?8iTQ^DBNiMyZ_lvs=QvBD1$%a}9h_85b%VD9iKs-VGT=-pMM0ij&<0 zA52yk3Y=UiZy~zs9&9YN@MxvB28At%@taFjGNoFEtobR&|ShbIn^Lw z^EQK8#>pl|%QoLOa$#JoV8Xmv(Y%#W{K115yGb4|7?_@vTrWK)v9^@w`4oe9yp#7^ joY>r9>C3qJn$;Yp&Be9{nI@Y$OrCtwVaMhsM@D7iO%Qg8s^G!ys$ro6>7`Y}( zv8pg~ZMI_-Vr1l+9KhDg$hG+{n>UD~!Lgc=Yw~3d3m&cq8Xg%d_C5t!GFg<i6C>AT zMsZn2uFZ1d1|XOCNz7p6n*2=SKO@)Vr;>*lxh5}{0vYvI>Mn=5sffXtUQ2w>#eoNG`EGXIs~ zGDfb=6O3FK8Mzi;F=l4u+I+>Vl~I!G!GjpPNggj4n4XkeFFhu)wv^}j6oYrXT$2kd nPB3z9wy^XCS7<2jSZ9ObP$vZre4>tlwJ9yLkhn5+eW*#0{AM diff --git a/doc/html/images/next.png b/doc/html/images/next.png index f9f1081f4f2ddc3a1890daf50cbd944c718afd9b..59800b4e87f60c0e3383ede2b384b9be0f5ffe8d 100644 GIT binary patch delta 73 zcmcb{bb*PdGr-TCmrII^fq{W{BHu#;mZ>)#l9-t%+}PK^d+g590~2^trx_V+aGYt) fW#Kgko@Q`=1GNUm7uB{sR delta 53 zcmcb>bd8CxGr-TCmy1h^i-CcGmun)=Ls2f4sW%;xn3*Ts*w?_zb?na30~2_;CjOUW KC5~qpvC0S1hJ diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png index 22b8ac2c1d7c4d2bfa100c3a29b5b0593f43a71f..d88a40f923e3c554125f01cd366707c60cfcad04 100644 GIT binary patch delta 33 ocmcb_bdHI=Gr-TCmrH6RCkG=B7t>4!N4Bd03I+)bljRwW0h0Cz0RR91 delta 37 scmX@dbcu^keJMpq6Bk#mNM**7J7!3db diff --git a/doc/html/images/toc-blank.png b/doc/html/images/toc-blank.png index 75b24d6fc4aafdebbc3b9adfe816fbbc546ea3e9..6ffad17a0c7a78deaae58716e8071cc40cb0b8e0 100644 GIT binary patch delta 25 gcmX@ew2z6WGr-TCmrII^fq{W{BcCASWCcb=08JnS>;M1& delta 29 kcmdnTbdZU!Gr-TCmy1h^i-CcGmun-BAR{B!WLZW<09_OX2mk;8 diff --git a/doc/html/images/toc-minus.png b/doc/html/images/toc-minus.png index 7a8a2740efa22c214ec701878b02c970eec0e56a..abbb020c8e2d6705ebc2f0fc17deed30f2977a46 100644 GIT binary patch delta 23 ecmZo;YG&f;4DfU3<&xrJU|`^#$aihxQ$+wh?giWc delta 57 zcmZo>YGdN-4DfU3<>Hd!Vqjq4<(kNIO^K_-HKHUSF+G*R(6qu*+d$jEyzIjc1_lNO MPgg&ebxsLQ0DRI8n*aa+ diff --git a/doc/html/images/toc-plus.png b/doc/html/images/toc-plus.png index 29fada25c1d6c039ab4ad5682d3a11bb80b56781..941312ce0dab168e0efcc5b572e387259880e541 100644 GIT binary patch delta 23 ecmeBX>R{sO4DfU3<&xrJU|`^#$aj0Sp5W4DfU3<>Hd!Vqjq4<(kNIn~`hcb4377P6iAB diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png index 74fc1ba2b4a7693f381d09607b6c2aaca3c043f7..1c33db8f34a8b42b373179b46a2d8d8a10e061a9 100644 GIT binary patch delta 21 ccmcb^d6Sd9Gr-TCmrH6R=MLu0hnS@p0Zo<$b^rhX delta 25 gcmcb~d54p;Gr-TCmzPV5cO&}_W=7u4` Date: Sat, 21 Apr 2012 20:36:10 +0000 Subject: [PATCH 18/30] Merged from trunk [SVN r78115] --- include/boost/move/move.hpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 1f89d03..e43623d 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -350,6 +350,15 @@ ::boost::rv< TYPE >& \ // + #define BOOST_RV_REF_BEG\ + ::boost::rv< \ + // + + #define BOOST_RV_REF_END\ + >& \ + // + + #define BOOST_FWD_REF(TYPE)\ const TYPE & \ @@ -363,6 +372,14 @@ const ::boost::rv< TYPE >& \ // + #define BOOST_COPY_ASSIGN_REF_BEG \ + const ::boost::rv< \ + // + + #define BOOST_COPY_ASSIGN_REF_END \ + >& \ + // + #define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ const ::boost::rv< TYPE >& \ // @@ -569,6 +586,25 @@ TYPE && \ // + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for template classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE. + //!As macros have problem with comma-separatd template arguments, + //!the template argument must be preceded with BOOST_RV_REF_START + //!and ended with BOOST_RV_REF_END + #define BOOST_RV_REF_BEG\ + \ + // + + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for template classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE. + //!As macros have problem with comma-separatd template arguments, + //!the template argument must be preceded with BOOST_RV_REF_START + //!and ended with BOOST_RV_REF_END + #define BOOST_RV_REF_END\ + && \ + //!This macro is used to achieve portable syntax in copy //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. #define BOOST_COPY_ASSIGN_REF(TYPE)\ From 9127a418031110bd77018995ceb842b36b2f1582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 22 Apr 2012 22:54:18 +0000 Subject: [PATCH 19/30] Fixed clang warnings and errors [SVN r78149] --- example/doc_clone_ptr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/doc_clone_ptr.cpp b/example/doc_clone_ptr.cpp index 280c94c..56c0816 100644 --- a/example/doc_clone_ptr.cpp +++ b/example/doc_clone_ptr.cpp @@ -30,6 +30,8 @@ class Base virtual Base *clone() const { return new Base(*this); } + + virtual ~Base(){} }; class Member From fd7aaebd3f20c65662931a5d0f90f5a0a143afe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 24 May 2012 17:02:29 +0000 Subject: [PATCH 20/30] Merge move from trunk [SVN r78592] --- include/boost/move/move.hpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index e43623d..172ef30 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -217,9 +217,9 @@ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers - #ifdef __GNUC__ - #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) - #else + #ifdef __GNUC__ + #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) + #else #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS #endif @@ -306,10 +306,10 @@ {}; template - struct has_move_emulation_enabled_aux + struct has_move_emulation_enabled_aux : has_move_emulation_enabled {}; - - template + + template struct has_nothrow_move : public BOOST_MOVE_BOOST_NS::integral_constant {}; @@ -319,7 +319,7 @@ // move() // ////////////////////////////////////////////////////////////////////////////// - + template inline typename BOOST_MOVE_BOOST_NS::disable_if, T&>::type move(T& x) { @@ -460,7 +460,7 @@ //! By default this traits returns false. Classes with non-throwing move constructor //! and assignment should specialize this trait to obtain some performance improvements. - template + template struct has_nothrow_move : public BOOST_MOVE_MPL_NS::integral_constant {}; @@ -494,7 +494,7 @@ //! This function provides a way to convert a reference into a rvalue reference //! in compilers with rvalue references. For other compilers converts T & into //! ::boost::rv & so that move emulation is activated. - template + template rvalue_reference move (input_reference); #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) @@ -508,7 +508,7 @@ template inline typename remove_reference::type && move(T&& t) - { return static_cast::type &&>(t); } + { return static_cast::type &&>(t); } #endif //Old move @@ -1222,7 +1222,7 @@ template< class T > struct remove_rvalue_reference { typedef T type; }; template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; -#endif // #ifndef BOOST_NO_RVALUE_REFERENCES +#endif // #ifndef BOOST_NO_RVALUE_REFERENCES template typename boost::move_detail::add_rvalue_reference::type declval(); @@ -1230,7 +1230,7 @@ typename boost::move_detail::add_rvalue_reference::type declval(); } // Ideas from Boost.Move review, Jeffrey Lee Hellrung: // -//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? +//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? // Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue // references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than // rv& (since T&& & -> T&). @@ -1238,7 +1238,7 @@ typename boost::move_detail::add_rvalue_reference::type declval(); //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? // //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated -// rvalue references in C++03. This may be necessary to prevent "accidental moves". +// rvalue references in C++03. This may be necessary to prevent "accidental moves". } //namespace boost { From 8cd85f9cd35ebc5a947b700a6894002be33290f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 16 Jul 2012 09:05:33 +0000 Subject: [PATCH 21/30] Merged from trunk [SVN r79560] --- include/boost/move/move.hpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp index 172ef30..6029d6d 100644 --- a/include/boost/move/move.hpp +++ b/include/boost/move/move.hpp @@ -217,7 +217,7 @@ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers - #ifdef __GNUC__ + #if defined(__GNUC__) && (__GNUC__ >= 4) #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__)) #else #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS @@ -812,13 +812,18 @@ class back_move_insert_iterator C* container_m; public: - typedef C container_type; + typedef C container_type; + typedef typename C::value_type value_type; + typedef typename C::reference reference; explicit back_move_insert_iterator(C& x) : container_m(&x) { } - back_move_insert_iterator& operator=(typename C::reference x) + back_move_insert_iterator& operator=(reference x) { container_m->push_back(boost::move(x)); return *this; } + back_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x) + { reference rx = x; return this->operator=(rx); } + back_move_insert_iterator& operator*() { return *this; } back_move_insert_iterator& operator++() { return *this; } back_move_insert_iterator& operator++(int) { return *this; } @@ -847,13 +852,18 @@ class front_move_insert_iterator C* container_m; public: - typedef C container_type; + typedef C container_type; + typedef typename C::value_type value_type; + typedef typename C::reference reference; explicit front_move_insert_iterator(C& x) : container_m(&x) { } - front_move_insert_iterator& operator=(typename C::reference x) + front_move_insert_iterator& operator=(reference x) { container_m->push_front(boost::move(x)); return *this; } + front_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x) + { reference rx = x; return this->operator=(rx); } + front_move_insert_iterator& operator*() { return *this; } front_move_insert_iterator& operator++() { return *this; } front_move_insert_iterator& operator++(int) { return *this; } @@ -880,19 +890,24 @@ class move_insert_iterator typename C::iterator pos_; public: - typedef C container_type; + typedef C container_type; + typedef typename C::value_type value_type; + typedef typename C::reference reference; explicit move_insert_iterator(C& x, typename C::iterator pos) : container_m(&x), pos_(pos) {} - move_insert_iterator& operator=(typename C::reference x) + move_insert_iterator& operator=(reference x) { pos_ = container_m->insert(pos_, ::boost::move(x)); ++pos_; return *this; } + move_insert_iterator& operator=(BOOST_RV_REF(value_type) x) + { reference rx = x; return this->operator=(rx); } + move_insert_iterator& operator*() { return *this; } move_insert_iterator& operator++() { return *this; } move_insert_iterator& operator++(int) { return *this; } From bf0d7d77279001ef8156e10618bbb9c4e38a69a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 16 Jul 2012 09:08:27 +0000 Subject: [PATCH 22/30] Merged from trunk [SVN r79561] --- doc/move.qbk | 8 ++++++ test/back_move_inserter.cpp | 49 +++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/move.qbk b/doc/move.qbk index bd90baa..7224176 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -787,6 +787,14 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[section:release_notes_boost_1_51_00 Boost 1.51 Release] + +* Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/7095 #7095], + [@https://svn.boost.org/trac/boost/ticket/7031 #7031]. + +[endsect] + [section:release_notes_boost_1_49_00 Boost 1.49 Release] * Fixed bugs diff --git a/test/back_move_inserter.cpp b/test/back_move_inserter.cpp index ca4720b..1505125 100644 --- a/test/back_move_inserter.cpp +++ b/test/back_move_inserter.cpp @@ -17,29 +17,42 @@ template int move_test() { - //Default construct 10 movable objects - Container v(10); + bool use_move_iterator = false; + bool done = false; + while(!done){ + //Default construct 10 movable objects + Container v(10); - //Test default constructed value - if(v.begin()->moved()){ - return 1; - } + //Test default constructed value + if(v.begin()->moved()){ + return 1; + } - //Move values - Container v2; - std::copy(v.begin(), v.end(), boost::back_move_inserter(v2)); + //Move values + Container v2; + if(use_move_iterator){ + ::boost::copy_or_move( boost::make_move_iterator(v.begin()) + , boost::make_move_iterator(v.end()) + , boost::back_move_inserter(v2)); + } + else{ + std::copy(v.begin(), v.end(), boost::back_move_inserter(v2)); + } - //Test values have been moved - if(!v.begin()->moved()){ - return 1; - } + //Test values have been moved + if(!v.begin()->moved()){ + return 1; + } - if(v2.size() != 10){ - return 1; - } + if(v2.size() != 10){ + return 1; + } - if(v2.begin()->moved()){ - return 1; + if(v2.begin()->moved()){ + return 1; + } + done = use_move_iterator; + use_move_iterator = true; } return 0; } From 69dc55a76a45778ca919fa2ba75575311c9789b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 1 Dec 2012 22:50:46 +0000 Subject: [PATCH 23/30] Merged from trunk [SVN r81661] --- doc/Jamfile.v2 | 2 +- doc/move.qbk | 15 ++++- example/copymovable.hpp | 6 +- example/doc_clone_ptr.cpp | 5 +- example/doc_construct_forward.cpp | 6 +- example/doc_file_descriptor.cpp | 8 ++- example/doc_how_works.cpp | 9 ++- example/doc_move_algorithms.cpp | 5 ++ example/doc_move_inserter.cpp | 12 ++-- example/doc_move_iterator.cpp | 4 +- example/movable.hpp | 7 +- proj/vc7ide/Move.sln | 106 +++--------------------------- test/back_move_inserter.cpp | 5 +- test/construct_forward.cpp | 24 +++---- test/conversion_test.cpp | 20 +++--- test/copy_elision_test.cpp | 13 ++-- test/copy_move_optimization.cpp | 4 +- test/move.cpp | 8 ++- test/move_algorithm.cpp | 5 +- test/move_iterator.cpp | 55 +--------------- 20 files changed, 122 insertions(+), 197 deletions(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 55c1702..f970d61 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -13,7 +13,7 @@ import quickbook ; doxygen autodoc : - [ glob ../../../boost/move/move.hpp ] + [ glob ../../../boost/move/*.hpp ] : HIDE_UNDOC_MEMBERS=YES HIDE_UNDOC_MEMBERS=YES diff --git a/doc/move.qbk b/doc/move.qbk index 7224176..e4591c1 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -7,7 +7,7 @@ [library Boost.Move [quickbook 1.5] [authors [Gaztanaga, Ion]] - [copyright 2008-2010 Ion Gaztanaga] + [copyright 2008-2012 Ion Gaztanaga] [id move] [dirname move] [purpose Move semantics] @@ -318,7 +318,7 @@ This library makes this emulation easy with the help of `BOOST_FWD_REF` and [import ../example/doc_construct_forward.cpp] [construct_forward_example] -Constructor forwarding comes handful to implement placement insertion in containers with +Constructor forwarding comes in handy to implement placement insertion in containers with just N overloads if the implementor accepts the limitations of this type of forwarding for C++03 compilers. In compilers with rvalue references perfect forwarding is achieved. @@ -778,7 +778,7 @@ presence of three overloads and the conversion operators in C++03 compilers: [section:thanks_to Thanks and credits] Thanks to all that developed ideas for move emulation: the first emulation was based on Howard Hinnant -emulation code for `unique_ptr`, David Abrahams suggested the use of `class rv` class, +emulation code for `unique_ptr`, David Abrahams suggested the use of `class rv`, and Klaus Triendl discovered how to bind const rlvalues using `class rv`. Many thanks to all boosters that have tested, reviewed and improved the library. @@ -787,6 +787,15 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[section:release_notes_boost_1_53_00 Boost 1.53 Release] + +* Better header segregation (bug + [@https://svn.boost.org/trac/boost/ticket/6524 #6524]). +* Small documentation fixes +* Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros. + +[endsect] + [section:release_notes_boost_1_51_00 Boost 1.51 Release] * Fixed bugs diff --git a/example/copymovable.hpp b/example/copymovable.hpp index c3b4793..cb2c050 100644 --- a/example/copymovable.hpp +++ b/example/copymovable.hpp @@ -11,9 +11,11 @@ #ifndef BOOST_MOVE_TEST_COPYMOVABLE_HPP #define BOOST_MOVE_TEST_COPYMOVABLE_HPP +#include + //[movable_definition //header file "copy_movable.hpp" -#include +#include //A copy_movable class class copy_movable @@ -43,4 +45,6 @@ class copy_movable //] +#include + #endif //BOOST_MOVE_TEST_COPYMOVABLE_HPP diff --git a/example/doc_clone_ptr.cpp b/example/doc_clone_ptr.cpp index 56c0816..976b142 100644 --- a/example/doc_clone_ptr.cpp +++ b/example/doc_clone_ptr.cpp @@ -8,7 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// -#include +#include +#include //[clone_ptr_base_derived class Base @@ -152,3 +153,5 @@ int main() //] return 0; } + +#include diff --git a/example/doc_construct_forward.cpp b/example/doc_construct_forward.cpp index 07be958..4eee536 100644 --- a/example/doc_construct_forward.cpp +++ b/example/doc_construct_forward.cpp @@ -9,8 +9,10 @@ // ////////////////////////////////////////////////////////////////////////////// +#include + //[construct_forward_example -#include +#include #include class copyable_only_tester @@ -103,3 +105,5 @@ int main() return 0; } //] + +#include diff --git a/example/doc_file_descriptor.cpp b/example/doc_file_descriptor.cpp index 6d008d3..e4e6ba3 100644 --- a/example/doc_file_descriptor.cpp +++ b/example/doc_file_descriptor.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2009. +// (C) Copyright Ion Gaztanaga 2008-2012. // 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) @@ -9,9 +9,11 @@ // ////////////////////////////////////////////////////////////////////////////// +#include + //[file_descriptor_def -#include +#include #include class file_descriptor @@ -85,3 +87,5 @@ int main() return 0; } //] + +#include diff --git a/example/doc_how_works.cpp b/example/doc_how_works.cpp index e2116c5..ef28be4 100644 --- a/example/doc_how_works.cpp +++ b/example/doc_how_works.cpp @@ -11,7 +11,7 @@ #include -#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) int main() { @@ -20,8 +20,10 @@ int main() #else +#include + //[how_works_example -#include +#include #include class sink_tester @@ -56,5 +58,6 @@ int main() } //] -#endif +#include +#endif diff --git a/example/doc_move_algorithms.cpp b/example/doc_move_algorithms.cpp index c9ca065..6fe487a 100644 --- a/example/doc_move_algorithms.cpp +++ b/example/doc_move_algorithms.cpp @@ -9,8 +9,11 @@ // ////////////////////////////////////////////////////////////////////////////// +#include + //[move_algorithms_example #include "movable.hpp" +#include #include #include @@ -39,3 +42,5 @@ int main() return 0; } //] + +#include diff --git a/example/doc_move_inserter.cpp b/example/doc_move_inserter.cpp index 1e0b9dc..c715412 100644 --- a/example/doc_move_inserter.cpp +++ b/example/doc_move_inserter.cpp @@ -9,10 +9,13 @@ // ////////////////////////////////////////////////////////////////////////////// +#include + //[move_inserter_example #include #include "movable.hpp" #include +#include using namespace ::boost::container; @@ -27,10 +30,9 @@ void test_move_inserter(list_t &l2, MoveInsertIterator mit) assert(!l.begin()->moved()); l2.clear(); - //Move construct - for(l_iterator itbeg = l.begin(), itend = l.end(); itbeg != itend; ++itbeg){ - *mit = *itbeg; - } + //Move insert into l2 containers + std::copy(l.begin(), l.end(), mit); + //Check size and status assert(l2.size() == l.size()); assert(l.begin()->moved()); @@ -46,3 +48,5 @@ int main() return 0; } //] + +#include diff --git a/example/doc_move_iterator.cpp b/example/doc_move_iterator.cpp index 0e7cc51..86d3893 100644 --- a/example/doc_move_iterator.cpp +++ b/example/doc_move_iterator.cpp @@ -8,7 +8,7 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// - +#include //[move_iterator_example #include #include "movable.hpp" @@ -37,3 +37,5 @@ int main() return 0; } //] + +#include diff --git a/example/movable.hpp b/example/movable.hpp index 89b4397..07912dd 100644 --- a/example/movable.hpp +++ b/example/movable.hpp @@ -11,9 +11,12 @@ #ifndef BOOST_MOVE_TEST_MOVABLE_HPP #define BOOST_MOVE_TEST_MOVABLE_HPP +#include + //[movable_definition //header file "movable.hpp" -#include +#include +#include //A movable class class movable @@ -46,4 +49,6 @@ struct has_nothrow_move } //namespace boost{ //] +#include + #endif //BOOST_MOVE_TEST_MOVABLE_HPP diff --git a/proj/vc7ide/Move.sln b/proj/vc7ide/Move.sln index 894918a..4e2b273 100644 --- a/proj/vc7ide/Move.sln +++ b/proj/vc7ide/Move.sln @@ -1,52 +1,4 @@ Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "construct_forward_test", "construct_forward_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_iterator_test", "move_iterator_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_test", "move_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_algorithm_test", "move_algorithm.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_clone_ptr", "doc_clone_ptr.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_descriptor", "doc_file_descriptor.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_iterator", "doc_move_iterator.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_inserter", "doc_move_inserter.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_algorithms", "doc_move_algorithms.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_construct_forward", "doc_construct_forward.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "back_move_inserter_test", "back_move_inserter_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_move_optimization_test", "copy_move_optimization.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_elision_test_test", "copy_elision_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" ProjectSection(ProjectDependencies) = postProject EndProjectSection @@ -67,54 +19,6 @@ Global GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 - {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 @@ -129,10 +33,18 @@ Global {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionItems) = postSolution + ..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.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\core.hpp = ..\..\..\..\boost\move\core.hpp + ..\..\..\..\boost\move\iterator.hpp = ..\..\..\..\boost\move\iterator.hpp ..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2 + ..\..\..\..\boost\move\detail\meta_utils.hpp = ..\..\..\..\boost\move\detail\meta_utils.hpp ..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp ..\..\doc\move.qbk = ..\..\doc\move.qbk - ..\..\..\..\boost\move\move_helpers.hpp = ..\..\..\..\boost\move\move_helpers.hpp + ..\..\..\..\boost\move\detail\move_helpers.hpp = ..\..\..\..\boost\move\detail\move_helpers.hpp + ..\..\..\..\boost\move\traits.hpp = ..\..\..\..\boost\move\traits.hpp + ..\..\..\..\boost\move\utility.hpp = ..\..\..\..\boost\move\utility.hpp EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/test/back_move_inserter.cpp b/test/back_move_inserter.cpp index 1505125..eeddd6b 100644 --- a/test/back_move_inserter.cpp +++ b/test/back_move_inserter.cpp @@ -8,7 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include #include #include @@ -72,3 +73,5 @@ int main() } return 0; } + +#include diff --git a/test/construct_forward.cpp b/test/construct_forward.cpp index bf4c526..6922d82 100644 --- a/test/construct_forward.cpp +++ b/test/construct_forward.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009-2011. +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009-2012. // 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) @@ -8,8 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// - -#include +#include +#include #include #include "../example/movable.hpp" #include "../example/copymovable.hpp" @@ -24,36 +24,36 @@ class non_movable template void catch_test(BOOST_RV_REF(MaybeRvalue) x - #ifdef BOOST_NO_RVALUE_REFERENCES + #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 - #endif //BOOST_NO_RVALUE_REFERENCES + #endif //BOOST_NO_CXX11_RVALUE_REFERENCES ) { (void)x;} template void catch_test(BOOST_COPY_ASSIGN_REF(MaybeRvalue) x - #ifdef BOOST_NO_RVALUE_REFERENCES + #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 - #endif //BOOST_NO_RVALUE_REFERENCES + #endif //BOOST_NO_CXX11_RVALUE_REFERENCES ) { (void)x;} template void catch_test(MaybeRvalue &x - #ifdef BOOST_NO_RVALUE_REFERENCES + #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled >::type* = 0 - #endif //BOOST_NO_RVALUE_REFERENCES + #endif //BOOST_NO_CXX11_RVALUE_REFERENCES ) { (void)x;} - #ifdef BOOST_NO_RVALUE_REFERENCES + #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template void catch_test(const MaybeRvalue& x ,typename ::boost::disable_if< ::boost::has_move_emulation_enabled >::type* = 0 ) { (void)x;} - #endif //BOOST_NO_RVALUE_REFERENCES + #endif //BOOST_NO_CXX11_RVALUE_REFERENCES movable create_movable() { return movable(); } @@ -113,3 +113,5 @@ int main() forward_test(); return 0; } + +#include diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp index 99157c1..5c973d7 100644 --- a/test/conversion_test.cpp +++ b/test/conversion_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2010-2011. +// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2010-2012. // 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) @@ -8,12 +8,14 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include #include #include -#include +#include +#include enum ConstructionType { Copied, Moved, Other }; @@ -105,11 +107,11 @@ class container template void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x) - { new (&storage_) T(::boost::forward(x)); } + { ::new (&storage_) T(::boost::forward(x)); } template iterator priv_insert(const_iterator, BOOST_MOVE_CATCH_FWD(U) x) - { new (&storage_) T(::boost::forward(x)); return 0; } + { ::new (&storage_) T(::boost::forward(x)); return 0; } }; @@ -292,8 +294,10 @@ int main() return 0; } +#include + /* -#include +#include #include #include #include @@ -366,7 +370,7 @@ class conversion_target_movable struct not_a_type; -#if defined(BOOST_NO_RVALUE_REFERENCES) +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #define BOOST_MOVE_CATCH_CONST(U) \ typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type #define BOOST_MOVE_CATCH_RVALUE(U)\ @@ -470,7 +474,7 @@ class container { return priv_push_back(::boost::move(x)); } //Tricks for C++03 - #if defined(BOOST_NO_RVALUE_REFERENCES) + #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) void push_back(T &x) { priv_push_back(const_cast(x)); } diff --git a/test/copy_elision_test.cpp b/test/copy_elision_test.cpp index 01bf212..b15ebf2 100644 --- a/test/copy_elision_test.cpp +++ b/test/copy_elision_test.cpp @@ -2,6 +2,7 @@ // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include #include #ifdef NO_MOVE @@ -11,7 +12,7 @@ # define BOOST_COPYABLE_AND_MOVABLE(X) # define MOVE(x) (x) #else -#include +#include # define MOVE(x) boost::move(x) #endif @@ -91,17 +92,17 @@ unsigned X::instances = 0; struct trace { trace(char const* name) - : name(name) + : m_name(name) { - std::cout << "->: " << name << "\n"; + std::cout << "->: " << m_name << "\n"; } ~trace() { - std::cout << "<-: " << name << "\n"; + std::cout << "<-: " << m_name << "\n"; } - char const* name; + char const* m_name; }; void sink(X a) @@ -168,3 +169,5 @@ int main(int argc, char* argv[]) CHECK_COPIES( X a = ternary( argc != 1000 ), 0, 2, "Return result of ternary operation again" ); return 0; } + +#include diff --git a/test/copy_move_optimization.cpp b/test/copy_move_optimization.cpp index 10a0f20..4702a6f 100644 --- a/test/copy_move_optimization.cpp +++ b/test/copy_move_optimization.cpp @@ -8,7 +8,8 @@ //Optimization: //Since RVO is better than move-construction, //avoid copy constructor overloading. -#include +#include +#include #include bool moved = false; @@ -103,3 +104,4 @@ int main() //1 const rv & constructor: copy constructor //1 T & constructor: copy constructor +#include diff --git a/test/move.cpp b/test/move.cpp index e3e3790..e0e21f1 100644 --- a/test/move.cpp +++ b/test/move.cpp @@ -8,8 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// - -#include +#include +#include #include "../example/movable.hpp" #include @@ -64,7 +64,7 @@ movable create_movable() { return movable(); } int main() { - #if defined(BOOST_NO_RVALUE_REFERENCES) + #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == true)); BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == false)); BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); @@ -112,3 +112,5 @@ int main() return 0; } + +#include diff --git a/test/move_algorithm.cpp b/test/move_algorithm.cpp index 0568f7c..d3944b1 100644 --- a/test/move_algorithm.cpp +++ b/test/move_algorithm.cpp @@ -8,7 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include #include "../example/movable.hpp" @@ -53,3 +54,5 @@ int main() return 0; } + +#include diff --git a/test/move_iterator.cpp b/test/move_iterator.cpp index 10cc2bd..37c39f3 100644 --- a/test/move_iterator.cpp +++ b/test/move_iterator.cpp @@ -8,8 +8,8 @@ // See http://www.boost.org/libs/move for documentation. // ////////////////////////////////////////////////////////////////////////////// - -#include +#include +#include #include #include "../example/movable.hpp" @@ -52,53 +52,4 @@ int main() return 0; } -/* -#include - - -class copy_movable -{ - BOOST_COPYABLE_AND_MOVABLE(copy_movable) - int value_; - - public: - copy_movable() : value_(1){} - - //Move constructor and assignment - copy_movable(BOOST_RV_REF(copy_movable) m) - { value_ = m.value_; m.value_ = 0; } - - copy_movable(const copy_movable &m) - { value_ = m.value_; } - - copy_movable & operator=(BOOST_RV_REF(copy_movable) m) - { value_ = m.value_; m.value_ = 0; return *this; } - - copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m) - { value_ = m.value_; return *this; } - - bool moved() const //Observer - { return value_ == 0; } -}; - -struct copy_movable_wrapper -{ - copy_movable cm; -}; - -copy_movable produce() -{ return copy_movable(); } - - -int main() -{ - copy_movable cm; - cm = produce(); - - const copy_movable_wrapper cmw; - copy_movable_wrapper cmw2; - cmw2 = cmw; - - return 0; -} -*/ \ No newline at end of file +#include From a194813177a2a54e5849ca1942ebe8ab4cc10ad0 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Thu, 13 Dec 2012 00:15:53 +0000 Subject: [PATCH 24/30] Move: Merging from trunk [SVN r81883] --- include/boost/move/algorithm.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/move/algorithm.hpp b/include/boost/move/algorithm.hpp index bc6639f..5a0c25f 100644 --- a/include/boost/move/algorithm.hpp +++ b/include/boost/move/algorithm.hpp @@ -80,6 +80,10 @@ namespace boost { return result; } +#else + + using ::std::move_backward; + #endif //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) ////////////////////////////////////////////////////////////////////////////// From c981f170ef6312bca2aaabbdc118ac16bea155e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 28 Dec 2012 23:09:30 +0000 Subject: [PATCH 25/30] Fixes #7830 & #7832 [SVN r82248] --- doc/move.qbk | 2 + include/boost/move/algorithm.hpp | 19 ++++++- include/boost/move/core.hpp | 24 +++++--- proj/vc7ide/Move.sln | 96 ++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 11 deletions(-) diff --git a/doc/move.qbk b/doc/move.qbk index e4591c1..6d2895d 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -793,6 +793,8 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [@https://svn.boost.org/trac/boost/ticket/6524 #6524]). * Small documentation fixes * Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros. +* Fixed [@https://svn.boost.org/trac/boost/ticket/7830 #7830], + [@https://svn.boost.org/trac/boost/ticket/7832 #7832]. [endsect] diff --git a/include/boost/move/algorithm.hpp b/include/boost/move/algorithm.hpp index 5a0c25f..36a46be 100644 --- a/include/boost/move/algorithm.hpp +++ b/include/boost/move/algorithm.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include //copy, copy_backward #include //uninitialized_copy @@ -110,10 +111,22 @@ F uninitialized_move(I f, I l, F r ) { typedef typename std::iterator_traits::value_type input_value_type; - while (f != l) { - ::new(static_cast(&*r)) input_value_type(boost::move(*f)); - ++f; ++r; + + F back = r; + BOOST_TRY{ + while (f != l) { + void * const addr = static_cast(::boost::move_detail::addressof(*r)); + ::new(addr) input_value_type(::boost::move(*f)); + ++f; ++r; + } } + BOOST_CATCH(...){ + for (; back != r; ++back){ + back->~input_value_type(); + } + BOOST_RETHROW; + } + BOOST_CATCH_END return r; } diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index 2a11bad..b900e83 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -122,10 +122,6 @@ const TYPE & \ // - #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ - const ::boost::rv< TYPE >& \ - // - #define BOOST_COPY_ASSIGN_REF(TYPE)\ const ::boost::rv< TYPE >& \ // @@ -138,14 +134,18 @@ >& \ // - #define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ const ::boost::rv< TYPE >& \ // - #define BOOST_MOVE_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ const ::boost::rv< TYPE >& \ // + #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const ::boost::rv< TYPE >& \ + // + ////////////////////////////////////////////////////////////////////////////// // // BOOST_MOVABLE_BUT_NOT_COPYABLE @@ -286,11 +286,19 @@ TYPE && \ // - #define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + #define BOOST_COPY_ASSIGN_REF_BEG \ + const \ + // + + #define BOOST_COPY_ASSIGN_REF_END \ + & \ + // + + #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ const TYPE & \ // - #define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ TYPE& \ // diff --git a/proj/vc7ide/Move.sln b/proj/vc7ide/Move.sln index 4e2b273..6c995e7 100644 --- a/proj/vc7ide/Move.sln +++ b/proj/vc7ide/Move.sln @@ -11,6 +11,54 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_test", "conversi ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "back_move_inserter_test", "back_move_inserter_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "construct_forward_test", "construct_forward_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_move_optimization_test", "copy_move_optimization.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_clone_ptr", "doc_clone_ptr.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_construct_forward", "doc_construct_forward.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_descriptor", "doc_file_descriptor.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_algorithms", "doc_move_algorithms.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_inserter", "doc_move_inserter.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_iterator", "doc_move_iterator.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_algorithm_test", "move_algorithm.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_iterator_test", "move_iterator_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_test", "move_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -31,6 +79,54 @@ Global {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.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32 + {C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32 + {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = 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.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionItems) = postSolution ..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp From 92e31e84e245074c9c77f1fa0e320c0b12121467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 18 May 2013 10:40:55 +0000 Subject: [PATCH 26/30] Container, Interprocess, Intrusive, Move merge for 1.54 [SVN r84341] --- include/boost/move/core.hpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index b900e83..d939f03 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -18,6 +18,21 @@ #include +#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS + #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ + private:\ + TYPE(TYPE &);\ + TYPE& operator=(TYPE &);\ + // +#else + #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ + public:\ + TYPE(TYPE const &) = delete;\ + TYPE& operator=(TYPE const &) = delete;\ + private:\ + // +#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS + #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) #include @@ -152,9 +167,7 @@ // ////////////////////////////////////////////////////////////////////////////// #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ - private:\ - TYPE(TYPE &);\ - TYPE& operator=(TYPE &);\ + BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\ public:\ operator ::boost::rv&() \ { return *static_cast< ::boost::rv* >(this); }\ @@ -210,11 +223,9 @@ //! and assignment. The user will need to write a move constructor/assignment as explained //! in the documentation to fully write a movable but not copyable class. #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\ public:\ typedef int boost_move_emulation_t;\ - private:\ - TYPE(const TYPE &);\ - TYPE& operator=(const TYPE &);\ // //! This macro marks a type as copyable and movable. @@ -228,6 +239,8 @@ // #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + namespace boost { + //!This trait yields to a compile-time true boolean if T was marked as //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and //!rvalue references are not available on the platform. False otherwise. @@ -237,6 +250,8 @@ static const bool value = false; }; + } //namespace boost{ + //!This macro is used to achieve portable syntax in move //!constructors and assignments for classes marked as //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE @@ -299,7 +314,7 @@ // #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ - TYPE& \ + const TYPE& \ // #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ From d98a4eebb76c16c6910bd5a8300efdabe31126aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 18 May 2013 10:52:46 +0000 Subject: [PATCH 27/30] Merge changes for 1.54 [SVN r84342] --- doc/Jamfile.v2 | 4 +- doc/html/boostbook.css | 538 ---------------------------------- doc/html/images/blank.png | Bin 374 -> 0 bytes doc/html/images/caution.png | Bin 1250 -> 0 bytes doc/html/images/draft.png | Bin 17454 -> 0 bytes doc/html/images/home.png | Bin 358 -> 0 bytes doc/html/images/important.png | Bin 722 -> 0 bytes doc/html/images/next.png | Bin 336 -> 0 bytes doc/html/images/note.png | Bin 490 -> 0 bytes doc/html/images/prev.png | Bin 334 -> 0 bytes doc/html/images/tip.png | Bin 449 -> 0 bytes doc/html/images/toc-blank.png | Bin 318 -> 0 bytes doc/html/images/toc-minus.png | Bin 259 -> 0 bytes doc/html/images/toc-plus.png | Bin 264 -> 0 bytes doc/html/images/up.png | Bin 370 -> 0 bytes doc/html/images/warning.png | Bin 1241 -> 0 bytes doc/html/reference.css | 13 - doc/move.qbk | 7 + test/move.cpp | 1 - 19 files changed, 9 insertions(+), 554 deletions(-) delete mode 100644 doc/html/boostbook.css delete mode 100644 doc/html/images/blank.png delete mode 100644 doc/html/images/caution.png delete mode 100644 doc/html/images/draft.png delete mode 100644 doc/html/images/home.png delete mode 100644 doc/html/images/important.png delete mode 100644 doc/html/images/next.png delete mode 100644 doc/html/images/note.png delete mode 100644 doc/html/images/prev.png delete mode 100644 doc/html/images/tip.png delete mode 100644 doc/html/images/toc-blank.png delete mode 100644 doc/html/images/toc-minus.png delete mode 100644 doc/html/images/toc-plus.png delete mode 100644 doc/html/images/up.png delete mode 100644 doc/html/images/warning.png delete mode 100644 doc/html/reference.css diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index f970d61..6824339 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -30,8 +30,8 @@ boostbook standalone : move : - boost.root=../../../.. - boost.libraries=../../../../libs/libraries.htm + html:boost.root=../../../.. + html:boost.libraries=../../../../libs/libraries.htm generate.section.toc.level=3 chunk.first.sections=1 autodoc diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css deleted file mode 100644 index e816cce..0000000 --- a/doc/html/boostbook.css +++ /dev/null @@ -1,538 +0,0 @@ -/*============================================================================= - Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ - - Use, modification and distribution is subject to 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) -=============================================================================*/ - -/*============================================================================= - Body defaults -=============================================================================*/ - - body - { - margin: 1em; - font-family: sans-serif; - } - -/*============================================================================= - Paragraphs -=============================================================================*/ - - p - { - text-align: left; - font-size: 10pt; - line-height: 1.15; - } - -/*============================================================================= - Program listings -=============================================================================*/ - - /* Code on paragraphs */ - p tt.computeroutput - { - font-size: 10pt; - } - - pre.synopsis - { - font-size: 10pt; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - .programlisting, - .screen - { - font-size: 10pt; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - -/*============================================================================= - Headings -=============================================================================*/ - - h1, h2, h3, h4, h5, h6 - { - text-align: left; - margin: 1em 0em 0.5em 0em; - font-weight: bold; - } - - h1 { font: 140% } - h2 { font: bold 140% } - h3 { font: bold 130% } - h4 { font: bold 120% } - h5 { font: italic 110% } - h6 { font: italic 100% } - - /* Top page titles */ - title, - h1.title, - h2.title - h3.title, - h4.title, - h5.title, - h6.title, - .refentrytitle - { - font-weight: bold; - margin-bottom: 1pc; - } - - h1.title { font-size: 140% } - h2.title { font-size: 140% } - h3.title { font-size: 130% } - h4.title { font-size: 120% } - h5.title { font-size: 110% } - h6.title { font-size: 100% } - - .section h1 - { - margin: 0em 0em 0.5em 0em; - font-size: 140%; - } - - .section h2 { font-size: 140% } - .section h3 { font-size: 130% } - .section h4 { font-size: 120% } - .section h5 { font-size: 110% } - .section h6 { font-size: 100% } - - /* Code on titles */ - h1 tt.computeroutput { font-size: 140% } - h2 tt.computeroutput { font-size: 140% } - h3 tt.computeroutput { font-size: 130% } - h4 tt.computeroutput { font-size: 120% } - h5 tt.computeroutput { font-size: 110% } - h6 tt.computeroutput { font-size: 100% } - -/*============================================================================= - Author -=============================================================================*/ - - h3.author - { - font-size: 100% - } - -/*============================================================================= - Lists -=============================================================================*/ - - li - { - font-size: 10pt; - line-height: 1.3; - } - - /* Unordered lists */ - ul - { - text-align: left; - } - - /* Ordered lists */ - ol - { - text-align: left; - } - -/*============================================================================= - Links -=============================================================================*/ - - a - { - text-decoration: none; /* no underline */ - } - - a:hover - { - text-decoration: underline; - } - -/*============================================================================= - Spirit style navigation -=============================================================================*/ - - .spirit-nav - { - text-align: right; - } - - .spirit-nav a - { - color: white; - padding-left: 0.5em; - } - - .spirit-nav img - { - border-width: 0px; - } - -/*============================================================================= - Table of contents -=============================================================================*/ - - .toc - { - margin: 1pc 4% 0pc 4%; - padding: 0.1pc 1pc 0.1pc 1pc; - font-size: 10pt; - line-height: 1.15; - } - - .toc-main - { - width: 600; - text-align: center; - margin: 1pc 1pc 1pc 10%; - padding: 2pc 1pc 3pc 1pc; - line-height: 0.1; - } - - .boost-toc - { - float: right; - padding: 0.5pc; - } - -/*============================================================================= - Tables -=============================================================================*/ - - .table-title, - div.table p.title - { - margin-left: 4%; - padding-right: 0.5em; - padding-left: 0.5em; - } - - .informaltable table, - .table table - { - width: 92%; - margin-left: 4%; - margin-right: 4%; - } - - div.informaltable table, - div.table table - { - padding: 4px; - } - - /* Table Cells */ - div.informaltable table tr td, - div.table table tr td - { - padding: 0.5em; - text-align: left; - } - - div.informaltable table tr th, - div.table table tr th - { - padding: 0.5em 0.5em 0.5em 0.5em; - border: 1pt solid white; - font-size: 120%; - } - -/*============================================================================= - Blurbs -=============================================================================*/ - - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - font-size: 10pt; - line-height: 1.2; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - p.blurb img - { - padding: 1pt; - } - -/*============================================================================= - Variable Lists -=============================================================================*/ - - span.term - { - font-weight: bold; - font-size: 10pt; - } - - div.variablelist table tbody tr td - { - text-align: left; - vertical-align: top; - padding: 0em 2em 0em 0em; - font-size: 10pt; - } - - div.variablelist table tbody tr td p - { - margin: 0em 0em 0.5em 0em; - } - - /* Make the terms in definition lists bold */ - div.variablelist dl dt - { - font-weight: bold; - font-size: 10pt; - } - - div.variablelist dl dd - { - margin: 1em 0em 1em 2em; - font-size: 10pt; - } - -/*============================================================================= - Misc -=============================================================================*/ - - /* Title of books and articles in bibliographies */ - span.title - { - font-style: italic; - } - - span.underline - { - text-decoration: underline; - } - - span.strikethrough - { - text-decoration: line-through; - } - - /* Copyright, Legal Notice */ - div div.legalnotice p - { - font-size: 8pt; - text-align: left - } - -/*============================================================================= - Colors -=============================================================================*/ - - @media screen - { - /* Links */ - a - { - color: #0C7445; - } - - a:visited - { - color: #663974; - } - - h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, - h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, - h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited - { - text-decoration: none; /* no underline */ - color: #000000; - } - - /* Syntax Highlighting */ - .keyword { color: #0000AA; } - .identifier { color: #000000; } - .special { color: #707070; } - .preprocessor { color: #402080; } - .char { color: teal; } - .comment { color: #800000; } - .string { color: teal; } - .number { color: teal; } - .white_bkd { background-color: #E8FBE9; } - .dk_grey_bkd { background-color: #A0DAAC; } - - /* Copyright, Legal Notice */ - .copyright - { - color: #666666; - font-size: small; - } - - div div.legalnotice p - { - color: #666666; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - .programlisting, - .screen - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - /* Blurbs */ - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - /* Table of contents */ - .toc - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - /* Table of contents */ - .toc-main - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - background-color: #FAFFFB; - } - - div.informaltable table tr th, - div.table table tr th - { - background-color: #E3F9E4; - border: 1px solid #DCDCDC; - } - - /* Misc */ - span.highlight - { - color: #00A000; - } - } - - @media print - { - /* Links */ - a - { - color: black; - } - - a:visited - { - color: black; - } - - .spirit-nav - { - display: none; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid gray; - background-color: #FAFFFB; - } - - .programlisting, - .screen - { - border: 1px solid gray; - background-color: #FAFFFB; - } - - /* Table of contents */ - .toc - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - /* Table of contents */ - .toc-main - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - background-color: #FAFFFB; - } - - .informaltable table, - .table table - { - border: 1px solid #DCDCDC; - border-bottom: 3px solid #9D9D9D; - border-right: 3px solid #9D9D9D; - border-collapse: collapse; - background-color: #FAFFFB; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - background-color: #FAFFFB; - } - - div.informaltable table tr th, - div.table table tr th - { - border: 1px solid #DCDCDC; - background-color: #FAFFFB; - } - - /* Misc */ - span.highlight - { - font-weight: bold; - } - } diff --git a/doc/html/images/blank.png b/doc/html/images/blank.png deleted file mode 100644 index 764bf4f0c3bb4a09960b04b6fa9c9024bca703bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4kiW$2A`O3a~K#HSkfJR9T^xl_H+M9WMyDr z)b(_645^s&_M)R8g96V1g9H1Y`?|@Qa8+HmHda4(nQ?zM!!?FAj1kNm*b;aTNHv%; cj9>w=gf!;AOne?`3=9kmp00i_>zopr0Be8NW(e>Jab;j&;NV~o5MYpy zU{F+KFf?Rva$<;zVn|MA$j)XcE@r5%W@u?)XlW_#>0#*UDemd%nKFf8%9P?MQ>y38 zVVEwkZjIWyHF@jSt$X(}?A@Du?i|Cp zbLXyIW4Lzh+_h`h?%iX!chB(NJdh*`E$$X&!4}4&+z{J`|sZwzJC|^ z{$1kxcf;@BzyJTw@c+NS|Nj#IN5NBISn~R-X--a%afBxQ|J!3zMjr_SU zk_iHr)f*lf{$5^Qz}I)@3FlWvw(w~u=1P@VsTP+$RNGvxbHL-(%M6nc6`{zlU zjGQJeveps+!&Jb&mD)L@hA} z1_tL6*NBqf{Irtt#G+IN2MuLS&)mfHRNut(%;anZ6Fnn63k6F{eFF=914D)6qRirw zN{8Ia;*!i{z0_j8l+uFyyb`_S{M?DV6n8K%Fld2|%S_KpEGaEYWk@zRFt#waFg8d` zG)YZPF-fe)lBATd3a!N{b-$VA&f+n^|#(~yCI Ofx*+&&t;ucLK6T%G-N*j diff --git a/doc/html/images/draft.png b/doc/html/images/draft.png deleted file mode 100644 index 0084708c9b8287c51efa6b40b8d492854191455e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17454 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 YsPxZ;53A2HFfcH9y85}Sb4q9e0Fi|iga7~l diff --git a/doc/html/images/home.png b/doc/html/images/home.png deleted file mode 100644 index 5584aacb097a80e66a5320312b6e4eb017af1a06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 358 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&Dfg?(A@OuseF>a6(*+nzF*onKLh6zO-%YmOy{sw6wJU|Nk%gvq74Hfq|za z$S?Rm0x$^OKX;CSfq}EYBeIx*fm;ZK886+f`@_J%pjzS@Q4*Y=R#Ki=l*-_nm|T>f zo0^iDsNj}alvU8YOY t9}F9JU6`43jMG5vNQA&8NcoN_f;wr$vARr(hAt9lu zscC6x>EvV>6{VS+EaBwj6ciMco$ZvI98_E!l$@NLot<4>UER|o(bHqOcQ41TYc{y!?kM?_wFg)yJvXsp5^oB z9Pi&Vyniq7|3Ab3{~Z7S3p{_W`TV)z`}cpO z$(;G%_wGG* z?AW<;=dNA5cJJQ3=g*(NfB*jb_wWDz|6hCQ@I3|w2F4_BcNgdM3%p4T42R|DNig) zWpL0?*7VFxOi%SqOwUZtRxr^s(z8&owA44S&^IttNG{4OE~#|Ltt>9dOx8;+)=McZ z$j>X$OU}=oxJz*d0|SE=*tpE}yu^~yqEv=t diff --git a/doc/html/images/next.png b/doc/html/images/next.png deleted file mode 100644 index 59800b4e87f60c0e3383ede2b384b9be0f5ffe8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 336 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&Dfg?(8r&Hr}>%OQ656nzF)*4nJa0`Jj)#l9-t%+}PK^d+g590~2^trx_V+aGYt)W#Kgko@Q{~>i6>w}LxPb)_bi1gN;4a>^d{wcuv&t)U99M06BF~bt=lC3t1z!y3OU-_; z>3=1k>J3(3i_72APIz-IDqpqc+E%+vGv;(%KfZ!%@4A+C&xmZ75-RagX8L}A{%x+r zX<~gz))PX{awr=ezabJ<%O$qq%HpE?3}IarYhrI#g}e)4`)(-lYr?KO{@fm?UzpsD z&F7x?_G;CcbIZ>^o0GCAMe@{JfwtZgS9s0dn=t$|`IrrC3yU6#%a-U6G$wZz0 z>m`@($9HNPdGJ4#pEvb;3eT@>Ck6%v=MvY5lHmNblJdl&R0anPWlhiA#Pn3(#PrPM zYy}fNBRvZROG|wN3w;Aah2)~l;*v^-+{)sT%w)aPV!f2og8aM^z2yAdiMtecFfcG^ zfsM;d&r2*RElOoDPD(L1F;6y4H8Hg?FgGwTOER!DNJ%kHHBU4$OExhPxjgw70|Nse jNLN5&dMbmFNrjP#wt==mQ8cF^C=xwg{an^LB{Ts5w*0vf diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png deleted file mode 100644 index d88a40f923e3c554125f01cd366707c60cfcad04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?WS z3GfMV6&DdqOG`60Hr}>%%ZlYo1O0u~loc*tzSP~>;p||S5Et|R|Noh1c$yg)73T~N2spa`a*~JRJ5eh~I1}5!gYtAz;Fo=OPI2WZRmSpDVDTHL^rZN~B=o=X8 z8<-ql-^0nkz!2u?;uumfC;0|1OPoRyGxLNShYX~Tl_Wf9G1_imu)%RA9}mw<0X2^e zQioc&m}WXSvRw^OFi2qFa&lm1W^U?K=~^Ook|m{hVvche^Q6-g?(V)Vn8U=toEqFE UkjD9gfq{X+)78&qol`;+00?PtqyPW_ diff --git a/doc/html/images/tip.png b/doc/html/images/tip.png deleted file mode 100644 index 5c4aab3bb3543191c360387c4af9a3cbaa051345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmeAS@N?(olHy`uVBq!ia0y~yV31^BV36QoU|?X-y2mNSz`($iDJ87yAgr${wU6ATeb^ycE^w7cIp z?_W?xU6%d(bb~@Shbi-aG=ETBbm~(ogOmrW&bwBIxdt+K+A3yD;V_t}R>0LF5GN)x zed{W(mq$!1ciVpPy1}W+9bm)Xrgda~bSbG?a3DdjluYV+O9SdLnMpASqX+9EZY3c7C@7#N&OTq83NAIrA4U>si~GJ7Ut&0mS)MRMrP)TsYwQg=9VeOrfC+2Nk)mu rLdL(;85kJ&K)M1F(^DCYOe>5`v<1B4~iR4S3j3^P6tl1hi%%HopDWWCg4y_C{| z{JavqiARt`YJFJnVhX)qGzOMplv!L->5yAl zT#}irms+fsQd*FoSE84kpF44v;tmD|1}(60ndy0nC8b5F42emG<`xDZ$;L?r7Ky3J=GDKJX@I;2(iM=Hp2}coT4AYeplx7Y_5oxZgQu&X%Q~lo FCIGT9P(J_w diff --git a/doc/html/images/up.png b/doc/html/images/up.png deleted file mode 100644 index 17d9c3ec491ae1ba22188ce85985623c92ffa9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj7G?$phK4%r{|pQa%*9TgAsieWw;%dHU|?X- z3h)VW6&DdqOG|Thu-mqE%ZlYoyE{8BU%nLR@2jS)FmvY2qel)W#Kk;%^zi@x|I?Un z*fKCM@RbDl1^-6|46X<6oM2#J;4JWnEM{Qf76M_$OLy!3FfcHvmbgZg1m~xflqVLY zGWaGY7v<-srer26xMdclmgg5`7c2NiC>R+Sn6#IzInThrAO_OlT$Gwvl9`{U5R#dj z%3x@qZ(yu%U~+tY4<`cyLy@P8V@SoEspmFwHW&!FJyeg_(XezvV9WvAI|r@_>dZZG zPW6aiOT!J--9O?NG0%AP;}ge|4lDQN4=-}8`?JGwx}?mMnO)OdyQdu$nQCjPRV}jm z$u!Qa8E-cQ-r3Nz>Y(YPTd#BPEH+&8GWqfD!}4*53%dA!%#3$cIv;a~fq{X+)78&q Iol`;+0POUaApigX diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png deleted file mode 100644 index 1c33db8f34a8b42b373179b46a2d8d8a10e061a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4rT@hhU+WOo?>8NW(e>JaphoO5CF?5GB9W| zFc>m0I59AIF)#!%FhnshWHT@nGcZ&$Ftji*^e`|?VPKe2T|Fl#Xiikroa*YO3=B&x zEth(EEp2I8I%UezrAyZ`FswB+TsvjTRtAQxnwndCdbZA)vvujxty{P5WnkF5cJ1D+ zTaPg?91{>YCLwX`*s*gA4Ce#{&Phm|)6~4iz;I1d^V+p*_ZS%N-Mjakf#JEL;`8Uv z-!m}0=iqq%{{43bhVS3M|7T$MKMF=efJz}yVEuRs0|NtNlDE4HLkFv@2Ll7c3r`ov zkcwNmlWOyu3izvS7ejxP>R-!INP5f(XN|IS^C^Iyp?`SUk1vQO?s(K&l| zi|Nkt0@~*ymDp65*E-HED6u(s{Mfrxmah{JrgAMTIq)Du?nC5nnYTRgThA|azEdIl zD^uvV>~q(b?>`Fd;xnAbe7so1I$-&keKN}|vNNOCvX<~g{)wp7{&hR__v^cBU*Gq* zV3YS!cBPWsl#eNWc|~nAXWMOB8tQWBuXo=4>}cytyX_5F^Az{bVJ>7~U~n#RjVKAu zPb(=;EJ|f?&`{R&%uP&B^-WCAOwLv?(KFJsP_VSrH?Yt*FjPn`$}BFabjYnNF3C*R zOD)z*DJ{s)E742N&z-nSaR&nfgBIAh%=Em(lG377hGY|?B=Z!b6jL*k#Ka_13kwTN zLrZf@a|7cv1EVApQ-8txlNlHo_&~Y>64O%|j7%zwOtcNO4T_>U4H+017(8A5T-G@y GGywozG)2h( diff --git a/doc/html/reference.css b/doc/html/reference.css deleted file mode 100644 index 956d7da..0000000 --- a/doc/html/reference.css +++ /dev/null @@ -1,13 +0,0 @@ -/*============================================================================= - Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ - - Use, modification and distribution is subject to 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) -=============================================================================*/ -PRE.synopsis { - background-color: #e0ffff; - border: thin solid blue; - padding: 1em -} diff --git a/doc/move.qbk b/doc/move.qbk index 6d2895d..e1d61ae 100644 --- a/doc/move.qbk +++ b/doc/move.qbk @@ -787,6 +787,13 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[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]). + +[endsect] + [section:release_notes_boost_1_53_00 Boost 1.53 Release] * Better header segregation (bug diff --git a/test/move.cpp b/test/move.cpp index e0e21f1..a48b4ef 100644 --- a/test/move.cpp +++ b/test/move.cpp @@ -108,7 +108,6 @@ int main() movable m2(boost::move(m)); movable m3(move_return_function2()); } - //limitations_test(); return 0; } From 26aecaa3c8d07c33b55a940cd0dd497437875c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 24 Aug 2013 10:34:37 +0000 Subject: [PATCH 28/30] First Move merge for 1.55 [SVN r85442] --- doc/move.qbk | 27 +++++++++++++++++++++------ example/doc_file_descriptor.cpp | 13 +++++++------ include/boost/move/algorithm.hpp | 1 - include/boost/move/core.hpp | 7 +++++++ include/boost/move/traits.hpp | 12 ++++++++++-- include/boost/move/utility.hpp | 22 +++++++++++----------- test/move.cpp | 1 - 7 files changed, 56 insertions(+), 27 deletions(-) diff --git a/doc/move.qbk b/doc/move.qbk index e1d61ae..64328be 100644 --- a/doc/move.qbk +++ b/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) { - std::swap(ptr, p.ptr); - delete p.ptr; - p.ptr = 0; + if(this != &p) + { + std::swap(ptr, p.ptr); + delete p.ptr; + p.ptr = 0; + } return *this; } @@ -171,7 +174,7 @@ You just need to follow these simple steps: * Put the following macro in the [*private] section: [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 [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)] * 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_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] -* 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] diff --git a/example/doc_file_descriptor.cpp b/example/doc_file_descriptor.cpp index e4e6ba3..1dd7bc0 100644 --- a/example/doc_file_descriptor.cpp +++ b/example/doc_file_descriptor.cpp @@ -10,6 +10,7 @@ ////////////////////////////////////////////////////////////////////////////// #include +#include //[file_descriptor_def @@ -24,8 +25,8 @@ class file_descriptor return 1; } - void operating_system_close_file(int) - {} + void operating_system_close_file(int fd) + { (void)fd; assert(fd != 0); } //-> int os_descr_; @@ -33,12 +34,12 @@ class file_descriptor BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor) public: - explicit file_descriptor(const char *filename = 0) //Constructor - : os_descr_(filename ? operating_system_open_file(filename) : 0) + explicit file_descriptor(const char *filename) //Constructor + : os_descr_(operating_system_open_file(filename)) { if(!os_descr_) throw std::runtime_error("file not found"); } ~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 : os_descr_(x.os_descr_) @@ -46,7 +47,7 @@ class file_descriptor 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_; x.os_descr_ = 0; return *this; diff --git a/include/boost/move/algorithm.hpp b/include/boost/move/algorithm.hpp index 36a46be..43a81c3 100644 --- a/include/boost/move/algorithm.hpp +++ b/include/boost/move/algorithm.hpp @@ -18,7 +18,6 @@ #include #include -#include #include #include //copy, copy_backward diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp index d939f03..9586eca 100644 --- a/include/boost/move/core.hpp +++ b/include/boost/move/core.hpp @@ -18,17 +18,24 @@ #include +//boost_move_no_copy_constructor_or_assign typedef +//used to detect noncopyable types for other Boost libraries. #ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ private:\ TYPE(TYPE &);\ TYPE& operator=(TYPE &);\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ + private:\ // #else #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ public:\ TYPE(TYPE const &) = delete;\ TYPE& operator=(TYPE const &) = delete;\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ private:\ // #endif //BOOST_NO_CXX11_DELETED_FUNCTIONS diff --git a/include/boost/move/traits.hpp b/include/boost/move/traits.hpp index e5c8444..ced1cdd 100644 --- a/include/boost/move/traits.hpp +++ b/include/boost/move/traits.hpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES @@ -38,11 +40,17 @@ struct has_trivial_destructor_after_move : ::boost::has_trivial_destructor {}; -//! By default this traits returns false. Classes with non-throwing move constructor +//! By default this traits returns +//!
boost::is_nothrow_move_constructible::value && boost::is_nothrow_move_assignable::value 
. +//! Classes with non-throwing move constructor //! and assignment can specialize this trait to obtain some performance improvements. template struct has_nothrow_move - : public ::boost::move_detail::integral_constant + : public ::boost::move_detail::integral_constant + < bool + , boost::is_nothrow_move_constructible::value && + boost::is_nothrow_move_assignable::value + > {}; namespace move_detail { diff --git a/include/boost/move/utility.hpp b/include/boost/move/utility.hpp index fb2ec69..964500e 100644 --- a/include/boost/move/utility.hpp +++ b/include/boost/move/utility.hpp @@ -37,7 +37,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && !has_move_emulation_enabled::value, T&>::type - move(T& x) + move(T& x) BOOST_NOEXCEPT { return x; } @@ -45,7 +45,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type - move(T& x) + move(T& x) BOOST_NOEXCEPT { return *static_cast* >(::boost::move_detail::addressof(x)); } @@ -53,7 +53,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type - move(rv& x) + move(rv& x) BOOST_NOEXCEPT { return x; } @@ -67,7 +67,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && ::boost::move_detail::is_rv::value, T &>::type - forward(const typename ::boost::move_detail::identity::type &x) + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return const_cast(x); } @@ -75,7 +75,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && !::boost::move_detail::is_rv::value, const T &>::type - forward(const typename ::boost::move_detail::identity::type &x) + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return x; } @@ -123,19 +123,19 @@ //! in compilers with rvalue references. For other compilers converts T & into //! ::boost::rv & so that move emulation is activated. template - rvalue_reference move (input_reference); + rvalue_reference move(input_reference) noexcept; #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references template - inline typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return t; } #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES template - inline typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return static_cast::type &&>(t); } #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES @@ -159,13 +159,13 @@ //! ::boost::rv & //! //! * Else, output_reference is equal to input_reference. - template output_reference forward(input_reference); + template output_reference forward(input_reference) noexcept; #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references template - inline T&& forward (typename ::boost::move_detail::identity::type&& t) + inline T&& forward(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT { return t; } #else //Old move @@ -178,7 +178,7 @@ move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* , typename ::boost::move_detail::enable_if_c< move_detail::is_convertible - ::type*, typename remove_reference::type*>::value>::type * = 0*/) + ::type*, typename remove_reference::type*>::value>::type * = 0*/) BOOST_NOEXCEPT { return static_cast(t); } #endif //BOOST_MOVE_DOXYGEN_INVOKED diff --git a/test/move.cpp b/test/move.cpp index a48b4ef..4d6eae7 100644 --- a/test/move.cpp +++ b/test/move.cpp @@ -66,7 +66,6 @@ int main() { #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == true)); - BOOST_STATIC_ASSERT((boost::has_nothrow_move::value == false)); BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled::value == false)); From 21ab9586dee21d7f3a492dc9b0d51519f4a5f2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 16 Sep 2013 16:59:03 +0000 Subject: [PATCH 29/30] Last merge for 1.55 [SVN r85702] --- include/boost/move/detail/move_helpers.hpp | 26 ++-- test/conversion_test.cpp | 145 +++++++++++++++++++-- 2 files changed, 146 insertions(+), 25 deletions(-) diff --git a/include/boost/move/detail/move_helpers.hpp b/include/boost/move/detail/move_helpers.hpp index ddfea9b..ed6f3d5 100644 --- a/include/boost/move/detail/move_helpers.hpp +++ b/include/boost/move/detail/move_helpers.hpp @@ -19,6 +19,8 @@ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined(_MSC_VER) && (_MSC_VER == 1600)) #include +#include +#include #include #endif #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) @@ -28,6 +30,7 @@ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) struct not_a_type; +struct not_a_type2; #define BOOST_MOVE_CATCH_CONST(U) \ typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type #define BOOST_MOVE_CATCH_RVALUE(U)\ @@ -40,7 +43,6 @@ struct not_a_type; #endif #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES - #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(static_cast(x)); }\ @@ -72,7 +74,7 @@ struct not_a_type; return FWD_FUNCTION(::boost::move(t));\ }\ // - +// ::boost::is_convertible::value && #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ @@ -108,7 +110,7 @@ struct not_a_type; #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ @@ -119,8 +121,7 @@ struct not_a_type; { return FWD_FUNCTION(arg1, const_cast(x)); }\ \ template\ - typename ::boost::enable_if_c\ - < ::boost::is_class::value &&\ + typename ::boost::enable_if_c<\ ::boost::is_same::value &&\ !::boost::has_move_emulation_enabled::value\ , RETURN_VALUE >::type\ @@ -128,10 +129,10 @@ struct not_a_type; { return FWD_FUNCTION(arg1, u); }\ \ template\ - typename ::boost::enable_if_c\ - < (!::boost::is_class::value || \ - !::boost::move_detail::is_rv::value) && \ - !::boost::is_same::value \ + typename ::boost::enable_if_c<\ + !::boost::move_detail::is_rv::value && \ + !::boost::is_same::value && \ + !::boost::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -142,7 +143,7 @@ struct not_a_type; #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ @@ -151,7 +152,8 @@ struct not_a_type; \ template\ typename ::boost::enable_if_c\ - < !::boost::is_same::value\ + < !::boost::is_same::value && \ + !::boost::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -162,7 +164,7 @@ struct not_a_type; #else -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp index 5c973d7..9412ddb 100644 --- a/test/conversion_test.cpp +++ b/test/conversion_test.cpp @@ -84,34 +84,99 @@ class conversion_target_movable template class container { - typename ::boost::aligned_storage::value>::type storage_; + T *storage_; public: + struct const_iterator{}; + struct iterator : const_iterator{}; + container() + : storage_(0) + {} - typedef T * iterator; - typedef const T * const_iterator; + ~container() + { delete storage_; } + + container(const container &c) + : storage_(c.storage_ ? new T(*c.storage_) : 0) + {} + + container &operator=(const container &c) + { + if(storage_){ + delete storage_; + storage_ = 0; + } + storage_ = c.storage_ ? new T(*c.storage_) : 0; + return *this; + } BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) - BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator) + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) + + template + iterator insert(Iterator, Iterator){ return iterator(); } ConstructionType construction_type() const - { return construction_type_impl(typename ::boost::is_class::type()); } + { return construction_type_impl(typename ::boost::is_class::type()); } + ConstructionType construction_type_impl(::boost::true_type) const - { return reinterpret_cast(storage_).construction_type(); } + { return storage_->construction_type(); } + ConstructionType construction_type_impl(::boost::false_type) const - { return Copied; } - - iterator begin() { return iterator(0); } + { return Copied; } + iterator begin() const { return iterator(); } + private: + template + void priv_construct(BOOST_MOVE_CATCH_FWD(U) x) + { + if(storage_){ + delete storage_; + storage_ = 0; + } + storage_ = new T(::boost::forward(x)); + } template void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x) - { ::new (&storage_) T(::boost::forward(x)); } + { priv_construct(::boost::forward(x)); } template iterator priv_insert(const_iterator, BOOST_MOVE_CATCH_FWD(U) x) - { ::new (&storage_) T(::boost::forward(x)); return 0; } + { priv_construct(::boost::forward(x)); return iterator(); } +}; + +class recursive_container +{ + BOOST_COPYABLE_AND_MOVABLE(recursive_container) + public: + recursive_container() + {} + + recursive_container(const recursive_container &c) + : container_(c.container_) + {} + + recursive_container(BOOST_RV_REF(recursive_container) c) + : container_(::boost::move(c.container_)) + {} + + recursive_container & operator =(BOOST_COPY_ASSIGN_REF(recursive_container) c) + { + container_= c.container_; + return *this; + } + + recursive_container & operator =(BOOST_RV_REF(recursive_container) c) + { + container_= ::boost::move(c.container_); + return *this; + } + + container container_; + friend bool operator< (const recursive_container &a, const recursive_container &b) + { return &a < &b; } }; @@ -289,6 +354,61 @@ int main() c.insert(c.begin(), conversion_source()); assert(c.construction_type() == Copied); } + //c.insert(c.begin(), c.begin()); + } + + { + container c; + { + int x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), c.construction_type()); + assert(c.construction_type() == Copied); + } + { + const int x = 0; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(int(0)); + assert(c.construction_type() == Copied); + c.insert(c.begin(), int(0)); + assert(c.construction_type() == Copied); + } + { + conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + + { + const conversion_source x; + c.push_back(x); + assert(c.construction_type() == Copied); + c.insert(c.begin(), x); + assert(c.construction_type() == Copied); + } + { + c.push_back(conversion_source()); + assert(c.construction_type() == Copied); + c.insert(c.begin(), conversion_source()); + assert(c.construction_type() == Copied); + } + c.insert(c.begin(), c.begin()); + } + + { + recursive_container c; + recursive_container internal; + c.container_.insert(c.container_.begin(), recursive_container()); + c.container_.insert(c.container_.begin(), internal); + c.container_.insert(c.container_.begin(), c.container_.begin()); } return 0; @@ -677,5 +797,4 @@ int main() return 0; } - -*/ \ No newline at end of file +*/ From ddee2b60f664796df95ace553820eea70c122e15 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 7 Oct 2016 23:07:35 -0500 Subject: [PATCH 30/30] Add, and update, documentation build targets. --- doc/Jamfile.v2 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 60420f4..d8262d3 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -47,3 +47,13 @@ boostbook standalone chunk.first.sections=1 autodoc ; + +############################################################################### +alias boostdoc + : move + : + : autodoc + : ; +explicit boostdoc ; +alias boostrelease ; +explicit boostrelease ;