@@ -70,6 +70,75 @@ find_in_object<string_view>(
70
70
object const & obj,
71
71
string_view key) noexcept ;
72
72
73
+ template < bool SmallTable, bool IgnoreDuplicates >
74
+ void init_from_unchecked ( object& obj, unchecked_object& uo )
75
+ {
76
+ // insert all elements, keeping
77
+ // the last of any duplicate keys, unless IgnoreDuplicates is false.
78
+ auto const begin = obj.begin ();
79
+ auto dest = begin;
80
+ for ( ; uo.size (); uo.pop_front () )
81
+ {
82
+ auto src = uo.front ();
83
+ access ::construct_key_value_pair (
84
+ dest, pilfer (src[0 ]), pilfer (src[1 ]));
85
+
86
+ string_view const key = dest->key ();
87
+ key_value_pair* duplicate = nullptr ;
88
+ BOOST_IF_CONSTEXPR ( SmallTable )
89
+ duplicate = find_in_object ( obj, key ).first ;
90
+ else
91
+ {
92
+ auto & head = obj.t_ ->bucket ( key );
93
+ auto i = head;
94
+ while ( true )
95
+ {
96
+ if ( i == object::null_index_ )
97
+ {
98
+ // end of bucket
99
+ access ::next (*dest) = head;
100
+ head = static_cast <object::index_t >( dest - begin );
101
+ break ;
102
+ }
103
+ auto & v = begin[i];
104
+ if ( v.key () != key )
105
+ {
106
+ i = access ::next (v);
107
+ continue ;
108
+ }
109
+
110
+ // handle duplicate
111
+ access ::next (*dest) = access ::next (v);
112
+ duplicate = &v;
113
+ break ;
114
+ }
115
+ }
116
+
117
+ if ( !duplicate )
118
+ {
119
+ ++dest;
120
+ ++obj.t_ ->size ;
121
+ continue ;
122
+ }
123
+
124
+ // handle duplicate
125
+ BOOST_IF_CONSTEXPR ( IgnoreDuplicates )
126
+ {
127
+ // don't bother to check if
128
+ // storage deallocate is trivial
129
+ duplicate->~key_value_pair ();
130
+ // trivial relocate
131
+ std::memcpy (
132
+ static_cast <void *>(duplicate), dest, sizeof (key_value_pair) );
133
+ }
134
+ else
135
+ {
136
+ dest->~key_value_pair ();
137
+ return ;
138
+ }
139
+ }
140
+ }
141
+
73
142
} // namespace detail
74
143
75
144
// ----------------------------------------------------------
@@ -212,85 +281,16 @@ object(detail::unchecked_object& uo)
212
281
uo.size (), 0 , sp_);
213
282
t_->size = 0 ;
214
283
215
- // insert all elements, keeping
216
- // the last of any duplicate keys, unless uo.ignore_duplicates is false.
217
- auto dest = begin ();
218
284
if (t_->is_small ())
219
- {
220
- for ( ; uo.size (); uo.pop_front () )
221
- {
222
- auto src = uo.front ();
223
- access ::construct_key_value_pair (
224
- dest, pilfer (src[0 ]), pilfer (src[1 ]));
225
- auto result = detail::find_in_object (*this , dest->key ());
226
- if (! result.first )
227
- {
228
- ++dest;
229
- ++t_->size ;
230
- continue ;
231
- }
232
- // handle duplicate
233
- if ( !uo.ignore_duplicate_keys () )
234
- {
235
- dest->~key_value_pair ();
236
- return ;
237
- }
238
- auto & v = *result.first ;
239
- // don't bother to check if
240
- // storage deallocate is trivial
241
- v.~key_value_pair ();
242
- // trivial relocate
243
- std::memcpy (
244
- static_cast <void *>(&v),
245
- dest, sizeof (v));
246
- }
247
- return ;
248
- }
249
- for ( ; uo.size () ; uo.pop_front () )
250
- {
251
- auto src = uo.front ();
252
- access ::construct_key_value_pair (
253
- dest, pilfer (src[0 ]), pilfer (src[1 ]));
254
- auto & head = t_->bucket (dest->key ());
255
- auto i = head;
256
- for (;;)
257
- {
258
- if (i == null_index_)
259
- {
260
- // end of bucket
261
- access ::next (
262
- *dest) = head;
263
- head = static_cast <index_t >(
264
- dest - begin ());
265
- ++dest;
266
- ++t_->size ;
267
- break ;
268
- }
269
- auto & v = (*t_)[i];
270
- if (v.key () != dest->key ())
271
- {
272
- i = access ::next (v);
273
- continue ;
274
- }
275
-
276
- // handle duplicate
277
- if ( !uo.ignore_duplicate_keys () )
278
- {
279
- dest->~key_value_pair ();
280
- return ;
281
- }
282
- access ::next (*dest) =
283
- access ::next (v);
284
- // don't bother to check if
285
- // storage deallocate is trivial
286
- v.~key_value_pair ();
287
- // trivial relocate
288
- std::memcpy (
289
- static_cast <void *>(&v),
290
- dest, sizeof (v));
291
- break ;
292
- }
293
- }
285
+ if ( uo.ignore_duplicate_keys () )
286
+ detail::init_from_unchecked< true , true >( *this , uo );
287
+ else
288
+ detail::init_from_unchecked< true , false >( *this , uo );
289
+ else
290
+ if ( uo.ignore_duplicate_keys () )
291
+ detail::init_from_unchecked< false , true >( *this , uo );
292
+ else
293
+ detail::init_from_unchecked< false , false >( *this , uo );
294
294
}
295
295
296
296
object::
0 commit comments