96 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// <flat_map>12 13// class flat_multimap14 15// void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);16 17#include <algorithm>18#include <deque>19#include <concepts>20#include <flat_map>21#include <functional>22 23#include "MinSequenceContainer.h"24#include "../helpers.h"25#include "test_macros.h"26#include "min_allocator.h"27 28template <class T, class... Args>29concept CanReplace = requires(T t, Args&&... args) { t.replace(std::forward<Args>(args)...); };30 31using Map = std::flat_multimap<int, int>;32static_assert(CanReplace<Map, std::vector<int>, std::vector<int>>);33static_assert(!CanReplace<Map, const std::vector<int>&, std::vector<int>>);34static_assert(!CanReplace<Map, std::vector<int>, const std::vector<int>&>);35static_assert(!CanReplace<Map, const std::vector<int>&, const std::vector<int>&>);36 37template <class KeyContainer, class ValueContainer>38constexpr void test() {39 using Key = typename KeyContainer::value_type;40 using Value = typename ValueContainer::value_type;41 using M = std::flat_multimap<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;42 43 M m = M({1, 1, 3}, {4, 5, 6});44 KeyContainer new_keys = {7, 7};45 ValueContainer new_values = {9, 10};46 auto expected_keys = new_keys;47 auto expected_values = new_values;48 m.replace(std::move(new_keys), std::move(new_values));49 assert(m.size() == 2);50 assert(std::ranges::equal(m.keys(), expected_keys));51 assert(std::ranges::equal(m.values(), expected_values));52}53 54constexpr bool test() {55 test<std::vector<int>, std::vector<double>>();56#ifndef __cpp_lib_constexpr_deque57 if (!TEST_IS_CONSTANT_EVALUATED)58#endif59 test<std::deque<int>, std::vector<double>>();60 test<MinSequenceContainer<int>, MinSequenceContainer<double>>();61 test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();62 63 if (!TEST_IS_CONSTANT_EVALUATED) {64#ifndef TEST_HAS_NO_EXCEPTIONS65 using KeyContainer = std::vector<int>;66 using ValueContainer = ThrowOnMoveContainer<int>;67 using M = std::flat_multimap<int, int, std::ranges::less, KeyContainer, ValueContainer>;68 69 M m;70 m.emplace(1, 1);71 m.emplace(2, 2);72 try {73 KeyContainer new_keys{3, 4};74 ValueContainer new_values{5, 6};75 m.replace(std::move(new_keys), std::move(new_values));76 assert(false);77 } catch (int) {78 check_invariant(m);79 // In libc++, we clear the map80 LIBCPP_ASSERT(m.size() == 0);81 }82#endif83 }84 85 return true;86}87 88int main(int, char**) {89 test();90#if TEST_STD_VER >= 2691 static_assert(test());92#endif93 94 return 0;95}96