summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/containers
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-06-20 19:32:00 +0000
committerLouis Dionne <ldionne@apple.com>2019-06-20 19:32:00 +0000
commitf2f7d72f0052b169433790d79e06b5160325c538 (patch)
tree7ecdf34ae66c507b4b0129c01c0413e03291a07e /libcxx/test/std/containers
parente0c1c3baf90d86ae9b83859790359c67f4e70bdd (diff)
downloadbcm5719-llvm-f2f7d72f0052b169433790d79e06b5160325c538.tar.gz
bcm5719-llvm-f2f7d72f0052b169433790d79e06b5160325c538.zip
[libc++] Take 2: Implement CTAD for map and multimap
This is a re-application of r362986 (which was reverted in r363688) with fixes for the issue that caused it to be reverted. Thanks to Arthur O'Dwyer for the patch. Differential Revision: https://reviews.llvm.org/D58587 llvm-svn: 363968
Diffstat (limited to 'libcxx/test/std/containers')
-rw-r--r--libcxx/test/std/containers/associative/map/map.cons/deduct.fail.cpp107
-rw-r--r--libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp137
-rw-r--r--libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp107
-rw-r--r--libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.fail.cpp107
-rw-r--r--libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.pass.cpp137
-rw-r--r--libcxx/test/std/containers/associative/multimap/multimap.cons/deduct_const.pass.cpp107
6 files changed, 702 insertions, 0 deletions
diff --git a/libcxx/test/std/containers/associative/map/map.cons/deduct.fail.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct.fail.cpp
new file mode 100644
index 00000000000..2e719da6442
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct.fail.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <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
+// clang-6 gives different error messages.
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// map(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> map<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// map(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> map<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// map(InputIterator, InputIterator, Allocator)
+// -> map<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// map(initializer_list<Key>, Allocator)
+// -> map<Key, less<Key>, Allocator>;
+
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+struct NotAnAllocator {
+ friend bool operator<(NotAnAllocator, NotAnAllocator) { return false; }
+};
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+
+int main(int, char**)
+{
+ {
+ // cannot deduce Key and T from nothing
+ std::map m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce Key and T from just (Compare)
+ std::map m(std::less<int>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce Key and T from just (Compare, Allocator)
+ std::map m(std::less<int>{}, std::allocator<PC>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce Key and T from just (Allocator)
+ std::map m(std::allocator<PC>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
+ const P arr[] = { {1,1L}, {2,2L}, {3,3L} };
+ std::map m(arr, arr + 3, std::allocator<P>());
+ // expected-error-re@map:* {{static_assert failed{{( due to requirement '.*')?}} "Allocator::value_type must be same type as value_type"}}
+ }
+ {
+ // cannot convert from some arbitrary unrelated type
+ NotAnAllocator a;
+ std::map m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::map m{ {1,1L}, {2,2L}, {3,3L} };
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // since we have parens, not braces, this deliberately does not find the initializer_list constructor
+ std::map m(P{1,1L});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+ {
+ // since we have parens, not braces, this deliberately does not find the initializer_list constructor
+ std::map m(PC{1,1L});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
new file mode 100644
index 00000000000..9075d27106d
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// map(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> map<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// map(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> map<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// map(InputIterator, InputIterator, Allocator)
+// -> map<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// map(initializer_list<Key>, Allocator)
+// -> map<Key, less<Key>, Allocator>;
+
+#include <algorithm> // std::equal
+#include <cassert>
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+#include "test_allocator.h"
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+
+int main(int, char**)
+{
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long>);
+ const PC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr), std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr), std::greater<int>(), test_allocator<PC>(0, 42));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 42);
+ }
+
+ {
+ std::map<int, long> source;
+ std::map m(source);
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::map<int, long> source;
+ std::map m{source}; // braces instead of parens
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::map<int, long> source;
+ std::map m(source, std::map<int, long>::allocator_type());
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::map m{ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} };
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long>);
+ const PC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, std::greater<int>(), test_allocator<PC>(0, 43));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 43);
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr), test_allocator<PC>(0, 44));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 44);
+ }
+
+ {
+ std::map m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, test_allocator<PC>(0, 45));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 45);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
new file mode 100644
index 00000000000..77785363403
--- /dev/null
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// map(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> map<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// map(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> map<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// map(InputIterator, InputIterator, Allocator)
+// -> map<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// map(initializer_list<Key>, Allocator)
+// -> map<Key, less<Key>, Allocator>;
+
+#include <algorithm> // std::equal
+#include <cassert>
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+#include "test_allocator.h"
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+using PCC = std::pair<const int, const long>;
+
+int main(int, char**)
+{
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, const long>);
+ const PCC expected_m[] = { {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr), std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, const long, std::greater<int>>);
+ const PCC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1, 1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::map m(std::begin(arr), std::end(arr), std::greater<int>(), test_allocator<PCC>(0, 42));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, const long, std::greater<int>, test_allocator<PCC>>);
+ const PCC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1, 1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 42);
+ }
+
+ {
+ std::map m{ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} };
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long>);
+ const PC expected_m[] = { {1, 1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1, 1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, std::greater<int>(), test_allocator<PC>(0, 43));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1, 1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 43);
+ }
+
+ {
+ std::map m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, test_allocator<PC>(0, 45));
+
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1, 1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 45);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.fail.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.fail.cpp
new file mode 100644
index 00000000000..70fa2522cc1
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.fail.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <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
+// clang-6 gives different error messages.
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// multimap(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> multimap<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// multimap(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> multimap<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// multimap(InputIterator, InputIterator, Allocator)
+// -> multimap<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// multimap(initializer_list<Key>, Allocator)
+// -> multimap<Key, less<Key>, Allocator>;
+
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+struct NotAnAllocator {
+ friend bool operator<(NotAnAllocator, NotAnAllocator) { return false; }
+};
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+
+int main(int, char**)
+{
+ {
+ // cannot deduce Key and T from nothing
+ std::multimap m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce Key and T from just (Compare)
+ std::multimap m(std::less<int>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce Key and T from just (Compare, Allocator)
+ std::multimap m(std::less<int>{}, std::allocator<PC>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce Key and T from just (Allocator)
+ std::multimap m(std::allocator<PC>{});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
+ const P arr[] = { {1,1L}, {2,2L}, {3,3L} };
+ std::multimap m(arr, arr + 3, std::allocator<P>());
+ // expected-error-re@map:* {{static_assert failed{{( due to requirement '.*')?}} "Allocator::value_type must be same type as value_type"}}
+ }
+ {
+ // cannot convert from some arbitrary unrelated type
+ NotAnAllocator a;
+ std::multimap m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::multimap m{ {1,1L}, {2,2L}, {3,3L} };
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // cannot deduce that the inner braced things should be std::pair and not something else
+ std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // since we have parens, not braces, this deliberately does not find the initializer_list constructor
+ std::multimap m(P{1,1L});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+ {
+ // since we have parens, not braces, this deliberately does not find the initializer_list constructor
+ std::multimap m(PC{1,1L});
+ // expected-error@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.pass.cpp
new file mode 100644
index 00000000000..0a28d7835ea
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// multimap(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> multimap<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// multimap(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> multimap<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// multimap(InputIterator, InputIterator, Allocator)
+// -> multimap<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// multimap(initializer_list<Key>, Allocator)
+// -> multimap<Key, less<Key>, Allocator>;
+
+#include <algorithm> // std::equal
+#include <cassert>
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+#include "test_allocator.h"
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+
+int main(int, char**)
+{
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr), std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr), std::greater<int>(), test_allocator<PC>(0, 42));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 42);
+ }
+
+ {
+ std::multimap<int, long> source;
+ std::multimap m(source);
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::multimap<int, long> source;
+ std::multimap m{source}; // braces instead of parens
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::multimap<int, long> source;
+ std::multimap m(source, std::map<int, long>::allocator_type());
+ ASSERT_SAME_TYPE(decltype(m), decltype(source));
+ assert(m.size() == 0);
+ }
+
+ {
+ std::multimap m{ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} };
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, std::greater<int>(), test_allocator<PC>(0, 43));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 43);
+ }
+
+ {
+ const P arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr), test_allocator<PC>(0, 44));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 44);
+ }
+
+ {
+ std::multimap m({ P{1,1L}, P{2,2L}, P{1,1L}, P{INT_MAX,1L}, P{3,1L} }, test_allocator<PC>(0, 45));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 45);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct_const.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct_const.pass.cpp
new file mode 100644
index 00000000000..1c1eb2fd74f
--- /dev/null
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct_const.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// template<class InputIterator,
+// class Compare = less<iter-value-type<InputIterator>>,
+// class Allocator = allocator<iter-value-type<InputIterator>>>
+// multimap(InputIterator, InputIterator,
+// Compare = Compare(), Allocator = Allocator())
+// -> multimap<iter-value-type<InputIterator>, Compare, Allocator>;
+// template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
+// multimap(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
+// -> multimap<Key, Compare, Allocator>;
+// template<class InputIterator, class Allocator>
+// multimap(InputIterator, InputIterator, Allocator)
+// -> multimap<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>;
+// template<class Key, class Allocator>
+// multimap(initializer_list<Key>, Allocator)
+// -> multimap<Key, less<Key>, Allocator>;
+
+#include <algorithm> // std::equal
+#include <cassert>
+#include <climits> // INT_MAX
+#include <functional>
+#include <map>
+#include <type_traits>
+
+#include "test_allocator.h"
+
+using P = std::pair<int, long>;
+using PC = std::pair<const int, long>;
+using PCC = std::pair<const int, const long>;
+
+int main(int, char**)
+{
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, const long>);
+ const PCC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr), std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, const long, std::greater<int>>);
+ const PCC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ const PCC arr[] = { {1,1L}, {2,2L}, {1,1L}, {INT_MAX,1L}, {3,1L} };
+ std::multimap m(std::begin(arr), std::end(arr), std::greater<int>(), test_allocator<PCC>(0, 42));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, const long, std::greater<int>, test_allocator<PCC>>);
+ const PCC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 42);
+ }
+
+ {
+ std::multimap m{ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} };
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, std::greater<int>());
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ }
+
+ {
+ std::multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, std::greater<int>(), test_allocator<PC>(0, 43));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::greater<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {INT_MAX,1L}, {3,1L}, {2,2L}, {1,1L}, {1,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 43);
+ }
+
+ {
+ std::multimap m({ PC{1,1L}, PC{2,2L}, PC{1,1L}, PC{INT_MAX,1L}, PC{3,1L} }, test_allocator<PC>(0, 45));
+
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, long, std::less<int>, test_allocator<PC>>);
+ const PC expected_m[] = { {1,1L}, {1,1L}, {2,2L}, {3,1L}, {INT_MAX,1L} };
+ assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
+ assert(m.get_allocator().get_id() == 45);
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud