diff options
author | Louis Dionne <ldionne@apple.com> | 2019-06-20 19:32:00 +0000 |
---|---|---|
committer | Louis Dionne <ldionne@apple.com> | 2019-06-20 19:32:00 +0000 |
commit | f2f7d72f0052b169433790d79e06b5160325c538 (patch) | |
tree | 7ecdf34ae66c507b4b0129c01c0413e03291a07e /libcxx/test/std/containers | |
parent | e0c1c3baf90d86ae9b83859790359c67f4e70bdd (diff) | |
download | bcm5719-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')
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; +} |