Przeglądaj źródła

Simplified the implementation of implicit casts

Benoit Blanchon 5 lat temu
rodzic
commit
ec43bf4fe9

+ 5 - 0
src/ArduinoJson/Array/ElementProxy.hpp

@@ -72,6 +72,11 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
     return getUpstreamElement().template as<T>();
   }
 
+  template <typename T>
+  FORCE_INLINE operator T() const {
+    return getUpstreamElement();
+  }
+
   template <typename T>
   FORCE_INLINE bool is() const {
     return getUpstreamElement().template is<T>();

+ 5 - 0
src/ArduinoJson/Object/MemberProxy.hpp

@@ -73,6 +73,11 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
     return getUpstreamMember().template as<TValue>();
   }
 
+  template <typename T>
+  FORCE_INLINE operator T() const {
+    return getUpstreamMember();
+  }
+
   template <typename TValue>
   FORCE_INLINE bool is() const {
     return getUpstreamMember().template is<TValue>();

+ 0 - 24
src/ArduinoJson/Operators/VariantCasts.hpp

@@ -1,24 +0,0 @@
-// ArduinoJson - arduinojson.org
-// Copyright Benoit Blanchon 2014-2020
-// MIT License
-
-#pragma once
-
-#include <ArduinoJson/Polyfills/attributes.hpp>
-
-namespace ARDUINOJSON_NAMESPACE {
-
-template <typename TImpl>
-class VariantCasts {
- public:
-  template <typename T>
-  FORCE_INLINE operator T() const {
-    return impl()->template as<T>();
-  }
-
- private:
-  const TImpl *impl() const {
-    return static_cast<const TImpl *>(this);
-  }
-};
-}  // namespace ARDUINOJSON_NAMESPACE

+ 1 - 3
src/ArduinoJson/Operators/VariantOperators.hpp

@@ -4,7 +4,6 @@
 
 #pragma once
 
-#include <ArduinoJson/Operators/VariantCasts.hpp>
 #include <ArduinoJson/Operators/VariantComparisons.hpp>
 #include <ArduinoJson/Operators/VariantOr.hpp>
 #include <ArduinoJson/Operators/VariantShortcuts.hpp>
@@ -12,8 +11,7 @@
 namespace ARDUINOJSON_NAMESPACE {
 
 template <typename TImpl>
-class VariantOperators : public VariantCasts<TImpl>,
-                         public VariantComparisons<TImpl>,
+class VariantOperators : public VariantComparisons<TImpl>,
                          public VariantOr<TImpl>,
                          public VariantShortcuts<TImpl> {};
 }  // namespace ARDUINOJSON_NAMESPACE

+ 20 - 12
src/ArduinoJson/Variant/VariantAs.hpp

@@ -53,44 +53,52 @@ struct VariantConstAs<ArrayRef> {
 
 template <typename T>
 inline typename enable_if<is_integral<T>::value, T>::type variantAs(
-    const VariantData* _data) {
-  return _data != 0 ? _data->asIntegral<T>() : T(0);
+    const VariantData* data) {
+  return data != 0 ? data->asIntegral<T>() : T(0);
 }
 
 template <typename T>
 inline typename enable_if<is_same<T, bool>::value, T>::type variantAs(
-    const VariantData* _data) {
-  return _data != 0 ? _data->asBoolean() : false;
+    const VariantData* data) {
+  return data != 0 ? data->asBoolean() : false;
 }
 
 template <typename T>
 inline typename enable_if<is_floating_point<T>::value, T>::type variantAs(
-    const VariantData* _data) {
-  return _data != 0 ? _data->asFloat<T>() : T(0);
+    const VariantData* data) {
+  return data != 0 ? data->asFloat<T>() : T(0);
 }
 
 template <typename T>
 inline typename enable_if<is_same<T, const char*>::value ||
                               is_same<T, char*>::value,
                           const char*>::type
-variantAs(const VariantData* _data) {
-  return _data != 0 ? _data->asString() : 0;
+variantAs(const VariantData* data) {
+  return data != 0 ? data->asString() : 0;
+}
+
+template <typename T>
+T variantAs(VariantData* data, MemoryPool*) {
+  // By default use the read-only conversion.
+  // There are specializations for
+  // - ArrayRef
+  return variantAs<T>(data);
 }
 
 template <typename T>
 inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
-    const VariantData* _data);
+    const VariantData* data);
 
 template <typename T>
 inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
-    const VariantData* _data);
+    const VariantData* data);
 
 template <typename T>
 inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
-variantAs(const VariantData* _data);
+variantAs(const VariantData* data);
 
 template <typename T>
 inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
-    const VariantData* _data);
+    const VariantData* data);
 
 }  // namespace ARDUINOJSON_NAMESPACE

+ 15 - 0
src/ArduinoJson/Variant/VariantAsImpl.hpp

@@ -39,4 +39,19 @@ inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
   return s;
 }
 
+template <>
+inline ArrayRef variantAs<ArrayRef>(VariantData* data, MemoryPool* pool) {
+  return ArrayRef(pool, data != 0 ? data->asArray() : 0);
+}
+
+template <>
+inline ObjectRef variantAs<ObjectRef>(VariantData* data, MemoryPool* pool) {
+  return ObjectRef(pool, data != 0 ? data->asObject() : 0);
+}
+
+template <>
+inline VariantRef variantAs<VariantRef>(VariantData* data, MemoryPool* pool) {
+  return VariantRef(pool, data);
+}
+
 }  // namespace ARDUINOJSON_NAMESPACE

+ 0 - 12
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -83,18 +83,6 @@ typename enable_if<IsVisitable<TVariant>::value, bool>::type VariantRef::set(
   return variantCopyFrom(_data, v._data, _pool);
 }
 
-template <typename T>
-inline typename enable_if<is_same<T, ArrayRef>::value, T>::type VariantRef::as()
-    const {
-  return ArrayRef(_pool, _data != 0 ? _data->asArray() : 0);
-}
-
-template <typename T>
-inline typename enable_if<is_same<T, ObjectRef>::value, T>::type
-VariantRef::as() const {
-  return ObjectRef(_pool, variantAsObject(_data));
-}
-
 template <typename T>
 inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type
 VariantRef::to() const {

+ 10 - 29
src/ArduinoJson/Variant/VariantRef.hpp

@@ -246,36 +246,14 @@ class VariantRef : public VariantRefBase<VariantData>,
     return variantSetSignedInteger(_data, static_cast<Integer>(value));
   }
 
-  // Get the variant as the specified type.
-  //
-  // std::string as<std::string>() const;
-  // String as<String>() const;
   template <typename T>
-  FORCE_INLINE typename enable_if<!is_same<T, ArrayRef>::value &&
-                                      !is_same<T, ObjectRef>::value &&
-                                      !is_same<T, VariantRef>::value,
-                                  typename VariantAs<T>::type>::type
-  as() const {
-    return variantAs<T>(_data);
+  FORCE_INLINE typename VariantAs<T>::type as() const {
+    return variantAs<typename VariantAs<T>::type>(_data, _pool);
   }
-  //
-  // ArrayRef as<ArrayRef>() const;
-  // const ArrayRef as<const ArrayRef>() const;
-  template <typename T>
-  FORCE_INLINE typename enable_if<is_same<T, ArrayRef>::value, T>::type as()
-      const;
-  //
-  // ObjectRef as<ObjectRef>() const;
-  // const ObjectRef as<const ObjectRef>() const;
-  template <typename T>
-  FORCE_INLINE typename enable_if<is_same<T, ObjectRef>::value, T>::type as()
-      const;
-  //
-  // VariantRef as<VariantRef> const;
+
   template <typename T>
-  FORCE_INLINE typename enable_if<is_same<T, VariantRef>::value, T>::type as()
-      const {
-    return *this;
+  FORCE_INLINE operator T() const {
+    return variantAs<T>(_data, _pool);
   }
 
   template <typename Visitor>
@@ -376,13 +354,16 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
     variantAccept(_data, visitor);
   }
 
-  // Get the variant as the specified type.
-  //
   template <typename T>
   FORCE_INLINE typename VariantConstAs<T>::type as() const {
     return variantAs<typename VariantConstAs<T>::type>(_data);
   }
 
+  template <typename T>
+  FORCE_INLINE operator T() const {
+    return variantAs<T>(_data);
+  }
+
   FORCE_INLINE VariantConstRef getElement(size_t) const;
 
   FORCE_INLINE VariantConstRef operator[](size_t index) const {