@@ -54,6 +54,10 @@ Variant& Variant::operator=(const Variant& other) {
54
54
set_mutable_string (other.mutable_string ());
55
55
break ;
56
56
}
57
+ case kTypeSmallString : {
58
+ strcpy (value_.small_string , other.value_ .small_string ); // NOLINT
59
+ break ;
60
+ }
57
61
case kTypeVector : {
58
62
set_vector (other.vector ());
59
63
break ;
@@ -72,6 +76,9 @@ Variant& Variant::operator=(const Variant& other) {
72
76
other.value_ .blob_value .size );
73
77
break ;
74
78
}
79
+ case kMaxTypeValue :
80
+ FIREBASE_ASSERT (false ); // Should never hit this
81
+ break ;
75
82
}
76
83
}
77
84
return *this ;
@@ -110,6 +117,12 @@ Variant& Variant::operator=(Variant&& other) {
110
117
other.value_ .mutable_string_value = nullptr ;
111
118
break ;
112
119
}
120
+ case kTypeSmallString : {
121
+ memcpy (value_.small_string , other.value_ .small_string ,
122
+ kMaxSmallStringSize );
123
+ other.value_ .small_string [0 ] = ' \0 ' ;
124
+ break ;
125
+ }
113
126
case kTypeVector : {
114
127
value_.vector_value = other.value_ .vector_value ;
115
128
other.value_ .vector_value = nullptr ;
@@ -132,6 +145,9 @@ Variant& Variant::operator=(Variant&& other) {
132
145
other.value_ .blob_value .size = 0 ;
133
146
break ;
134
147
}
148
+ case kMaxTypeValue :
149
+ FIREBASE_ASSERT (false ); // Should never hit this
150
+ break ;
135
151
}
136
152
}
137
153
return *this ;
@@ -156,6 +172,7 @@ bool Variant::operator==(const Variant& other) const {
156
172
return bool_value () == other.bool_value ();
157
173
case kTypeMutableString :
158
174
case kTypeStaticString :
175
+ case kTypeSmallString :
159
176
// string == performs string comparison
160
177
return strcmp (string_value (), other.string_value ()) == 0 ;
161
178
case kTypeVector :
@@ -172,16 +189,45 @@ bool Variant::operator==(const Variant& other) const {
172
189
((is_static_blob () && other.is_static_blob () &&
173
190
blob_data () == other.blob_data ()) ||
174
191
memcmp (blob_data (), other.blob_data (), blob_size ()) == 0 );
192
+ case kMaxTypeValue :
193
+ FIREBASE_ASSERT (false ); // Should never hit this
194
+ break ;
175
195
}
176
196
return false ; // Should never reach this.
177
197
}
178
198
179
199
bool Variant::operator <(const Variant& other) const {
200
+ Type left_type = type ();
201
+ Type right_type = other.type ();
202
+
203
+ // If we are any string type set type to static string as we care about string
204
+ // value not type of string.
205
+ if (is_string ()) {
206
+ left_type = kTypeStaticString ;
207
+ }
208
+
209
+ // If other is any string type set type to static string as we care about
210
+ // string value not type of string.
211
+ if (other.is_string ()) {
212
+ right_type = kTypeStaticString ;
213
+ }
214
+
215
+ // If we are any blob type set type to static blob as we care about blob value
216
+ // not type of blob.
217
+ if (is_blob ()) {
218
+ left_type = kTypeStaticBlob ;
219
+ }
220
+
221
+ // If other is any blob type set type to static blob as we care about blob
222
+ // value not type of blob.
223
+ if (other.is_blob ()) {
224
+ right_type = kTypeStaticBlob ;
225
+ }
226
+
180
227
// If the types don't match (except count both string types as matching, and
181
228
// both blob types as matching), compare the types.
182
- if (type () != other.type () && !(is_string () && other.is_string ()) &&
183
- !(is_blob () && other.is_blob ()))
184
- return static_cast <int >(type ()) < static_cast <int >(other.type ());
229
+ if (left_type != right_type)
230
+ return static_cast <int >(left_type) < static_cast <int >(right_type);
185
231
// Type is now equal (or both strings, or both blobs).
186
232
switch (type_) {
187
233
case kTypeNull : {
@@ -198,6 +244,7 @@ bool Variant::operator<(const Variant& other) const {
198
244
}
199
245
case kTypeMutableString :
200
246
case kTypeStaticString :
247
+ case kTypeSmallString :
201
248
return strcmp (string_value (), other.string_value ()) < 0 ;
202
249
case kTypeVector : {
203
250
auto i = vector ().begin ();
@@ -229,6 +276,9 @@ bool Variant::operator<(const Variant& other) const {
229
276
return blob_size () == other.blob_size ()
230
277
? memcmp (blob_data (), other.blob_data (), blob_size ()) < 0
231
278
: blob_size () < other.blob_size ();
279
+ case kMaxTypeValue :
280
+ FIREBASE_ASSERT (false ); // Should never hit this
281
+ break ;
232
282
}
233
283
return false ; // Should never reach this.
234
284
}
@@ -255,18 +305,35 @@ void Variant::Clear(Type new_type) {
255
305
break ;
256
306
}
257
307
case kTypeMutableString : {
258
- delete value_.mutable_string_value ;
259
- value_.mutable_string_value = nullptr ;
308
+ if (new_type != kTypeMutableString
309
+ || value_.mutable_string_value == nullptr ) {
310
+ delete value_.mutable_string_value ;
311
+ value_.mutable_string_value = nullptr ;
312
+ } else {
313
+ value_.mutable_string_value ->clear ();
314
+ }
315
+ break ;
316
+ }
317
+ case kTypeSmallString : {
318
+ value_.small_string [0 ] = ' \0 ' ;
260
319
break ;
261
320
}
262
321
case kTypeVector : {
263
- delete value_.vector_value ;
264
- value_.vector_value = nullptr ;
322
+ if (new_type != kTypeVector || value_.vector_value == nullptr ) {
323
+ delete value_.vector_value ;
324
+ value_.vector_value = nullptr ;
325
+ } else {
326
+ value_.vector_value ->clear ();
327
+ }
265
328
break ;
266
329
}
267
330
case kTypeMap : {
268
- delete value_.map_value ;
269
- value_.map_value = nullptr ;
331
+ if (new_type != kTypeMap || value_.map_value == nullptr ) {
332
+ delete value_.map_value ;
333
+ value_.map_value = nullptr ;
334
+ } else {
335
+ value_.map_value ->clear ();
336
+ }
270
337
break ;
271
338
}
272
339
case kTypeStaticBlob : {
@@ -279,7 +346,12 @@ void Variant::Clear(Type new_type) {
279
346
delete[] prev_data;
280
347
break ;
281
348
}
349
+ case kMaxTypeValue :
350
+ FIREBASE_ASSERT (false ); // Should never hit this
351
+ break ;
282
352
}
353
+
354
+ Type old_type = type_;
283
355
type_ = new_type;
284
356
switch (type_) {
285
357
case kTypeNull : {
@@ -302,15 +374,26 @@ void Variant::Clear(Type new_type) {
302
374
break ;
303
375
}
304
376
case kTypeMutableString : {
305
- value_.mutable_string_value = new std::string ();
377
+ if (old_type != kTypeMutableString ||
378
+ value_.mutable_string_value == nullptr ) {
379
+ value_.mutable_string_value = new std::string ();
380
+ }
381
+ break ;
382
+ }
383
+ case kTypeSmallString : {
384
+ value_.small_string [0 ] = ' \0 ' ;
306
385
break ;
307
386
}
308
387
case kTypeVector : {
309
- value_.vector_value = new std::vector<Variant>(0 );
388
+ if (old_type != kTypeVector || value_.vector_value == nullptr ) {
389
+ value_.vector_value = new std::vector<Variant>(0 );
390
+ }
310
391
break ;
311
392
}
312
393
case kTypeMap : {
313
- value_.map_value = new std::map<Variant, Variant>();
394
+ if (old_type != kTypeMap || value_.map_value == nullptr ) {
395
+ value_.map_value = new std::map<Variant, Variant>();
396
+ }
314
397
break ;
315
398
}
316
399
case kTypeStaticBlob : {
@@ -321,17 +404,24 @@ void Variant::Clear(Type new_type) {
321
404
set_blob_pointer (nullptr , 0 );
322
405
break ;
323
406
}
407
+ case kMaxTypeValue :
408
+ FIREBASE_ASSERT (false ); // Should never hit this
409
+ break ;
324
410
}
325
411
}
326
412
327
413
const char * const Variant::kTypeNames [] = {
328
414
// In case you want to iterate through these for some reason.
329
- " Null" , " Int64" , " Double" , " Bool" ,
330
- " StaticString" , " MutableString" , " Vector" , " Map" ,
331
- " StaticBlob" , " MutableBlob" , nullptr ,
415
+ " Null" , " Int64" , " Double" , " Bool" ,
416
+ " StaticString" , " MutableString" , " Vector" , " Map" ,
417
+ " StaticBlob" , " MutableBlob" , " SmallString " , nullptr ,
332
418
};
333
419
334
420
void Variant::assert_is_type (Variant::Type type) const {
421
+ static_assert (FIREBASE_ARRAYSIZE (Variant::kTypeNames ) ==
422
+ Variant::kMaxTypeValue + 1 ,
423
+ " Type Enum should match kTypeNames" );
424
+
335
425
FIREBASE_ASSERT_MESSAGE (
336
426
this ->type () == type,
337
427
" Expected Variant to be of type %s, but it was of type %s." ,
@@ -394,7 +484,8 @@ Variant Variant::AsString() const {
394
484
return bool_value () ? Variant (" true" ) : Variant (" false" );
395
485
}
396
486
case kTypeMutableString :
397
- case kTypeStaticString : {
487
+ case kTypeStaticString :
488
+ case kTypeSmallString : {
398
489
return *this ;
399
490
}
400
491
default : {
@@ -415,7 +506,8 @@ Variant Variant::AsInt64() const {
415
506
return bool_value () ? Variant::One () : Variant::Zero ();
416
507
}
417
508
case kTypeMutableString :
418
- case kTypeStaticString : {
509
+ case kTypeStaticString :
510
+ case kTypeSmallString : {
419
511
return Variant::FromInt64 (strtol (string_value (), nullptr , 10 )); // NOLINT
420
512
}
421
513
default : {
@@ -436,7 +528,8 @@ Variant Variant::AsDouble() const {
436
528
return bool_value () ? Variant::OnePointZero () : Variant::ZeroPointZero ();
437
529
}
438
530
case kTypeMutableString :
439
- case kTypeStaticString : {
531
+ case kTypeStaticString :
532
+ case kTypeSmallString : {
440
533
return Variant::FromDouble (strtod (string_value (), nullptr ));
441
534
}
442
535
default : {
0 commit comments