1951a39d68df598db08dfced8b4707755864a0492Ying Wang// Move, forward and identity for C++0x + swap -*- C++ -*-
2951a39d68df598db08dfced8b4707755864a0492Ying Wang
3951a39d68df598db08dfced8b4707755864a0492Ying Wang// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
4951a39d68df598db08dfced8b4707755864a0492Ying Wang//
5951a39d68df598db08dfced8b4707755864a0492Ying Wang// This file is part of the GNU ISO C++ Library.  This library is free
6951a39d68df598db08dfced8b4707755864a0492Ying Wang// software; you can redistribute it and/or modify it under the
7951a39d68df598db08dfced8b4707755864a0492Ying Wang// terms of the GNU General Public License as published by the
8951a39d68df598db08dfced8b4707755864a0492Ying Wang// Free Software Foundation; either version 3, or (at your option)
9951a39d68df598db08dfced8b4707755864a0492Ying Wang// any later version.
10951a39d68df598db08dfced8b4707755864a0492Ying Wang
11951a39d68df598db08dfced8b4707755864a0492Ying Wang// This library is distributed in the hope that it will be useful,
12951a39d68df598db08dfced8b4707755864a0492Ying Wang// but WITHOUT ANY WARRANTY; without even the implied warranty of
13951a39d68df598db08dfced8b4707755864a0492Ying Wang// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14951a39d68df598db08dfced8b4707755864a0492Ying Wang// GNU General Public License for more details.
15951a39d68df598db08dfced8b4707755864a0492Ying Wang
16951a39d68df598db08dfced8b4707755864a0492Ying Wang// Under Section 7 of GPL version 3, you are granted additional
17951a39d68df598db08dfced8b4707755864a0492Ying Wang// permissions described in the GCC Runtime Library Exception, version
18951a39d68df598db08dfced8b4707755864a0492Ying Wang// 3.1, as published by the Free Software Foundation.
19951a39d68df598db08dfced8b4707755864a0492Ying Wang
20951a39d68df598db08dfced8b4707755864a0492Ying Wang// You should have received a copy of the GNU General Public License and
21951a39d68df598db08dfced8b4707755864a0492Ying Wang// a copy of the GCC Runtime Library Exception along with this program;
22951a39d68df598db08dfced8b4707755864a0492Ying Wang// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23951a39d68df598db08dfced8b4707755864a0492Ying Wang// <http://www.gnu.org/licenses/>.
24951a39d68df598db08dfced8b4707755864a0492Ying Wang
25951a39d68df598db08dfced8b4707755864a0492Ying Wang/** @file move.h
26951a39d68df598db08dfced8b4707755864a0492Ying Wang *  This is an internal header file, included by other library headers.
27951a39d68df598db08dfced8b4707755864a0492Ying Wang *  You should not attempt to use it directly.
28951a39d68df598db08dfced8b4707755864a0492Ying Wang */
29951a39d68df598db08dfced8b4707755864a0492Ying Wang
30951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifndef _MOVE_H
31951a39d68df598db08dfced8b4707755864a0492Ying Wang#define _MOVE_H 1
32951a39d68df598db08dfced8b4707755864a0492Ying Wang
33951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <bits/c++config.h>
34951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <cstddef>
35951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <bits/concept_check.h>
36951a39d68df598db08dfced8b4707755864a0492Ying Wang
37951a39d68df598db08dfced8b4707755864a0492Ying Wang#ifdef __GXX_EXPERIMENTAL_CXX0X__
38951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <type_traits>
39951a39d68df598db08dfced8b4707755864a0492Ying Wang
40951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_BEGIN_NAMESPACE(std)
41951a39d68df598db08dfced8b4707755864a0492Ying Wang
42951a39d68df598db08dfced8b4707755864a0492Ying Wang  // 20.2.2, forward/move
43951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Tp>
44951a39d68df598db08dfced8b4707755864a0492Ying Wang    struct identity
45951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
46951a39d68df598db08dfced8b4707755864a0492Ying Wang      typedef _Tp type;
47951a39d68df598db08dfced8b4707755864a0492Ying Wang    };
48951a39d68df598db08dfced8b4707755864a0492Ying Wang
49951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Tp>
50951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline _Tp&&
513123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    forward(typename std::remove_reference<_Tp>::type& __t)
523123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#ifdef __clang__
533123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    { return static_cast<_Tp&&>(__t); }
543123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#else
55951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return __t; }
563123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#endif
573123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh
583123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh  template<typename _Tp>
593123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    inline _Tp&&
603123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    forward(typename std::remove_reference<_Tp>::type&& __t)
613123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    {
623123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#ifdef __clang__
633123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh      static_assert(!std::is_lvalue_reference<_Tp>::value,
643123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh                    "Can't instantiate this forward() with an"
653123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh                    " lvalue reference type.");
663123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh      return static_cast<_Tp&&>(__t);
673123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#else
683123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh      return __t;
693123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#endif
703123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    }
71951a39d68df598db08dfced8b4707755864a0492Ying Wang
72951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Tp>
73951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline typename std::remove_reference<_Tp>::type&&
74951a39d68df598db08dfced8b4707755864a0492Ying Wang    move(_Tp&& __t)
753123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#ifdef __clang__
763123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh    { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
773123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#else
78951a39d68df598db08dfced8b4707755864a0492Ying Wang    { return __t; }
793123853ede6209e485fb7110bdcd38aea0f33d23Andrew Hsieh#endif
80951a39d68df598db08dfced8b4707755864a0492Ying Wang
81951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_END_NAMESPACE
82951a39d68df598db08dfced8b4707755864a0492Ying Wang
83951a39d68df598db08dfced8b4707755864a0492Ying Wang#define _GLIBCXX_MOVE(_Tp) std::move(_Tp)
84951a39d68df598db08dfced8b4707755864a0492Ying Wang#else
85951a39d68df598db08dfced8b4707755864a0492Ying Wang#define _GLIBCXX_MOVE(_Tp) (_Tp)
86951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif
87951a39d68df598db08dfced8b4707755864a0492Ying Wang
88951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_BEGIN_NAMESPACE(std)
89951a39d68df598db08dfced8b4707755864a0492Ying Wang
90951a39d68df598db08dfced8b4707755864a0492Ying Wang  /**
91951a39d68df598db08dfced8b4707755864a0492Ying Wang   *  @brief Swaps two values.
92951a39d68df598db08dfced8b4707755864a0492Ying Wang   *  @param  a  A thing of arbitrary type.
93951a39d68df598db08dfced8b4707755864a0492Ying Wang   *  @param  b  Another thing of arbitrary type.
94951a39d68df598db08dfced8b4707755864a0492Ying Wang   *  @return   Nothing.
95951a39d68df598db08dfced8b4707755864a0492Ying Wang  */
96951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Tp>
97951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
98951a39d68df598db08dfced8b4707755864a0492Ying Wang    swap(_Tp& __a, _Tp& __b)
99951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
100951a39d68df598db08dfced8b4707755864a0492Ying Wang      // concept requirements
101951a39d68df598db08dfced8b4707755864a0492Ying Wang      __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
102951a39d68df598db08dfced8b4707755864a0492Ying Wang
103951a39d68df598db08dfced8b4707755864a0492Ying Wang      _Tp __tmp = _GLIBCXX_MOVE(__a);
104951a39d68df598db08dfced8b4707755864a0492Ying Wang      __a = _GLIBCXX_MOVE(__b);
105951a39d68df598db08dfced8b4707755864a0492Ying Wang      __b = _GLIBCXX_MOVE(__tmp);
106951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
107951a39d68df598db08dfced8b4707755864a0492Ying Wang
108951a39d68df598db08dfced8b4707755864a0492Ying Wang  // _GLIBCXX_RESOLVE_LIB_DEFECTS
109951a39d68df598db08dfced8b4707755864a0492Ying Wang  // DR 809. std::swap should be overloaded for array types.
110951a39d68df598db08dfced8b4707755864a0492Ying Wang  template<typename _Tp, size_t _Nm>
111951a39d68df598db08dfced8b4707755864a0492Ying Wang    inline void
112951a39d68df598db08dfced8b4707755864a0492Ying Wang    swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
113951a39d68df598db08dfced8b4707755864a0492Ying Wang    {
114951a39d68df598db08dfced8b4707755864a0492Ying Wang      for (size_t __n = 0; __n < _Nm; ++__n)
115951a39d68df598db08dfced8b4707755864a0492Ying Wang	swap(__a[__n], __b[__n]);
116951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
117951a39d68df598db08dfced8b4707755864a0492Ying Wang
118951a39d68df598db08dfced8b4707755864a0492Ying Wang_GLIBCXX_END_NAMESPACE
119951a39d68df598db08dfced8b4707755864a0492Ying Wang
120951a39d68df598db08dfced8b4707755864a0492Ying Wang#endif /* _MOVE_H */
121