1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
// Move, forward and identity for C++11 + swap -*- C++ -*-
// Copyright (C) 2007-2017 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/move.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{utility}
*/
#ifndef _MOVE_H
#define _MOVE_H 1
#include <bits/c++config.h>
#include <bits/concept_check.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Used, in C++03 mode too, by allocators, etc.
/**
* @brief Same as C++11 std::addressof
* @ingroup utilities
*/
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR _Tp*
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{ return __builtin_addressof(__r); }
#if __cplusplus >= 201103L
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#include <type_traits> // Brings in std::declval too.
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
/**
* @brief Forward an rvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
" substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
template<typename _Tp>
struct __move_if_noexcept_cond
: public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
is_copy_constructible<_Tp>>::type { };
/**
* @brief Conditionally convert a value to an rvalue.
* @param __x A thing of arbitrary type.
* @return The parameter, possibly cast to an rvalue-reference.
*
* Same as std::move unless the type's move constructor could throw and the
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
constexpr typename
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }
// declval, from type_traits.
#if __cplusplus > 201402L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2296. std::addressof should be constexpr
# define __cpp_lib_addressof_constexpr 201603
#endif
/**
* @brief Returns the actual address of the object or function
* referenced by r, even in the presence of an overloaded
* operator&.
* @param __r Reference to an object or function.
* @return The actual address.
*/
template<typename _Tp>
inline _GLIBCXX17_CONSTEXPR _Tp*
addressof(_Tp& __r) noexcept
{ return std::__addressof(__r); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2598. addressof works on temporaries
template<typename _Tp>
const _Tp* addressof(const _Tp&&) = delete;
// C++11 version of std::exchange for internal use.
template <typename _Tp, typename _Up = _Tp>
inline _Tp
__exchange(_Tp& __obj, _Up&& __new_val)
{
_Tp __old_val = std::move(__obj);
__obj = std::forward<_Up>(__new_val);
return __old_val;
}
/// @} group utilities
#define _GLIBCXX_MOVE(__val) std::move(__val)
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
#else
#define _GLIBCXX_MOVE(__val) (__val)
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
#endif
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Swaps two values.
* @param __a A thing of arbitrary type.
* @param __b Another thing of arbitrary type.
* @return Nothing.
*/
template<typename _Tp>
inline
#if __cplusplus >= 201103L
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
is_move_constructible<_Tp>,
is_move_assignable<_Tp>>::value>::type
swap(_Tp& __a, _Tp& __b)
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value)
#else
void
swap(_Tp& __a, _Tp& __b)
#endif
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
_Tp __tmp = _GLIBCXX_MOVE(__a);
__a = _GLIBCXX_MOVE(__b);
__b = _GLIBCXX_MOVE(__tmp);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 809. std::swap should be overloaded for array types.
/// Swap the contents of two arrays.
template<typename _Tp, size_t _Nm>
inline
#if __cplusplus >= 201103L
typename enable_if<__is_swappable<_Tp>::value>::type
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
noexcept(__is_nothrow_swappable<_Tp>::value)
#else
void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
#endif
{
for (size_t __n = 0; __n < _Nm; ++__n)
swap(__a[__n], __b[__n]);
}
/// @} group utilities
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _MOVE_H */
|