commit 4358c27ef8a0e6786e8c819038c2382c8fc1d2e5 Author: Ion GaztaƱaga Date: Thu Jul 21 17:47:15 2011 +0000 Added Move to the release branch [SVN r73281] 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