Implement observer_ptr.
authorVille Voutilainen <ville.voutilainen@gmail.com>
Fri, 1 May 2015 21:01:11 +0000 (00:01 +0300)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 1 May 2015 21:01:11 +0000 (22:01 +0100)
2015-05-01  Ville Voutilainen  <ville.voutilainen@gmail.com>

Implement observer_ptr.
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/experimental/memory: New.
* testsuite/experimental/memory/observer_ptr/assignment/assign.cc: New.
* testsuite/experimental/memory/observer_ptr/cons/cons.cc: New.
* testsuite/experimental/memory/observer_ptr/hash/hash.cc: New.
* testsuite/experimental/memory/observer_ptr/make_observer.cc: New.
* testsuite/experimental/memory/observer_ptr/relops/relops.cc: New.
* testsuite/experimental/memory/observer_ptr/requirements.cc: New.
* testsuite/experimental/memory/observer_ptr/swap/swap.cc: New.
* testsuite/experimental/memory/observer_ptr/typedefs.cc: New.

From-SVN: r222706

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/experimental/memory [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc [new file with mode: 0644]

index a955a0f506d3e436e57079a39055c06d1621580d..a899842223c689bc37f26dc2952b5455b00d39e7 100644 (file)
@@ -1,3 +1,18 @@
+2015-05-01  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       Implement observer_ptr.
+       * include/Makefile.am: Add new header.
+       * include/Makefile.in: Regenerate.
+       * include/experimental/memory: New.
+       * testsuite/experimental/memory/observer_ptr/assignment/assign.cc: New.
+       * testsuite/experimental/memory/observer_ptr/cons/cons.cc: New.
+       * testsuite/experimental/memory/observer_ptr/hash/hash.cc: New.
+       * testsuite/experimental/memory/observer_ptr/make_observer.cc: New.
+       * testsuite/experimental/memory/observer_ptr/relops/relops.cc: New.
+       * testsuite/experimental/memory/observer_ptr/requirements.cc: New.
+       * testsuite/experimental/memory/observer_ptr/swap/swap.cc: New.
+       * testsuite/experimental/memory/observer_ptr/typedefs.cc: New.
+
 2015-05-01  Jonathan Wakely  <jwakely@redhat.com>
 
        * src/filesystem/path.cc (path::compare): Do not copy strings.
index 32be43e7e04c8888cb37121edda0beb25b08fa51..6ba702c4e102d5f0a1975ad68d120ddca0aca79d 100644 (file)
@@ -653,6 +653,7 @@ experimental_headers = \
        ${experimental_srcdir}/functional \
        ${experimental_srcdir}/list \
        ${experimental_srcdir}/map \
+       ${experimental_srcdir}/memory \
        ${experimental_srcdir}/optional \
        ${experimental_srcdir}/ratio \
        ${experimental_srcdir}/set \
index e59ee689a26aba77da5fec480a5c76f2866108c3..f23ff63d540cce7b5f979faa2bfdc888b63c2304 100644 (file)
@@ -920,6 +920,7 @@ experimental_headers = \
        ${experimental_srcdir}/functional \
        ${experimental_srcdir}/list \
        ${experimental_srcdir}/map \
+       ${experimental_srcdir}/memory \
        ${experimental_srcdir}/optional \
        ${experimental_srcdir}/ratio \
        ${experimental_srcdir}/set \
diff --git a/libstdc++-v3/include/experimental/memory b/libstdc++-v3/include/experimental/memory
new file mode 100644 (file)
index 0000000..d3c9509
--- /dev/null
@@ -0,0 +1,255 @@
+// <experimental/memory> -*- C++ -*-
+
+// Copyright (C) 2015 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
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/memory
+ *  This is a TS C++ Library header.
+ */
+
+//
+// N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2
+//
+
+#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY
+#define _GLIBCXX_EXPERIMENTAL_MEMORY 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include <bits/c++14_warning.h>
+#else
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <functional>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+inline namespace fundamentals_v2
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template <typename _Tp>
+    class observer_ptr
+    {
+    public:
+      // publish our template parameter and variations thereof
+      using element_type = _Tp;
+      using __pointer = add_pointer_t<_Tp>;            // exposition-only
+      using __reference = add_lvalue_reference_t<_Tp>; // exposition-only
+
+      // 3.2.2, observer_ptr constructors
+      // default c’tor
+      constexpr observer_ptr() noexcept
+      : __t()
+      { }
+
+      // pointer-accepting c’tors
+      constexpr observer_ptr(nullptr_t) noexcept
+      : __t()
+      { }
+
+      constexpr explicit observer_ptr(__pointer __p) noexcept
+      : __t(__p)
+      { }
+
+      // copying c’tors (in addition to compiler-generated copy c’tor)
+      template <typename _Up,
+               typename = typename enable_if<
+                 is_convertible<typename add_pointer<_Up>::type, __pointer
+                 >::value
+               >::type>
+      constexpr observer_ptr(observer_ptr<_Up> __p) noexcept
+      : __t(__p.get())
+      {
+      }
+
+      // 3.2.3, observer_ptr observers
+      constexpr __pointer
+      get() const noexcept
+      {
+       return __t;
+      }
+
+      constexpr __reference
+      operator*() const
+      {
+       return *get();
+      }
+
+      constexpr __pointer
+      operator->() const noexcept
+      {
+       return get();
+      }
+
+      constexpr explicit operator bool() const noexcept
+      {
+       return get() != nullptr;
+      }
+
+      // 3.2.4, observer_ptr conversions
+      constexpr explicit operator __pointer() const noexcept
+      {
+       return get();
+      }
+
+      // 3.2.5, observer_ptr modifiers
+      constexpr __pointer
+      release() noexcept
+      {
+       __pointer tmp = get();
+       reset();
+       return tmp;
+      }
+
+      constexpr void
+      reset(__pointer __p = nullptr) noexcept
+      {
+       __t = __p;
+      }
+
+      constexpr void
+      swap(observer_ptr& __p) noexcept
+      {
+       std::swap(__t, __p.__t);
+      }
+
+    private:
+      __pointer __t;
+    }; // observer_ptr<>
+
+  template<typename _Tp>
+    void
+    swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
+    {
+      __p1.swap(__p2);
+    }
+
+  template<typename _Tp>
+    observer_ptr<_Tp>
+    make_observer(_Tp* __p) noexcept
+    {
+      return observer_ptr<_Tp>(__p);
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+      return __p1.get() == __p2.get();
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+    return !(__p1 == __p2);
+    }
+
+  template<typename _Tp>
+    bool
+    operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
+    {
+      return !__p;
+    }
+
+  template<typename _Tp>
+    bool
+    operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
+    {
+      return !__p;
+    }
+
+  template<typename _Tp>
+    bool
+    operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept
+    {
+      return bool(__p);
+    }
+
+  template<typename _Tp>
+    bool
+    operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
+    {
+      return bool(__p);
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+      return std::less<typename common_type<typename add_pointer<_Tp>::type,
+                                           typename add_pointer<_Up>::type
+                                           >::type
+                      >{}(__p1.get(), __p2.get());
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+      return __p2 < __p1;
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+      return !(__p2 < __p1);
+    }
+
+  template<typename _Tp, typename _Up>
+    bool
+    operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
+    {
+      return !(__p1 < __p2);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace fundamentals_v2
+} // namespace experimental
+
+template <typename _Tp>
+  struct hash<experimental::observer_ptr<_Tp>>
+  {
+    using result_type = size_t;
+    using argument_type = experimental::observer_ptr<_Tp>;
+
+    size_t
+    operator()(const experimental::observer_ptr<_Tp>& __t) const
+    noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get())))
+    {
+      return hash<typename add_pointer<_Tp>::type> {}(__t.get());
+    }
+
+  };
+
+} // namespace std
+
+#endif // __cplusplus <= 201103L
+
+#endif // _GLIBCXX_EXPERIMENTAL_MEMORY
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc
new file mode 100644 (file)
index 0000000..6ccf407
--- /dev/null
@@ -0,0 +1,89 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+
+using std::experimental::observer_ptr;
+
+struct B {};
+struct D : B {};
+
+void test01()
+{
+  observer_ptr<int> a, b;
+  a = b;
+  VERIFY(a == b);
+}
+
+void test02()
+{
+  int x{};
+  observer_ptr<int> a;
+  observer_ptr<int> b{&x};
+  VERIFY(a != b);
+  a = b;
+  VERIFY(a == b);
+}
+
+void test03()
+{
+  int x{};
+  observer_ptr<const int> a;
+  observer_ptr<int> b{&x};
+  VERIFY(a != b);
+  a = b;
+  VERIFY(a == b);
+}
+
+void test04()
+{
+  D x{};
+  observer_ptr<B> a;
+  observer_ptr<D> b{&x};
+  VERIFY(a != b);
+  a = b;
+  VERIFY(a == b);
+}
+
+constexpr bool test05_helper(observer_ptr<const int> a, 
+                             observer_ptr<const int> b)
+{
+  a = b;
+  return (a.get() == b.get());
+}
+
+void test05()
+{
+  static constexpr int x{};
+  constexpr observer_ptr<const int> a;
+  constexpr observer_ptr<const int> b{&x};
+  constexpr bool assigned = test05_helper(a, b);
+  VERIFY(assigned);
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  test05();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc
new file mode 100644 (file)
index 0000000..c6c435b
--- /dev/null
@@ -0,0 +1,92 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+#include <utility>
+
+using std::experimental::observer_ptr;
+
+struct B {};
+struct D : B {};
+
+void test01()
+{
+  observer_ptr<int> a;
+  VERIFY(!a);
+  observer_ptr<int> b{nullptr};
+  VERIFY(!b);
+}
+
+void test02()
+{
+  int x{};
+  observer_ptr<int> a{&x};
+  observer_ptr<int> b{a};
+  VERIFY(a == b);
+}
+
+void test03()
+{
+  int x{};
+  observer_ptr<int> a;
+  observer_ptr<const int> b{a};
+  VERIFY(a == b);
+}
+
+void test04()
+{
+  D x{};
+  observer_ptr<D> a{&x};
+  observer_ptr<B> b{a};
+  VERIFY(a == b);
+}
+
+void test05()
+{
+  D x{};
+  observer_ptr<D> a{&x};
+  observer_ptr<B> b{std::move(a)};
+  VERIFY(a == b);
+}
+
+void test06()
+{
+  static constexpr D x{};
+  constexpr observer_ptr<const D> a{&x};
+  constexpr observer_ptr<const B> b{std::move(a)};
+  VERIFY(a == b);
+  constexpr observer_ptr<const B> c{a};
+  VERIFY(a == b && a == c && b == c);
+  constexpr observer_ptr<int> d;
+  constexpr observer_ptr<int> e{nullptr};
+  VERIFY(!d);
+  VERIFY(!e);
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  test05();
+  test06();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc
new file mode 100644 (file)
index 0000000..eb318fc
--- /dev/null
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+
+using std::experimental::observer_ptr;
+
+struct B {};
+struct D : B {};
+
+void test01()
+{
+  observer_ptr<int> a;
+  VERIFY(std::hash<observer_ptr<int>>{}(a) == std::hash<int*>{}(nullptr));
+}
+
+void test02()
+{
+  int x{};
+  observer_ptr<int> a{&x};
+  VERIFY(std::hash<observer_ptr<int>>{}(a) == std::hash<int*>{}(&x));
+}
+
+int main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc
new file mode 100644 (file)
index 0000000..b6075fa
--- /dev/null
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  const int i = 42;
+  auto o = std::experimental::make_observer(&i);
+  static_assert( std::is_same<decltype(o),
+                 std::experimental::observer_ptr<const int>>(), "" );
+  VERIFY( o && *o == 42 );
+  VERIFY( o.get() == &i );
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc
new file mode 100644 (file)
index 0000000..9cf39de
--- /dev/null
@@ -0,0 +1,80 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+
+using std::experimental::observer_ptr;
+
+void test01()
+{
+  observer_ptr<int> a, b;
+  VERIFY(a == b);
+}
+
+void test02()
+{
+  int x[2]{};
+  observer_ptr<int> a{&x[0]};
+  observer_ptr<int> b{&x[1]};
+  VERIFY(a != b);
+  VERIFY(a < b);
+  VERIFY(a <= b);
+  VERIFY(b >= a);
+  VERIFY(b > a);
+}
+
+void test03()
+{
+  int x{};
+  observer_ptr<int> a{&x};
+  observer_ptr<int> b{&x};
+  VERIFY(a == b);
+}
+
+void test04()
+{
+  static constexpr int x[2]{};
+  constexpr observer_ptr<const int> a{&x[0]};
+  constexpr observer_ptr<const int> b{&x[1]};
+  VERIFY(a != b);
+  VERIFY(a < b);
+  VERIFY(a <= b);
+  VERIFY(b >= a);
+  VERIFY(b > a);
+}
+
+void test05()
+{
+  static constexpr int x{};
+  constexpr observer_ptr<const int> a{&x};
+  constexpr observer_ptr<const int> b{&x};
+  VERIFY(a == b);
+}
+
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+  test05();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc
new file mode 100644 (file)
index 0000000..36ffcab
--- /dev/null
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do compile }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+
+using std::experimental::observer_ptr;
+
+struct nontrivial {nontrivial() {}};
+struct other {};
+struct base {};
+struct derived : base {};
+
+static_assert(!std::is_trivially_constructible<
+              observer_ptr<nontrivial>>::value, "");
+static_assert(std::is_trivially_copyable<
+              observer_ptr<nontrivial>>::value, "");
+static_assert(std::is_trivially_destructible<
+              observer_ptr<nontrivial>>::value, "");
+
+static_assert(std::is_constructible<
+              observer_ptr<nontrivial>, nontrivial*>::value,
+              "");
+static_assert(std::is_constructible<observer_ptr<base>, base*>::value, "");
+static_assert(std::is_constructible<observer_ptr<base>, derived*>::value, "");
+static_assert(!std::is_constructible<observer_ptr<base>, other*>::value, "");
+static_assert(std::is_constructible<
+                observer_ptr<base>, observer_ptr<base>>::value, "");
+static_assert(std::is_constructible<
+                observer_ptr<base>, observer_ptr<derived>>::value, "");
+static_assert(!std::is_constructible<
+                observer_ptr<base>, observer_ptr<other>>::value, "");
+
+static_assert(!std::is_assignable<
+              observer_ptr<nontrivial>, nontrivial*>::value,
+              "");
+static_assert(std::is_assignable<
+              observer_ptr<nontrivial>, observer_ptr<nontrivial>>::value,
+              "");
+static_assert(std::is_assignable<observer_ptr<base>, 
+              observer_ptr<base>>::value, "");
+static_assert(std::is_assignable<observer_ptr<base>, 
+              observer_ptr<derived>>::value, "");
+static_assert(!std::is_assignable<
+                observer_ptr<base>, observer_ptr<other>>::value, "");
+static_assert(std::is_assignable<observer_ptr<const int>, 
+              observer_ptr<int>>::value, "");
+static_assert(!std::is_assignable<observer_ptr<int>, 
+              observer_ptr<const int>>::value, "");
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc
new file mode 100644 (file)
index 0000000..f7bfc2d
--- /dev/null
@@ -0,0 +1,67 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do run }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <testsuite_hooks.h>
+
+using std::experimental::observer_ptr;
+
+struct B {};
+struct D : B {};
+
+void test01()
+{
+  observer_ptr<int> a, b;
+  VERIFY(a == b);
+  swap(a, b);
+  VERIFY(a == b);
+}
+
+void test02()
+{
+  int x{};
+  observer_ptr<int> a;
+  observer_ptr<int> b{&x};
+  VERIFY(!a);
+  VERIFY(b);
+  swap(a, b);
+  VERIFY(a);
+  VERIFY(!b);
+}
+
+void test03()
+{
+  int x[2]{1,2};
+  observer_ptr<int> a{&x[0]};
+  observer_ptr<int> b{&x[1]};
+  VERIFY(*a == 1);
+  VERIFY(*b == 2);
+  swap(a, b);
+  VERIFY(*a == 2);
+  VERIFY(*b == 1);
+}
+
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+}
diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc
new file mode 100644 (file)
index 0000000..b738232
--- /dev/null
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do compile }
+
+// Copyright (C) 2015 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 moved_to of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <experimental/memory>
+#include <type_traits>
+
+static_assert(std::is_same<
+              std::experimental::observer_ptr<int>::element_type,
+              int>::value, "");
+static_assert(std::is_same<
+              std::experimental::observer_ptr<const int>::element_type,
+              const int>::value, "");
+static_assert(std::is_same<
+              std::experimental::observer_ptr<volatile int>::element_type,
+              volatile int>::value, "");