3232#define FIREBASE_NAMESPACE firebase
3333#endif
3434
35+ namespace firebase {
36+ namespace internal {
37+ class VariantInternal ;
38+ }
39+ }
40+
3541namespace FIREBASE_NAMESPACE {
3642
3743// <SWIG>
@@ -69,11 +75,8 @@ class Variant {
6975 // / Variant::FromMutableBlob() to create a Variant of this type, and copy
7076 // / binary data from an existing source.
7177 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;
7780 };
7881
7982// <SWIG>
@@ -85,7 +88,7 @@ class Variant {
8588 // /
8689 // / The Variant constructed will be of type Null.
8790 Variant ()
88- : type_(kTypeNull )
91+ : type_(kInternalTypeNull )
8992 , value_({}) {}
9093
9194 // / @brief Construct a Variant with the given templated type.
@@ -127,7 +130,7 @@ class Variant {
127130 // / * `std::map<K, V>` where K and V is convertible to variant type
128131 template <typename T>
129132 Variant (T value) // NOLINT
130- : type_(kTypeNull ) {
133+ : type_(kInternalTypeNull ) {
131134 set_value_t <T>(value);
132135 }
133136
@@ -138,7 +141,8 @@ class Variant {
138141 // / will return true.
139142 // /
140143 // / @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 ) {
142146 set_mutable_string (value);
143147 }
144148
@@ -147,7 +151,8 @@ class Variant {
147151 // / The Variant constructed will be of type Vector.
148152 // /
149153 // / @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 ) {
151156 set_vector (value);
152157 }
153158
@@ -160,7 +165,8 @@ class Variant {
160165 // / to Variant (such as ints, strings, vectors). A Variant will be created for
161166 // / each element, and copied into the Vector Variant constructed here.
162167 template <typename T>
163- Variant (const std::vector<T>& value) : type_(kTypeNull ) {
168+ Variant (const std::vector<T>& value) // NOLINT
169+ : type_(kInternalTypeNull ) {
164170 Clear (kTypeVector );
165171 vector ().reserve (value.size ());
166172 for (size_t i = 0 ; i < value.size (); i++) {
@@ -178,7 +184,8 @@ class Variant {
178184 // / here.
179185 // / @param[in] array_size Number of elements of the array.
180186 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 ) {
182189 Clear (kTypeVector );
183190 vector ().reserve (array_size);
184191 for (size_t i = 0 ; i < array_size; i++) {
@@ -192,7 +199,8 @@ class Variant {
192199 // / The Variant constructed will be of type Map.
193200 // /
194201 // / @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 ) {
196204 set_map (value);
197205 }
198206
@@ -207,7 +215,8 @@ class Variant {
207215 // / created for each key and for each value, and copied by pairs into the Map
208216 // / Variant constructed here.
209217 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 ) {
211220 Clear (kTypeMap );
212221 for (typename std::map<K, V>::const_iterator i = value.begin ();
213222 i != value.end (); ++i) {
@@ -218,7 +227,7 @@ class Variant {
218227 // / @brief Copy constructor. Performs a deep copy.
219228 // /
220229 // / @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; }
222231
223232 // / @brief Copy assignment operator. Performs a deep copy.
224233 // /
@@ -231,7 +240,9 @@ class Variant {
231240 // / simply reassigning pointer ownership.
232241 // /
233242 // / @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+ }
235246
236247 // / @brief Move assignment operator. Efficiently moves the more complex data
237248 // / types by simply reassigning pointer ownership.
@@ -418,7 +429,15 @@ class Variant {
418429 // / @brief Get the current type contained in this Variant.
419430 // /
420431 // / @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+ }
422441
423442 // / @brief Get whether this Variant is currently null.
424443 // /
@@ -460,11 +479,6 @@ class Variant {
460479 // / @return True if the Variant's type is MutableString, false otherwise.
461480 bool is_mutable_string () const { return type () == kTypeMutableString ; }
462481
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-
468482 // / @brief Get whether this Variant contains a string.
469483 // /
470484 // / @return True if the Variant's type is either StaticString or
@@ -566,7 +580,8 @@ class Variant {
566580 // /
567581 // / @note If the Variant is not one of the two String types, this will assert.
568582 std::string& mutable_string () {
569- if (type_ == kTypeStaticString || type_ == kTypeSmallString ) {
583+ if (type_ == kInternalTypeStaticString ||
584+ type_ == kInternalTypeSmallString ) {
570585 // Automatically promote a static or small string to a mutable string.
571586 set_mutable_string (string_value (), false );
572587 }
@@ -602,7 +617,7 @@ class Variant {
602617 // / @returns Pointer to a mutable buffer of binary data. The size of the
603618 // / buffer cannot be changed, but the contents are mutable.
604619 uint8_t * mutable_blob_data () {
605- if (type_ == kTypeStaticBlob ) {
620+ if (type_ == kInternalTypeStaticBlob ) {
606621 // Automatically promote a static blob to a mutable blob.
607622 set_mutable_blob (blob_data (), blob_size ());
608623 }
@@ -684,11 +699,11 @@ class Variant {
684699 // / will assert.
685700 const char * string_value () const {
686701 assert_is_string ();
687- if (type_ == kTypeMutableString )
702+ if (type_ == kInternalTypeMutableString )
688703 return value_.mutable_string_value ->c_str ();
689- else if (type_ == kTypeStaticString )
704+ else if (type_ == kInternalTypeStaticString )
690705 return value_.static_string_value ;
691- else // if (type_ == kTypeSmallString )
706+ else // if (type_ == kInternalTypeSmallString )
692707 return value_.small_string ;
693708 }
694709
@@ -787,7 +802,7 @@ class Variant {
787802 void set_string_value (char * value) {
788803 size_t len = strlen (value);
789804 if (len < kMaxSmallStringSize ) {
790- Clear (kTypeSmallString );
805+ Clear (static_cast <Type>( kInternalTypeSmallString ) );
791806 strncpy (value_.small_string , value, len + 1 );
792807 } else {
793808 set_mutable_string (std::string (value, len));
@@ -813,7 +828,7 @@ class Variant {
813828 void set_mutable_string (const std::string& value,
814829 bool use_small_string = true ) {
815830 if (value.size () < kMaxSmallStringSize && use_small_string) {
816- Clear (kTypeSmallString );
831+ Clear (static_cast <Type>( kInternalTypeSmallString ) );
817832 strncpy (value_.small_string , value.data (), value.size () + 1 );
818833 } else {
819834 Clear (kTypeMutableString );
@@ -889,7 +904,7 @@ class Variant {
889904 // / you passed in to NULL.
890905 void AssignMutableString (std::string** str) {
891906 Clear (kTypeNull );
892- type_ = kTypeMutableString ;
907+ type_ = kInternalTypeMutableString ;
893908 value_.mutable_string_value = *str;
894909 *str = NULL ; // NOLINT
895910 }
@@ -906,7 +921,7 @@ class Variant {
906921 // / you passed in to NULL.
907922 void AssignVector (std::vector<Variant>** vect) {
908923 Clear (kTypeNull );
909- type_ = kTypeVector ;
924+ type_ = kInternalTypeVector ;
910925 value_.vector_value = *vect;
911926 *vect = NULL ; // NOLINT
912927 }
@@ -923,7 +938,7 @@ class Variant {
923938 // / passed in to NULL.
924939 void AssignMap (std::map<Variant, Variant>** map) {
925940 Clear (kTypeNull );
926- type_ = kTypeMap ;
941+ type_ = kInternalTypeMap ;
927942 value_.map_value = *map;
928943 *map = NULL ; // NOLINT
929944 }
@@ -1029,6 +1044,40 @@ class Variant {
10291044 static const char * TypeName (Type type);
10301045
10311046 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+
10321081 // / Human-readable type names, for error logging.
10331082 static const char * const kTypeNames [];
10341083
@@ -1064,8 +1113,11 @@ class Variant {
10641113 template <typename T>
10651114 void set_value_t (T value);
10661115
1116+ // Get whether this Variant contains a small string.
1117+ bool is_small_string () const { return type_ == kInternalTypeSmallString ; }
1118+
10671119 // Current type contained in this Variant.
1068- Type type_;
1120+ InternalType type_;
10691121
10701122 // Older versions of visual studio cant have this inline in the union and do
10711123 // sizeof for small string
@@ -1088,6 +1140,8 @@ class Variant {
10881140 } value_;
10891141
10901142 static const size_t kMaxSmallStringSize = sizeof (Value::small_string);
1143+
1144+ friend class firebase ::internal::VariantInternal;
10911145};
10921146
10931147template <>
0 commit comments