Index: libcxx/trunk/include/unordered_set =================================================================== --- libcxx/trunk/include/unordered_set +++ libcxx/trunk/include/unordered_set @@ -383,9 +383,9 @@ // 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), @@ -733,6 +733,62 @@ }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template>, + class _Pred = equal_to<__iter_value_type<_InputIterator>>, + class _Allocator = allocator<__iter_value_type<_InputIterator>>, + class = _EnableIf::value>, + class = _EnableIf::value>, + class = _EnableIf::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 _Pred = equal_to<_Tp>, + class _Allocator = allocator<_Tp>, + class = _EnableIf::value>, + class = _EnableIf::value>, + class = _EnableIf::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::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::value>, + class = _EnableIf::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::value>> +unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + +template::value>, + class = _EnableIf::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 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql) @@ -986,9 +1042,9 @@ // 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), @@ -1304,6 +1360,60 @@ }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template>, + class _Pred = equal_to<__iter_value_type<_InputIterator>>, + class _Allocator = allocator<__iter_value_type<_InputIterator>>, + class = _EnableIf::value>, + class = _EnableIf::value>, + class = _EnableIf::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 _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>, + class = _EnableIf::value>, + class = _EnableIf::value>, + class = _EnableIf::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::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::value>, + class = _EnableIf::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::value>> +unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + +template::value>, + class = _EnableIf::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 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( size_type __n, const hasher& __hf, const key_equal& __eql) Index: 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.fail.cpp +++ libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.fail.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template>, +// class Pred = equal_to>, +// class Allocator = allocator>> +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multiset, +// Hash, Pred, Allocator>; +// +// template, +// class Pred = equal_to, class Allocator = allocator> +// unordered_multiset(initializer_list, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multiset; +// +// template +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_multiset, +// hash>, +// equal_to>, +// Allocator>; +// +// template +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, +// Hash, Allocator) +// -> unordered_multiset, Hash, +// equal_to>, +// Allocator>; +// +// template +// unordered_multiset(initializer_list, typename see below::size_type, Allocator) +// -> unordered_multiset, equal_to, Allocator>; +// +// template +// unordered_multiset(initializer_list, typename see below::size_type, Hash, Allocator) +// -> unordered_multiset, Allocator>; + +#include +#include + +int main(int, char**) +{ + { + // cannot deduce Key from nothing + std::unordered_multiset s; + // expected-error@-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@-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()); + // expected-error@-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(), std::equal_to<>()); + // expected-error@-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(), std::equal_to<>(), std::allocator()); + // expected-error@-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{}); + // expected-error@-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()); + // expected-error@-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(), std::allocator()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + } + + return 0; +} Index: libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp =================================================================== --- libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp +++ libcxx/trunk/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.pass.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template>, +// class Pred = equal_to>, +// class Allocator = allocator>> +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multiset, +// Hash, Pred, Allocator>; +// +// template, +// class Pred = equal_to, class Allocator = allocator> +// unordered_multiset(initializer_list, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multiset; +// +// template +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_multiset, +// hash>, +// equal_to>, +// Allocator>; +// +// template +// unordered_multiset(InputIterator, InputIterator, typename see below::size_type, +// Hash, Allocator) +// -> unordered_multiset, Hash, +// equal_to>, +// Allocator>; +// +// template +// unordered_multiset(initializer_list, typename see below::size_type, Allocator) +// -> unordered_multiset, equal_to, Allocator>; +// +// template +// unordered_multiset(initializer_list, typename see below::size_type, Hash, Allocator) +// -> unordered_multiset, Allocator>; + +#include // is_permutation +#include +#include // INT_MAX +#include +#include + +#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); + 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); + 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()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset>); + 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(), test_allocator(0, 40)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to, test_allocator>); + 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, std::equal_to<>, test_allocator> source; + std::unordered_multiset s(source); + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + } + + { + std::unordered_multiset, std::equal_to<>, test_allocator> source; + std::unordered_multiset s{source}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + } + + { + std::unordered_multiset, std::equal_to<>, test_allocator> source; + std::unordered_multiset s(source, test_allocator(0, 41)); + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + assert(s.get_allocator().get_id() == 41); + } + + { + std::unordered_multiset, std::equal_to<>, test_allocator> source; + std::unordered_multiset s{source, test_allocator(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); + 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); + 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()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset>); + 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(), std::equal_to<>()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, 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(), std::equal_to<>(), test_allocator(0, 43)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to<>, test_allocator>); + 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(0, 44)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to, test_allocator>); + 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(), test_allocator(0, 44)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to, test_allocator>); + 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(0, 43)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to, test_allocator>); + 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(), test_allocator(0, 42)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_multiset, std::equal_to, test_allocator>); + 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; +} Index: 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.fail.cpp +++ libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.fail.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template>, +// class Pred = equal_to>, +// class Allocator = allocator>> +// unordered_set(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_set, +// Hash, Pred, Allocator>; +// +// template, +// class Pred = equal_to, class Allocator = allocator> +// unordered_set(initializer_list, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_set; +// +// template +// unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_set, +// hash>, +// equal_to>, +// Allocator>; +// +// template +// unordered_set(InputIterator, InputIterator, typename see below::size_type, +// Hash, Allocator) +// -> unordered_set, Hash, +// equal_to>, +// Allocator>; +// +// template +// unordered_set(initializer_list, typename see below::size_type, Allocator) +// -> unordered_set, equal_to, Allocator>; +// +// template +// unordered_set(initializer_list, typename see below::size_type, Hash, Allocator) +// -> unordered_set, Allocator>; + +#include +#include + +int main(int, char**) +{ + { + // cannot deduce Key from nothing + std::unordered_set s; + // expected-error@-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@-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()); + // expected-error@-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(), std::equal_to<>()); + // expected-error@-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(), std::equal_to<>(), std::allocator()); + // expected-error@-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{}); + // expected-error@-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()); + // expected-error@-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(), std::allocator()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + } + + return 0; +} Index: libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp =================================================================== --- libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp +++ libcxx/trunk/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.pass.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template>, +// class Pred = equal_to>, +// class Allocator = allocator>> +// unordered_set(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_set, +// Hash, Pred, Allocator>; +// +// template, +// class Pred = equal_to, class Allocator = allocator> +// unordered_set(initializer_list, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_set; +// +// template +// unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_set, +// hash>, +// equal_to>, +// Allocator>; +// +// template +// unordered_set(InputIterator, InputIterator, typename see below::size_type, +// Hash, Allocator) +// -> unordered_set, Hash, +// equal_to>, +// Allocator>; +// +// template +// unordered_set(initializer_list, typename see below::size_type, Allocator) +// -> unordered_set, equal_to, Allocator>; +// +// template +// unordered_set(initializer_list, typename see below::size_type, Hash, Allocator) +// -> unordered_set, Allocator>; + +#include // is_permutation +#include +#include // INT_MAX +#include +#include + +#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); + 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); + 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()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set>); + 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(), test_allocator(0, 40)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to, test_allocator>); + 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, std::equal_to<>, test_allocator> source; + std::unordered_set s(source); + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + } + + { + std::unordered_set, std::equal_to<>, test_allocator> source; + std::unordered_set s{source}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + } + + { + std::unordered_set, std::equal_to<>, test_allocator> source; + std::unordered_set s(source, test_allocator(0, 41)); + ASSERT_SAME_TYPE(decltype(s), decltype(source)); + assert(s.size() == 0); + assert(s.get_allocator().get_id() == 41); + } + + { + std::unordered_set, std::equal_to<>, test_allocator> source; + std::unordered_set s{source, test_allocator(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); + 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); + 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()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set>); + 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(), std::equal_to<>()); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, 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(), std::equal_to<>(), test_allocator(0, 43)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to<>, test_allocator>); + 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(0, 44)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to, test_allocator>); + 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(), test_allocator(0, 44)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to, test_allocator>); + 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(0, 43)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to, test_allocator>); + 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(), test_allocator(0, 42)); + + ASSERT_SAME_TYPE(decltype(s), std::unordered_set, std::equal_to, test_allocator>); + 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; +}