summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/containers
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-07-15 20:06:01 +0000
committerLouis Dionne <ldionne@apple.com>2019-07-15 20:06:01 +0000
commitdfcd4384cbcac0eeb7e5cbce350f875ba4da79d5 (patch)
treec5e8c0c139b09f37b59f7e5357f072aca2512366 /libcxx/test/std/containers
parentc5e7f5624966aa4a83869ca4fceb4d7b96a22d34 (diff)
downloadbcm5719-llvm-dfcd4384cbcac0eeb7e5cbce350f875ba4da79d5.tar.gz
bcm5719-llvm-dfcd4384cbcac0eeb7e5cbce350f875ba4da79d5.zip
[libc++] Implement P0433: deduction guides for <unordered_map>
Thanks to Arthur O'Dwyer for the patch. Differential Revision: https://reviews.llvm.org/D58590 llvm-svn: 366124
Diffstat (limited to 'libcxx/test/std/containers')
-rw-r--r--libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.fail.cpp106
-rw-r--r--libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.pass.cpp204
-rw-r--r--libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct_const.pass.cpp172
-rw-r--r--libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.fail.cpp106
-rw-r--r--libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.pass.cpp204
-rw-r--r--libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct_const.pass.cpp173
6 files changed, 965 insertions, 0 deletions
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 00000000000..642abce8a27
--- /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 00000000000..0923597dcc9
--- /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 00000000000..1fb4d674d5f
--- /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 00000000000..7f170472d7a
--- /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 00000000000..f620f1e3711
--- /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 00000000000..8a4a3836411
--- /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;
+}
OpenPOWER on IntegriCloud