1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
13 // template <class... Args>
14 // pair<iterator, bool> emplace(Args&&... args);
23 #include "MinSequenceContainer.h"
24 #include "../helpers.h"
25 #include "test_macros.h"
26 #include "../../../Emplaceable.h"
27 #include "DefaultOnly.h"
28 #include "min_allocator.h"
30 // Constraints: is_constructible_v<pair<key_type, mapped_type>, Args...> is true.
31 template <class M
, class... Args
>
32 concept CanEmplace
= requires(M m
, Args
&&... args
) { m
.emplace(std::forward
<Args
>(args
)...); };
34 using Map
= std::flat_map
<Emplaceable
, Emplaceable
>;
35 static_assert(CanEmplace
<Map
>);
36 static_assert(CanEmplace
<Map
, Emplaceable
, Emplaceable
>);
37 static_assert(CanEmplace
<Map
, std::piecewise_construct_t
, std::tuple
<int, double>, std::tuple
<int, double>>);
38 static_assert(!CanEmplace
<Map
, Emplaceable
>);
39 static_assert(!CanEmplace
<Map
, int, double>);
41 template <class KeyContainer
, class ValueContainer
>
43 using Key
= typename
KeyContainer::value_type
;
44 using Value
= typename
ValueContainer::value_type
;
45 using M
= std::flat_map
<Key
, Value
, std::less
<Key
>, KeyContainer
, ValueContainer
>;
46 using R
= std::pair
<typename
M::iterator
, bool>;
50 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 3.5));
52 assert(r
.first
== m
.begin());
53 assert(m
.size() == 1);
54 assert(r
.first
->first
== 2);
55 assert(r
.first
->second
== 3.5);
58 // key does not exist and inserted at the begin
59 M m
= {{3, 4.0}, {5, 3.0}, {6, 1.0}, {7, 0.0}};
60 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
62 assert(r
.first
== m
.begin());
63 assert(m
.size() == 5);
64 assert(r
.first
->first
== 2);
65 assert(r
.first
->second
== 2.0);
68 // key does not exist and inserted in the middle
69 M m
= {{0, 4.0}, {1, 3.0}, {3, 1.0}, {4, 0.0}};
70 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
72 assert(r
.first
== m
.begin() + 2);
73 assert(m
.size() == 5);
74 assert(r
.first
->first
== 2);
75 assert(r
.first
->second
== 2.0);
78 // key does not exist and inserted at the end
79 M m
= {{0, 4.0}, {1, 3.0}};
80 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
82 assert(r
.first
== m
.begin() + 2);
83 assert(m
.size() == 3);
84 assert(r
.first
->first
== 2);
85 assert(r
.first
->second
== 2.0);
88 // key already exists and original at the begin
89 M m
= {{2, 4.0}, {3, 3.0}, {5, 1.0}, {6, 0.0}};
90 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
92 assert(r
.first
== m
.begin());
93 assert(m
.size() == 4);
94 assert(r
.first
->first
== 2);
95 assert(r
.first
->second
== 4.0);
98 // key already exists and original in the middle
99 M m
= {{0, 4.0}, {2, 3.0}, {3, 1.0}, {4, 0.0}};
100 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
102 assert(r
.first
== m
.begin() + 1);
103 assert(m
.size() == 4);
104 assert(r
.first
->first
== 2);
105 assert(r
.first
->second
== 3.0);
108 // key already exists and original at the end
109 M m
= {{0, 4.0}, {1, 3.0}, {2, 1.0}};
110 std::same_as
<R
> decltype(auto) r
= m
.emplace(typename
M::value_type(2, 2.0));
112 assert(r
.first
== m
.begin() + 2);
113 assert(m
.size() == 3);
114 assert(r
.first
->first
== 2);
115 assert(r
.first
->second
== 1.0);
119 template <class KeyContainer
, class ValueContainer
>
120 void test_emplaceable() {
121 using M
= std::flat_map
<int, Emplaceable
, std::less
<int>, KeyContainer
, ValueContainer
>;
122 using R
= std::pair
<typename
M::iterator
, bool>;
125 ASSERT_SAME_TYPE(decltype(m
.emplace()), R
);
126 R r
= m
.emplace(std::piecewise_construct
, std::forward_as_tuple(2), std::forward_as_tuple());
128 assert(r
.first
== m
.begin());
129 assert(m
.size() == 1);
130 assert(m
.begin()->first
== 2);
131 assert(m
.begin()->second
== Emplaceable());
132 r
= m
.emplace(std::piecewise_construct
, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5));
134 assert(r
.first
== m
.begin());
135 assert(m
.size() == 2);
136 assert(m
.begin()->first
== 1);
137 assert(m
.begin()->second
== Emplaceable(2, 3.5));
138 r
= m
.emplace(std::piecewise_construct
, std::forward_as_tuple(1), std::forward_as_tuple(2, 3.5));
140 assert(r
.first
== m
.begin());
141 assert(m
.size() == 2);
142 assert(m
.begin()->first
== 1);
143 assert(m
.begin()->second
== Emplaceable(2, 3.5));
146 int main(int, char**) {
147 test
<std::vector
<int>, std::vector
<double>>();
148 test
<std::deque
<int>, std::vector
<double>>();
149 test
<MinSequenceContainer
<int>, MinSequenceContainer
<double>>();
150 test
<std::vector
<int, min_allocator
<int>>, std::vector
<double, min_allocator
<double>>>();
152 test_emplaceable
<std::vector
<int>, std::vector
<Emplaceable
>>();
153 test_emplaceable
<std::deque
<int>, std::vector
<Emplaceable
>>();
154 test_emplaceable
<MinSequenceContainer
<int>, MinSequenceContainer
<Emplaceable
>>();
155 test_emplaceable
<std::vector
<int, min_allocator
<int>>, std::vector
<Emplaceable
, min_allocator
<Emplaceable
>>>();
158 auto emplace_func
= [](auto& m
, auto key_arg
, auto value_arg
) {
159 m
.emplace(std::piecewise_construct
, std::tuple(key_arg
), std::tuple(value_arg
));
161 test_emplace_exception_guarantee(emplace_func
);