//===----------------------------------------------------------------------===// // // 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 // // flat_map(key_container_type key_cont, mapped_container_type mapped_cont, // const key_compare& comp = key_compare()); // template // flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, // const Allocator& a); // template // flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, // const key_compare& comp, const Alloc& a); #include #include #include #include #include #include "min_allocator.h" #include "MoveOnly.h" #include "test_allocator.h" #include "test_iterators.h" #include "test_macros.h" #include "../../../test_compare.h" struct P { int first; int second; template bool operator==(const std::pair& rhs) const { return MoveOnly(first) == rhs.first && MoveOnly(second) == rhs.second; } }; int main(int, char**) { { // The constructors in this subclause shall not participate in overload // resolution unless uses_allocator_v is true // and uses_allocator_v is true. using C = test_less; using A1 = test_allocator; using A2 = other_allocator; using V1 = std::vector; using V2 = std::vector; using M1 = std::flat_map; using M2 = std::flat_map; using M3 = std::flat_map; static_assert(std::is_constructible_v); static_assert(!std::is_constructible_v); static_assert(!std::is_constructible_v); static_assert(!std::is_constructible_v); static_assert(std::is_constructible_v); static_assert(!std::is_constructible_v); static_assert(!std::is_constructible_v); static_assert(!std::is_constructible_v); } { // flat_map(key_container_type , mapped_container_type) using M = std::flat_map; std::vector ks = {1, 1, 1, 2, 2, 3, 2, 3, 3}; std::vector vs = {1, 2, 3, 4, 5, 6, 7, 8, 9}; auto m = M(ks, vs); assert((m.keys() == std::vector{1, 2, 3})); LIBCPP_ASSERT((m.values() == std::vector{1, 4, 6})); // explicit(false) M m2 = {ks, vs}; assert(m2 == m); m = M(std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from assert((m.keys() == std::vector{1, 2, 3})); LIBCPP_ASSERT((m.values() == std::vector{1, 4, 6})); } { // flat_map(key_container_type , mapped_container_type) // move-only P expected[] = {{3, 2}, {2, 1}, {1, 3}}; using Ks = std::deque>; using Vs = std::vector>; using M = std::flat_map, Ks, Vs>; Ks ks = {1, 3, 2}; Vs vs; vs.push_back(3); vs.push_back(2); vs.push_back(1); auto m = M(std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from assert(std::ranges::equal(m, expected, std::equal_to<>())); } { // flat_map(key_container_type , mapped_container_type) // container's allocators are used using A = test_allocator; using M = std::flat_map, std::vector, std::deque>; auto ks = std::vector({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(5)); auto vs = std::deque({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(6)); auto m = M(std::move(ks), std::move(vs)); assert(ks.empty()); // it was moved-from assert(vs.empty()); // it was moved-from assert((m == M{{1, 1}, {2, 2}, {3, 3}})); assert(m.keys().get_allocator() == A(5)); assert(m.values().get_allocator() == A(6)); } { // flat_map(key_container_type , mapped_container_type, key_compare) using C = test_less; using M = std::flat_map; std::vector ks = {1, 1, 1, 2, 2, 3, 2, 3, 3}; std::vector vs = {1, 2, 3, 4, 5, 6, 7, 8, 9}; auto m = M(ks, vs, C(4)); assert((m.keys() == std::vector{1, 2, 3})); LIBCPP_ASSERT((m.values() == std::vector{1, 4, 6})); assert(m.key_comp() == C(4)); // explicit(false) M m2 = {ks, vs, C(4)}; assert(m2 == m); assert(m2.key_comp() == C(4)); } { // flat_map(key_container_type , mapped_container_type, const Allocator&) using A = test_allocator; using M = std::flat_map, std::vector, std::deque>; auto ks = std::vector({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(5)); auto vs = std::deque({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(6)); auto m = M(ks, vs, A(4)); // replaces the allocators assert(!ks.empty()); // it was an lvalue above assert(!vs.empty()); // it was an lvalue above assert((m == M{{1, 1}, {2, 2}, {3, 3}})); assert(m.keys().get_allocator() == A(4)); assert(m.values().get_allocator() == A(4)); } { // flat_map(key_container_type , mapped_container_type, const Allocator&) // explicit(false) using A = test_allocator; using M = std::flat_map, std::vector, std::deque>; auto ks = std::vector({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(5)); auto vs = std::deque({1, 1, 1, 2, 2, 3, 2, 3, 3}, A(6)); M m = {ks, vs, A(4)}; // implicit ctor assert(!ks.empty()); // it was an lvalue above assert(!vs.empty()); // it was an lvalue above assert((m == M{{1, 1}, {2, 2}, {3, 3}})); assert(m.keys().get_allocator() == A(4)); assert(m.values().get_allocator() == A(4)); } { // flat_map(key_container_type , mapped_container_type, key_compare, const Allocator&) using C = test_less; using A = test_allocator; using M = std::flat_map, std::vector>; std::vector ks = {1, 1, 1, 2, 2, 3, 2, 3, 3}; std::vector vs = {1, 2, 3, 4, 5, 6, 7, 8, 9}; auto m = M(ks, vs, C(4), A(5)); assert((m.keys() == std::vector{1, 2, 3})); LIBCPP_ASSERT((m.values() == std::vector{1, 4, 6})); assert(m.key_comp() == C(4)); assert(m.keys().get_allocator() == A(5)); assert(m.values().get_allocator() == A(5)); // explicit(false) M m2 = {ks, vs, C(4), A(5)}; assert(m2 == m); assert(m2.key_comp() == C(4)); assert(m2.keys().get_allocator() == A(5)); assert(m2.values().get_allocator() == A(5)); } return 0; }