Add deduction guides for C++17 (P0433R2, partial)
authorJonathan Wakely <jwakely@redhat.com>
Wed, 22 Mar 2017 15:58:35 +0000 (15:58 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 22 Mar 2017 15:58:35 +0000 (15:58 +0000)
* include/bits/shared_ptr.h (shared_ptr, weak_ptr): Add deduction
guides for C++17.
* include/bits/std_function.h (function): Likewise.
* include/bits/stl_pair.h (pair): Likewise.
* include/debug/array (__gnu_debug::array): Likewise.
* include/std/array (array): Likewise.
* include/std/functional (make_default_searcher)
(make_boyer_moore_searcher, make_boyer_moore_horspool_searcher):
Remove generator functions.
* include/std/tuple (tuple): Add deduction guides.
* include/std/valarray (valarray): Likewise.
* testsuite/20_util/function_objects/searchers.cc: Adjust to use
class template argument deduction instead of generator functions.
* testsuite/20_util/function/cons/deduction.cc: New test.
* testsuite/20_util/optional/cons/deduction_guide.cc: Rename to ...
* testsuite/20_util/optional/cons/deduction.cc: ... here.
* testsuite/20_util/pair/cons/deduction.cc: New test.
* testsuite/20_util/shared_ptr/cons/deduction.cc: New test.
* testsuite/20_util/tuple/cons/deduction.cc: New test.
* testsuite/20_util/tuple/element_access/get_neg.cc: Adjust dg-error.
* testsuite/20_util/unique_ptr/cons/deduction_neg.cc: New test.
* testsuite/20_util/weak_ptr/cons/deduction.cc: New test.
* testsuite/23_containers/array/cons/deduction.cc: New test.
* testsuite/23_containers/array/cons/deduction_neg.cc: New test.
* testsuite/23_containers/array/tuple_interface/get_debug_neg.cc:
Adjust dg-error.
* testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise.
* testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
Likewise.
* testsuite/26_numerics/valarray/deduction.cc: New test.
* testsuite/30_threads/lock_guard/cons/deduction.cc: New test.
* testsuite/30_threads/scoped_lock/cons/deduction.cc: New test.
* testsuite/30_threads/unique_lock/cons/deduction.cc: New test.

From-SVN: r246389

28 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/shared_ptr.h
libstdc++-v3/include/bits/std_function.h
libstdc++-v3/include/bits/stl_pair.h
libstdc++-v3/include/debug/array
libstdc++-v3/include/std/array
libstdc++-v3/include/std/functional
libstdc++-v3/include/std/tuple
libstdc++-v3/include/std/valarray
libstdc++-v3/testsuite/20_util/function/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/function_objects/searchers.cc
libstdc++-v3/testsuite/20_util/optional/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc [deleted file]
libstdc++-v3/testsuite/20_util/pair/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/tuple/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
libstdc++-v3/testsuite/20_util/unique_ptr/cons/deduction_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/weak_ptr/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/array/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/array/cons/deduction_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
libstdc++-v3/testsuite/26_numerics/valarray/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/lock_guard/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/scoped_lock/cons/deduction.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/unique_lock/cons/deduction.cc [new file with mode: 0644]

index 6114393e6e44b6d0053c41a2705a82c16707ee6c..56a80c7ce6251657a6b80cf233ac7bd09559bbb8 100644 (file)
@@ -1,3 +1,39 @@
+2017-03-22  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/shared_ptr.h (shared_ptr, weak_ptr): Add deduction
+       guides for C++17.
+       * include/bits/std_function.h (function): Likewise.
+       * include/bits/stl_pair.h (pair): Likewise.
+       * include/debug/array (__gnu_debug::array): Likewise.
+       * include/std/array (array): Likewise.
+       * include/std/functional (make_default_searcher)
+       (make_boyer_moore_searcher, make_boyer_moore_horspool_searcher):
+       Remove generator functions.
+       * include/std/tuple (tuple): Add deduction guides.
+       * include/std/valarray (valarray): Likewise.
+       * testsuite/20_util/function_objects/searchers.cc: Adjust to use
+       class template argument deduction instead of generator functions.
+       * testsuite/20_util/function/cons/deduction.cc: New test.
+       * testsuite/20_util/optional/cons/deduction_guide.cc: Rename to ...
+       * testsuite/20_util/optional/cons/deduction.cc: ... here.
+       * testsuite/20_util/pair/cons/deduction.cc: New test.
+       * testsuite/20_util/shared_ptr/cons/deduction.cc: New test.
+       * testsuite/20_util/tuple/cons/deduction.cc: New test.
+       * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust dg-error.
+       * testsuite/20_util/unique_ptr/cons/deduction_neg.cc: New test.
+       * testsuite/20_util/weak_ptr/cons/deduction.cc: New test.
+       * testsuite/23_containers/array/cons/deduction.cc: New test.
+       * testsuite/23_containers/array/cons/deduction_neg.cc: New test.
+       * testsuite/23_containers/array/tuple_interface/get_debug_neg.cc:
+       Adjust dg-error.
+       * testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise.
+       * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
+       Likewise.
+       * testsuite/26_numerics/valarray/deduction.cc: New test.
+       * testsuite/30_threads/lock_guard/cons/deduction.cc: New test.
+       * testsuite/30_threads/scoped_lock/cons/deduction.cc: New test.
+       * testsuite/30_threads/unique_lock/cons/deduction.cc: New test.
+
 2017-03-20  François Dumont  <fdumont@gcc.gnu.org>
 
        * include/bits/stl_deque.h (deque): Access allocator value_type only if
index 851f9cfa60c2a6111ff6bf09d523f3cb68c021f8..fe933ff2afecd0c2906127c5fdcbcf8631a0225c 100644 (file)
@@ -355,6 +355,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       friend class weak_ptr<_Tp>;
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _Tp>
+    shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;
+  template<typename _Tp, typename _Del>
+    shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;
+#endif
+
   // 20.7.2.2.7 shared_ptr comparisons
   template<typename _Tp, typename _Up>
     inline bool
@@ -577,6 +584,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return shared_ptr<_Tp>(*this, std::nothrow); }
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _Tp>
+    weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;
+#endif
+
   // 20.7.2.3.6 weak_ptr specialized algorithms.
   template<typename _Tp>
     inline void
index 7d77e213b502aadab683f92948ee241ec0666b89..b393a944818f30604a62ee4e9529e4f140874965 100644 (file)
@@ -629,6 +629,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Invoker_type _M_invoker;
   };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename>
+    struct __function_guide_helper
+    { };
+
+  template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+    struct __function_guide_helper<
+      _Res (_Tp::*) (_Args...) noexcept(_Nx)
+    >
+    { using type = _Res(_Args...); };
+
+  template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+    struct __function_guide_helper<
+      _Res (_Tp::*) (_Args...) & noexcept(_Nx)
+    >
+    { using type = _Res(_Args...); };
+
+  template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+    struct __function_guide_helper<
+      _Res (_Tp::*) (_Args...) const noexcept(_Nx)
+    >
+    { using type = _Res(_Args...); };
+
+  template<typename _Res, typename _Tp, bool _Nx, typename... _Args>
+    struct __function_guide_helper<
+      _Res (_Tp::*) (_Args...) const & noexcept(_Nx)
+    >
+    { using type = _Res(_Args...); };
+
+  template<typename _Res, typename... _ArgTypes>
+    function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>;
+
+  template<typename _Functor, typename _Signature = typename
+          __function_guide_helper<decltype(&_Functor::operator())>::type>
+    function(_Functor) -> function<_Signature>;
+#endif
+
   // Out-of-line member definitions.
   template<typename _Res, typename... _ArgTypes>
     function<_Res(_ArgTypes...)>::
index e5e9f1c8c433ee34d5cacd5533a0c8d6bfb20512..66f52b3358e9156624c218d87a749eab39dbab93 100644 (file)
@@ -425,6 +425,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
+#endif
+
   /// Two pairs of the same type are equal iff their members are equal.
   template<typename _T1, typename _T2>
     inline _GLIBCXX_CONSTEXPR bool
index 3ff786a1247161d76fc2ee03533e7a32ef1a5ace..9c279221040a64f8e779708934921a98ead1861c 100644 (file)
@@ -225,6 +225,13 @@ namespace __debug
       { return _AT_Type::_S_ptr(_M_elems); }
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _Tp, typename... _Up>
+    array(_Tp, _Up...)
+      -> array<std::enable_if_t<(std::is_same_v<_Tp, _Up> && ...), _Tp>,
+              1 + sizeof...(_Up)>;
+#endif
+
   // Array comparisons.
   template<typename _Tp, std::size_t _Nm>
     inline bool
index 261f2af4cedbae04ce067377854181bda6fdfc27..1c7d6dc4ab128b1100d51c9271a04e80089dcb6f 100644 (file)
@@ -239,6 +239,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { return _AT_Type::_S_ptr(_M_elems); }
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _Tp, typename... _Up>
+    array(_Tp, _Up...)
+      -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
+              1 + sizeof...(_Up)>;
+#endif
+
   // Array comparisons.
   template<typename _Tp, std::size_t _Nm>
     inline bool
index ae5bc0a3bf9388972f9a2301918d6aca13197d6d..3db10cade1c8f4db68054d58aecb97a73397bdbf 100644 (file)
@@ -1175,36 +1175,6 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
       _RAIter _M_pat_end;
     };
 
-  /// Generator function for default_searcher
-  template<typename _ForwardIterator,
-          typename _BinaryPredicate = std::equal_to<>>
-    inline default_searcher<_ForwardIterator, _BinaryPredicate>
-    make_default_searcher(_ForwardIterator __pat_first,
-                         _ForwardIterator __pat_last,
-                         _BinaryPredicate __pred = _BinaryPredicate())
-    { return { __pat_first, __pat_last, __pred }; }
-
-  /// Generator function for boyer_moore_searcher
-  template<typename _RAIter, typename _Hash
-            = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
-          typename _BinaryPredicate = equal_to<>>
-    inline boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>
-    make_boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last,
-                             _Hash __hf = _Hash(),
-                             _BinaryPredicate __pred = _BinaryPredicate())
-    { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; }
-
-  /// Generator function for boyer_moore_horspool_searcher
-  template<typename _RAIter, typename _Hash
-            = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
-          typename _BinaryPredicate = equal_to<>>
-    inline boyer_moore_horspool_searcher<_RAIter, _Hash, _BinaryPredicate>
-    make_boyer_moore_horspool_searcher(_RAIter __pat_first, _RAIter __pat_last,
-                                      _Hash __hf = _Hash(),
-                                      _BinaryPredicate __pred
-                                      = _BinaryPredicate())
-    { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; }
-
   template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
     boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
     boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end,
index f53daf1b1828fc21c324007fbb4c46dd14ccb683..ae495d9dc513e69ce26ce5a0a35e554c8fee8516 100644 (file)
@@ -872,6 +872,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { _Inherited::_M_swap(__in); }
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename... _UTypes>
+    tuple(_UTypes...) -> tuple<_UTypes...>;
+  template<typename _T1, typename _T2>
+    tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
+  template<typename _Alloc, typename... _UTypes>
+    tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
+  template<typename _Alloc, typename _T1, typename _T2>
+    tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
+  template<typename _Alloc, typename... _UTypes>
+    tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
+#endif
+
   // Explicit specialization, zero-element tuple.
   template<>
     class tuple<>
index ad506503c93fc6e0e4fa44348c528db9f187b831..2dc6e42ca05273e6e68d08aad0922c77a52355cc 100644 (file)
@@ -563,6 +563,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       friend class _Array<_Tp>;
     };
 
+#if __cpp_deduction_guides >= 201606
+  template<typename _Tp, size_t _Nm>
+    valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>;
+#endif
+
   template<typename _Tp>
     inline const _Tp&
     valarray<_Tp>::operator[](size_t __i) const
diff --git a/libstdc++-v3/testsuite/20_util/function/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/function/cons/deduction.cc
new file mode 100644 (file)
index 0000000..a4346e0
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <functional>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void f0v();
+void f0vn() noexcept;
+int f0i();
+int f0in() noexcept;
+long f1l(int&);
+long f1ln(double*) noexcept;
+
+void
+test01()
+{
+  std::function func1 = f0v;
+  check_type<std::function<void()>>(func1);
+
+  std::function func2 = f0vn;
+  check_type<std::function<void()>>(func2);
+
+  std::function func3 = f0i;
+  check_type<std::function<int()>>(func3);
+
+  std::function func4 = f0in;
+  check_type<std::function<int()>>(func4);
+
+  std::function func5 = f1l;
+  check_type<std::function<long(int&)>>(func5);
+
+  std::function func6 = f1ln;
+  check_type<std::function<long(double*)>>(func6);
+
+  std::function func5a = func5;
+  check_type<std::function<long(int&)>>(func5a);
+
+  std::function func6a = func6;
+  check_type<std::function<long(double*)>>(func6a);
+}
+
+struct X {
+  int operator()(const short&, void*);
+};
+
+struct Y {
+  void operator()(int) const & noexcept;
+};
+
+void
+test02()
+{
+  X x;
+  std::function func1 = x;
+  check_type<std::function<int(const short&, void*)>>(func1);
+
+  Y y;
+  std::function func2 = y;
+  check_type<std::function<void(int)>>(func2);
+
+  std::function func3 = [&x](float) -> X& { return x; };
+  check_type<std::function<X&(float)>>(func3);
+}
index 0506ea49069a7d4a4b309929584366a6283ef222..9cc1455c85cad28b82fd96b1033050decd7cf9af 100644 (file)
@@ -31,9 +31,9 @@
 # error "Feature-test macro for searchers has wrong value"
 #endif
 
-using std::make_default_searcher;
-using std::make_boyer_moore_searcher;
-using std::make_boyer_moore_horspool_searcher;
+using std::default_searcher;
+using std::boyer_moore_searcher;
+using std::boyer_moore_horspool_searcher;
 
 void
 test01()
@@ -50,9 +50,9 @@ test01()
   for (auto n : needles)
   {
     auto ne = n + std::strlen(n);
-    auto d = make_default_searcher(n, ne);
-    auto bm = make_boyer_moore_searcher(n, ne);
-    auto bmh = make_boyer_moore_horspool_searcher(n, ne);
+    default_searcher d(n, ne);
+    boyer_moore_searcher bm(n, ne);
+    boyer_moore_horspool_searcher bmh(n, ne);
     for (auto h : haystacks)
     {
       auto he = h + std::strlen(h);
@@ -83,9 +83,9 @@ test02()
   for (auto n : needles)
   {
     auto ne = n + std::wcslen(n);
-    auto d = make_default_searcher(n, ne);
-    auto bm = make_boyer_moore_searcher(n, ne);
-    auto bmh = make_boyer_moore_horspool_searcher(n, ne);
+    default_searcher d(n, ne);
+    boyer_moore_searcher bm(n, ne);
+    boyer_moore_horspool_searcher bmh(n, ne);
     for (auto h : haystacks)
     {
       auto he = h + std::wcslen(h);
@@ -122,9 +122,9 @@ test03()
   const char* ne = needle + std::strlen(needle);
   const char* he = haystack + std::strlen(haystack);
 
-  auto d = make_default_searcher(needle, ne, eq);
-  auto bm = make_boyer_moore_searcher(needle, ne, eq, eq);
-  auto bmh = make_boyer_moore_horspool_searcher(needle, ne, eq, eq);
+  default_searcher d(needle, ne, eq);
+  boyer_moore_searcher bm(needle, ne, eq, eq);
+  boyer_moore_horspool_searcher bmh(needle, ne, eq, eq);
 
   auto res = std::search(haystack, he, needle, ne, eq);
   auto d_res = d(haystack, he);
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/optional/cons/deduction.cc
new file mode 100644 (file)
index 0000000..e15db0b
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+#include <optional>
+#include <type_traits>
+
+struct MoveOnly
+{
+  MoveOnly() = default;
+  MoveOnly(MoveOnly&&) {}
+  MoveOnly& operator=(MoveOnly&&) {}
+};
+
+int main()
+{
+  std::optional x = 5;
+  static_assert(std::is_same_v<decltype(x), std::optional<int>>);
+  int y = 42;
+  std::optional x2 = y;
+  static_assert(std::is_same_v<decltype(x2), std::optional<int>>);
+  const int z = 666;
+  std::optional x3 = z;
+  static_assert(std::is_same_v<decltype(x3), std::optional<int>>);
+  std::optional mo = MoveOnly();
+  static_assert(std::is_same_v<decltype(mo), std::optional<MoveOnly>>);
+  mo = MoveOnly();
+
+  std::optional copy = x;
+  static_assert(std::is_same_v<decltype(copy), std::optional<int>>);
+  std::optional move = std::move(mo);
+  static_assert(std::is_same_v<decltype(move), std::optional<MoveOnly>>);
+}
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc b/libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc
deleted file mode 100644 (file)
index 59698dc..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-// Copyright (C) 2017 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/>.
-
-#include <optional>
-#include <type_traits>
-
-struct MoveOnly
-{
-  MoveOnly() = default;
-  MoveOnly(MoveOnly&&) {}
-  MoveOnly& operator=(MoveOnly&&) {}
-};
-
-int main()
-{
-    std::optional x = 5;
-    static_assert(std::is_same_v<decltype(x), std::optional<int>>);
-    int y = 42;
-    std::optional x2 = y;
-    static_assert(std::is_same_v<decltype(x2), std::optional<int>>);
-    const int z = 666;
-    std::optional x3 = z;
-    static_assert(std::is_same_v<decltype(x3), std::optional<int>>);
-    std::optional mo = MoveOnly();
-    static_assert(std::is_same_v<decltype(mo), std::optional<MoveOnly>>);
-    mo = MoveOnly();
-}
diff --git a/libstdc++-v3/testsuite/20_util/pair/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/pair/cons/deduction.cc
new file mode 100644 (file)
index 0000000..c8e6fd6
--- /dev/null
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+// Copyright (C) 2017 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/>.
+
+#include <utility>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+struct MoveOnly
+{
+  MoveOnly() = default;
+  MoveOnly(MoveOnly&&) {}
+  MoveOnly& operator=(MoveOnly&&) {}
+};
+
+void
+test01()
+{
+  std::pair x{5, 6u};
+  check_type<std::pair<int, unsigned>>(x);
+  int y = 42;
+  std::pair x2{y, 48u};
+  check_type<std::pair<int, unsigned>>(x2);
+  const int z = 666;
+  std::pair x3{z, y};
+  check_type<std::pair<int, int>>(x3);
+  std::pair x4{1, x};
+  check_type<std::pair<int, std::pair<int, unsigned>>>(x4);
+  std::pair mo{MoveOnly(), 2l};
+  check_type<std::pair<MoveOnly, long>>(mo);
+  mo = {MoveOnly(), 3l};
+
+  std::pair copy = x;
+  check_type<decltype(x)>(copy);
+  std::pair copy2{x};
+  check_type<decltype(x)>(copy2);
+  std::pair move = std::move(mo);
+  check_type<decltype(mo)>(move);
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/deduction.cc
new file mode 100644 (file)
index 0000000..ecd0780
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <memory>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::shared_ptr<long> s;
+  std::shared_ptr s2 = s;
+  check_type<std::shared_ptr<long>>(s2);
+
+  std::weak_ptr<long> w;
+  std::shared_ptr s3(w);
+  check_type<std::shared_ptr<long>>(s3);
+
+  struct D { void operator()(double*) { } };
+  std::unique_ptr<double, D> u;
+  std::shared_ptr s4 = std::move(u);
+  check_type<std::shared_ptr<double>>(s4);
+}
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/deduction.cc
new file mode 100644 (file)
index 0000000..47e2488
--- /dev/null
@@ -0,0 +1,166 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+// Copyright (C) 2017 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/>.
+
+#include <tuple>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+struct MoveOnly
+{
+  MoveOnly() = default;
+  MoveOnly(MoveOnly&&) {}
+  MoveOnly& operator=(MoveOnly&&) {}
+};
+
+void
+test00()
+{
+  std::tuple x;
+  check_type<std::tuple<>>(x);
+
+  std::tuple copy = x;
+  check_type<decltype(x)>(copy);
+  std::tuple move = std::move(x);
+  check_type<decltype(x)>(move);
+}
+
+void
+test01()
+{
+  std::tuple x = 5;
+  check_type<std::tuple<int>>(x);
+  int y = 42;
+  std::tuple x2 = y;
+  check_type<std::tuple<int>>(x2);
+  const int z = 666;
+  std::tuple x3 = z;
+  check_type<std::tuple<int>>(x3);
+  std::tuple mo = MoveOnly();
+  check_type<std::tuple<MoveOnly>>(mo);
+  mo = MoveOnly();
+
+  std::tuple copy = x;
+  check_type<decltype(x)>(copy);
+  std::tuple move = std::move(mo);
+  check_type<decltype(mo)>(move);
+}
+
+void
+test02()
+{
+  std::tuple x{5, 6u};
+  check_type<std::tuple<int, unsigned>>(x);
+  int y = 42;
+  std::tuple x2{y, 48u};
+  check_type<std::tuple<int, unsigned>>(x2);
+  const int z = 666;
+  std::tuple x3{z, y};
+  check_type<std::tuple<int, int>>(x3);
+  std::tuple x4{1, x};
+  check_type<std::tuple<int, decltype(x)>>(x4);
+  std::tuple mo{MoveOnly(), 2l};
+  check_type<std::tuple<MoveOnly, long>>(mo);
+  mo = {MoveOnly(), 3l};
+
+  std::tuple copy = x;
+  check_type<decltype(x)>(copy);
+  std::tuple copy2{x};
+  check_type<decltype(x)>(copy2);
+  std::tuple move = std::move(mo);
+  check_type<decltype(mo)>(move);
+}
+
+void
+test03()
+{
+  std::tuple x{5, 6u, '7'};
+  check_type<std::tuple<int, unsigned, char>>(x);
+  int y = 42;
+  std::tuple x2{y, 48u, 54l};
+  check_type<std::tuple<int, unsigned, long>>(x2);
+  const int z = 666;
+  std::tuple x3{z, y, x};
+  check_type<std::tuple<int, int, decltype(x)>>(x3);
+  std::tuple x4{1, x, x2};
+  check_type<std::tuple<int, decltype(x), decltype(x2)>>(x4);
+  std::tuple mo{MoveOnly(), 2l};
+  check_type<std::tuple<MoveOnly, long>>(mo);
+  mo = {MoveOnly(), 3l};
+
+  std::tuple copy = x;
+  check_type<decltype(x)>(copy);
+  std::tuple copy2{x};
+  check_type<decltype(x)>(copy2);
+  std::tuple move = std::move(mo);
+  check_type<decltype(mo)>(move);
+}
+
+void
+test04()
+{
+  std::pair<int, unsigned> p;
+  std::tuple x = p;
+  check_type<std::tuple<int, unsigned>>(x);
+  int y = 42;
+  std::tuple x2{p};
+  check_type<std::tuple<int, unsigned>>(x2);
+  const int z = 666;
+  std::pair<const int, unsigned> p2;
+  std::tuple x3{p2};
+  check_type<std::tuple<const int, unsigned>>(x3);
+  std::pair<int&, const unsigned&> p3{p.first, p.second};
+  std::tuple x4{p3};
+  check_type<std::tuple<int&, const unsigned&>>(x4);
+  std::tuple mo = std::pair<MoveOnly, MoveOnly>();
+  check_type<std::tuple<MoveOnly, MoveOnly>>(mo);
+
+  std::tuple copy = x4;
+  check_type<decltype(x4)>(copy);
+  std::tuple copy2{x4};
+  check_type<decltype(x4)>(copy2);
+  std::tuple move = std::move(mo);
+  check_type<decltype(mo)>(move);
+}
+
+void
+test05()
+{
+  std::allocator<double> a;
+  std::tuple x{std::allocator_arg, a, 1};
+  check_type<std::tuple<int>>(x);
+  std::tuple x2{std::allocator_arg, a, 1, '2'};
+  check_type<std::tuple<int, char>>(x2);
+
+  std::pair<float, const short> p{};
+  std::tuple x3{std::allocator_arg, a, p};
+  check_type<std::tuple<float, const short>>(x3);
+  std::tuple x4{std::allocator_arg, a, std::move(p)};
+  check_type<std::tuple<float, const short>>(x4);
+
+  std::tuple x5{std::allocator_arg, a, x};
+  check_type<decltype(x)>(x5);
+  std::tuple x6{std::allocator_arg, a, std::move(x)};
+  check_type<decltype(x)>(x6);
+}
index 0dc62a226b8a686f5cf3e016e4bcd315f5f02854..03835f40188f4d4815b046c94a2fea23eb4c9e2b 100644 (file)
@@ -17,7 +17,7 @@
 
 // { dg-options "-fno-show-column" }
 // { dg-do compile { target c++14 } }
-// { dg-error "in range" "" { target *-*-* } 1284 }
+// { dg-error "in range" "" { target *-*-* } 1297 }
 
 #include <tuple>
 
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/deduction_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/deduction_neg.cc
new file mode 100644 (file)
index 0000000..23aca62
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <memory>
+
+void
+test01()
+{
+  std::unique_ptr<long> s;
+  std::unique_ptr s2 = std::move(s); // OK
+
+  std::unique_ptr bad{new int}; // { dg-error "class template argument deduction failed" }
+
+  struct D { void operator()(double*) { } };
+  std::unique_ptr bad2{new double, D()}; // { dg-error "class template argument deduction failed" }
+}
+
+// { dg-error "no matching function" "" { target *-*-* } 29 }
+// { dg-error "no matching function" "" { target *-*-* } 32 }
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/cons/deduction.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/cons/deduction.cc
new file mode 100644 (file)
index 0000000..ea38417
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <memory>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::shared_ptr<long> s;
+  std::weak_ptr w(s);
+  check_type<std::weak_ptr<long>>(w);
+
+  std::weak_ptr w2(w);
+  check_type<std::weak_ptr<long>>(w2);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/array/cons/deduction.cc
new file mode 100644 (file)
index 0000000..5ce2909
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <array>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::array a1{ 1, 2, 3 };
+  check_type<std::array<int, 3>>(a1);
+  int y = 2;
+  const int z = 3;
+  std::array a2{ 1, y, z };
+  check_type<std::array<int, 3>>(a2);
+  std::array a3{ 'a', 'b', 'c', 'd', 'e' };
+  check_type<std::array<char, 5>>(a3);
+
+  std::array copy = a1;
+  check_type<decltype(a1)>(copy);
+  std::array move = std::move(a1);
+  check_type<decltype(a1)>(move);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/cons/deduction_neg.cc b/libstdc++-v3/testsuite/23_containers/array/cons/deduction_neg.cc
new file mode 100644 (file)
index 0000000..ec11b05
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <array>
+
+void
+test01()
+{
+  std::array a1{}; // { dg-error "class template argument deduction failed" }
+  std::array a2{1, 2u, 3}; // { dg-error "class template argument deduction failed" }
+}
+// { dg-error "no matching function for call" "" { target *-*-* } 26 }
+// { dg-error "no matching function for call" "" { target *-*-* } 27 }
+// { dg-error "no type named .*enable_if" "" { target *-*-* } 0 }
index 03d284b0a4ea8aaf7d4cfc7eae7c1c6f464fd5c7..81d8b931753ac9b11bfa861434f89352d2e9e734 100644 (file)
@@ -27,6 +27,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 281 }
-// { dg-error "static assertion failed" "" { target *-*-* } 290 }
-// { dg-error "static assertion failed" "" { target *-*-* } 298 }
+// { dg-error "static assertion failed" "" { target *-*-* } 288 }
+// { dg-error "static assertion failed" "" { target *-*-* } 297 }
+// { dg-error "static assertion failed" "" { target *-*-* } 305 }
index 0b9ca95f57a108bdfcf5736fe962f8110331d668..8983ad7c7b289c9aa5187ce2a89e2762653bee54 100644 (file)
@@ -27,6 +27,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 302 }
-// { dg-error "static assertion failed" "" { target *-*-* } 311 }
-// { dg-error "static assertion failed" "" { target *-*-* } 319 }
+// { dg-error "static assertion failed" "" { target *-*-* } 309 }
+// { dg-error "static assertion failed" "" { target *-*-* } 318 }
+// { dg-error "static assertion failed" "" { target *-*-* } 326 }
index c6a8d00218f90ef04c9744826e76a79ecfd7cd1b..493449a235ba6fd078d91d7f58c8ceb6a7f072b0 100644 (file)
@@ -22,4 +22,4 @@
 
 typedef std::tuple_element<1, std::array<int, 1>>::type type;
 
-// { dg-error "static assertion failed" "" { target *-*-* } 350 }
+// { dg-error "static assertion failed" "" { target *-*-* } 357 }
diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/deduction.cc b/libstdc++-v3/testsuite/26_numerics/valarray/deduction.cc
new file mode 100644 (file)
index 0000000..72d4bc0
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <valarray>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  int arr[4] = { 1, 2, 3, 4 };
+  std::valarray v(arr, 4);
+  check_type<std::valarray<int>>(v);
+
+  std::valarray v2 = v;
+  check_type<std::valarray<int>>(v2);
+
+  std::valarray v3 = std::move(v);
+  check_type<std::valarray<int>>(v3);
+}
diff --git a/libstdc++-v3/testsuite/30_threads/lock_guard/cons/deduction.cc b/libstdc++-v3/testsuite/30_threads/lock_guard/cons/deduction.cc
new file mode 100644 (file)
index 0000000..b72c1a1
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <mutex>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::mutex m;
+  std::lock_guard l(m);
+  check_type<std::lock_guard<std::mutex>>(l);
+
+  struct Mutex {
+    void lock() { }
+    void unlock() { }
+  } m2;
+
+  std::lock_guard l2(m2);
+  check_type<std::lock_guard<Mutex>>(l2);
+}
diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/deduction.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/deduction.cc
new file mode 100644 (file)
index 0000000..399de7a
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <mutex>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::scoped_lock l0;
+  check_type<std::scoped_lock<>>(l0);
+
+  struct BasicLockable {
+    void lock() { }
+    void unlock() { }
+  } m1;
+
+  std::scoped_lock l1(m1);
+  check_type<std::scoped_lock<BasicLockable>>(l1);
+
+  struct Lockable {
+    void lock() { }
+    void unlock() { }
+    bool try_lock() { return true; }
+  } m2;
+
+  std::mutex m3;
+  std::scoped_lock l2(m2, m3);
+  check_type<std::scoped_lock<Lockable, std::mutex>>(l2);
+}
diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/deduction.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/deduction.cc
new file mode 100644 (file)
index 0000000..4f36bab
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2017 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+
+#include <mutex>
+
+template<typename T, typename U> struct require_same;
+template<typename T> struct require_same<T, T> { using type = void; };
+
+template<typename T, typename U>
+  typename require_same<T, U>::type
+  check_type(U&) { }
+
+void
+test01()
+{
+  std::mutex m;
+  std::unique_lock l(m);
+  check_type<std::unique_lock<std::mutex>>(l);
+
+  struct Mutex {
+    void lock() { }
+    void unlock() { }
+  } m2;
+
+  std::unique_lock l2(m2);
+  check_type<std::unique_lock<Mutex>>(l2);
+}