[libcxx-commits] [libcxx] r365788 - [libc++] Implement deduction guides for <unordered_set>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 11 08:16:39 PDT 2019


Author: ldionne
Date: Thu Jul 11 08:16:39 2019
New Revision: 365788

URL: http://llvm.org/viewvc/llvm-project?rev=365788&view=rev
Log:
[libc++] Implement deduction guides for <unordered_set>

Thanks to Arthur O'Dwyer for the patch.
Differential Revision: https://reviews.llvm.org/D58617

Added:
    libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp
    libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp
    libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp
    libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp
Modified:
    libcxx/trunk/include/unordered_set

Modified: libcxx/trunk/include/unordered_set
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_set?rev=365788&r1=365787&r2=365788&view=diff
==============================================================================
--- libcxx/trunk/include/unordered_set (original)
+++ libcxx/trunk/include/unordered_set Thu Jul 11 08:16:39 2019
@@ -383,9 +383,9 @@ public:
     // types
     typedef _Value                                                     key_type;
     typedef key_type                                                   value_type;
-    typedef _Hash                                                      hasher;
-    typedef _Pred                                                      key_equal;
-    typedef _Alloc                                                     allocator_type;
+    typedef typename __identity<_Hash>::type                           hasher;
+    typedef typename __identity<_Pred>::type                           key_equal;
+    typedef typename __identity<_Alloc>::type                          allocator_type;
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
@@ -733,6 +733,62 @@ public:
 
 };
 
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _InputIterator,
+         class _Hash = hash<__iter_value_type<_InputIterator>>,
+         class _Pred = equal_to<__iter_value_type<_InputIterator>>,
+         class _Allocator = allocator<__iter_value_type<_InputIterator>>,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<!__is_allocator<_Pred>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
+
+template<class _Tp, class _Hash = hash<_Tp>,
+         class _Pred = equal_to<_Tp>,
+         class _Allocator = allocator<_Tp>,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<!__is_allocator<_Pred>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
+
+template<class _InputIterator, class _Allocator,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(_InputIterator, _InputIterator,
+              typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_set<__iter_value_type<_InputIterator>,
+                   hash<__iter_value_type<_InputIterator>>,
+                   equal_to<__iter_value_type<_InputIterator>>,
+                   _Allocator>;
+
+template<class _InputIterator, class _Hash, class _Allocator,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(_InputIterator, _InputIterator,
+              typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_set<__iter_value_type<_InputIterator>, _Hash,
+                   equal_to<__iter_value_type<_InputIterator>>,
+                   _Allocator>;
+
+template<class _Tp, class _Allocator,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+template<class _Tp, class _Hash, class _Allocator,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+#endif
+
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
         const hasher& __hf, const key_equal& __eql)
@@ -986,9 +1042,9 @@ public:
     // types
     typedef _Value                                                     key_type;
     typedef key_type                                                   value_type;
-    typedef _Hash                                                      hasher;
-    typedef _Pred                                                      key_equal;
-    typedef _Alloc                                                     allocator_type;
+    typedef typename __identity<_Hash>::type                           hasher;
+    typedef typename __identity<_Pred>::type                           key_equal;
+    typedef typename __identity<_Alloc>::type                          allocator_type;
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
@@ -1304,6 +1360,60 @@ public:
 
 };
 
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template<class _InputIterator,
+         class _Hash = hash<__iter_value_type<_InputIterator>>,
+         class _Pred = equal_to<__iter_value_type<_InputIterator>>,
+         class _Allocator = allocator<__iter_value_type<_InputIterator>>,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<!__is_allocator<_Pred>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
+
+template<class _Tp, class _Hash = hash<_Tp>,
+         class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<!__is_allocator<_Pred>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0,
+              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
+  -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
+
+template<class _InputIterator, class _Allocator,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_multiset<__iter_value_type<_InputIterator>,
+                   hash<__iter_value_type<_InputIterator>>,
+                   equal_to<__iter_value_type<_InputIterator>>,
+                   _Allocator>;
+
+template<class _InputIterator, class _Hash, class _Allocator,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type,
+              _Hash, _Allocator)
+  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash,
+                   equal_to<__iter_value_type<_InputIterator>>,
+                   _Allocator>;
+
+template<class _Tp, class _Allocator,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
+  -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
+
+template<class _Tp, class _Hash, class _Allocator,
+         class = _EnableIf<!__is_allocator<_Hash>::value>,
+         class = _EnableIf<!is_integral<_Hash>::value>,
+         class = _EnableIf<__is_allocator<_Allocator>::value>>
+unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
+  -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
+#endif
+
 template <class _Value, class _Hash, class _Pred, class _Alloc>
 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         size_type __n, const hasher& __hf, const key_equal& __eql)

Added: libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp?rev=365788&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp (added)
+++ libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp Thu Jul 11 08:16:39 2019
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+//        class Hash = hash<iter-value-type<InputIterator>>,
+//        class Pred = equal_to<iter-value-type<InputIterator>>,
+//        class Allocator = allocator<iter-value-type<InputIterator>>>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type = see below,
+//                    Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_multiset<iter-value-type<InputIterator>,
+//                         Hash, Pred, Allocator>;
+//
+// template<class T, class Hash = hash<T>,
+//        class Pred = equal_to<T>, class Allocator = allocator<T>>
+// unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
+//                    Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_multiset<T, Hash, Pred, Allocator>;
+//
+// template<class InputIterator, class Allocator>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator)
+//   -> unordered_multiset<iter-value-type<InputIterator>,
+//                         hash<iter-value-type<InputIterator>>,
+//                         equal_to<iter-value-type<InputIterator>>,
+//                         Allocator>;
+//
+// template<class InputIterator, class Hash, class Allocator>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
+//                    Hash, Allocator)
+//   -> unordered_multiset<iter-value-type<InputIterator>, Hash,
+//                         equal_to<iter-value-type<InputIterator>>,
+//                         Allocator>;
+//
+// template<class T, class Allocator>
+// unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
+//   -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;
+//
+// template<class T, class Hash, class Allocator>
+// unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
+//   -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;
+
+#include <functional>
+#include <unordered_set>
+
+int main(int, char**)
+{
+    {
+        // cannot deduce Key from nothing
+        std::unordered_multiset s;
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size)
+        std::unordered_multiset s(42);
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash)
+        std::unordered_multiset s(42, std::hash<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Pred)
+        std::unordered_multiset s(42, std::hash<int>(), std::equal_to<>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Pred, Allocator)
+        std::unordered_multiset s(42, std::hash<int>(), std::equal_to<>(), std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Allocator)
+        std::unordered_multiset s(std::allocator<int>{});
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Allocator)
+        std::unordered_multiset s(42, std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Allocator)
+        std::unordered_multiset s(42, std::hash<short>(), std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+    }
+
+    return 0;
+}

Added: libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp?rev=365788&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp Thu Jul 11 08:16:39 2019
@@ -0,0 +1,196 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+//        class Hash = hash<iter-value-type<InputIterator>>,
+//        class Pred = equal_to<iter-value-type<InputIterator>>,
+//        class Allocator = allocator<iter-value-type<InputIterator>>>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type = see below,
+//                    Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_multiset<iter-value-type<InputIterator>,
+//                         Hash, Pred, Allocator>;
+//
+// template<class T, class Hash = hash<T>,
+//        class Pred = equal_to<T>, class Allocator = allocator<T>>
+// unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
+//                    Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_multiset<T, Hash, Pred, Allocator>;
+//
+// template<class InputIterator, class Allocator>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator)
+//   -> unordered_multiset<iter-value-type<InputIterator>,
+//                         hash<iter-value-type<InputIterator>>,
+//                         equal_to<iter-value-type<InputIterator>>,
+//                         Allocator>;
+//
+// template<class InputIterator, class Hash, class Allocator>
+// unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
+//                    Hash, Allocator)
+//   -> unordered_multiset<iter-value-type<InputIterator>, Hash,
+//                         equal_to<iter-value-type<InputIterator>>,
+//                         Allocator>;
+//
+// template<class T, class Allocator>
+// unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
+//   -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;
+//
+// template<class T, class Hash, class Allocator>
+// unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
+//   -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;
+
+#include <algorithm> // is_permutation
+#include <cassert>
+#include <climits> // INT_MAX
+#include <type_traits>
+#include <unordered_set>
+
+#include "test_allocator.h"
+
+int main(int, char**)
+{
+    const int expected_s[] = {1, 1, 2, 3, INT_MAX};
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr), 42);
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr), 42, std::hash<short>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<int>(0, 40));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 40);
+    }
+
+    {
+    std::unordered_multiset<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_multiset s(source);
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    }
+
+    {
+    std::unordered_multiset<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_multiset s{source};  // braces instead of parens
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    }
+
+    {
+    std::unordered_multiset<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_multiset s(source, test_allocator<int>(0, 41));
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    assert(s.get_allocator().get_id() == 41);
+    }
+
+    {
+    std::unordered_multiset<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_multiset s{source, test_allocator<int>(0, 42)};  // braces instead of parens
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    assert(s.get_allocator().get_id() == 42);
+    }
+
+    {
+    std::unordered_multiset s{ 1, 2, 1, INT_MAX, 3 };
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42);
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), std::equal_to<>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>, std::equal_to<>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<int>(0, 43));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>, std::equal_to<>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 43);
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr), 42, test_allocator<int>(0, 44));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 44);
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_multiset s(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<int>(0, 44));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 44);
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42, test_allocator<int>(0, 43));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 43);
+    }
+
+    {
+    std::unordered_multiset s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), test_allocator<int>(0, 42));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 42);
+    }
+
+    return 0;
+}

Added: libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp?rev=365788&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp (added)
+++ libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp Thu Jul 11 08:16:39 2019
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+//        class Hash = hash<iter-value-type<InputIterator>>,
+//        class Pred = equal_to<iter-value-type<InputIterator>>,
+//        class Allocator = allocator<iter-value-type<InputIterator>>>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
+//               Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_set<iter-value-type<InputIterator>,
+//                    Hash, Pred, Allocator>;
+//
+// template<class T, class Hash = hash<T>,
+//        class Pred = equal_to<T>, class Allocator = allocator<T>>
+// unordered_set(initializer_list<T>, typename see below::size_type = see below,
+//               Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_set<T, Hash, Pred, Allocator>;
+//
+// template<class InputIterator, class Allocator>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator)
+//   -> unordered_set<iter-value-type<InputIterator>,
+//                    hash<iter-value-type<InputIterator>>,
+//                    equal_to<iter-value-type<InputIterator>>,
+//                    Allocator>;
+//
+// template<class InputIterator, class Hash, class Allocator>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type,
+//               Hash, Allocator)
+//   -> unordered_set<iter-value-type<InputIterator>, Hash,
+//                    equal_to<iter-value-type<InputIterator>>,
+//                    Allocator>;
+//
+// template<class T, class Allocator>
+// unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
+//   -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;
+//
+// template<class T, class Hash, class Allocator>
+// unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
+//   -> unordered_set<T, Hash, equal_to<T>, Allocator>;
+
+#include <functional>
+#include <unordered_set>
+
+int main(int, char**)
+{
+    {
+        // cannot deduce Key from nothing
+        std::unordered_set s;
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size)
+        std::unordered_set s(42);
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash)
+        std::unordered_set s(42, std::hash<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Pred)
+        std::unordered_set s(42, std::hash<int>(), std::equal_to<>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Pred, Allocator)
+        std::unordered_set s(42, std::hash<int>(), std::equal_to<>(), std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Allocator)
+        std::unordered_set s(std::allocator<int>{});
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Allocator)
+        std::unordered_set s(42, std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+    {
+        // cannot deduce Key from just (Size, Hash, Allocator)
+        std::unordered_set s(42, std::hash<short>(), std::allocator<int>());
+            // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+    }
+
+    return 0;
+}

Added: libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp?rev=365788&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp Thu Jul 11 08:16:39 2019
@@ -0,0 +1,196 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+//        class Hash = hash<iter-value-type<InputIterator>>,
+//        class Pred = equal_to<iter-value-type<InputIterator>>,
+//        class Allocator = allocator<iter-value-type<InputIterator>>>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
+//               Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_set<iter-value-type<InputIterator>,
+//                    Hash, Pred, Allocator>;
+//
+// template<class T, class Hash = hash<T>,
+//        class Pred = equal_to<T>, class Allocator = allocator<T>>
+// unordered_set(initializer_list<T>, typename see below::size_type = see below,
+//               Hash = Hash(), Pred = Pred(), Allocator = Allocator())
+//   -> unordered_set<T, Hash, Pred, Allocator>;
+//
+// template<class InputIterator, class Allocator>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator)
+//   -> unordered_set<iter-value-type<InputIterator>,
+//                    hash<iter-value-type<InputIterator>>,
+//                    equal_to<iter-value-type<InputIterator>>,
+//                    Allocator>;
+//
+// template<class InputIterator, class Hash, class Allocator>
+// unordered_set(InputIterator, InputIterator, typename see below::size_type,
+//               Hash, Allocator)
+//   -> unordered_set<iter-value-type<InputIterator>, Hash,
+//                    equal_to<iter-value-type<InputIterator>>,
+//                    Allocator>;
+//
+// template<class T, class Allocator>
+// unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
+//   -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;
+//
+// template<class T, class Hash, class Allocator>
+// unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
+//   -> unordered_set<T, Hash, equal_to<T>, Allocator>;
+
+#include <algorithm> // is_permutation
+#include <cassert>
+#include <climits> // INT_MAX
+#include <type_traits>
+#include <unordered_set>
+
+#include "test_allocator.h"
+
+int main(int, char**)
+{
+    const int expected_s[] = {1, 2, 3, INT_MAX};
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr), 42);
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr), 42, std::hash<short>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<int>(0, 40));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 40);
+    }
+
+    {
+    std::unordered_set<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_set s(source);
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    }
+
+    {
+    std::unordered_set<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_set s{source};  // braces instead of parens
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    }
+
+    {
+    std::unordered_set<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_set s(source, test_allocator<int>(0, 41));
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    assert(s.get_allocator().get_id() == 41);
+    }
+
+    {
+    std::unordered_set<int, std::hash<short>, std::equal_to<>, test_allocator<int>> source;
+    std::unordered_set s{source, test_allocator<int>(0, 42)};  // braces instead of parens
+    ASSERT_SAME_TYPE(decltype(s), decltype(source));
+    assert(s.size() == 0);
+    assert(s.get_allocator().get_id() == 42);
+    }
+
+    {
+    std::unordered_set s{ 1, 2, 1, INT_MAX, 3 };
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42);
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), std::equal_to<>());
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>, std::equal_to<>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<int>(0, 43));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>, std::equal_to<>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 43);
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr), 42, test_allocator<int>(0, 44));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 44);
+    }
+
+    {
+    const int arr[] = { 1, 2, 1, INT_MAX, 3 };
+    std::unordered_set s(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<int>(0, 44));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 44);
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42, test_allocator<int>(0, 43));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<int>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 43);
+    }
+
+    {
+    std::unordered_set s({ 1, 2, 1, INT_MAX, 3 }, 42, std::hash<short>(), test_allocator<int>(0, 42));
+
+    ASSERT_SAME_TYPE(decltype(s), std::unordered_set<int, std::hash<short>, std::equal_to<int>, test_allocator<int>>);
+    assert(std::is_permutation(s.begin(), s.end(), std::begin(expected_s), std::end(expected_s)));
+    assert(s.get_allocator().get_id() == 42);
+    }
+
+    return 0;
+}




More information about the libcxx-commits mailing list