//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // #include #include #include #include #include #include #include #include #include #include #include #include #include #include "deduction_guides_sfinae_checks.h" #include "test_allocator.h" using P = std::pair; using PC = std::pair; void test_copy() { { std::flat_multimap source = {{1, 2}, {1, 3}}; std::flat_multimap s(source); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { std::flat_multimap> source = {{1, 2}, {1, 3}}; std::flat_multimap s{source}; // braces instead of parens ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { std::flat_multimap> source = {{1, 2}, {1, 3}}; std::flat_multimap s(source, std::allocator()); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } } void test_containers() { std::deque> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator(0, 42)); std::deque> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator(0, 43)); std::deque> sorted_ks({1, 1, 2, 2, 2, 3, INT_MAX}, test_allocator(0, 42)); std::deque> sorted_vs({1, 3, 2, 4, 5, 4, 3}, test_allocator(0, 43)); const std::pair expected[] = {{1, 1}, {1, 3}, {2, 2}, {2, 4}, {2, 5}, {3, 4}, {INT_MAX, 3}}; { std::flat_multimap s(ks, vs); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); } { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); } { std::flat_multimap s(ks, vs, test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); } { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); } } void test_containers_compare() { std::deque> ks({1, 2, 1, 2, 2, INT_MAX, 3}, test_allocator(0, 42)); std::deque> vs({1, 2, 3, 4, 5, 3, 4}, test_allocator(0, 43)); std::deque> sorted_ks({INT_MAX, 3, 2, 2, 2, 1, 1}, test_allocator(0, 42)); std::deque> sorted_vs({3, 4, 2, 4, 5, 1, 3}, test_allocator(0, 43)); const std::pair expected[] = {{INT_MAX, 3}, {3, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 1}, {1, 3}}; { std::flat_multimap s(ks, vs, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); } { std::flat_multimap s(std::sorted_equivalent, sorted_ks, sorted_vs, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 43); } { std::flat_multimap s(ks, vs, std::greater(), test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); } { std::flat_multimap s( std::sorted_equivalent, sorted_ks, sorted_vs, std::greater(), test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap, decltype(ks), decltype(vs)>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 44); assert(s.values().get_allocator().get_id() == 44); } } void test_iter_iter() { const P arr[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}; const P sorted_arr[] = {{1, 1L}, {1, 1L}, {2, 2L}, {3, 1L}, {INT_MAX, 1L}}; const PC arrc[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}; const PC sorted_arrc[] = {{1, 1L}, {1, 1L}, {2, 2L}, {3, 1L}, {INT_MAX, 1L}}; { std::flat_multimap m(std::begin(arr), std::end(arr)); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::begin(arrc), std::end(arrc)); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr)); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc)); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap mo; std::flat_multimap m(mo.begin(), mo.end()); ASSERT_SAME_TYPE(decltype(m), decltype(mo)); } { std::flat_multimap mo; std::flat_multimap m(mo.cbegin(), mo.cend()); ASSERT_SAME_TYPE(decltype(m), decltype(mo)); } { std::pair source[3] = {{1, 1}, {1, 1}, {3, 3}}; std::flat_multimap s = {source, source + 3}; // flat_multimap(InputIterator, InputIterator) ASSERT_SAME_TYPE(decltype(s), std::flat_multimap); assert(s.size() == 3); } { std::pair source[3] = {{1, 1}, {1, 1}, {3, 3}}; std::flat_multimap s{source, source + 3}; // flat_multimap(InputIterator, InputIterator) ASSERT_SAME_TYPE(decltype(s), std::flat_multimap); assert(s.size() == 3); } { std::pair source[3] = {{1, 1}, {1, 2}, {3, 3}}; std::flat_multimap s{ std::sorted_equivalent, source, source + 3}; // flat_multimap(sorted_equivalent_t, InputIterator, InputIterator) static_assert(std::is_same_v>); assert(s.size() == 3); } } void test_iter_iter_compare() { const P arr[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}; const P sorted_arr[] = {{INT_MAX, 1L}, {3, 1L}, {2, 2L}, {1, 1L}, {1, 1L}}; const PC arrc[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}; const PC sorted_arrc[] = {{INT_MAX, 1L}, {3, 1L}, {2, 2L}, {1, 1L}, {1, 1L}}; using C = std::greater; { std::flat_multimap m(std::begin(arr), std::end(arr), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::begin(arrc), std::end(arrc), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap mo; std::flat_multimap m(mo.begin(), mo.end(), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); } { std::flat_multimap mo; std::flat_multimap m(mo.cbegin(), mo.cend(), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); } } void test_initializer_list() { const P sorted_arr[] = {{1, 1L}, {1, 1L}, {2, 2L}, {3, 1L}, {INT_MAX, 1L}}; { std::flat_multimap m{std::pair{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}; ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, {std::pair{1, 1L}, {1, 1L}, {2, 2L}, {3, 1L}, {INT_MAX, 1L}}); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap s = {std::make_pair(1, 'a')}; // flat_multimap(initializer_list>) ASSERT_SAME_TYPE(decltype(s), std::flat_multimap); assert(s.size() == 1); } { using M = std::flat_multimap; M m; std::flat_multimap s = {std::make_pair(m, m)}; // flat_multimap(initializer_list>) ASSERT_SAME_TYPE(decltype(s), std::flat_multimap); assert(s.size() == 1); assert(s.find(m)->second == m); } } void test_initializer_list_compare() { const P sorted_arr[] = {{INT_MAX, 1L}, {3, 1L}, {2, 2L}, {1, 1L}, {1, 1L}}; using C = std::greater; { std::flat_multimap m({std::pair{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}}, C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } { std::flat_multimap m(std::sorted_equivalent, {std::pair{INT_MAX, 1L}, {3, 1L}, {2, 2L}, {1, 1L}, {1, 1L}}, C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multimap); assert(std::ranges::equal(m, sorted_arr)); } } void test_from_range() { std::list> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; const std::pair expected[] = {{1, 1}, {1, 1}, {2, 2}, {3, 5}, {INT_MAX, 4}}; { std::flat_multimap s(std::from_range, r); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap>); assert(std::ranges::equal(s, expected)); } { std::flat_multimap s(std::from_range, r, test_allocator(0, 42)); ASSERT_SAME_TYPE( decltype(s), std::flat_multimap, std::vector>, std::vector>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); } } void test_from_range_compare() { std::list> r = {{1, 1}, {2, 2}, {1, 1}, {INT_MAX, 4}, {3, 5}}; const std::pair expected[] = {{INT_MAX, 4}, {3, 5}, {2, 2}, {1, 1}, {1, 1}}; { std::flat_multimap s(std::from_range, r, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multimap>); assert(std::ranges::equal(s, expected)); } { std::flat_multimap s(std::from_range, r, std::greater(), test_allocator(0, 42)); ASSERT_SAME_TYPE( decltype(s), std::flat_multimap, std::vector>, std::vector>>); assert(std::ranges::equal(s, expected)); assert(s.keys().get_allocator().get_id() == 42); assert(s.values().get_allocator().get_id() == 42); } } void test_tuple_like_deduction() { std::vector> pair_vec = {{1, 1.1f}, {2, 2.2f}, {3, 3.3f}}; std::flat_multimap fmm1(pair_vec.begin(), pair_vec.end()); ASSERT_SAME_TYPE(decltype(fmm1), std::flat_multimap); std::vector> tuple_vec = {{10, 1.1}, {20, 2.2}, {30, 3.3}}; std::flat_multimap fmm2(tuple_vec.begin(), tuple_vec.end()); ASSERT_SAME_TYPE(decltype(fmm2), std::flat_multimap); std::vector> array_vec = {{100L, 101L}, {200L, 201L}, {300L, 301L}}; std::flat_multimap fmm3(array_vec.begin(), array_vec.end()); ASSERT_SAME_TYPE(decltype(fmm3), std::flat_multimap); std::vector> non_const_key_pair_vec = {{5, 'a'}, {6, 'b'}}; std::flat_multimap fmm4(non_const_key_pair_vec.begin(), non_const_key_pair_vec.end()); ASSERT_SAME_TYPE(decltype(fmm4), std::flat_multimap); } int main(int, char**) { // Each test function also tests the sorted_equivalent-prefixed and allocator-suffixed overloads. test_copy(); test_containers(); test_containers_compare(); test_iter_iter(); test_iter_iter_compare(); test_initializer_list(); test_initializer_list_compare(); test_from_range(); test_from_range_compare(); test_tuple_like_deduction(); AssociativeContainerDeductionGuidesSfinaeAway>(); return 0; }