//===----------------------------------------------------------------------===// // // 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 // // template // pair emplace(Args&&... args); #include #include #include #include #include #include #include "MinSequenceContainer.h" #include "../helpers.h" #include "test_macros.h" #include "../../../Emplaceable.h" #include "DefaultOnly.h" #include "min_allocator.h" // Constraints: is_constructible_v, Args...> is true. template concept CanEmplace = requires(M m, Args&&... args) { m.emplace(std::forward(args)...); }; using Map = std::flat_map; static_assert(CanEmplace); static_assert(CanEmplace); static_assert(CanEmplace, std::tuple>); static_assert(!CanEmplace); static_assert(!CanEmplace); template void test() { using Key = typename KeyContainer::value_type; using Value = typename ValueContainer::value_type; using M = std::flat_map, KeyContainer, ValueContainer>; using R = std::pair; { // was empty M m; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 3.5)); assert(r.second); assert(r.first == m.begin()); assert(m.size() == 1); assert(r.first->first == 2); assert(r.first->second == 3.5); } { // key does not exist and inserted at the begin M m = {{3, 4.0}, {5, 3.0}, {6, 1.0}, {7, 0.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(r.second); assert(r.first == m.begin()); assert(m.size() == 5); assert(r.first->first == 2); assert(r.first->second == 2.0); } { // key does not exist and inserted in the middle M m = {{0, 4.0}, {1, 3.0}, {3, 1.0}, {4, 0.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(r.second); assert(r.first == m.begin() + 2); assert(m.size() == 5); assert(r.first->first == 2); assert(r.first->second == 2.0); } { // key does not exist and inserted at the end M m = {{0, 4.0}, {1, 3.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(r.second); assert(r.first == m.begin() + 2); assert(m.size() == 3); assert(r.first->first == 2); assert(r.first->second == 2.0); } { // key already exists and original at the begin M m = {{2, 4.0}, {3, 3.0}, {5, 1.0}, {6, 0.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(!r.second); assert(r.first == m.begin()); assert(m.size() == 4); assert(r.first->first == 2); assert(r.first->second == 4.0); } { // key already exists and original in the middle M m = {{0, 4.0}, {2, 3.0}, {3, 1.0}, {4, 0.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(!r.second); assert(r.first == m.begin() + 1); assert(m.size() == 4); assert(r.first->first == 2); assert(r.first->second == 3.0); } { // key already exists and original at the end M m = {{0, 4.0}, {1, 3.0}, {2, 1.0}}; std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); assert(!r.second); assert(r.first == m.begin() + 2); assert(m.size() == 3); assert(r.first->first == 2); assert(r.first->second == 1.0); } } template void test_emplaceable() { using M = std::flat_map, KeyContainer, ValueContainer>; using R = std::pair; M m; ASSERT_SAME_TYPE(decltype(m.emplace()), R); R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple()); assert(r.second); assert(r.first == m.begin()); assert(m.size() == 1); assert(m.begin()->first == 2); assert(m.begin()->second == Emplaceable()); r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5)); assert(r.second); assert(r.first == m.begin()); assert(m.size() == 2); assert(m.begin()->first == 1); assert(m.begin()->second == Emplaceable(2, 3.5)); r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5)); assert(!r.second); assert(r.first == m.begin()); assert(m.size() == 2); assert(m.begin()->first == 1); assert(m.begin()->second == Emplaceable(2, 3.5)); } int main(int, char**) { test, std::vector>(); test, std::vector>(); test, MinSequenceContainer>(); test>, std::vector>>(); test_emplaceable, std::vector>(); test_emplaceable, std::vector>(); test_emplaceable, MinSequenceContainer>(); test_emplaceable>, std::vector>>(); { auto emplace_func = [](auto& m, auto key_arg, auto value_arg) { m.emplace(std::piecewise_construct, std::tuple(key_arg), std::tuple(value_arg)); }; test_emplace_exception_guarantee(emplace_func); } return 0; }