annotate DEPENDENCIES/generic/include/boost/move/adl_move_swap.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 //////////////////////////////////////////////////////////////////////////////
Chris@102 2 //
Chris@102 3 // (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
Chris@102 4 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
Chris@102 5 // Software License, Version 1.0. (See accompanying file
Chris@102 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@102 7 //
Chris@102 8 // See http://www.boost.org/libs/container for documentation.
Chris@102 9 //
Chris@102 10 //////////////////////////////////////////////////////////////////////////////
Chris@102 11
Chris@102 12 #ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
Chris@102 13 #define BOOST_MOVE_ADL_MOVE_SWAP_HPP
Chris@102 14
Chris@102 15 #ifndef BOOST_CONFIG_HPP
Chris@102 16 # include <boost/config.hpp>
Chris@102 17 #endif
Chris@102 18 #
Chris@102 19 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@102 20 # pragma once
Chris@102 21 #endif
Chris@102 22
Chris@102 23 //Based on Boost.Core's swap.
Chris@102 24 //Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker.
Chris@102 25
Chris@102 26 #include <boost/config.hpp>
Chris@102 27 #include <cstddef> //for std::size_t
Chris@102 28
Chris@102 29 //Try to avoid including <algorithm>, as it's quite big
Chris@102 30 #if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
Chris@102 31 #include <utility> //Dinkum libraries define std::swap in utility which is lighter than algorithm
Chris@102 32 #elif defined(BOOST_GNU_STDLIB)
Chris@102 33 //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions
Chris@102 34 //use the good old stl_algobase header, which is quite lightweight
Chris@102 35 #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)))
Chris@102 36 #include <bits/stl_algobase.h>
Chris@102 37 #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
Chris@102 38 //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities
Chris@102 39 #include <bits/stl_move.h>
Chris@102 40 #else
Chris@102 41 //In GCC 4.4 stl_move.h was renamed to move.h
Chris@102 42 #include <bits/move.h>
Chris@102 43 #endif
Chris@102 44 #elif defined(_LIBCPP_VERSION)
Chris@102 45 #include <type_traits> //The initial import of libc++ defines std::swap and still there
Chris@102 46 #elif __cplusplus >= 201103L
Chris@102 47 #include <utility> //Fallback for C++ >= 2011
Chris@102 48 #else
Chris@102 49 #include <algorithm> //Fallback for C++98/03
Chris@102 50 #endif
Chris@102 51
Chris@102 52 #include <boost/move/utility_core.hpp> //for boost::move
Chris@102 53
Chris@102 54 #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
Chris@102 55
Chris@102 56 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Chris@102 57 namespace boost_move_member_swap {
Chris@102 58
Chris@102 59 struct dont_care
Chris@102 60 {
Chris@102 61 dont_care(...);
Chris@102 62 };
Chris@102 63
Chris@102 64 struct private_type
Chris@102 65 {
Chris@102 66 static private_type p;
Chris@102 67 private_type const &operator,(int) const;
Chris@102 68 };
Chris@102 69
Chris@102 70 typedef char yes_type;
Chris@102 71 struct no_type{ char dummy[2]; };
Chris@102 72
Chris@102 73 template<typename T>
Chris@102 74 no_type is_private_type(T const &);
Chris@102 75
Chris@102 76 yes_type is_private_type(private_type const &);
Chris@102 77
Chris@102 78 template <typename Type>
Chris@102 79 class has_member_function_named_swap
Chris@102 80 {
Chris@102 81 struct BaseMixin
Chris@102 82 {
Chris@102 83 void swap();
Chris@102 84 };
Chris@102 85
Chris@102 86 struct Base : public Type, public BaseMixin { Base(); };
Chris@102 87 template <typename T, T t> class Helper{};
Chris@102 88
Chris@102 89 template <typename U>
Chris@102 90 static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
Chris@102 91 static yes_type deduce(...);
Chris@102 92
Chris@102 93 public:
Chris@102 94 static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
Chris@102 95 };
Chris@102 96
Chris@102 97 template<typename Fun, bool HasFunc>
Chris@102 98 struct has_member_swap_impl
Chris@102 99 {
Chris@102 100 static const bool value = false;
Chris@102 101 };
Chris@102 102
Chris@102 103 template<typename Fun>
Chris@102 104 struct has_member_swap_impl<Fun, true>
Chris@102 105 {
Chris@102 106 struct FunWrap : Fun
Chris@102 107 {
Chris@102 108 FunWrap();
Chris@102 109
Chris@102 110 using Fun::swap;
Chris@102 111 private_type swap(dont_care) const;
Chris@102 112 };
Chris@102 113
Chris@102 114 static Fun &declval_fun();
Chris@102 115 static FunWrap declval_wrap();
Chris@102 116
Chris@102 117 static bool const value =
Chris@102 118 sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
Chris@102 119 };
Chris@102 120
Chris@102 121 template<typename Fun>
Chris@102 122 struct has_member_swap : public has_member_swap_impl
Chris@102 123 <Fun, has_member_function_named_swap<Fun>::value>
Chris@102 124 {};
Chris@102 125
Chris@102 126 } //namespace boost_move_member_swap
Chris@102 127
Chris@102 128 namespace boost_move_adl_swap{
Chris@102 129
Chris@102 130 template<class P1, class P2, bool = P1::value>
Chris@102 131 struct and_op_impl
Chris@102 132 { static const bool value = false; };
Chris@102 133
Chris@102 134 template<class P1, class P2>
Chris@102 135 struct and_op_impl<P1, P2, true>
Chris@102 136 { static const bool value = P2::value; };
Chris@102 137
Chris@102 138 template<class P1, class P2>
Chris@102 139 struct and_op
Chris@102 140 : and_op_impl<P1, P2>
Chris@102 141 {};
Chris@102 142
Chris@102 143 //////
Chris@102 144
Chris@102 145 template<class P1, class P2, bool = P1::value>
Chris@102 146 struct and_op_not_impl
Chris@102 147 { static const bool value = false; };
Chris@102 148
Chris@102 149 template<class P1, class P2>
Chris@102 150 struct and_op_not_impl<P1, P2, true>
Chris@102 151 { static const bool value = !P2::value; };
Chris@102 152
Chris@102 153 template<class P1, class P2>
Chris@102 154 struct and_op_not
Chris@102 155 : and_op_not_impl<P1, P2>
Chris@102 156 {};
Chris@102 157
Chris@102 158 template<class T>
Chris@102 159 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)
Chris@102 160 {
Chris@102 161 //use std::swap if argument dependent lookup fails
Chris@102 162 //Use using directive ("using namespace xxx;") instead as some older compilers
Chris@102 163 //don't do ADL with using declarations ("using ns::func;").
Chris@102 164 using namespace std;
Chris@102 165 swap(x, y);
Chris@102 166 }
Chris@102 167
Chris@102 168 template<class T>
Chris@102 169 void swap_proxy(T& x, T& y
Chris@102 170 , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
Chris@102 171 , boost_move_member_swap::has_member_swap<T> >
Chris@102 172 >::type* = 0)
Chris@102 173 { T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t); }
Chris@102 174
Chris@102 175 template<class T>
Chris@102 176 void swap_proxy(T& x, T& y
Chris@102 177 , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T>
Chris@102 178 , boost_move_member_swap::has_member_swap<T> >
Chris@102 179 >::type* = 0)
Chris@102 180 { x.swap(y); }
Chris@102 181
Chris@102 182 } //namespace boost_move_adl_swap{
Chris@102 183
Chris@102 184 #else
Chris@102 185
Chris@102 186 namespace boost_move_adl_swap{
Chris@102 187
Chris@102 188 template<class T>
Chris@102 189 void swap_proxy(T& x, T& y)
Chris@102 190 {
Chris@102 191 using std::swap;
Chris@102 192 swap(x, y);
Chris@102 193 }
Chris@102 194
Chris@102 195 } //namespace boost_move_adl_swap{
Chris@102 196
Chris@102 197 #endif //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Chris@102 198
Chris@102 199 namespace boost_move_adl_swap{
Chris@102 200
Chris@102 201 template<class T, std::size_t N>
Chris@102 202 void swap_proxy(T (& x)[N], T (& y)[N])
Chris@102 203 {
Chris@102 204 for (std::size_t i = 0; i < N; ++i){
Chris@102 205 ::boost_move_adl_swap::swap_proxy(x[i], y[i]);
Chris@102 206 }
Chris@102 207 }
Chris@102 208
Chris@102 209 } //namespace boost_move_adl_swap {
Chris@102 210
Chris@102 211 #endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
Chris@102 212
Chris@102 213 namespace boost{
Chris@102 214
Chris@102 215 //! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a
Chris@102 216 //! specialized swap function if available. If no specialized swap function is available,
Chris@102 217 //! std::swap is used.
Chris@102 218 //!
Chris@102 219 //! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has
Chris@102 220 //! no rvalue references then:
Chris@102 221 //!
Chris@102 222 //! - If T has a <code>T::swap(T&)</code> member, that member is called.
Chris@102 223 //! - Otherwise a move-based swap is called, equivalent to:
Chris@102 224 //! <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>.
Chris@102 225 template<class T>
Chris@102 226 void adl_move_swap(T& x, T& y)
Chris@102 227 {
Chris@102 228 ::boost_move_adl_swap::swap_proxy(x, y);
Chris@102 229 }
Chris@102 230
Chris@102 231 } //namespace boost{
Chris@102 232
Chris@102 233 #endif //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP