123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (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>
- inline void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0)
- {
- //use std::swap if argument dependent lookup fails
- //Use using directive ("using namespace xxx;") instead as some older compilers
- //don't do ADL with using declarations ("using ns::func;").
- using namespace std;
- swap(x, y);
- }
- template<class T>
- void swap_proxy(T& x, T& y
- , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
- , boost_move_member_swap::has_member_swap<T> >
- >::type* = 0)
- { T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t); }
- template<class T>
- inline 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>
- inline 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>
- inline 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;
- }
- template<class ForwardIt1, class ForwardIt2>
- void adl_move_iter_swap(ForwardIt1 a, ForwardIt2 b)
- {
- boost::adl_move_swap(*a, *b);
- }
- } //namespace boost{
- #endif //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
|