diff options
Diffstat (limited to 'libcxx')
8 files changed, 1106 insertions, 7 deletions
diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index 4dfe698..63aecc8b 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -844,9 +844,9 @@ public: // types typedef _Key key_type; typedef _Tp mapped_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 pair<const key_type, mapped_type> value_type; typedef value_type& reference; typedef const value_type& const_reference; @@ -1348,6 +1348,73 @@ private: #endif }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _InputIterator, + class _Hash = hash<__iter_key_type<_InputIterator>>, + class _Pred = equal_to<__iter_key_type<_InputIterator>>, + class _Allocator = allocator<__iter_to_alloc_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_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; + +template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, + class _Pred = equal_to<remove_const_t<_Key>>, + class _Allocator = allocator<pair<const _Key, _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_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; + +template<class _InputIterator, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; + +template<class _InputIterator, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_map(_InputIterator, _InputIterator, _Allocator) + -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_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_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; + +template<class _Key, class _Tp, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_map<remove_const_t<_Key>, _Tp, + hash<remove_const_t<_Key>>, + equal_to<remove_const_t<_Key>>, _Allocator>; + +template<class _Key, class _Tp, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator) + -> unordered_map<remove_const_t<_Key>, _Tp, + hash<remove_const_t<_Key>>, + equal_to<remove_const_t<_Key>>, _Allocator>; + +template<class _Key, 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_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, + equal_to<remove_const_t<_Key>>, _Allocator>; +#endif + template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql) @@ -1673,9 +1740,9 @@ public: // types typedef _Key key_type; typedef _Tp mapped_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 pair<const key_type, mapped_type> value_type; typedef value_type& reference; typedef const value_type& const_reference; @@ -2041,6 +2108,73 @@ public: }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _InputIterator, + class _Hash = hash<__iter_key_type<_InputIterator>>, + class _Pred = equal_to<__iter_key_type<_InputIterator>>, + class _Allocator = allocator<__iter_to_alloc_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_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; + +template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, + class _Pred = equal_to<remove_const_t<_Key>>, + class _Allocator = allocator<pair<const _Key, _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_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; + +template<class _InputIterator, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; + +template<class _InputIterator, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_multimap(_InputIterator, _InputIterator, _Allocator) + -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_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_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, + _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; + +template<class _Key, class _Tp, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_multimap<remove_const_t<_Key>, _Tp, + hash<remove_const_t<_Key>>, + equal_to<remove_const_t<_Key>>, _Allocator>; + +template<class _Key, class _Tp, class _Allocator, + class = _EnableIf<__is_allocator<_Allocator>::value>> +unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) + -> unordered_multimap<remove_const_t<_Key>, _Tp, + hash<remove_const_t<_Key>>, + equal_to<remove_const_t<_Key>>, _Allocator>; + +template<class _Key, 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_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, + equal_to<remove_const_t<_Key>>, _Allocator>; +#endif + template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql) diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.fail.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.fail.cpp new file mode 100644 index 0000000..642abce --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.fail.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides +// XFAIL: clang-6, apple-clang-9.0, apple-clang-9.1, apple-clang-10.0 + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_map(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <functional> +#include <unordered_map> + +int main(int, char**) +{ + using P = std::pair<const int, int>; + { + // cannot deduce Key from nothing + std::unordered_map m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size) + std::unordered_map m(42); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size, Hash) + std::unordered_map m(42, std::hash<int>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size, Hash, Pred) + std::unordered_map m(42, std::hash<int>(), std::equal_to<int>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size, Hash, Pred, Allocator) + std::unordered_map m(42, std::hash<int>(), std::equal_to<int>(), std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Allocator) + std::unordered_map m(std::allocator<P>{}); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size, Allocator) + std::unordered_map m(42, std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + { + // cannot deduce Key from just (Size, Hash, Allocator) + std::unordered_map m(42, std::hash<int>(), std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.pass.cpp new file mode 100644 index 0000000..0923597 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.pass.cpp @@ -0,0 +1,204 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_map(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <algorithm> // is_permutation +#include <cassert> +#include <climits> // INT_MAX +#include <type_traits> +#include <unordered_map> + +#include "test_allocator.h" + +using P = std::pair<int, long>; +using PC = std::pair<const int, long>; + +int main(int, char**) +{ + const PC expected_m[] = { {1,1}, {2,2}, {3,1}, {INT_MAX,1} }; + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 41)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 41); + } + + { + std::unordered_map<int, long> source; + std::unordered_map m(source); + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.size() == 0); + } + + { + std::unordered_map<int, long> source; + std::unordered_map m{source}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.size() == 0); + } + + { + std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source; + test_allocator<PC> a(0, 42); + std::unordered_map m(source, a); + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.get_allocator().get_id() == 42); + assert(m.size() == 0); + } + + { + std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source; + test_allocator<PC> a(0, 43); + std::unordered_map m{source, a}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.get_allocator().get_id() == 43); + assert(m.size() == 0); + } + + { + std::unordered_map m { P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }; + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 44)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 44); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, test_allocator<PC>(0, 45)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 45); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<PC>(0, 46)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 46); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, test_allocator<PC>(0, 47)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 47); + } + + { + std::unordered_map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), test_allocator<PC>(0, 48)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 48); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct_const.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct_const.pass.cpp new file mode 100644 index 0000000..1fb4d67 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct_const.pass.cpp @@ -0,0 +1,172 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_map(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_map<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_map(InputIterator, InputIterator, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <algorithm> // std::is_permutation +#include <cassert> +#include <climits> // INT_MAX +#include <type_traits> +#include <unordered_map> + +#include "test_allocator.h" + +using P = std::pair<int, long>; +using PC = std::pair<const int, long>; + +int main(int, char**) +{ + const PC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} }; + + { + const PC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} }; + std::unordered_map m(std::begin(arr), std::end(arr)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 41)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 41); + } + + { + std::unordered_map m { PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }; + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 44)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 44); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, test_allocator<PC>(0, 45)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 45); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_map m(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<PC>(0, 46)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 46); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, test_allocator<PC>(0, 47)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 47); + } + + { + std::unordered_map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), test_allocator<PC>(0, 48)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 48); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.fail.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.fail.cpp new file mode 100644 index 0000000..7f17047 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.fail.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides +// XFAIL: clang-6, apple-clang-9.0, apple-clang-9.1, apple-clang-10.0 + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_multimap(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <functional> +#include <unordered_map> + +int main(int, char**) +{ + using P = std::pair<const int, int>; + { + // cannot deduce Key from nothing + std::unordered_multimap m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size) + std::unordered_multimap m(42); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size, Hash) + std::unordered_multimap m(42, std::hash<int>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size, Hash, Pred) + std::unordered_multimap m(42, std::hash<int>(), std::equal_to<int>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size, Hash, Pred, Allocator) + std::unordered_multimap m(42, std::hash<int>(), std::equal_to<int>(), std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Allocator) + std::unordered_multimap m(std::allocator<P>{}); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size, Allocator) + std::unordered_multimap m(42, std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + { + // cannot deduce Key from just (Size, Hash, Allocator) + std::unordered_multimap m(42, std::hash<int>(), std::allocator<P>()); + // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.pass.cpp new file mode 100644 index 0000000..f620f1e --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.pass.cpp @@ -0,0 +1,204 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_multimap(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <algorithm> // is_permutation +#include <cassert> +#include <climits> // INT_MAX +#include <type_traits> +#include <unordered_map> + +#include "test_allocator.h" + +using P = std::pair<int, long>; +using PC = std::pair<const int, long>; + +int main(int, char**) +{ + const PC expected_m[] = { {1,1}, {1,1}, {2,2}, {3,1}, {INT_MAX,1} }; + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 41)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 41); + } + + { + std::unordered_multimap<int, long> source; + std::unordered_multimap m(source); + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.size() == 0); + } + + { + std::unordered_multimap<int, long> source; + std::unordered_multimap m{source}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.size() == 0); + } + + { + std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source; + test_allocator<PC> a(0, 42); + std::unordered_multimap m(source, a); + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.get_allocator().get_id() == 42); + assert(m.size() == 0); + } + + { + std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>> source; + test_allocator<PC> a(0, 43); + std::unordered_multimap m{source, a}; // braces instead of parens + ASSERT_SAME_TYPE(decltype(m), decltype(source)); + assert(m.get_allocator().get_id() == 43); + assert(m.size() == 0); + } + + { + std::unordered_multimap m { P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }; + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 44)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 44); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, test_allocator<PC>(0, 45)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 45); + } + + { + const P arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<PC>(0, 46)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 46); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, test_allocator<PC>(0, 47)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 47); + } + + { + std::unordered_multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, 42, std::hash<short>(), test_allocator<PC>(0, 48)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 48); + } + + return 0; +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct_const.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct_const.pass.cpp new file mode 100644 index 0000000..8a4a383 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct_const.pass.cpp @@ -0,0 +1,173 @@ +//===----------------------------------------------------------------------===// +// +// 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_map> +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template<class InputIterator, +// class Hash = hash<iter-key-type<InputIterator>>, +// class Pred = equal_to<iter-key-type<InputIterator>>, +// class Allocator = allocator<iter-to-alloc-type<InputIterator>>> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, +// Hash = Hash(), Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred, +// Allocator>; +// +// template<class Key, class T, class Hash = hash<Key>, +// class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> +// unordered_multimap(initializer_list<pair<Key, T>>, +// typename see below::size_type = see below, Hash = Hash(), +// Pred = Pred(), Allocator = Allocator()) +// -> unordered_multimap<Key, T, Hash, Pred, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Allocator> +// unordered_multimap(InputIterator, InputIterator, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, +// hash<iter-key-type<InputIterator>>, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class InputIterator, class Hash, class Allocator> +// unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) +// -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, +// equal_to<iter-key-type<InputIterator>>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, Allocator) +// -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; +// +// template<class Key, class T, class Hash, class Allocator> +// unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, +// Allocator) +// -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>; + +#include <algorithm> // is_permutation +#include <cassert> +#include <climits> // INT_MAX +#include <functional> +#include <type_traits> +#include <unordered_map> + +#include "test_allocator.h" + +using P = std::pair<int, long>; +using PC = std::pair<const int, long>; + +int main(int, char**) +{ + const PC expected_m[] = { {1,1}, {1,1}, {2,2}, {3,1}, {INT_MAX,1} }; + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 41)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 41); + } + + { + std::unordered_multimap m { PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }; + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), std::equal_to<>()); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), std::equal_to<>(), test_allocator<PC>(0, 44)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 44); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, test_allocator<PC>(0, 45)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 45); + } + + { + const PC arr[] = { {1,1}, {2,2}, {1,1}, {INT_MAX,1}, {3,1} }; + std::unordered_multimap m(std::begin(arr), std::end(arr), 42, std::hash<short>(), test_allocator<PC>(0, 46)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 46); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, test_allocator<PC>(0, 47)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<int>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 47); + } + + { + std::unordered_multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, 42, std::hash<short>(), test_allocator<PC>(0, 48)); + ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, long, std::hash<short>, std::equal_to<int>, test_allocator<PC>>); + assert(std::is_permutation(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m))); + assert(m.get_allocator().get_id() == 48); + } + + return 0; +} diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html index b800ef0..2b19eb8 100644 --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -283,7 +283,7 @@ <tr><td><a href="https://wg21.link/LWG2996">2996</a></td><td>Missing rvalue overloads for <tt>shared_ptr</tt> operations</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3008">3008</a></td><td><tt>make_shared</tt> (sub)object destruction semantics are not specified</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3022">3022</a></td><td><tt>is_convertible<derived*, base*></tt> may lead to ODR</td><td>San Diego</td><td>Resolved by 1285R0</td></tr> - <tr><td><a href="https://wg21.link/LWG3025">3025</a></td><td>Map-like container deduction guides should use <tt>pair<Key, T></tt>, not <tt>pair<const Key, T></tt></td><td>San Diego</td><td></td></tr> + <tr><td><a href="https://wg21.link/LWG3025">3025</a></td><td>Map-like container deduction guides should use <tt>pair<Key, T></tt>, not <tt>pair<const Key, T></tt></td><td>San Diego</td><td>Complete</td></tr> <tr><td><a href="https://wg21.link/LWG3031">3031</a></td><td>Algorithms and predicates with non-const reference arguments</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3037">3037</a></td><td><tt>polymorphic_allocator</tt> and incomplete types</td><td>San Diego</td><td></td></tr> <tr><td><a href="https://wg21.link/LWG3038">3038</a></td><td><tt>polymorphic_allocator::allocate</tt> should not allow integer overflow to create vulnerabilities</td><td>San Diego</td><td></td></tr> |