[clang][bytecode][NFC] Only call getSource() when necessary (#125419)
[llvm-project.git] / libcxx / test / std / containers / container.adaptors / flat.map / flat.map.modifiers / try_emplace_transparent.pass.cpp
blob21fda437809674b342d06ec30d202c27d34d103c
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // <flat_map>
13 // template<class K, class... Args>
14 // pair<iterator, bool> try_emplace(K&& k, Args&&... args);
15 // template<class K, class... Args>
16 // iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
18 #include <flat_map>
19 #include <cassert>
20 #include <functional>
21 #include <deque>
22 #include <vector>
24 #include "MinSequenceContainer.h"
25 #include "test_macros.h"
26 #include "../helpers.h"
27 #include "min_allocator.h"
28 #include "../../../Emplaceable.h"
30 // Constraints:
31 // The qualified-id Compare::is_transparent is valid and denotes a type.
32 // is_constructible_v<key_type, K> is true.
33 // is_constructible_v<mapped_type, Args...> is true.
34 // For the first overload, is_convertible_v<K&&, const_iterator> and is_convertible_v<K&&, iterator> are both false
35 template <class M, class... Args>
36 concept CanTryEmplace = requires(M m, Args&&... args) { m.try_emplace(std::forward<Args>(args)...); };
38 using TransparentMap = std::flat_map<int, Emplaceable, TransparentComparator>;
39 using NonTransparentMap = std::flat_map<int, Emplaceable, NonTransparentComparator>;
41 using TransparentMapIter = typename TransparentMap::iterator;
42 using TransparentMapConstIter = typename TransparentMap::const_iterator;
44 static_assert(!CanTryEmplace<TransparentMap>);
45 static_assert(!CanTryEmplace<NonTransparentMap>);
47 static_assert(CanTryEmplace<TransparentMap, ConvertibleTransparent<int>>);
48 static_assert(CanTryEmplace<TransparentMap, ConvertibleTransparent<int>, Emplaceable>);
49 static_assert(CanTryEmplace<TransparentMap, ConvertibleTransparent<int>, int, double>);
50 static_assert(!CanTryEmplace<TransparentMap, ConvertibleTransparent<int>, const Emplaceable&>);
51 static_assert(!CanTryEmplace<TransparentMap, ConvertibleTransparent<int>, int>);
52 static_assert(!CanTryEmplace<TransparentMap, NonConvertibleTransparent<int>, Emplaceable>);
53 static_assert(!CanTryEmplace<NonTransparentMap, NonConvertibleTransparent<int>, Emplaceable>);
54 static_assert(!CanTryEmplace<TransparentMap, ConvertibleTransparent<int>, int>);
55 static_assert(!CanTryEmplace<TransparentMap, TransparentMapIter, Emplaceable>);
56 static_assert(!CanTryEmplace<TransparentMap, TransparentMapConstIter, Emplaceable>);
58 static_assert(CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>>);
59 static_assert(CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>, Emplaceable>);
60 static_assert(CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>, int, double>);
61 static_assert(!CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>, const Emplaceable&>);
62 static_assert(!CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>, int>);
63 static_assert(!CanTryEmplace<TransparentMap, TransparentMapConstIter, NonConvertibleTransparent<int>, Emplaceable>);
64 static_assert(!CanTryEmplace<NonTransparentMap, TransparentMapConstIter, NonConvertibleTransparent<int>, Emplaceable>);
65 static_assert(!CanTryEmplace<TransparentMap, TransparentMapConstIter, ConvertibleTransparent<int>, int>);
67 template <class KeyContainer, class ValueContainer>
68 void test() {
69 using Key = typename KeyContainer::value_type;
70 using Value = typename ValueContainer::value_type;
71 using M = std::flat_map<Key, Value, TransparentComparator, KeyContainer, ValueContainer>;
73 { // pair<iterator, bool> try_emplace(K&& k, Args&&... args);
74 using R = std::pair<typename M::iterator, bool>;
75 M m;
76 for (int i = 0; i < 20; i += 2)
77 m.emplace(i, Moveable(i, (double)i));
79 assert(m.size() == 10);
81 Moveable mv1(3, 3.0);
82 for (int i = 0; i < 20; i += 2) {
83 std::same_as<R> decltype(auto) r = m.try_emplace(ConvertibleTransparent<int>{i}, std::move(mv1));
84 assert(m.size() == 10);
85 assert(!r.second); // was not inserted
86 assert(!mv1.moved()); // was not moved from
87 assert(r.first->first == i); // key
90 std::same_as<R> decltype(auto) r2 = m.try_emplace(ConvertibleTransparent<int>{-1}, std::move(mv1));
91 assert(m.size() == 11);
92 assert(r2.second); // was inserted
93 assert(mv1.moved()); // was moved from
94 assert(r2.first->first == -1); // key
95 assert(r2.first->second.get() == 3); // value
97 Moveable mv2(5, 3.0);
98 std::same_as<R> decltype(auto) r3 = m.try_emplace(ConvertibleTransparent<int>{5}, std::move(mv2));
99 assert(m.size() == 12);
100 assert(r3.second); // was inserted
101 assert(mv2.moved()); // was moved from
102 assert(r3.first->first == 5); // key
103 assert(r3.first->second.get() == 5); // value
105 Moveable mv3(-1, 3.0);
106 std::same_as<R> decltype(auto) r4 = m.try_emplace(ConvertibleTransparent<int>{117}, std::move(mv2));
107 assert(m.size() == 13);
108 assert(r4.second); // was inserted
109 assert(mv2.moved()); // was moved from
110 assert(r4.first->first == 117); // key
111 assert(r4.first->second.get() == -1); // value
114 { // iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
115 using R = typename M::iterator;
116 M m;
117 for (int i = 0; i < 20; i += 2)
118 m.try_emplace(i, Moveable(i, (double)i));
119 assert(m.size() == 10);
120 typename M::const_iterator it = m.find(2);
122 Moveable mv1(3, 3.0);
123 for (int i = 0; i < 20; i += 2) {
124 std::same_as<R> decltype(auto) r1 = m.try_emplace(it, ConvertibleTransparent<int>{i}, std::move(mv1));
125 assert(m.size() == 10);
126 assert(!mv1.moved()); // was not moved from
127 assert(r1->first == i); // key
128 assert(r1->second.get() == i); // value
131 std::same_as<R> decltype(auto) r2 = m.try_emplace(it, ConvertibleTransparent<int>{3}, std::move(mv1));
132 assert(m.size() == 11);
133 assert(mv1.moved()); // was moved from
134 assert(r2->first == 3); // key
135 assert(r2->second.get() == 3); // value
139 int main(int, char**) {
140 test<std::vector<int>, std::vector<Moveable>>();
141 test<std::deque<int>, std::vector<Moveable>>();
142 test<MinSequenceContainer<int>, MinSequenceContainer<Moveable>>();
143 test<std::vector<int, min_allocator<int>>, std::vector<Moveable, min_allocator<Moveable>>>();
146 bool transparent_used = false;
147 TransparentComparator c(transparent_used);
148 std::flat_map<int, int, TransparentComparator> m(std::sorted_unique, {{1, 1}, {2, 2}, {3, 3}}, c);
149 assert(!transparent_used);
150 auto p = m.try_emplace(ConvertibleTransparent<int>{3}, 3);
151 assert(!p.second);
152 assert(transparent_used);
155 bool transparent_used = false;
156 TransparentComparator c(transparent_used);
157 std::flat_map<int, int, TransparentComparator> m(std::sorted_unique, {{1, 1}, {2, 2}, {3, 3}}, c);
158 assert(!transparent_used);
159 auto p = m.try_emplace(m.begin(), ConvertibleTransparent<int>{3}, 3);
160 assert(p->second == 3);
161 assert(transparent_used);
164 auto try_emplace = [](auto& m, auto key_arg, auto value_arg) {
165 using M = std::decay_t<decltype(m)>;
166 using Key = typename M::key_type;
167 m.try_emplace(ConvertibleTransparent<Key>{key_arg}, value_arg);
169 test_emplace_exception_guarantee(try_emplace);
173 auto try_emplace_iter = [](auto& m, auto key_arg, auto value_arg) {
174 using M = std::decay_t<decltype(m)>;
175 using Key = typename M::key_type;
176 m.try_emplace(m.begin(), ConvertibleTransparent<Key>{key_arg}, value_arg);
178 test_emplace_exception_guarantee(try_emplace_iter);
181 return 0;