32
32
#define FIREBASE_NAMESPACE firebase
33
33
#endif
34
34
35
+ namespace firebase {
36
+ namespace internal {
37
+ class VariantInternal ;
38
+ }
39
+ }
40
+
35
41
namespace FIREBASE_NAMESPACE {
36
42
37
43
// <SWIG>
@@ -69,11 +75,8 @@ class Variant {
69
75
// / Variant::FromMutableBlob() to create a Variant of this type, and copy
70
76
// / binary data from an existing source.
71
77
kTypeMutableBlob ,
72
- // / A c string stored in the Variant internal data blob as opposed to be
73
- // / newed as a std::string. Max size is 16 bytes on x64 and 8 bytes on x86.
74
- kTypeSmallString ,
75
- // / Not a valid type. Used to get the total number of Variant types.
76
- kMaxTypeValue ,
78
+
79
+ // Note: If you add new types update enum InternalType;
77
80
};
78
81
79
82
// <SWIG>
@@ -85,7 +88,7 @@ class Variant {
85
88
// /
86
89
// / The Variant constructed will be of type Null.
87
90
Variant ()
88
- : type_(kTypeNull )
91
+ : type_(kInternalTypeNull )
89
92
, value_({}) {}
90
93
91
94
// / @brief Construct a Variant with the given templated type.
@@ -127,7 +130,7 @@ class Variant {
127
130
// / * `std::map<K, V>` where K and V is convertible to variant type
128
131
template <typename T>
129
132
Variant (T value) // NOLINT
130
- : type_(kTypeNull ) {
133
+ : type_(kInternalTypeNull ) {
131
134
set_value_t <T>(value);
132
135
}
133
136
@@ -138,7 +141,8 @@ class Variant {
138
141
// / will return true.
139
142
// /
140
143
// / @param[in] value The string to use for the Variant.
141
- Variant (const std::string& value) : type_(kTypeNull ) {
144
+ Variant (const std::string& value) // NOLINT
145
+ : type_(kInternalTypeNull ) {
142
146
set_mutable_string (value);
143
147
}
144
148
@@ -147,7 +151,8 @@ class Variant {
147
151
// / The Variant constructed will be of type Vector.
148
152
// /
149
153
// / @param[in] value The STL vector to copy into the Variant.
150
- Variant (const std::vector<Variant>& value) : type_(kTypeNull ) {
154
+ Variant (const std::vector<Variant>& value) // NOLINT
155
+ : type_(kInternalTypeNull ) {
151
156
set_vector (value);
152
157
}
153
158
@@ -160,7 +165,8 @@ class Variant {
160
165
// / to Variant (such as ints, strings, vectors). A Variant will be created for
161
166
// / each element, and copied into the Vector Variant constructed here.
162
167
template <typename T>
163
- Variant (const std::vector<T>& value) : type_(kTypeNull ) {
168
+ Variant (const std::vector<T>& value) // NOLINT
169
+ : type_(kInternalTypeNull ) {
164
170
Clear (kTypeVector );
165
171
vector ().reserve (value.size ());
166
172
for (size_t i = 0 ; i < value.size (); i++) {
@@ -178,7 +184,8 @@ class Variant {
178
184
// / here.
179
185
// / @param[in] array_size Number of elements of the array.
180
186
template <typename T>
181
- Variant (const T array_of_values[], size_t array_size) : type_(kTypeNull ) {
187
+ Variant (const T array_of_values[], size_t array_size)
188
+ : type_(kInternalTypeNull ) {
182
189
Clear (kTypeVector );
183
190
vector ().reserve (array_size);
184
191
for (size_t i = 0 ; i < array_size; i++) {
@@ -192,7 +199,8 @@ class Variant {
192
199
// / The Variant constructed will be of type Map.
193
200
// /
194
201
// / @param[in] value The STL map to copy into the Variant.
195
- Variant (const std::map<Variant, Variant>& value) : type_(kTypeNull ) {
202
+ Variant (const std::map<Variant, Variant>& value) // NOLINT
203
+ : type_(kInternalTypeNull ) {
196
204
set_map (value);
197
205
}
198
206
@@ -207,7 +215,8 @@ class Variant {
207
215
// / created for each key and for each value, and copied by pairs into the Map
208
216
// / Variant constructed here.
209
217
template <typename K, typename V>
210
- Variant (const std::map<K, V>& value) : type_(kTypeNull ) {
218
+ Variant (const std::map<K, V>& value) // NOLINT
219
+ : type_(kInternalTypeNull ) {
211
220
Clear (kTypeMap );
212
221
for (typename std::map<K, V>::const_iterator i = value.begin ();
213
222
i != value.end (); ++i) {
@@ -218,7 +227,7 @@ class Variant {
218
227
// / @brief Copy constructor. Performs a deep copy.
219
228
// /
220
229
// / @param[in] other Source Variant to copy from.
221
- Variant (const Variant& other) : type_(kTypeNull ) { *this = other; }
230
+ Variant (const Variant& other) : type_(kInternalTypeNull ) { *this = other; }
222
231
223
232
// / @brief Copy assignment operator. Performs a deep copy.
224
233
// /
@@ -231,7 +240,9 @@ class Variant {
231
240
// / simply reassigning pointer ownership.
232
241
// /
233
242
// / @param[in] other Source Variant to move from.
234
- Variant (Variant&& other) : type_(kTypeNull ) { *this = std::move (other); }
243
+ Variant (Variant&& other) : type_(kInternalTypeNull ) {
244
+ *this = std::move (other);
245
+ }
235
246
236
247
// / @brief Move assignment operator. Efficiently moves the more complex data
237
248
// / types by simply reassigning pointer ownership.
@@ -418,7 +429,15 @@ class Variant {
418
429
// / @brief Get the current type contained in this Variant.
419
430
// /
420
431
// / @return The Variant's type.
421
- Type type () const { return type_; }
432
+ Type type () const {
433
+ // To avoid breaking user code, alias the small string type to mutable
434
+ // string.
435
+ if (type_ == kInternalTypeSmallString ) {
436
+ return kTypeMutableString ;
437
+ }
438
+
439
+ return static_cast <Type>(type_);
440
+ }
422
441
423
442
// / @brief Get whether this Variant is currently null.
424
443
// /
@@ -460,11 +479,6 @@ class Variant {
460
479
// / @return True if the Variant's type is MutableString, false otherwise.
461
480
bool is_mutable_string () const { return type () == kTypeMutableString ; }
462
481
463
- // / @brief Get whether this Variant contains a small string.
464
- // /
465
- // / @return True if the Variant's type is SmallString, false otherwise.
466
- bool is_small_string () const { return type () == kTypeSmallString ; }
467
-
468
482
// / @brief Get whether this Variant contains a string.
469
483
// /
470
484
// / @return True if the Variant's type is either StaticString or
@@ -566,7 +580,8 @@ class Variant {
566
580
// /
567
581
// / @note If the Variant is not one of the two String types, this will assert.
568
582
std::string& mutable_string () {
569
- if (type_ == kTypeStaticString || type_ == kTypeSmallString ) {
583
+ if (type_ == kInternalTypeStaticString ||
584
+ type_ == kInternalTypeSmallString ) {
570
585
// Automatically promote a static or small string to a mutable string.
571
586
set_mutable_string (string_value (), false );
572
587
}
@@ -602,7 +617,7 @@ class Variant {
602
617
// / @returns Pointer to a mutable buffer of binary data. The size of the
603
618
// / buffer cannot be changed, but the contents are mutable.
604
619
uint8_t * mutable_blob_data () {
605
- if (type_ == kTypeStaticBlob ) {
620
+ if (type_ == kInternalTypeStaticBlob ) {
606
621
// Automatically promote a static blob to a mutable blob.
607
622
set_mutable_blob (blob_data (), blob_size ());
608
623
}
@@ -684,11 +699,11 @@ class Variant {
684
699
// / will assert.
685
700
const char * string_value () const {
686
701
assert_is_string ();
687
- if (type_ == kTypeMutableString )
702
+ if (type_ == kInternalTypeMutableString )
688
703
return value_.mutable_string_value ->c_str ();
689
- else if (type_ == kTypeStaticString )
704
+ else if (type_ == kInternalTypeStaticString )
690
705
return value_.static_string_value ;
691
- else // if (type_ == kTypeSmallString )
706
+ else // if (type_ == kInternalTypeSmallString )
692
707
return value_.small_string ;
693
708
}
694
709
@@ -787,7 +802,7 @@ class Variant {
787
802
void set_string_value (char * value) {
788
803
size_t len = strlen (value);
789
804
if (len < kMaxSmallStringSize ) {
790
- Clear (kTypeSmallString );
805
+ Clear (static_cast <Type>( kInternalTypeSmallString ) );
791
806
strncpy (value_.small_string , value, len + 1 );
792
807
} else {
793
808
set_mutable_string (std::string (value, len));
@@ -813,7 +828,7 @@ class Variant {
813
828
void set_mutable_string (const std::string& value,
814
829
bool use_small_string = true ) {
815
830
if (value.size () < kMaxSmallStringSize && use_small_string) {
816
- Clear (kTypeSmallString );
831
+ Clear (static_cast <Type>( kInternalTypeSmallString ) );
817
832
strncpy (value_.small_string , value.data (), value.size () + 1 );
818
833
} else {
819
834
Clear (kTypeMutableString );
@@ -889,7 +904,7 @@ class Variant {
889
904
// / you passed in to NULL.
890
905
void AssignMutableString (std::string** str) {
891
906
Clear (kTypeNull );
892
- type_ = kTypeMutableString ;
907
+ type_ = kInternalTypeMutableString ;
893
908
value_.mutable_string_value = *str;
894
909
*str = NULL ; // NOLINT
895
910
}
@@ -906,7 +921,7 @@ class Variant {
906
921
// / you passed in to NULL.
907
922
void AssignVector (std::vector<Variant>** vect) {
908
923
Clear (kTypeNull );
909
- type_ = kTypeVector ;
924
+ type_ = kInternalTypeVector ;
910
925
value_.vector_value = *vect;
911
926
*vect = NULL ; // NOLINT
912
927
}
@@ -923,7 +938,7 @@ class Variant {
923
938
// / passed in to NULL.
924
939
void AssignMap (std::map<Variant, Variant>** map) {
925
940
Clear (kTypeNull );
926
- type_ = kTypeMap ;
941
+ type_ = kInternalTypeMap ;
927
942
value_.map_value = *map;
928
943
*map = NULL ; // NOLINT
929
944
}
@@ -1029,6 +1044,40 @@ class Variant {
1029
1044
static const char * TypeName (Type type);
1030
1045
1031
1046
private:
1047
+ // Internal Type of data that this variant object contains to avoid breaking
1048
+ // API
1049
+ enum InternalType {
1050
+ // / Null, or no data.
1051
+ kInternalTypeNull = kTypeNull ,
1052
+ // / A 64-bit integer.
1053
+ kInternalTypeInt64 = kTypeInt64 ,
1054
+ // / A double-precision floating point number.
1055
+ kInternalTypeDouble = kTypeDouble ,
1056
+ // / A boolean value.
1057
+ kInternalTypeBool = kTypeBool ,
1058
+ // / A statically-allocated string we point to.
1059
+ kInternalTypeStaticString = kTypeStaticString ,
1060
+ // / A std::string.
1061
+ kInternalTypeMutableString = kTypeMutableString ,
1062
+ // / A std::vector of Variant.
1063
+ kInternalTypeVector = kTypeVector ,
1064
+ // / A std::map, mapping Variant to Variant.
1065
+ kInternalTypeMap = kTypeMap ,
1066
+ // / An statically-allocated blob of data that we point to. Never constructed
1067
+ // / by default. Use Variant::FromStaticBlob() to create a Variant of this
1068
+ // / type.
1069
+ kInternalTypeStaticBlob = kTypeStaticBlob ,
1070
+ // / A blob of data that the Variant holds. Never constructed by default. Use
1071
+ // / Variant::FromMutableBlob() to create a Variant of this type, and copy
1072
+ // / binary data from an existing source.
1073
+ kInternalTypeMutableBlob = kTypeMutableBlob ,
1074
+ // A c string stored in the Variant internal data blob as opposed to be
1075
+ // newed as a std::string. Max size is 16 bytes on x64 and 8 bytes on x86.
1076
+ kInternalTypeSmallString = kTypeMutableBlob + 1 ,
1077
+ // Not a valid type. Used to get the total number of Variant types.
1078
+ kMaxTypeValue ,
1079
+ };
1080
+
1032
1081
// / Human-readable type names, for error logging.
1033
1082
static const char * const kTypeNames [];
1034
1083
@@ -1064,8 +1113,11 @@ class Variant {
1064
1113
template <typename T>
1065
1114
void set_value_t (T value);
1066
1115
1116
+ // Get whether this Variant contains a small string.
1117
+ bool is_small_string () const { return type_ == kInternalTypeSmallString ; }
1118
+
1067
1119
// Current type contained in this Variant.
1068
- Type type_;
1120
+ InternalType type_;
1069
1121
1070
1122
// Older versions of visual studio cant have this inline in the union and do
1071
1123
// sizeof for small string
@@ -1088,6 +1140,8 @@ class Variant {
1088
1140
} value_;
1089
1141
1090
1142
static const size_t kMaxSmallStringSize = sizeof (Value::small_string);
1143
+
1144
+ friend class firebase ::internal::VariantInternal;
1091
1145
};
1092
1146
1093
1147
template <>
0 commit comments