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
15 // template <class... Args>
16 // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
17 // template <class... Args>
18 // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
19 // template <class... Args>
20 // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
21 // template <class... Args>
22 // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
29 #include "test_macros.h"
33 Moveable(const Moveable
&);
34 Moveable
& operator=(const Moveable
&);
39 Moveable() : int_(0), double_(0) {}
40 Moveable(int i
, double d
) : int_(i
), double_(d
) {}
41 Moveable(Moveable
&& x
)
42 : int_(x
.int_
), double_(x
.double_
)
43 {x
.int_
= -1; x
.double_
= -1;}
44 Moveable
& operator=(Moveable
&& x
)
45 {int_
= x
.int_
; x
.int_
= -1;
46 double_
= x
.double_
; x
.double_
= -1;
50 bool operator==(const Moveable
& x
) const
51 {return int_
== x
.int_
&& double_
== x
.double_
;}
52 bool operator<(const Moveable
& x
) const
53 {return int_
< x
.int_
|| (int_
== x
.int_
&& double_
< x
.double_
);}
55 int get() const {return int_
;}
56 bool moved() const {return int_
== -1;}
62 { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
63 typedef std::map
<int, Moveable
> M
;
64 typedef std::pair
<M::iterator
, bool> R
;
67 for (int i
= 0; i
< 20; i
+= 2)
68 m
.emplace (i
, Moveable(i
, (double) i
));
69 assert(m
.size() == 10);
72 for (int i
=0; i
< 20; i
+= 2)
74 r
= m
.try_emplace(i
, std::move(mv1
));
75 assert(m
.size() == 10);
76 assert(!r
.second
); // was not inserted
77 assert(!mv1
.moved()); // was not moved from
78 assert(r
.first
->first
== i
); // key
81 r
= m
.try_emplace(-1, std::move(mv1
));
82 assert(m
.size() == 11);
83 assert(r
.second
); // was inserted
84 assert(mv1
.moved()); // was moved from
85 assert(r
.first
->first
== -1); // key
86 assert(r
.first
->second
.get() == 3); // value
89 r
= m
.try_emplace(5, std::move(mv2
));
90 assert(m
.size() == 12);
91 assert(r
.second
); // was inserted
92 assert(mv2
.moved()); // was moved from
93 assert(r
.first
->first
== 5); // key
94 assert(r
.first
->second
.get() == 5); // value
96 Moveable
mv3(-1, 3.0);
97 r
= m
.try_emplace(117, std::move(mv2
));
98 assert(m
.size() == 13);
99 assert(r
.second
); // was inserted
100 assert(mv2
.moved()); // was moved from
101 assert(r
.first
->first
== 117); // key
102 assert(r
.first
->second
.get() == -1); // value
105 { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
106 typedef std::map
<Moveable
, Moveable
> M
;
107 typedef std::pair
<M::iterator
, bool> R
;
110 for ( int i
= 0; i
< 20; i
+= 2 )
111 m
.emplace ( Moveable(i
, (double) i
), Moveable(i
+1, (double) i
+1));
112 assert(m
.size() == 10);
114 Moveable
mvkey1(2, 2.0);
115 Moveable
mv1(4, 4.0);
116 r
= m
.try_emplace(std::move(mvkey1
), std::move(mv1
));
117 assert(m
.size() == 10);
118 assert(!r
.second
); // was not inserted
119 assert(!mv1
.moved()); // was not moved from
120 assert(!mvkey1
.moved()); // was not moved from
121 assert(r
.first
->first
== mvkey1
); // key
123 Moveable
mvkey2(3, 3.0);
124 r
= m
.try_emplace(std::move(mvkey2
), std::move(mv1
));
125 assert(m
.size() == 11);
126 assert(r
.second
); // was inserted
127 assert(mv1
.moved()); // was moved from
128 assert(mvkey2
.moved()); // was moved from
129 assert(r
.first
->first
.get() == 3); // key
130 assert(r
.first
->second
.get() == 4); // value
133 { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
134 typedef std::map
<int, Moveable
> M
;
137 for ( int i
= 0; i
< 20; i
+= 2 )
138 m
.try_emplace ( i
, Moveable(i
, (double) i
));
139 assert(m
.size() == 10);
140 M::const_iterator it
= m
.find(2);
142 Moveable
mv1(3, 3.0);
143 for (int i
=0; i
< 20; i
+= 2)
145 r
= m
.try_emplace(it
, i
, std::move(mv1
));
146 assert(m
.size() == 10);
147 assert(!mv1
.moved()); // was not moved from
148 assert(r
->first
== i
); // key
149 assert(r
->second
.get() == i
); // value
152 r
= m
.try_emplace(it
, 3, std::move(mv1
));
153 assert(m
.size() == 11);
154 assert(mv1
.moved()); // was moved from
155 assert(r
->first
== 3); // key
156 assert(r
->second
.get() == 3); // value
159 { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
160 typedef std::map
<Moveable
, Moveable
> M
;
163 for ( int i
= 0; i
< 20; i
+= 2 )
164 m
.emplace ( Moveable(i
, (double) i
), Moveable(i
+1, (double) i
+1));
165 assert(m
.size() == 10);
166 M::const_iterator it
= std::next(m
.cbegin());
168 Moveable
mvkey1(2, 2.0);
169 Moveable
mv1(4, 4.0);
170 r
= m
.try_emplace(it
, std::move(mvkey1
), std::move(mv1
));
171 assert(m
.size() == 10);
172 assert(!mv1
.moved()); // was not moved from
173 assert(!mvkey1
.moved()); // was not moved from
174 assert(r
->first
== mvkey1
); // key
176 Moveable
mvkey2(3, 3.0);
177 r
= m
.try_emplace(it
, std::move(mvkey2
), std::move(mv1
));
178 assert(m
.size() == 11);
179 assert(mv1
.moved()); // was moved from
180 assert(mvkey2
.moved()); // was moved from
181 assert(r
->first
.get() == 3); // key
182 assert(r
->second
.get() == 4); // value