//===----------------------------------------------------------------------===// // // 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 "deduction_guides_sfinae_checks.h" #include "test_allocator.h" void test() { { // Deduction guide generated from // flat_multiset(const flat_multiset&) std::flat_multiset source = {1, 2, 2}; std::flat_multiset s(source); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { // Deduction guide generated from // flat_multiset(const flat_multiset&) // braces instead of parens std::flat_multiset> source = {1, 2, 2}; std::flat_multiset s{source}; ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { // Deduction guide generated from // flat_set(const flat_set&, const Allocator&) std::flat_multiset> source = {1, 2, 2}; std::flat_multiset s(source, std::allocator()); ASSERT_SAME_TYPE(decltype(s), decltype(source)); assert(s == source); } { std::deque> ks({1, 2, 1, INT_MAX, 3}, test_allocator(0, 42)); std::deque> sorted_ks({1, 1, 2, 3, INT_MAX}, test_allocator(0, 42)); int expected[] = {1, 1, 2, 3, INT_MAX}; { // template> // flat_multiset(KeyContainer, Compare = Compare()) // -> flat_multiset; std::flat_multiset s(ks); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } { // template> // flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare()) // -> flat_multiset; std::flat_multiset s(std::sorted_equivalent, sorted_ks); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } { // template // flat_multiset(KeyContainer, Allocator) // -> flat_multiset, KeyContainer>; std::flat_multiset s(ks, test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 44); } { // template // flat_multiset(sorted_equivalent_t, KeyContainer, Allocator) // -> flat_multiset, KeyContainer>; std::flat_multiset s(std::sorted_equivalent, sorted_ks, test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 44); } } { std::deque> ks({1, 2, 1, INT_MAX, 3}, test_allocator(0, 42)); std::deque> sorted_ks({INT_MAX, 3, 2, 1, 1}, test_allocator(0, 42)); int expected[] = {INT_MAX, 3, 2, 1, 1}; { // template> // flat_multiset(KeyContainer, Compare = Compare()) // -> flat_multiset; std::flat_multiset s(ks, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } { // template> // flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare()) // -> flat_multiset; std::flat_multiset s(std::sorted_equivalent, sorted_ks, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } { // template // flat_multiset(KeyContainer, Compare, Allocator) // -> flat_multiset; std::flat_multiset s(ks, std::greater(), test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 44); } { // template // flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator) // -> flat_multiset; std::flat_multiset s(std::sorted_equivalent, sorted_ks, std::greater(), test_allocator(0, 44)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, decltype(ks)>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 44); } } { int arr[] = {1, 2, 1, INT_MAX, 3}; int sorted_arr[] = {1, 1, 2, 3, INT_MAX}; const int arrc[] = {1, 2, 1, INT_MAX, 3}; const int sorted_arrc[] = {1, 1, 2, 3, INT_MAX}; { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; std::flat_multiset m(std::begin(arr), std::end(arr)); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // const std::flat_multiset m(std::begin(arrc), std::end(arrc)); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr)); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // const std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc)); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // flat_multiset iterator std::flat_multiset mo; std::flat_multiset m(mo.begin(), mo.end()); ASSERT_SAME_TYPE(decltype(m), decltype(mo)); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // flat_multiset const_iterator std::flat_multiset mo; std::flat_multiset m(mo.cbegin(), mo.cend()); ASSERT_SAME_TYPE(decltype(m), decltype(mo)); } { // This does not deduce to flat_multiset(InputIterator, InputIterator) // But deduces to flat_multiset(initializer_list) int source[3] = {1, 2, 3}; std::flat_multiset s = {source, source + 3}; ASSERT_SAME_TYPE(decltype(s), std::flat_multiset); assert(s.size() == 2); } { // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator) // braces int source[3] = {1, 2, 3}; std::flat_multiset s{std::sorted_equivalent, source, source + 3}; static_assert(std::is_same_v>); assert(s.size() == 3); } } { int arr[] = {1, 2, 1, INT_MAX, 3}; int sorted_arr[] = {INT_MAX, 3, 2, 1, 1}; const int arrc[] = {1, 2, 1, INT_MAX, 3}; const int sorted_arrc[] = {INT_MAX, 3, 2, 1, 1}; using C = std::greater; { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; std::flat_multiset m(std::begin(arr), std::end(arr), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // const std::flat_multiset m(std::begin(arrc), std::end(arrc), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // const std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // flat_multiset iterator std::flat_multiset mo; std::flat_multiset m(mo.begin(), mo.end(), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); } { // template>> // flat_multiset(InputIterator, InputIterator, Compare = Compare()) // -> flat_multiset, Compare>; // flat_multiset const_iterator std::flat_multiset mo; std::flat_multiset m(mo.cbegin(), mo.cend(), C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); } } { const int sorted_arr[] = {1, 1, 2, 3, INT_MAX}; { // template> // flat_multiset(initializer_list, Compare = Compare()) // -> flat_multiset; std::flat_multiset m{1, 2, 1, INT_MAX, 3}; ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template> // flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) // -> flat_multiset; std::flat_multiset m(std::sorted_equivalent, {1, 1, 2, 3, INT_MAX}); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // One element with brace was treated as initializer_list std::flat_multiset s = {1}; ASSERT_SAME_TYPE(decltype(s), std::flat_multiset); assert(s.size() == 1); } { // Two elements with brace was treated as initializer_list using M = std::flat_multiset; M m; std::flat_multiset s{m, m}; // flat_multiset(initializer_list) ASSERT_SAME_TYPE(decltype(s), std::flat_multiset); assert(s.size() == 2); } } { const int sorted_arr[] = {INT_MAX, 3, 2, 1, 1}; using C = std::greater; { // template> // flat_multiset(initializer_list, Compare = Compare()) // -> flat_multiset; std::flat_multiset m({1, 2, 1, INT_MAX, 3}, C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } { // template> // flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) // -> flat_multiset; std::flat_multiset m(std::sorted_equivalent, {INT_MAX, 3, 2, 1, 1}, C()); ASSERT_SAME_TYPE(decltype(m), std::flat_multiset); assert(std::ranges::equal(m, sorted_arr)); } } { std::list r = {1, 2, 1, INT_MAX, 3}; const int expected[] = {1, 1, 2, 3, INT_MAX}; { // template>, // class Allocator = allocator>> // flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) // -> flat_multiset, Compare, // vector, // alloc-rebind>>>; std::flat_multiset s(std::from_range, r); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset>); assert(std::ranges::equal(s, expected)); } { // template // flat_multiset(from_range_t, R&&, Allocator) // -> flat_multiset, less>, // vector, // alloc-rebind>>>; std::flat_multiset s(std::from_range, r, test_allocator(0, 42)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, std::vector>>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } } { // with comparator std::list r = {1, 2, 1, INT_MAX, 3}; const int expected[] = {INT_MAX, 3, 2, 1, 1}; { // template>, // class Allocator = allocator>> // flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) // -> flat_multiset, Compare, // vector, // alloc-rebind>>>; std::flat_multiset s(std::from_range, r, std::greater()); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset>); assert(std::ranges::equal(s, expected)); } { // template // flat_multiset(from_range_t, R&&, Allocator) // -> flat_multiset, less>, // vector, // alloc-rebind>>>; std::flat_multiset s(std::from_range, r, std::greater(), test_allocator(0, 42)); ASSERT_SAME_TYPE(decltype(s), std::flat_multiset, std::vector>>); assert(std::ranges::equal(s, expected)); assert(std::move(s).extract().get_allocator().get_id() == 42); } } AssociativeContainerDeductionGuidesSfinaeAway>(); } int main(int, char**) { test(); return 0; }