267 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			267 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | ////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | // (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker | ||
|  | // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost | ||
|  | // Software License, Version 1.0. (See accompanying file | ||
|  | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|  | // | ||
|  | // See http://www.boost.org/libs/container for documentation. | ||
|  | // | ||
|  | ////////////////////////////////////////////////////////////////////////////// | ||
|  | 
 | ||
|  | #ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP | ||
|  | #define BOOST_MOVE_ADL_MOVE_SWAP_HPP | ||
|  | 
 | ||
|  | #ifndef BOOST_CONFIG_HPP | ||
|  | #  include <boost/config.hpp> | ||
|  | #endif | ||
|  | # | ||
|  | #if defined(BOOST_HAS_PRAGMA_ONCE) | ||
|  | #  pragma once | ||
|  | #endif | ||
|  | 
 | ||
|  | //Based on Boost.Core's swap. | ||
|  | //Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker. | ||
|  | #include <cstddef> //for std::size_t | ||
|  | #include <boost/move/detail/workaround.hpp>  //forceinline | ||
|  | 
 | ||
|  | //Try to avoid including <algorithm>, as it's quite big | ||
|  | #if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB) | ||
|  |    #include <utility>   //Dinkum libraries define std::swap in utility which is lighter than algorithm | ||
|  | #elif defined(BOOST_GNU_STDLIB) | ||
|  |    //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions | ||
|  |    //use the good old stl_algobase header, which is quite lightweight | ||
|  |    #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3))) | ||
|  |       #include <bits/stl_algobase.h> | ||
|  |    #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) | ||
|  |       //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities | ||
|  |       #include <bits/stl_move.h> | ||
|  |    #else | ||
|  |       //In GCC 4.4 stl_move.h was renamed to move.h | ||
|  |       #include <bits/move.h> | ||
|  |    #endif | ||
|  | #elif defined(_LIBCPP_VERSION) | ||
|  |    #include <type_traits>  //The initial import of libc++ defines std::swap and still there | ||
|  | #elif __cplusplus >= 201103L | ||
|  |    #include <utility>    //Fallback for C++ >= 2011 | ||
|  | #else | ||
|  |    #include <algorithm>  //Fallback for C++98/03 | ||
|  | #endif | ||
|  | 
 | ||
|  | #include <boost/move/utility_core.hpp> //for boost::move | ||
|  | 
 | ||
|  | #if !defined(BOOST_MOVE_DOXYGEN_INVOKED) | ||
|  | 
 | ||
|  | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | ||
|  | namespace boost_move_member_swap { | ||
|  | 
 | ||
|  | struct dont_care | ||
|  | { | ||
|  |    dont_care(...); | ||
|  | }; | ||
|  | 
 | ||
|  | struct private_type | ||
|  | { | ||
|  |    static private_type p; | ||
|  |    private_type const &operator,(int) const; | ||
|  | }; | ||
|  | 
 | ||
|  | typedef char yes_type;             | ||
|  | struct no_type{ char dummy[2]; };  | ||
|  | 
 | ||
|  | template<typename T> | ||
|  | no_type is_private_type(T const &); | ||
|  | 
 | ||
|  | yes_type is_private_type(private_type const &); | ||
|  | 
 | ||
|  | template <typename Type> | ||
|  | class has_member_function_named_swap | ||
|  | { | ||
|  |    struct BaseMixin | ||
|  |    { | ||
|  |       void swap(); | ||
|  |    }; | ||
|  | 
 | ||
|  |    struct Base : public Type, public BaseMixin { Base(); }; | ||
|  |    template <typename T, T t> class Helper{}; | ||
|  | 
 | ||
|  |    template <typename U> | ||
|  |    static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0); | ||
|  |    static yes_type deduce(...); | ||
|  | 
 | ||
|  |    public: | ||
|  |    static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0))); | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename Fun, bool HasFunc> | ||
|  | struct has_member_swap_impl | ||
|  | { | ||
|  |    static const bool value = false; | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename Fun> | ||
|  | struct has_member_swap_impl<Fun, true> | ||
|  | { | ||
|  |    struct FunWrap : Fun | ||
|  |    { | ||
|  |       FunWrap(); | ||
|  | 
 | ||
|  |       using Fun::swap; | ||
|  |       private_type swap(dont_care) const; | ||
|  |    }; | ||
|  | 
 | ||
|  |    static Fun &declval_fun(); | ||
|  |    static FunWrap declval_wrap(); | ||
|  | 
 | ||
|  |    static bool const value = | ||
|  |       sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) ); | ||
|  | }; | ||
|  | 
 | ||
|  | template<typename Fun> | ||
|  | struct has_member_swap : public has_member_swap_impl | ||
|  |       <Fun, has_member_function_named_swap<Fun>::value> | ||
|  | {}; | ||
|  | 
 | ||
|  | }  //namespace boost_move_member_swap | ||
|  | 
 | ||
|  | namespace boost_move_adl_swap{ | ||
|  | 
 | ||
|  | template<class P1, class P2, bool = P1::value> | ||
|  | struct and_op_impl | ||
|  | {  static const bool value = false; }; | ||
|  | 
 | ||
|  | template<class P1, class P2> | ||
|  | struct and_op_impl<P1, P2, true> | ||
|  | {  static const bool value = P2::value;   }; | ||
|  | 
 | ||
|  | template<class P1, class P2> | ||
|  | struct and_op | ||
|  |    : and_op_impl<P1, P2> | ||
|  | {}; | ||
|  | 
 | ||
|  | ////// | ||
|  | 
 | ||
|  | template<class P1, class P2, bool = P1::value> | ||
|  | struct and_op_not_impl | ||
|  | {  static const bool value = false; }; | ||
|  | 
 | ||
|  | template<class P1, class P2> | ||
|  | struct and_op_not_impl<P1, P2, true> | ||
|  | {  static const bool value = !P2::value;   }; | ||
|  | 
 | ||
|  | template<class P1, class P2> | ||
|  | struct and_op_not | ||
|  |    : and_op_not_impl<P1, P2> | ||
|  | {}; | ||
|  | 
 | ||
|  | template<class T> | ||
|  | BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0) | ||
|  | { | ||
|  |    //use std::swap if argument dependent lookup fails | ||
|  |    //Use using directive ("using namespace xxx;") instead as some older compilers | ||
|  |    //don't do ADL with using declarations ("using ns::func;"). | ||
|  |    using namespace std; | ||
|  |    swap(x, y); | ||
|  | } | ||
|  | 
 | ||
|  | template<class T> | ||
|  | BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y | ||
|  |                , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T> | ||
|  |                                                                         , boost_move_member_swap::has_member_swap<T> > | ||
|  |                                                        >::type* = 0) | ||
|  | {  T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);  } | ||
|  | 
 | ||
|  | template<class T> | ||
|  | BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y | ||
|  |                , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T> | ||
|  |                                                                     , boost_move_member_swap::has_member_swap<T> > | ||
|  |                                                        >::type* = 0) | ||
|  | {  x.swap(y);  } | ||
|  | 
 | ||
|  | }  //namespace boost_move_adl_swap{ | ||
|  | 
 | ||
|  | #else | ||
|  | 
 | ||
|  | namespace boost_move_adl_swap{ | ||
|  | 
 | ||
|  | template<class T> | ||
|  | BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y) | ||
|  | { | ||
|  |    using std::swap; | ||
|  |    swap(x, y); | ||
|  | } | ||
|  | 
 | ||
|  | }  //namespace boost_move_adl_swap{ | ||
|  | 
 | ||
|  | #endif   //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | ||
|  | 
 | ||
|  | namespace boost_move_adl_swap{ | ||
|  | 
 | ||
|  | template<class T, std::size_t N> | ||
|  | void swap_proxy(T (& x)[N], T (& y)[N]) | ||
|  | { | ||
|  |    for (std::size_t i = 0; i < N; ++i){ | ||
|  |       ::boost_move_adl_swap::swap_proxy(x[i], y[i]); | ||
|  |    } | ||
|  | } | ||
|  | 
 | ||
|  | }  //namespace boost_move_adl_swap { | ||
|  | 
 | ||
|  | #endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED) | ||
|  | 
 | ||
|  | namespace boost{ | ||
|  | 
 | ||
|  | //! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a | ||
|  | //! specialized swap function if available. If no specialized swap function is available, | ||
|  | //! std::swap is used. | ||
|  | //! | ||
|  | //! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has | ||
|  | //! no rvalue references then: | ||
|  | //! | ||
|  | //!   -  If T has a <code>T::swap(T&)</code> member, that member is called. | ||
|  | //!   -  Otherwise a move-based swap is called, equivalent to:  | ||
|  | //!      <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>. | ||
|  | template<class T> | ||
|  | BOOST_MOVE_FORCEINLINE void adl_move_swap(T& x, T& y) | ||
|  | { | ||
|  |    ::boost_move_adl_swap::swap_proxy(x, y); | ||
|  | } | ||
|  | 
 | ||
|  | //! Exchanges elements between range [first1, last1) and another range starting at first2 | ||
|  | //! using boost::adl_move_swap. | ||
|  | //!  | ||
|  | //! Parameters: | ||
|  | //!   first1, last1   -   the first range of elements to swap | ||
|  | //!   first2   -   beginning of the second range of elements to swap | ||
|  | //! | ||
|  | //! Type requirements: | ||
|  | //!   - ForwardIt1, ForwardIt2 must meet the requirements of ForwardIterator. | ||
|  | //!   - The types of dereferenced ForwardIt1 and ForwardIt2 must meet the | ||
|  | //!     requirements of Swappable | ||
|  | //! | ||
|  | //! Return value: Iterator to the element past the last element exchanged in the range | ||
|  | //! beginning with first2. | ||
|  | template<class ForwardIt1, class ForwardIt2> | ||
|  | ForwardIt2 adl_move_swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2) | ||
|  | { | ||
|  |     while (first1 != last1) { | ||
|  |       ::boost::adl_move_swap(*first1, *first2); | ||
|  |       ++first1; | ||
|  |       ++first2; | ||
|  |     } | ||
|  |    return first2; | ||
|  | } | ||
|  | 
 | ||
|  | template<class BidirIt1, class BidirIt2> | ||
|  | BidirIt2 adl_move_swap_ranges_backward(BidirIt1 first1, BidirIt1 last1, BidirIt2 last2) | ||
|  | { | ||
|  |    while (first1 != last1) { | ||
|  |       ::boost::adl_move_swap(*(--last1), *(--last2)); | ||
|  |    } | ||
|  |    return last2; | ||
|  | } | ||
|  | 
 | ||
|  | }  //namespace boost{ | ||
|  | 
 | ||
|  | #endif   //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP |