utility (exchange): Define.
authorJonathan Wakely <jwakely.gcc@gmail.com>
Sat, 18 May 2013 16:18:35 +0000 (16:18 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Sat, 18 May 2013 16:18:35 +0000 (17:18 +0100)
* include/std/utility (exchange): Define.
* testsuite/20_util/exchange/1.cc: New.

From-SVN: r199061

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/utility
libstdc++-v3/testsuite/20_util/exchange/1.cc [new file with mode: 0644]

index 3fba85c1989955b5cd105f8c82f16b4b104fe516..0f9cee846282c86359b4705c9414c9ffddc76ccd 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-18  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+       * include/std/utility (exchange): Define.
+       * testsuite/20_util/exchange/1.cc: New.
+
 2013-05-18  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
        * include/bits/unique_ptr.h (make_unique): Define.
index 8142ea466e4e6510af2cb7b14ec0d630b501dfa9..ee8c6b19609e62be1abe5c4709db0b66e260fec8 100644 (file)
@@ -152,6 +152,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     get(const std::pair<_Tp1, _Tp2>& __in) noexcept
     { return __pair_get<_Int>::__const_get(__in); }
 
+#if __cplusplus > 201103L
+  /// Assign @p __new_val to @p __obj and return its previous value.
+  template <class _Tp, class _Up = _Tp>
+    inline _Tp
+    exchange(_Tp& __obj, _Up&& __new_val)
+    {
+      _Tp __old_val = std::move(__obj);
+      __obj = std::forward<_Up>(__new_val);
+      return __old_val;
+    }
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git a/libstdc++-v3/testsuite/20_util/exchange/1.cc b/libstdc++-v3/testsuite/20_util/exchange/1.cc
new file mode 100644 (file)
index 0000000..d16d9e9
--- /dev/null
@@ -0,0 +1,103 @@
+// { dg-options "-std=gnu++1y" }
+
+// Copyright (C) 2013 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 20.2.3 exchange [utility.exchange]
+
+#include <utility>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  const unsigned val = 4;
+  int i = 1;
+  auto prev = std::exchange(i, val);
+  static_assert( std::is_same<decltype(prev), int>::value, "return type" );
+  VERIFY( i == 4 );
+  VERIFY( prev == 1 );
+  prev = std::exchange(i, 3);
+  VERIFY( i == 3 );
+  VERIFY( prev == 4 );
+}
+
+// Default construction from empty braces
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  struct DefaultConstructible
+  {
+    DefaultConstructible(int i = 0) : value(i) { }
+    int value;
+  };
+
+  DefaultConstructible x = 1;
+  auto old = std::exchange(x, {});
+  VERIFY( x.value == 0 );
+  VERIFY( old.value == 1 );
+}
+
+// Deduce type of overloaded function
+void
+test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  int (*fp)(int);
+  int f(int);
+  double f(double);
+  std::exchange(fp, &f);
+  VERIFY( fp != nullptr );
+}
+
+void test04()
+{
+  struct From { };
+  struct To {
+    int value = 0;
+    To() = default;
+    To(const To&) = default;
+    To(const From&) = delete;
+    To& operator=(const From&) { value = 1; }
+    To& operator=(From&&) { value = 2; }
+  };
+
+  To t;
+  From f;
+
+  auto prev = std::exchange(t, f);
+  VERIFY( t.value == 1 );
+  VERIFY( prev.value == 0 );
+
+  prev = std::exchange(t, From{});
+  VERIFY( t.value == 2 );
+  VERIFY( prev.value == 1 );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  return 0;
+}