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