11debfc3dSmrg // Move, forward and identity for C++11 + swap -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg // Copyright (C) 2007-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /** @file bits/move.h
261debfc3dSmrg * This is an internal header file, included by other library headers.
271debfc3dSmrg * Do not attempt to use it directly. @headername{utility}
281debfc3dSmrg */
291debfc3dSmrg
301debfc3dSmrg #ifndef _MOVE_H
311debfc3dSmrg #define _MOVE_H 1
321debfc3dSmrg
331debfc3dSmrg #include <bits/c++config.h>
34*8feb0f0bSmrg #if __cplusplus < 201103L
351debfc3dSmrg # include <bits/concept_check.h>
36*8feb0f0bSmrg #endif
371debfc3dSmrg
_GLIBCXX_VISIBILITY(default)381debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
391debfc3dSmrg {
401debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
411debfc3dSmrg
421debfc3dSmrg // Used, in C++03 mode too, by allocators, etc.
431debfc3dSmrg /**
441debfc3dSmrg * @brief Same as C++11 std::addressof
451debfc3dSmrg * @ingroup utilities
461debfc3dSmrg */
471debfc3dSmrg template<typename _Tp>
481debfc3dSmrg inline _GLIBCXX_CONSTEXPR _Tp*
491debfc3dSmrg __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
501debfc3dSmrg { return __builtin_addressof(__r); }
511debfc3dSmrg
52a2dc1f3fSmrg #if __cplusplus >= 201103L
53a2dc1f3fSmrg
541debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
551debfc3dSmrg } // namespace
561debfc3dSmrg
571debfc3dSmrg #include <type_traits> // Brings in std::declval too.
581debfc3dSmrg
_GLIBCXX_VISIBILITY(default)591debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
601debfc3dSmrg {
611debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
621debfc3dSmrg
631debfc3dSmrg /**
641debfc3dSmrg * @addtogroup utilities
651debfc3dSmrg * @{
661debfc3dSmrg */
671debfc3dSmrg
681debfc3dSmrg /**
691debfc3dSmrg * @brief Forward an lvalue.
701debfc3dSmrg * @return The parameter cast to the specified type.
711debfc3dSmrg *
721debfc3dSmrg * This function is used to implement "perfect forwarding".
731debfc3dSmrg */
741debfc3dSmrg template<typename _Tp>
751debfc3dSmrg constexpr _Tp&&
761debfc3dSmrg forward(typename std::remove_reference<_Tp>::type& __t) noexcept
771debfc3dSmrg { return static_cast<_Tp&&>(__t); }
781debfc3dSmrg
791debfc3dSmrg /**
801debfc3dSmrg * @brief Forward an rvalue.
811debfc3dSmrg * @return The parameter cast to the specified type.
821debfc3dSmrg *
831debfc3dSmrg * This function is used to implement "perfect forwarding".
841debfc3dSmrg */
851debfc3dSmrg template<typename _Tp>
861debfc3dSmrg constexpr _Tp&&
871debfc3dSmrg forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
881debfc3dSmrg {
89*8feb0f0bSmrg static_assert(!std::is_lvalue_reference<_Tp>::value,
90*8feb0f0bSmrg "std::forward must not be used to convert an rvalue to an lvalue");
911debfc3dSmrg return static_cast<_Tp&&>(__t);
921debfc3dSmrg }
931debfc3dSmrg
941debfc3dSmrg /**
951debfc3dSmrg * @brief Convert a value to an rvalue.
961debfc3dSmrg * @param __t A thing of arbitrary type.
971debfc3dSmrg * @return The parameter cast to an rvalue-reference to allow moving it.
981debfc3dSmrg */
991debfc3dSmrg template<typename _Tp>
1001debfc3dSmrg constexpr typename std::remove_reference<_Tp>::type&&
1011debfc3dSmrg move(_Tp&& __t) noexcept
1021debfc3dSmrg { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
1031debfc3dSmrg
1041debfc3dSmrg
1051debfc3dSmrg template<typename _Tp>
1061debfc3dSmrg struct __move_if_noexcept_cond
1071debfc3dSmrg : public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
1081debfc3dSmrg is_copy_constructible<_Tp>>::type { };
1091debfc3dSmrg
1101debfc3dSmrg /**
1111debfc3dSmrg * @brief Conditionally convert a value to an rvalue.
1121debfc3dSmrg * @param __x A thing of arbitrary type.
1131debfc3dSmrg * @return The parameter, possibly cast to an rvalue-reference.
1141debfc3dSmrg *
1151debfc3dSmrg * Same as std::move unless the type's move constructor could throw and the
1161debfc3dSmrg * type is copyable, in which case an lvalue-reference is returned instead.
1171debfc3dSmrg */
1181debfc3dSmrg template<typename _Tp>
1191debfc3dSmrg constexpr typename
1201debfc3dSmrg conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
1211debfc3dSmrg move_if_noexcept(_Tp& __x) noexcept
1221debfc3dSmrg { return std::move(__x); }
1231debfc3dSmrg
1241debfc3dSmrg // declval, from type_traits.
1251debfc3dSmrg
1261debfc3dSmrg #if __cplusplus > 201402L
1271debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
1281debfc3dSmrg // 2296. std::addressof should be constexpr
1291debfc3dSmrg # define __cpp_lib_addressof_constexpr 201603
1301debfc3dSmrg #endif
1311debfc3dSmrg /**
1321debfc3dSmrg * @brief Returns the actual address of the object or function
1331debfc3dSmrg * referenced by r, even in the presence of an overloaded
1341debfc3dSmrg * operator&.
1351debfc3dSmrg * @param __r Reference to an object or function.
1361debfc3dSmrg * @return The actual address.
1371debfc3dSmrg */
1381debfc3dSmrg template<typename _Tp>
1391debfc3dSmrg inline _GLIBCXX17_CONSTEXPR _Tp*
1401debfc3dSmrg addressof(_Tp& __r) noexcept
1411debfc3dSmrg { return std::__addressof(__r); }
1421debfc3dSmrg
1431debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
1441debfc3dSmrg // 2598. addressof works on temporaries
1451debfc3dSmrg template<typename _Tp>
1461debfc3dSmrg const _Tp* addressof(const _Tp&&) = delete;
1471debfc3dSmrg
1481debfc3dSmrg // C++11 version of std::exchange for internal use.
1491debfc3dSmrg template <typename _Tp, typename _Up = _Tp>
150*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR
1511debfc3dSmrg inline _Tp
1521debfc3dSmrg __exchange(_Tp& __obj, _Up&& __new_val)
1531debfc3dSmrg {
1541debfc3dSmrg _Tp __old_val = std::move(__obj);
1551debfc3dSmrg __obj = std::forward<_Up>(__new_val);
1561debfc3dSmrg return __old_val;
1571debfc3dSmrg }
1581debfc3dSmrg
1591debfc3dSmrg /// @} group utilities
1601debfc3dSmrg
1611debfc3dSmrg #define _GLIBCXX_MOVE(__val) std::move(__val)
1621debfc3dSmrg #define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
1631debfc3dSmrg #else
1641debfc3dSmrg #define _GLIBCXX_MOVE(__val) (__val)
1651debfc3dSmrg #define _GLIBCXX_FORWARD(_Tp, __val) (__val)
1661debfc3dSmrg #endif
1671debfc3dSmrg
1681debfc3dSmrg /**
1691debfc3dSmrg * @addtogroup utilities
1701debfc3dSmrg * @{
1711debfc3dSmrg */
1721debfc3dSmrg
1731debfc3dSmrg /**
1741debfc3dSmrg * @brief Swaps two values.
1751debfc3dSmrg * @param __a A thing of arbitrary type.
1761debfc3dSmrg * @param __b Another thing of arbitrary type.
1771debfc3dSmrg * @return Nothing.
1781debfc3dSmrg */
1791debfc3dSmrg template<typename _Tp>
180*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR
1811debfc3dSmrg inline
1821debfc3dSmrg #if __cplusplus >= 201103L
1831debfc3dSmrg typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
1841debfc3dSmrg is_move_constructible<_Tp>,
1851debfc3dSmrg is_move_assignable<_Tp>>::value>::type
1861debfc3dSmrg #else
1871debfc3dSmrg void
1881debfc3dSmrg #endif
189*8feb0f0bSmrg swap(_Tp& __a, _Tp& __b)
190*8feb0f0bSmrg _GLIBCXX_NOEXCEPT_IF(__and_<is_nothrow_move_constructible<_Tp>,
191*8feb0f0bSmrg is_nothrow_move_assignable<_Tp>>::value)
1921debfc3dSmrg {
193*8feb0f0bSmrg #if __cplusplus < 201103L
1941debfc3dSmrg // concept requirements
1951debfc3dSmrg __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
196*8feb0f0bSmrg #endif
1971debfc3dSmrg _Tp __tmp = _GLIBCXX_MOVE(__a);
1981debfc3dSmrg __a = _GLIBCXX_MOVE(__b);
1991debfc3dSmrg __b = _GLIBCXX_MOVE(__tmp);
2001debfc3dSmrg }
2011debfc3dSmrg
2021debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
2031debfc3dSmrg // DR 809. std::swap should be overloaded for array types.
2041debfc3dSmrg /// Swap the contents of two arrays.
2051debfc3dSmrg template<typename _Tp, size_t _Nm>
206*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR
2071debfc3dSmrg inline
2081debfc3dSmrg #if __cplusplus >= 201103L
2091debfc3dSmrg typename enable_if<__is_swappable<_Tp>::value>::type
2101debfc3dSmrg #else
2111debfc3dSmrg void
2121debfc3dSmrg #endif
213*8feb0f0bSmrg swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
214*8feb0f0bSmrg _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Tp>::value)
2151debfc3dSmrg {
2161debfc3dSmrg for (size_t __n = 0; __n < _Nm; ++__n)
2171debfc3dSmrg swap(__a[__n], __b[__n]);
2181debfc3dSmrg }
2191debfc3dSmrg
2201debfc3dSmrg /// @} group utilities
2211debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
2221debfc3dSmrg } // namespace
2231debfc3dSmrg
2241debfc3dSmrg #endif /* _MOVE_H */
225