[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