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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 |
10 | |
11 | // <flat_map> |
12 | |
13 | // class flat_multimap |
14 | |
15 | // template <class InputIterator> |
16 | // void insert(InputIterator first, InputIterator last); |
17 | |
18 | #include <flat_map> |
19 | #include <algorithm> |
20 | #include <cassert> |
21 | #include <functional> |
22 | #include <deque> |
23 | |
24 | #include "MinSequenceContainer.h" |
25 | #include "../helpers.h" |
26 | #include "test_macros.h" |
27 | #include "test_iterators.h" |
28 | #include "min_allocator.h" |
29 | |
30 | // test constraint InputIterator |
31 | template <class M, class... Args> |
32 | concept CanInsert = requires(M m, Args&&... args) { m.insert(std::forward<Args>(args)...); }; |
33 | |
34 | using Map = std::flat_multimap<int, int>; |
35 | using Pair = std::pair<int, int>; |
36 | |
37 | static_assert(CanInsert<Map, Pair*, Pair*>); |
38 | static_assert(CanInsert<Map, cpp17_input_iterator<Pair*>, cpp17_input_iterator<Pair*>>); |
39 | static_assert(!CanInsert<Map, int, int>); |
40 | static_assert(!CanInsert<Map, cpp20_input_iterator<Pair*>, cpp20_input_iterator<Pair*>>); |
41 | |
42 | template <class KeyContainer, class ValueContainer> |
43 | void test() { |
44 | using P = std::pair<int, double>; |
45 | using M = std::flat_multimap<int, double, std::less<int>, KeyContainer, ValueContainer>; |
46 | |
47 | P ar1[] = { |
48 | P(2, 1), |
49 | P(2, 1.5), |
50 | P(2, 2), |
51 | P(1, 1), |
52 | P(1, 1.5), |
53 | P(1, 2), |
54 | P(3, 1), |
55 | P(3, 1.5), |
56 | P(3, 2), |
57 | }; |
58 | P ar2[] = { |
59 | P(4, 1), |
60 | P(4, 1.5), |
61 | P(4, 2), |
62 | P(1, 1), |
63 | P(1, 1.5), |
64 | P(1, 2), |
65 | P(0, 1), |
66 | P(0, 1.5), |
67 | P(0, 2), |
68 | }; |
69 | |
70 | M m; |
71 | m.insert(cpp17_input_iterator<P*>(ar1), cpp17_input_iterator<P*>(ar1 + sizeof(ar1) / sizeof(ar1[0]))); |
72 | assert(m.size() == 9); |
73 | std::vector<P> expected{{1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2}}; |
74 | assert(std::ranges::equal(m, expected)); |
75 | |
76 | m.insert(cpp17_input_iterator<P*>(ar2), cpp17_input_iterator<P*>(ar2 + sizeof(ar2) / sizeof(ar2[0]))); |
77 | assert(m.size() == 18); |
78 | std::vector<P> expected2{ |
79 | {0, 1}, |
80 | {0, 1.5}, |
81 | {0, 2}, |
82 | {1, 1}, |
83 | {1, 1.5}, |
84 | {1, 2}, |
85 | {1, 1}, |
86 | {1, 1.5}, |
87 | {1, 2}, |
88 | {2, 1}, |
89 | {2, 1.5}, |
90 | {2, 2}, |
91 | {3, 1}, |
92 | {3, 1.5}, |
93 | {3, 2}, |
94 | {4, 1}, |
95 | {4, 1.5}, |
96 | {4, 2}}; |
97 | assert(std::ranges::equal(m, expected2)); |
98 | } |
99 | int main(int, char**) { |
100 | test<std::vector<int>, std::vector<double>>(); |
101 | test<std::deque<int>, std::vector<double>>(); |
102 | test<MinSequenceContainer<int>, MinSequenceContainer<double>>(); |
103 | test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>(); |
104 | |
105 | { |
106 | auto insert_func = [](auto& m, const auto& newValues) { m.insert(newValues.begin(), newValues.end()); }; |
107 | test_insert_range_exception_guarantee(insert_function&: insert_func); |
108 | } |
109 | { |
110 | std::flat_multimap<int, int, std::less<int>, SillyReserveVector<int>, SillyReserveVector<int>> m{{1, 1}, {2, 2}}; |
111 | std::vector<std::pair<int, int>> v{{3, 3}, {4, 4}}; |
112 | m.insert(v.begin(), v.end()); |
113 | assert(std::ranges::equal(m, std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {3, 3}, {4, 4}})); |
114 | } |
115 | return 0; |
116 | } |
117 | |