Explorar el Código

Add `VariantType`

Benoit Blanchon hace 1 año
padre
commit
65ba36622c

+ 25 - 24
src/ArduinoJson/Variant/VariantContent.hpp

@@ -13,38 +13,39 @@
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
-enum {
-  OWNED_VALUE_BIT = 0x01,
-  VALUE_IS_NULL = 0,
-  VALUE_IS_RAW_STRING = 0x03,
-  VALUE_IS_LINKED_STRING = 0x04,
-  VALUE_IS_OWNED_STRING = 0x05,
-
-  // CAUTION: no OWNED_VALUE_BIT below
-
-  VALUE_IS_BOOLEAN = 0x06,
-
-  NUMBER_BIT = 0x08,       // 0000 1000
-  VALUE_IS_UINT32 = 0x0A,  // 0000 1010
-  VALUE_IS_INT32 = 0x0C,   // 0000 1100
-  VALUE_IS_FLOAT = 0x0E,   // 0000 1110
-
+enum class VariantTypeBits : uint8_t {
+  OwnedStringBit = 0x01,  // 0000 0001
+  NumberBit = 0x08,       // 0000 1000
 #if ARDUINOJSON_USE_EXTENSIONS
-  EXTENSION_BIT = 0x10,  // 0001 0000
+  ExtensionBit = 0x10,  // 0001 0000
 #endif
+  CollectionMask = 0x60,
+};
+
+enum class VariantType : uint8_t {
+  Null = 0,             // 0000 0000
+  RawString = 0x03,     // 0000 0011
+  LinkedString = 0x04,  // 0000 0100
+  OwnedString = 0x05,   // 0000 0101
+  Boolean = 0x06,       // 0000 0110
+  Uint32 = 0x0A,        // 0000 1010
+  Int32 = 0x0C,         // 0000 1100
+  Float = 0x0E,         // 0000 1110
 #if ARDUINOJSON_USE_LONG_LONG
-  VALUE_IS_UINT64 = 0x1A,  // 0001 1010
-  VALUE_IS_INT64 = 0x1C,   // 0001 1100
+  Uint64 = 0x1A,  // 0001 1010
+  Int64 = 0x1C,   // 0001 1100
 #endif
 #if ARDUINOJSON_USE_DOUBLE
-  VALUE_IS_DOUBLE = 0x1E,  // 0001 1110
+  Double = 0x1E,  // 0001 1110
 #endif
-
-  COLLECTION_MASK = 0x60,
-  VALUE_IS_OBJECT = 0x20,
-  VALUE_IS_ARRAY = 0x40,
+  Object = 0x20,
+  Array = 0x40,
 };
 
+inline bool operator&(VariantType type, VariantTypeBits bit) {
+  return (uint8_t(type) & uint8_t(bit)) != 0;
+}
+
 union VariantContent {
   VariantContent() {}
 

+ 71 - 70
src/ArduinoJson/Variant/VariantData.hpp

@@ -19,7 +19,7 @@ T parseNumber(const char* s);
 
 class VariantData {
   VariantContent content_;  // must be first to allow cast from array to variant
-  uint8_t type_;
+  VariantType type_;
   SlotId next_;
 
  public:
@@ -30,7 +30,7 @@ class VariantData {
 
   static void operator delete(void*, void*) noexcept {}
 
-  VariantData() : type_(VALUE_IS_NULL), next_(NULL_SLOT) {}
+  VariantData() : type_(VariantType::Null), next_(NULL_SLOT) {}
 
   SlotId next() const {
     return next_;
@@ -45,47 +45,47 @@ class VariantData {
       TVisitor& visit, const ResourceManager* resources) const {
     (void)resources;  // silence warning
     switch (type_) {
-      case VALUE_IS_FLOAT:
+      case VariantType::Float:
         return visit.visit(static_cast<JsonFloat>(content_.asFloat));
 
 #if ARDUINOJSON_USE_DOUBLE
-      case VALUE_IS_DOUBLE:
+      case VariantType::Double:
         return visit.visit(getExtension(resources)->asDouble);
 #endif
 
-      case VALUE_IS_ARRAY:
+      case VariantType::Array:
         return visit.visit(content_.asArray);
 
-      case VALUE_IS_OBJECT:
+      case VariantType::Object:
         return visit.visit(content_.asObject);
 
-      case VALUE_IS_LINKED_STRING:
+      case VariantType::LinkedString:
         return visit.visit(JsonString(content_.asLinkedString));
 
-      case VALUE_IS_OWNED_STRING:
+      case VariantType::OwnedString:
         return visit.visit(JsonString(content_.asOwnedString->data,
                                       content_.asOwnedString->length,
                                       JsonString::Copied));
 
-      case VALUE_IS_RAW_STRING:
+      case VariantType::RawString:
         return visit.visit(RawString(content_.asOwnedString->data,
                                      content_.asOwnedString->length));
 
-      case VALUE_IS_INT32:
+      case VariantType::Int32:
         return visit.visit(static_cast<JsonInteger>(content_.asInt32));
 
-      case VALUE_IS_UINT32:
+      case VariantType::Uint32:
         return visit.visit(static_cast<JsonUInt>(content_.asUint32));
 
 #if ARDUINOJSON_USE_LONG_LONG
-      case VALUE_IS_INT64:
+      case VariantType::Int64:
         return visit.visit(getExtension(resources)->asInt64);
 
-      case VALUE_IS_UINT64:
+      case VariantType::Uint64:
         return visit.visit(getExtension(resources)->asUint64);
 #endif
 
-      case VALUE_IS_BOOLEAN:
+      case VariantType::Boolean:
         return visit.visit(content_.asBoolean != 0);
 
       default:
@@ -132,22 +132,22 @@ class VariantData {
   bool asBoolean(const ResourceManager* resources) const {
     (void)resources;  // silence warning
     switch (type_) {
-      case VALUE_IS_BOOLEAN:
+      case VariantType::Boolean:
         return content_.asBoolean;
-      case VALUE_IS_UINT32:
-      case VALUE_IS_INT32:
+      case VariantType::Uint32:
+      case VariantType::Int32:
         return content_.asUint32 != 0;
-      case VALUE_IS_FLOAT:
+      case VariantType::Float:
         return content_.asFloat != 0;
 #if ARDUINOJSON_USE_DOUBLE
-      case VALUE_IS_DOUBLE:
+      case VariantType::Double:
         return getExtension(resources)->asDouble != 0;
 #endif
-      case VALUE_IS_NULL:
+      case VariantType::Null:
         return false;
 #if ARDUINOJSON_USE_LONG_LONG
-      case VALUE_IS_UINT64:
-      case VALUE_IS_INT64:
+      case VariantType::Uint64:
+      case VariantType::Int64:
         return getExtension(resources)->asUint64 != 0;
 #endif
       default:
@@ -176,25 +176,25 @@ class VariantData {
     static_assert(is_floating_point<T>::value, "T must be a floating point");
     (void)resources;  // silence warning
     switch (type_) {
-      case VALUE_IS_BOOLEAN:
+      case VariantType::Boolean:
         return static_cast<T>(content_.asBoolean);
-      case VALUE_IS_UINT32:
+      case VariantType::Uint32:
         return static_cast<T>(content_.asUint32);
-      case VALUE_IS_INT32:
+      case VariantType::Int32:
         return static_cast<T>(content_.asInt32);
 #if ARDUINOJSON_USE_LONG_LONG
-      case VALUE_IS_UINT64:
+      case VariantType::Uint64:
         return static_cast<T>(getExtension(resources)->asUint64);
-      case VALUE_IS_INT64:
+      case VariantType::Int64:
         return static_cast<T>(getExtension(resources)->asInt64);
 #endif
-      case VALUE_IS_LINKED_STRING:
-      case VALUE_IS_OWNED_STRING:
+      case VariantType::LinkedString:
+      case VariantType::OwnedString:
         return parseNumber<T>(content_.asOwnedString->data);
-      case VALUE_IS_FLOAT:
+      case VariantType::Float:
         return static_cast<T>(content_.asFloat);
 #if ARDUINOJSON_USE_DOUBLE
-      case VALUE_IS_DOUBLE:
+      case VariantType::Double:
         return static_cast<T>(getExtension(resources)->asDouble);
 #endif
       default:
@@ -207,26 +207,26 @@ class VariantData {
     static_assert(is_integral<T>::value, "T must be an integral type");
     (void)resources;  // silence warning
     switch (type_) {
-      case VALUE_IS_BOOLEAN:
+      case VariantType::Boolean:
         return content_.asBoolean;
-      case VALUE_IS_UINT32:
+      case VariantType::Uint32:
         return convertNumber<T>(content_.asUint32);
-      case VALUE_IS_INT32:
+      case VariantType::Int32:
         return convertNumber<T>(content_.asInt32);
 #if ARDUINOJSON_USE_LONG_LONG
-      case VALUE_IS_UINT64:
+      case VariantType::Uint64:
         return convertNumber<T>(getExtension(resources)->asUint64);
-      case VALUE_IS_INT64:
+      case VariantType::Int64:
         return convertNumber<T>(getExtension(resources)->asInt64);
 #endif
-      case VALUE_IS_LINKED_STRING:
+      case VariantType::LinkedString:
         return parseNumber<T>(content_.asLinkedString);
-      case VALUE_IS_OWNED_STRING:
+      case VariantType::OwnedString:
         return parseNumber<T>(content_.asOwnedString->data);
-      case VALUE_IS_FLOAT:
+      case VariantType::Float:
         return convertNumber<T>(content_.asFloat);
 #if ARDUINOJSON_USE_DOUBLE
-      case VALUE_IS_DOUBLE:
+      case VariantType::Double:
         return convertNumber<T>(getExtension(resources)->asDouble);
 #endif
       default:
@@ -244,7 +244,7 @@ class VariantData {
 
   JsonString asRawString() const {
     switch (type_) {
-      case VALUE_IS_RAW_STRING:
+      case VariantType::RawString:
         return JsonString(content_.asOwnedString->data,
                           content_.asOwnedString->length, JsonString::Copied);
       default:
@@ -254,9 +254,9 @@ class VariantData {
 
   JsonString asString() const {
     switch (type_) {
-      case VALUE_IS_LINKED_STRING:
+      case VariantType::LinkedString:
         return JsonString(content_.asLinkedString, JsonString::Linked);
-      case VALUE_IS_OWNED_STRING:
+      case VariantType::OwnedString:
         return JsonString(content_.asOwnedString->data,
                           content_.asOwnedString->length, JsonString::Copied);
       default:
@@ -310,36 +310,36 @@ class VariantData {
   }
 
   bool isArray() const {
-    return type_ == VALUE_IS_ARRAY;
+    return type_ == VariantType::Array;
   }
 
   bool isBoolean() const {
-    return type_ == VALUE_IS_BOOLEAN;
+    return type_ == VariantType::Boolean;
   }
 
   bool isCollection() const {
-    return (type_ & COLLECTION_MASK) != 0;
+    return type_ & VariantTypeBits::CollectionMask;
   }
 
   bool isFloat() const {
-    return (type_ & NUMBER_BIT) != 0;
+    return type_ & VariantTypeBits::NumberBit;
   }
 
   template <typename T>
   bool isInteger(const ResourceManager* resources) const {
     (void)resources;  // silence warning
     switch (type_) {
-      case VALUE_IS_UINT32:
+      case VariantType::Uint32:
         return canConvertNumber<T>(content_.asUint32);
 
-      case VALUE_IS_INT32:
+      case VariantType::Int32:
         return canConvertNumber<T>(content_.asInt32);
 
 #if ARDUINOJSON_USE_LONG_LONG
-      case VALUE_IS_UINT64:
+      case VariantType::Uint64:
         return canConvertNumber<T>(getExtension(resources)->asUint64);
 
-      case VALUE_IS_INT64:
+      case VariantType::Int64:
         return canConvertNumber<T>(getExtension(resources)->asInt64);
 #endif
 
@@ -349,7 +349,7 @@ class VariantData {
   }
 
   bool isNull() const {
-    return type_ == VALUE_IS_NULL;
+    return type_ == VariantType::Null;
   }
 
   static bool isNull(const VariantData* var) {
@@ -359,11 +359,12 @@ class VariantData {
   }
 
   bool isObject() const {
-    return type_ == VALUE_IS_OBJECT;
+    return type_ == VariantType::Object;
   }
 
   bool isString() const {
-    return type_ == VALUE_IS_LINKED_STRING || type_ == VALUE_IS_OWNED_STRING;
+    return type_ == VariantType::LinkedString ||
+           type_ == VariantType::OwnedString;
   }
 
   size_t nesting(const ResourceManager* resources) const {
@@ -406,19 +407,19 @@ class VariantData {
   }
 
   void reset() {  // TODO: remove
-    type_ = VALUE_IS_NULL;
+    type_ = VariantType::Null;
   }
 
   void setBoolean(bool value) {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-    type_ = VALUE_IS_BOOLEAN;
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+    type_ = VariantType::Boolean;
     content_.asBoolean = value;
   }
 
   template <typename T>
   enable_if_t<sizeof(T) == 4, bool> setFloat(T value, ResourceManager*) {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-    type_ = VALUE_IS_FLOAT;
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+    type_ = VariantType::Float;
     content_.asFloat = value;
     return true;
   }
@@ -435,9 +436,9 @@ class VariantData {
       T value, ResourceManager* resources);
 
   void setRawString(StringNode* s) {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
     ARDUINOJSON_ASSERT(s);
-    type_ = VALUE_IS_RAW_STRING;
+    type_ = VariantType::RawString;
     content_.asOwnedString = s;
   }
 
@@ -471,16 +472,16 @@ class VariantData {
   }
 
   void setLinkedString(const char* s) {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
     ARDUINOJSON_ASSERT(s);
-    type_ = VALUE_IS_LINKED_STRING;
+    type_ = VariantType::LinkedString;
     content_.asLinkedString = s;
   }
 
   void setOwnedString(StringNode* s) {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
     ARDUINOJSON_ASSERT(s);
-    type_ = VALUE_IS_OWNED_STRING;
+    type_ = VariantType::OwnedString;
     content_.asOwnedString = s;
   }
 
@@ -499,8 +500,8 @@ class VariantData {
   }
 
   ArrayData& toArray() {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-    type_ = VALUE_IS_ARRAY;
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+    type_ = VariantType::Array;
     new (&content_.asArray) ArrayData();
     return content_.asArray;
   }
@@ -513,8 +514,8 @@ class VariantData {
   }
 
   ObjectData& toObject() {
-    ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-    type_ = VALUE_IS_OBJECT;
+    ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+    type_ = VariantType::Object;
     new (&content_.asObject) ObjectData();
     return content_.asObject;
   }
@@ -526,7 +527,7 @@ class VariantData {
     return &var->toObject();
   }
 
-  uint8_t type() const {
+  VariantType type() const {
     return type_;
   }
 

+ 19 - 19
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -12,7 +12,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 template <typename T>
 inline void VariantData::setRawString(SerializedValue<T> value,
                                       ResourceManager* resources) {
-  ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
+  ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
   auto dup = resources->saveString(adaptString(value.data(), value.size()));
   if (dup)
     setRawString(dup);
@@ -21,7 +21,7 @@ inline void VariantData::setRawString(SerializedValue<T> value,
 template <typename TAdaptedString>
 inline bool VariantData::setString(TAdaptedString value,
                                    ResourceManager* resources) {
-  ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
+  ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
 
   if (value.isNull())
     return false;
@@ -41,11 +41,11 @@ inline bool VariantData::setString(TAdaptedString value,
 }
 
 inline void VariantData::clear(ResourceManager* resources) {
-  if (type_ & OWNED_VALUE_BIT)
+  if (type_ & VariantTypeBits::OwnedStringBit)
     resources->dereferenceString(content_.asOwnedString->data);
 
 #if ARDUINOJSON_USE_EXTENSIONS
-  if (type_ & EXTENSION_BIT)
+  if (type_ & VariantTypeBits::ExtensionBit)
     resources->freeExtension(content_.asSlotId);
 #endif
 
@@ -53,13 +53,13 @@ inline void VariantData::clear(ResourceManager* resources) {
   if (collection)
     collection->clear(resources);
 
-  type_ = VALUE_IS_NULL;
+  type_ = VariantType::Null;
 }
 
 #if ARDUINOJSON_USE_EXTENSIONS
 inline const VariantExtension* VariantData::getExtension(
     const ResourceManager* resources) const {
-  ARDUINOJSON_ASSERT(type_ & EXTENSION_BIT);
+  ARDUINOJSON_ASSERT(type_ & VariantTypeBits::ExtensionBit);
   return resources->getExtension(content_.asSlotId);
 }
 #endif
@@ -67,25 +67,25 @@ inline const VariantExtension* VariantData::getExtension(
 template <typename T>
 enable_if_t<sizeof(T) == 8, bool> VariantData::setFloat(
     T value, ResourceManager* resources) {
-  ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-  (void)resources;                             // silence warning
+  ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+  (void)resources;                                 // silence warning
 
   float valueAsFloat = static_cast<float>(value);
 
 #if ARDUINOJSON_USE_DOUBLE
   if (value == valueAsFloat) {
-    type_ = VALUE_IS_FLOAT;
+    type_ = VariantType::Float;
     content_.asFloat = valueAsFloat;
   } else {
     auto extension = resources->allocExtension();
     if (!extension)
       return false;
-    type_ = VALUE_IS_DOUBLE;
+    type_ = VariantType::Double;
     content_.asSlotId = extension.id();
     extension->asDouble = value;
   }
 #else
-  type_ = VALUE_IS_FLOAT;
+  type_ = VariantType::Float;
   content_.asFloat = valueAsFloat;
 #endif
   return true;
@@ -94,11 +94,11 @@ enable_if_t<sizeof(T) == 8, bool> VariantData::setFloat(
 template <typename T>
 enable_if_t<is_signed<T>::value, bool> VariantData::setInteger(
     T value, ResourceManager* resources) {
-  ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-  (void)resources;                             // silence warning
+  ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+  (void)resources;                                 // silence warning
 
   if (canConvertNumber<int32_t>(value)) {
-    type_ = VALUE_IS_INT32;
+    type_ = VariantType::Int32;
     content_.asInt32 = static_cast<int32_t>(value);
   }
 #if ARDUINOJSON_USE_LONG_LONG
@@ -106,7 +106,7 @@ enable_if_t<is_signed<T>::value, bool> VariantData::setInteger(
     auto extension = resources->allocExtension();
     if (!extension)
       return false;
-    type_ = VALUE_IS_INT64;
+    type_ = VariantType::Int64;
     content_.asSlotId = extension.id();
     extension->asInt64 = value;
   }
@@ -117,11 +117,11 @@ enable_if_t<is_signed<T>::value, bool> VariantData::setInteger(
 template <typename T>
 enable_if_t<is_unsigned<T>::value, bool> VariantData::setInteger(
     T value, ResourceManager* resources) {
-  ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL);  // must call clear() first
-  (void)resources;                             // silence warning
+  ARDUINOJSON_ASSERT(type_ == VariantType::Null);  // must call clear() first
+  (void)resources;                                 // silence warning
 
   if (canConvertNumber<uint32_t>(value)) {
-    type_ = VALUE_IS_UINT32;
+    type_ = VariantType::Uint32;
     content_.asUint32 = static_cast<uint32_t>(value);
   }
 #if ARDUINOJSON_USE_LONG_LONG
@@ -129,7 +129,7 @@ enable_if_t<is_unsigned<T>::value, bool> VariantData::setInteger(
     auto extension = resources->allocExtension();
     if (!extension)
       return false;
-    type_ = VALUE_IS_UINT64;
+    type_ = VariantType::Uint64;
     content_.asSlotId = extension.id();
     extension->asUint64 = value;
   }