xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/move.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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