@@ -161,26 +161,10 @@ class SmallSet {
161
161
// / Returns a pair. The first value of it is an iterator to the inserted
162
162
// / element or the existing element in the set. The second value is true
163
163
// / if the element is inserted (it was not in the set before).
164
- std::pair<const_iterator, bool > insert (const T &V) {
165
- if (!isSmall ()) {
166
- auto [I, Inserted] = Set.insert (V);
167
- return std::make_pair (const_iterator (I), Inserted);
168
- }
164
+ std::pair<const_iterator, bool > insert (const T &V) { return insertImpl (V); }
169
165
170
- auto I = std::find (Vector.begin (), Vector.end (), V);
171
- if (I != Vector.end ()) // Don't reinsert if it already exists.
172
- return std::make_pair (const_iterator (I), false );
173
- if (Vector.size () < N) {
174
- Vector.push_back (V);
175
- return std::make_pair (const_iterator (std::prev (Vector.end ())), true );
176
- }
177
-
178
- // Otherwise, grow from vector to set.
179
- while (!Vector.empty ()) {
180
- Set.insert (Vector.back ());
181
- Vector.pop_back ();
182
- }
183
- return std::make_pair (const_iterator (Set.insert (V).first ), true );
166
+ std::pair<const_iterator, bool > insert (T &&V) {
167
+ return insertImpl (std::move (V));
184
168
}
185
169
186
170
template <typename IterT>
@@ -226,6 +210,31 @@ class SmallSet {
226
210
227
211
private:
228
212
bool isSmall () const { return Set.empty (); }
213
+
214
+ template <typename ArgType>
215
+ std::pair<const_iterator, bool > insertImpl (ArgType &&V) {
216
+ static_assert (std::is_convertible_v<ArgType, T>,
217
+ " ArgType must be convertible to T!" );
218
+ if (!isSmall ()) {
219
+ auto [I, Inserted] = Set.insert (std::forward<ArgType>(V));
220
+ return std::make_pair (const_iterator (I), Inserted);
221
+ }
222
+
223
+ auto I = std::find (Vector.begin (), Vector.end (), V);
224
+ if (I != Vector.end ()) // Don't reinsert if it already exists.
225
+ return std::make_pair (const_iterator (I), false );
226
+ if (Vector.size () < N) {
227
+ Vector.push_back (std::forward<ArgType>(V));
228
+ return std::make_pair (const_iterator (std::prev (Vector.end ())), true );
229
+ }
230
+
231
+ // Otherwise, grow from vector to set.
232
+ Set.insert (std::make_move_iterator (Vector.begin ()),
233
+ std::make_move_iterator (Vector.end ()));
234
+ Vector.clear ();
235
+ return std::make_pair (
236
+ const_iterator (Set.insert (std::forward<ArgType>(V)).first ), true );
237
+ }
229
238
};
230
239
231
240
// / If this set is of pointer values, transparently switch over to using
0 commit comments