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