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