// Move, forward and identity for C++0x + swap -*- C++ -*- // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 // . /** @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 #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Used, in C++03 mode too, by allocators, etc. template inline _Tp* __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT { return reinterpret_cast<_Tp*> (&const_cast(reinterpret_cast(__r))); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #ifdef __GXX_EXPERIMENTAL_CXX0X__ #include // Brings in std::declval too. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// forward (as per N3143) template inline _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept { return static_cast<_Tp&&>(__t); } template inline _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 Move a value. * @ingroup utilities * @param __t A thing of arbitrary type. * @return Same, moved. */ template inline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return static_cast::type&&>(__t); } /** * @brief Move unless it could throw and the type is copyable. * @ingroup utilities * @param __x A thing of arbitrary type. * @return Same, possibly moved. */ template inline typename conditional<(!is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value), const _Tp&, _Tp&&>::type move_if_noexcept(_Tp& __x) noexcept { return std::move(__x); } /// declval, from type_traits. /** * @brief Returns the actual address of the object or function * referenced by r, even in the presence of an overloaded * operator&. * @ingroup utilities * @param __r Reference to an object or function. * @return The actual address. */ template inline _Tp* addressof(_Tp& __r) noexcept { return std::__addressof(__r); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #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 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Swaps two values. * @ingroup utilities * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return Nothing. */ template inline void swap(_Tp& __a, _Tp& __b) #ifdef __GXX_EXPERIMENTAL_CXX0X__ noexcept(is_nothrow_move_constructible<_Tp>::value && is_nothrow_move_assignable<_Tp>::value) #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. template inline void swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) // noexcept waits for c++/49045 { for (size_t __n = 0; __n < _Nm; ++__n) swap(__a[__n], __b[__n]); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _MOVE_H */