Browse Source

Replace `getData()/getResourceManager()` with `getImpl()`

Benoit Blanchon 8 months ago
parent
commit
0b9a8b6d2b

+ 9 - 13
src/ArduinoJson/Array/ElementProxy.hpp

@@ -50,21 +50,17 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
       : upstream_(src.upstream_), index_(src.index_) {}
       : upstream_(src.upstream_), index_(src.index_) {}
   // clang-format on
   // clang-format on
 
 
-  ResourceManager* getResourceManager() const {
-    return VariantAttorney::getResourceManager(upstream_);
+  VariantImpl getImpl() const {
+    auto impl = VariantAttorney::getImpl(upstream_);
+    return VariantImpl(impl.getElement(index_), impl.getResourceManager());
   }
   }
 
 
-  FORCE_INLINE VariantData* getData() const {
-    return VariantAttorney::getVariantImpl(upstream_).getElement(index_);
-  }
-
-  VariantData* getOrCreateData() const {
-    auto data = VariantAttorney::getOrCreateData(upstream_);
-    auto resources = VariantAttorney::getResourceManager(upstream_);
-    if (!data)
-      return nullptr;
-    data->getOrCreateArray();
-    return VariantImpl(data, resources).getOrAddElement(index_);
+  VariantImpl getOrCreateImpl() const {
+    auto impl = VariantAttorney::getOrCreateImpl(upstream_);
+    auto data = impl.getData();
+    if (data)
+      data->getOrCreateArray();
+    return VariantImpl(impl.getOrAddElement(index_), impl.getResourceManager());
   }
   }
 
 
   TUpstream upstream_;
   TUpstream upstream_;

+ 4 - 12
src/ArduinoJson/Array/JsonArray.hpp

@@ -22,10 +22,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   // Constructs an unbound reference.
   // Constructs an unbound reference.
   JsonArray() {}
   JsonArray() {}
 
 
-  // INTERNAL USE ONLY
-  JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
-      : impl_(data, resources) {}
-
   // INTERNAL USE ONLY
   // INTERNAL USE ONLY
   JsonArray(detail::VariantImpl impl) : impl_(impl) {}
   JsonArray(detail::VariantImpl impl) : impl_(impl) {}
 
 
@@ -199,16 +195,12 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   }
   }
 
 
  private:
  private:
-  detail::ResourceManager* getResourceManager() const {
-    return impl_.getResourceManager();
-  }
-
-  detail::VariantData* getData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
-  detail::VariantData* getOrCreateData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getOrCreateImpl() const {
+    return impl_;
   }
   }
 
 
   mutable detail::VariantImpl impl_;
   mutable detail::VariantImpl impl_;

+ 2 - 6
src/ArduinoJson/Array/JsonArrayConst.hpp

@@ -36,10 +36,6 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
   // Creates an unbound reference.
   // Creates an unbound reference.
   JsonArrayConst() {}
   JsonArrayConst() {}
 
 
-  // INTERNAL USE ONLY
-  JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
-      : impl_(data, resources) {}
-
   // INTERNAL USE ONLY
   // INTERNAL USE ONLY
   JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
   JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
 
 
@@ -98,8 +94,8 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
   }
   }
 
 
  private:
  private:
-  const detail::VariantData* getData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
   detail::VariantImpl impl_;
   detail::VariantImpl impl_;

+ 4 - 4
src/ArduinoJson/Deserialization/deserialize.hpp

@@ -44,13 +44,13 @@ template <template <typename> class TDeserializer, typename TDestination,
           typename TReader, typename TOptions>
           typename TReader, typename TOptions>
 DeserializationError doDeserialize(TDestination&& dst, TReader reader,
 DeserializationError doDeserialize(TDestination&& dst, TReader reader,
                                    TOptions options) {
                                    TOptions options) {
-  auto data = VariantAttorney::getOrCreateData(dst);
-  if (!data)
+  auto impl = VariantAttorney::getOrCreateImpl(dst);
+  if (impl.getData() == nullptr)
     return DeserializationError::NoMemory;
     return DeserializationError::NoMemory;
-  auto resources = VariantAttorney::getResourceManager(dst);
+  auto resources = impl.getResourceManager();
   dst.clear();
   dst.clear();
   auto err = TDeserializer<TReader>(resources, reader)
   auto err = TDeserializer<TReader>(resources, reader)
-                 .parse(data, options.filter, options.nestingLimit);
+                 .parse(impl.getData(), options.filter, options.nestingLimit);
   shrinkJsonDocument(dst);
   shrinkJsonDocument(dst);
   return err;
   return err;
 }
 }

+ 18 - 34
src/ArduinoJson/Document/JsonDocument.hpp

@@ -120,13 +120,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   // Returns the depth (nesting level) of the array.
   // Returns the depth (nesting level) of the array.
   // https://arduinojson.org/v7/api/jsondocument/nesting/
   // https://arduinojson.org/v7/api/jsondocument/nesting/
   size_t nesting() const {
   size_t nesting() const {
-    return getVariantImpl().nesting();
+    return getImpl().nesting();
   }
   }
 
 
   // Returns the number of elements in the root array or object.
   // Returns the number of elements in the root array or object.
   // https://arduinojson.org/v7/api/jsondocument/size/
   // https://arduinojson.org/v7/api/jsondocument/size/
   size_t size() const {
   size_t size() const {
-    return getVariantImpl().size();
+    return getImpl().size();
   }
   }
 
 
   // Copies the specified document.
   // Copies the specified document.
@@ -165,7 +165,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename TChar>
   template <typename TChar>
   ARDUINOJSON_DEPRECATED("use doc[\"key\"].is<T>() instead")
   ARDUINOJSON_DEPRECATED("use doc[\"key\"].is<T>() instead")
   bool containsKey(TChar* key) const {
   bool containsKey(TChar* key) const {
-    return getVariantImpl().getMember(detail::adaptString(key)) != 0;
+    return getImpl().getMember(detail::adaptString(key)) != 0;
   }
   }
 
 
   // DEPRECATED: use obj[key].is<T>() instead
   // DEPRECATED: use obj[key].is<T>() instead
@@ -174,7 +174,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
   ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead")
   ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead")
   bool containsKey(const TString& key) const {
   bool containsKey(const TString& key) const {
-    return getVariantImpl().getMember(detail::adaptString(key)) != 0;
+    return getImpl().getMember(detail::adaptString(key)) != 0;
   }
   }
 
 
   // DEPRECATED: use obj[key].is<T>() instead
   // DEPRECATED: use obj[key].is<T>() instead
@@ -211,8 +211,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename TString,
   template <typename TString,
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
   JsonVariantConst operator[](const TString& key) const {
   JsonVariantConst operator[](const TString& key) const {
-    return JsonVariantConst(
-        getVariantImpl().getMember(detail::adaptString(key)), &resources_);
+    return JsonVariantConst(getImpl().getMember(detail::adaptString(key)),
+                            &resources_);
   }
   }
 
 
   // Gets a root object's member.
   // Gets a root object's member.
@@ -222,8 +222,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
                                     !detail::is_const<TChar>::value,
                                     !detail::is_const<TChar>::value,
                                 int> = 0>
                                 int> = 0>
   JsonVariantConst operator[](TChar* key) const {
   JsonVariantConst operator[](TChar* key) const {
-    return JsonVariantConst(
-        getVariantImpl().getMember(detail::adaptString(key)), &resources_);
+    return JsonVariantConst(getImpl().getMember(detail::adaptString(key)),
+                            &resources_);
   }
   }
 
 
   // Gets or sets a root array's element.
   // Gets or sets a root array's element.
@@ -237,7 +237,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   // Gets a root array's member.
   // Gets a root array's member.
   // https://arduinojson.org/v7/api/jsondocument/subscript/
   // https://arduinojson.org/v7/api/jsondocument/subscript/
   JsonVariantConst operator[](size_t index) const {
   JsonVariantConst operator[](size_t index) const {
-    return JsonVariantConst(getVariantImpl().getElement(index), &resources_);
+    return JsonVariantConst(getImpl().getElement(index), &resources_);
   }
   }
 
 
   // Gets or sets a root object's member.
   // Gets or sets a root object's member.
@@ -290,7 +290,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename T,
   template <typename T,
             detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
             detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
   void remove(T index) {
   void remove(T index) {
-    getVariantImpl().removeElement(size_t(index));
+    getImpl().removeElement(size_t(index));
   }
   }
 
 
   // Removes a member of the root object.
   // Removes a member of the root object.
@@ -300,7 +300,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
                                     !detail::is_const<TChar>::value,
                                     !detail::is_const<TChar>::value,
                                 int> = 0>
                                 int> = 0>
   void remove(TChar* key) {
   void remove(TChar* key) {
-    getVariantImpl().removeMember(detail::adaptString(key));
+    getImpl().removeMember(detail::adaptString(key));
   }
   }
 
 
   // Removes a member of the root object.
   // Removes a member of the root object.
@@ -308,7 +308,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename TString,
   template <typename TString,
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
             detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
   void remove(const TString& key) {
   void remove(const TString& key) {
-    getVariantImpl().removeMember(detail::adaptString(key));
+    getImpl().removeMember(detail::adaptString(key));
   }
   }
 
 
   // Removes a member of the root object or an element of the root array.
   // Removes a member of the root object or an element of the root array.
@@ -388,16 +388,16 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   }
   }
 
 
  private:
  private:
-  detail::VariantImpl getVariantImpl() const {
-    return detail::VariantImpl(&data_, &resources_);
+  detail::VariantImpl getImpl() const {
+    return {&data_, &resources_};
   }
   }
 
 
-  detail::VariantImpl getOrCreateArray() {
-    return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
+  detail::VariantImpl getOrCreateImpl() {
+    return {&data_, &resources_};
   }
   }
 
 
-  detail::VariantImpl getOrCreateObject() {
-    return detail::VariantImpl(data_.getOrCreateObject(), &resources_);
+  detail::VariantImpl getOrCreateArray() {
+    return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
   }
   }
 
 
   JsonVariant getVariant() {
   JsonVariant getVariant() {
@@ -408,22 +408,6 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
     return JsonVariantConst(&data_, &resources_);
     return JsonVariantConst(&data_, &resources_);
   }
   }
 
 
-  detail::ResourceManager* getResourceManager() {
-    return &resources_;
-  }
-
-  detail::VariantData* getData() {
-    return &data_;
-  }
-
-  const detail::VariantData* getData() const {
-    return &data_;
-  }
-
-  detail::VariantData* getOrCreateData() {
-    return &data_;
-  }
-
   mutable detail::ResourceManager resources_;
   mutable detail::ResourceManager resources_;
   mutable detail::VariantData data_;
   mutable detail::VariantData data_;
 };
 };

+ 5 - 4
src/ArduinoJson/MsgPack/MsgPackBinary.hpp

@@ -25,11 +25,12 @@ class MsgPackBinary {
 template <>
 template <>
 struct Converter<MsgPackBinary> : private detail::VariantAttorney {
 struct Converter<MsgPackBinary> : private detail::VariantAttorney {
   static void toJson(MsgPackBinary src, JsonVariant dst) {
   static void toJson(MsgPackBinary src, JsonVariant dst) {
-    auto data = VariantAttorney::getData(dst);
+    auto impl = getImpl(dst);
+    auto data = impl.getData();
     if (!data)
     if (!data)
       return;
       return;
-    auto resources = getResourceManager(dst);
-    detail::VariantImpl(data, resources).clear();
+    auto resources = impl.getResourceManager();
+    impl.clear();
     if (src.data()) {
     if (src.data()) {
       size_t headerSize = src.size() >= 0x10000 ? 5
       size_t headerSize = src.size() >= 0x10000 ? 5
                           : src.size() >= 0x100 ? 3
                           : src.size() >= 0x100 ? 3
@@ -66,7 +67,7 @@ struct Converter<MsgPackBinary> : private detail::VariantAttorney {
   }
   }
 
 
   static MsgPackBinary fromJson(JsonVariantConst src) {
   static MsgPackBinary fromJson(JsonVariantConst src) {
-    auto variant = VariantAttorney::getVariantImpl(src);
+    auto variant = getImpl(src);
     auto rawstr = variant.asRawString();
     auto rawstr = variant.asRawString();
     auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
     auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
     auto n = rawstr.size();
     auto n = rawstr.size();

+ 5 - 4
src/ArduinoJson/MsgPack/MsgPackExtension.hpp

@@ -31,11 +31,12 @@ class MsgPackExtension {
 template <>
 template <>
 struct Converter<MsgPackExtension> : private detail::VariantAttorney {
 struct Converter<MsgPackExtension> : private detail::VariantAttorney {
   static void toJson(MsgPackExtension src, JsonVariant dst) {
   static void toJson(MsgPackExtension src, JsonVariant dst) {
-    auto data = getData(dst);
+    auto impl = getImpl(dst);
+    auto data = impl.getData();
+    auto resources = impl.getResourceManager();
     if (!data)
     if (!data)
       return;
       return;
-    auto resources = getResourceManager(dst);
-    detail::VariantImpl(data, resources).clear();
+    impl.clear();
     if (src.data()) {
     if (src.data()) {
       uint8_t format, sizeBytes;
       uint8_t format, sizeBytes;
       if (src.size() >= 0x10000) {
       if (src.size() >= 0x10000) {
@@ -80,7 +81,7 @@ struct Converter<MsgPackExtension> : private detail::VariantAttorney {
   }
   }
 
 
   static MsgPackExtension fromJson(JsonVariantConst src) {
   static MsgPackExtension fromJson(JsonVariantConst src) {
-    auto variant = VariantAttorney::getVariantImpl(src);
+    auto variant = detail::VariantAttorney::getImpl(src);
     auto rawstr = variant.asRawString();
     auto rawstr = variant.asRawString();
     if (rawstr.size() == 0)
     if (rawstr.size() == 0)
       return {};
       return {};

+ 4 - 12
src/ArduinoJson/Object/JsonObject.hpp

@@ -22,10 +22,6 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
   // Creates an unbound reference.
   // Creates an unbound reference.
   JsonObject() {}
   JsonObject() {}
 
 
-  // INTERNAL USE ONLY
-  JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
-      : impl_(data, resource) {}
-
   // INTERNAL USE ONLY
   // INTERNAL USE ONLY
   JsonObject(detail::VariantImpl impl) : impl_(impl) {}
   JsonObject(detail::VariantImpl impl) : impl_(impl) {}
 
 
@@ -222,16 +218,12 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
   }
   }
 
 
  private:
  private:
-  detail::ResourceManager* getResourceManager() const {
-    return impl_.getResourceManager();
-  }
-
-  detail::VariantData* getData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
-  detail::VariantData* getOrCreateData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getOrCreateImpl() const {
+    return impl_;
   }
   }
 
 
   mutable detail::VariantImpl impl_;
   mutable detail::VariantImpl impl_;

+ 2 - 6
src/ArduinoJson/Object/JsonObjectConst.hpp

@@ -21,10 +21,6 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
   // Creates an unbound reference.
   // Creates an unbound reference.
   JsonObjectConst() {}
   JsonObjectConst() {}
 
 
-  // INTERNAL USE ONLY
-  JsonObjectConst(detail::VariantData* data, detail::ResourceManager* resources)
-      : impl_(data, resources) {}
-
   // INTERNAL USE ONLY
   // INTERNAL USE ONLY
   JsonObjectConst(const detail::VariantImpl& impl) : impl_(impl) {}
   JsonObjectConst(const detail::VariantImpl& impl) : impl_(impl) {}
 
 
@@ -132,8 +128,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
   }
   }
 
 
  private:
  private:
-  const detail::VariantData* getData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
   detail::VariantImpl impl_;
   detail::VariantImpl impl_;

+ 9 - 13
src/ArduinoJson/Object/MemberProxy.hpp

@@ -51,21 +51,17 @@ class MemberProxy
       : upstream_(src.upstream_), key_(src.key_) {}
       : upstream_(src.upstream_), key_(src.key_) {}
   // clang-format on
   // clang-format on
 
 
-  ResourceManager* getResourceManager() const {
-    return VariantAttorney::getResourceManager(upstream_);
+  VariantImpl getImpl() const {
+    auto impl = VariantAttorney::getImpl(upstream_);
+    return VariantImpl(impl.getMember(key_), impl.getResourceManager());
   }
   }
 
 
-  VariantData* getData() const {
-    return VariantAttorney::getVariantImpl(upstream_).getMember(key_);
-  }
-
-  VariantData* getOrCreateData() const {
-    auto data = VariantAttorney::getOrCreateData(upstream_);
-    auto resources = VariantAttorney::getResourceManager(upstream_);
-    if (!data)
-      return nullptr;
-    data->getOrCreateObject();
-    return VariantImpl(data, resources).getOrAddMember(key_);
+  VariantImpl getOrCreateImpl() const {
+    auto impl = VariantAttorney::getOrCreateImpl(upstream_);
+    auto data = impl.getData();
+    if (data)
+      data->getOrCreateObject();
+    return VariantImpl(impl.getOrAddMember(key_), impl.getResourceManager());
   }
   }
 
 
  private:
  private:

+ 3 - 4
src/ArduinoJson/Serialization/measure.hpp

@@ -11,10 +11,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 template <template <typename> class TSerializer>
 template <template <typename> class TSerializer>
 size_t measure(ArduinoJson::JsonVariantConst source) {
 size_t measure(ArduinoJson::JsonVariantConst source) {
   DummyWriter dp;
   DummyWriter dp;
-  auto data = VariantAttorney::getData(source);
-  auto resources = VariantAttorney::getResourceManager(source);
-  TSerializer<DummyWriter> serializer(dp, resources);
-  return VariantImpl(data, resources).accept(serializer);
+  auto impl = VariantAttorney::getImpl(source);
+  TSerializer<DummyWriter> serializer(dp, impl.getResourceManager());
+  return impl.accept(serializer);
 }
 }
 
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 3 - 4
src/ArduinoJson/Serialization/serialize.hpp

@@ -10,10 +10,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
 
 template <template <typename> class TSerializer, typename TWriter>
 template <template <typename> class TSerializer, typename TWriter>
 size_t doSerialize(ArduinoJson::JsonVariantConst source, TWriter writer) {
 size_t doSerialize(ArduinoJson::JsonVariantConst source, TWriter writer) {
-  auto data = VariantAttorney::getData(source);
-  auto resources = VariantAttorney::getResourceManager(source);
-  TSerializer<TWriter> serializer(writer, resources);
-  return VariantImpl(data, resources).accept(serializer);
+  auto impl = VariantAttorney::getImpl(source);
+  TSerializer<TWriter> serializer(writer, impl.getResourceManager());
+  return impl.accept(serializer);
 }
 }
 
 
 template <template <typename> class TSerializer, typename TDestination>
 template <template <typename> class TSerializer, typename TDestination>

+ 42 - 52
src/ArduinoJson/Variant/ConverterImpl.hpp

@@ -60,18 +60,18 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
     : private detail::VariantAttorney {
     : private detail::VariantAttorney {
   static bool toJson(T src, JsonVariant dst) {
   static bool toJson(T src, JsonVariant dst) {
     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
-    auto variant = getVariantImpl(dst);
+    auto variant = getImpl(dst);
     variant.clear();
     variant.clear();
     return variant.setInteger(src);
     return variant.setInteger(src);
   }
   }
 
 
   static T fromJson(JsonVariantConst src) {
   static T fromJson(JsonVariantConst src) {
     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
-    return getVariantImpl(src).template asIntegral<T>();
+    return getImpl(src).template asIntegral<T>();
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    return getVariantImpl(src).template isInteger<T>();
+    return getImpl(src).template isInteger<T>();
   }
   }
 };
 };
 
 
@@ -83,29 +83,28 @@ struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
   }
   }
 
 
   static T fromJson(JsonVariantConst src) {
   static T fromJson(JsonVariantConst src) {
-    return static_cast<T>(getVariantImpl(src).template asIntegral<int>());
+    return static_cast<T>(getImpl(src).template asIntegral<int>());
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    return getVariantImpl(src).template isInteger<int>();
+    return getImpl(src).template isInteger<int>();
   }
   }
 };
 };
 
 
 template <>
 template <>
 struct Converter<bool> : private detail::VariantAttorney {
 struct Converter<bool> : private detail::VariantAttorney {
   static bool toJson(bool src, JsonVariant dst) {
   static bool toJson(bool src, JsonVariant dst) {
-    auto variant = getVariantImpl(dst);
-    variant.clear();
-    return variant.setBoolean(src);
+    auto impl = getImpl(dst);
+    impl.clear();
+    return impl.setBoolean(src);
   }
   }
 
 
   static bool fromJson(JsonVariantConst src) {
   static bool fromJson(JsonVariantConst src) {
-    return getVariantImpl(src).asBoolean();
+    return getImpl(src).asBoolean();
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->type == detail::VariantType::Boolean;
+    return getImpl(src).type() == detail::VariantType::Boolean;
   }
   }
 };
 };
 
 
@@ -113,61 +112,58 @@ template <typename T>
 struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
 struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
     : private detail::VariantAttorney {
     : private detail::VariantAttorney {
   static bool toJson(T src, JsonVariant dst) {
   static bool toJson(T src, JsonVariant dst) {
-    auto variant = getVariantImpl(dst);
-    variant.clear();
-    return variant.setFloat(src);
+    auto impl = getImpl(dst);
+    impl.clear();
+    return impl.setFloat(src);
   }
   }
 
 
   static T fromJson(JsonVariantConst src) {
   static T fromJson(JsonVariantConst src) {
-    return getVariantImpl(src).template asFloat<T>();
+    return getImpl(src).template asFloat<T>();
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->isFloat();
+    return getImpl(src).isFloat();
   }
   }
 };
 };
 
 
 template <>
 template <>
 struct Converter<const char*> : private detail::VariantAttorney {
 struct Converter<const char*> : private detail::VariantAttorney {
   static void toJson(const char* src, JsonVariant dst) {
   static void toJson(const char* src, JsonVariant dst) {
-    auto variant = getVariantImpl(dst);
-    variant.clear();
-    variant.setString(detail::adaptString(src));
+    auto impl = getImpl(dst);
+    impl.clear();
+    impl.setString(detail::adaptString(src));
   }
   }
 
 
   static const char* fromJson(JsonVariantConst src) {
   static const char* fromJson(JsonVariantConst src) {
-    return getVariantImpl(src).asString().c_str();
+    return getImpl(src).asString().c_str();
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->isString();
+    return getImpl(src).isString();
   }
   }
 };
 };
 
 
 template <>
 template <>
 struct Converter<JsonString> : private detail::VariantAttorney {
 struct Converter<JsonString> : private detail::VariantAttorney {
   static void toJson(JsonString src, JsonVariant dst) {
   static void toJson(JsonString src, JsonVariant dst) {
-    auto variant = getVariantImpl(dst);
-    variant.clear();
-    variant.setString(detail::adaptString(src));
+    auto impl = getImpl(dst);
+    impl.clear();
+    impl.setString(detail::adaptString(src));
   }
   }
 
 
   static JsonString fromJson(JsonVariantConst src) {
   static JsonString fromJson(JsonVariantConst src) {
-    return getVariantImpl(src).asString();
+    return getImpl(src).asString();
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->isString();
+    return getImpl(src).isString();
   }
   }
 };
 };
 
 
 template <typename T>
 template <typename T>
 inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
 inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
     const T& src, JsonVariant dst) {
     const T& src, JsonVariant dst) {
-  auto variant = detail::VariantAttorney::getVariantImpl(dst);
+  auto variant = detail::VariantAttorney::getImpl(dst);
   variant.clear();
   variant.clear();
   variant.setString(detail::adaptString(src));
   variant.setString(detail::adaptString(src));
 }
 }
@@ -178,7 +174,7 @@ inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
 template <typename T>
 template <typename T>
 struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
 struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
   static void toJson(SerializedValue<T> src, JsonVariant dst) {
   static void toJson(SerializedValue<T> src, JsonVariant dst) {
-    auto variant = getVariantImpl(dst);
+    auto variant = getImpl(dst);
     variant.clear();
     variant.clear();
     variant.setRawString(src);
     variant.setRawString(src);
   }
   }
@@ -187,14 +183,13 @@ struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
 template <>
 template <>
 struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
 struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
   static void toJson(detail::nullptr_t, JsonVariant dst) {
   static void toJson(detail::nullptr_t, JsonVariant dst) {
-    getVariantImpl(dst).clear();
+    getImpl(dst).clear();
   }
   }
   static detail::nullptr_t fromJson(JsonVariantConst) {
   static detail::nullptr_t fromJson(JsonVariantConst) {
     return nullptr;
     return nullptr;
   }
   }
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data == 0 || data->type == detail::VariantType::Null;
+    return getImpl(src).isNull();
   }
   }
 };
 };
 
 
@@ -236,16 +231,15 @@ class StringBuilderPrint : public Print {
 }  // namespace detail
 }  // namespace detail
 
 
 inline void convertToJson(const ::Printable& src, JsonVariant dst) {
 inline void convertToJson(const ::Printable& src, JsonVariant dst) {
-  auto resources = detail::VariantAttorney::getResourceManager(dst);
-  auto data = detail::VariantAttorney::getData(dst);
-  if (!resources || !data)
+  auto impl = detail::VariantAttorney::getImpl(dst);
+  if (!impl.getData())
     return;
     return;
-  detail::VariantImpl(data, resources).clear();
-  detail::StringBuilderPrint print(resources);
+  impl.clear();
+  detail::StringBuilderPrint print(impl.getResourceManager());
   src.printTo(print);
   src.printTo(print);
   if (print.overflowed())
   if (print.overflowed())
     return;
     return;
-  print.save(data);
+  print.save(impl.getData());
 }
 }
 
 
 #endif
 #endif
@@ -306,12 +300,11 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
   }
   }
 
 
   static JsonArrayConst fromJson(JsonVariantConst src) {
   static JsonArrayConst fromJson(JsonVariantConst src) {
-    return JsonArrayConst(getData(src), getResourceManager(src));
+    return JsonArrayConst(getImpl(src));
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->type == detail::VariantType::Array;
+    return getImpl(src).type() == detail::VariantType::Array;
   }
   }
 };
 };
 
 
@@ -325,12 +318,11 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
   }
   }
 
 
   static JsonArray fromJson(JsonVariant src) {
   static JsonArray fromJson(JsonVariant src) {
-    return JsonArray(getData(src), getResourceManager(src));
+    return JsonArray(getImpl(src));
   }
   }
 
 
   static bool checkJson(JsonVariant src) {
   static bool checkJson(JsonVariant src) {
-    auto data = getData(src);
-    return data && data->type == detail::VariantType::Array;
+    return getImpl(src).type() == detail::VariantType::Array;
   }
   }
 };
 };
 
 
@@ -344,12 +336,11 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
   }
   }
 
 
   static JsonObjectConst fromJson(JsonVariantConst src) {
   static JsonObjectConst fromJson(JsonVariantConst src) {
-    return JsonObjectConst(getData(src), getResourceManager(src));
+    return JsonObjectConst(getImpl(src));
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
-    return data && data->type == detail::VariantType::Object;
+    return getImpl(src).type() == detail::VariantType::Object;
   }
   }
 };
 };
 
 
@@ -363,12 +354,11 @@ struct Converter<JsonObject> : private detail::VariantAttorney {
   }
   }
 
 
   static JsonObject fromJson(JsonVariant src) {
   static JsonObject fromJson(JsonVariant src) {
-    return JsonObject(getData(src), getResourceManager(src));
+    return JsonObject(getImpl(src));
   }
   }
 
 
   static bool checkJson(JsonVariant src) {
   static bool checkJson(JsonVariant src) {
-    auto data = getData(src);
-    return data && data->type == detail::VariantType::Object;
+    return getImpl(src).type() == detail::VariantType::Object;
   }
   }
 };
 };
 
 

+ 7 - 11
src/ArduinoJson/Variant/JsonVariant.hpp

@@ -26,16 +26,12 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
   JsonVariant(detail::VariantImpl impl) : impl_(impl) {}
   JsonVariant(detail::VariantImpl impl) : impl_(impl) {}
 
 
  private:
  private:
-  detail::ResourceManager* getResourceManager() const {
-    return impl_.getResourceManager();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
-  detail::VariantData* getData() const {
-    return impl_.getData();
-  }
-
-  detail::VariantData* getOrCreateData() const {
-    return impl_.getData();
+  const detail::VariantImpl& getOrCreateImpl() const {
+    return impl_;
   }
   }
 
 
   mutable detail::VariantImpl impl_;
   mutable detail::VariantImpl impl_;
@@ -56,7 +52,7 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
   }
   }
 
 
   static bool checkJson(JsonVariant src) {
   static bool checkJson(JsonVariant src) {
-    auto data = getData(src);
+    auto data = getImpl(src).getData();
     return !!data;
     return !!data;
   }
   }
 };
 };
@@ -68,11 +64,11 @@ struct Converter<JsonVariantConst> : private detail::VariantAttorney {
   }
   }
 
 
   static JsonVariantConst fromJson(JsonVariantConst src) {
   static JsonVariantConst fromJson(JsonVariantConst src) {
-    return JsonVariantConst(getData(src), getResourceManager(src));
+    return JsonVariantConst(getImpl(src));
   }
   }
 
 
   static bool checkJson(JsonVariantConst src) {
   static bool checkJson(JsonVariantConst src) {
-    auto data = getData(src);
+    auto data = getImpl(src).getData();
     return !!data;
     return !!data;
   }
   }
 };
 };

+ 2 - 6
src/ArduinoJson/Variant/JsonVariantConst.hpp

@@ -179,12 +179,8 @@ class JsonVariantConst : public detail::VariantTag,
   }
   }
 
 
  protected:
  protected:
-  detail::VariantData* getData() const {
-    return impl_.getData();
-  }
-
-  detail::ResourceManager* getResourceManager() const {
-    return impl_.getResourceManager();
+  const detail::VariantImpl& getImpl() const {
+    return impl_;
   }
   }
 
 
  private:
  private:

+ 2 - 3
src/ArduinoJson/Variant/JsonVariantVisitor.hpp

@@ -48,10 +48,9 @@ class VisitorAdapter {
 template <typename TVisitor>
 template <typename TVisitor>
 typename TVisitor::result_type accept(JsonVariantConst variant,
 typename TVisitor::result_type accept(JsonVariantConst variant,
                                       TVisitor& visit) {
                                       TVisitor& visit) {
-  auto data = VariantAttorney::getData(variant);
-  auto resources = VariantAttorney::getResourceManager(variant);
+  auto impl = VariantAttorney::getImpl(variant);
   VisitorAdapter<TVisitor> adapter(visit);
   VisitorAdapter<TVisitor> adapter(visit);
-  return VariantImpl(data, resources).accept(adapter);
+  return impl.accept(adapter);
 }
 }
 
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 4 - 15
src/ArduinoJson/Variant/VariantAttorney.hpp

@@ -16,24 +16,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 class VariantAttorney {
 class VariantAttorney {
  public:
  public:
   template <typename TClient>
   template <typename TClient>
-  static auto getResourceManager(TClient& client)
-      -> decltype(client.getResourceManager()) {
-    return client.getResourceManager();
+  static VariantImpl getImpl(TClient& client) {
+    return client.getImpl();
   }
   }
 
 
   template <typename TClient>
   template <typename TClient>
-  static auto getData(TClient& client) -> decltype(client.getData()) {
-    return client.getData();
-  }
-
-  template <typename TClient>
-  static VariantImpl getVariantImpl(TClient& client) {
-    return VariantImpl(client.getData(), client.getResourceManager());
-  }
-
-  template <typename TClient>
-  static VariantData* getOrCreateData(TClient& client) {
-    return client.getOrCreateData();
+  static VariantImpl getOrCreateImpl(TClient& client) {
+    return client.getOrCreateImpl();
   }
   }
 };
 };
 
 

+ 1 - 1
src/ArduinoJson/Variant/VariantCompare.hpp

@@ -199,7 +199,7 @@ struct Comparer<
     T, enable_if_t<is_convertible<T, ArduinoJson::JsonVariantConst>::value>>
     T, enable_if_t<is_convertible<T, ArduinoJson::JsonVariantConst>::value>>
     : VariantComparer {
     : VariantComparer {
   explicit Comparer(const T& value)
   explicit Comparer(const T& value)
-      : VariantComparer(static_cast<JsonVariantConst>(value)) {}
+      : VariantComparer(JsonVariantConst(VariantAttorney::getImpl(value))) {}
 };
 };
 
 
 template <typename T>
 template <typename T>

+ 21 - 39
src/ArduinoJson/Variant/VariantRefBase.hpp

@@ -29,18 +29,18 @@ class VariantRefBase : public VariantTag {
   // Sets the value to null.
   // Sets the value to null.
   // https://arduinojson.org/v7/api/jsonvariant/clear/
   // https://arduinojson.org/v7/api/jsonvariant/clear/
   void clear() const {
   void clear() const {
-    getOrCreateVariantImpl().clear();
+    getOrCreateImpl().clear();
   }
   }
 
 
   // Returns true if the value is null or the reference is unbound.
   // Returns true if the value is null or the reference is unbound.
   // https://arduinojson.org/v7/api/jsonvariant/isnull/
   // https://arduinojson.org/v7/api/jsonvariant/isnull/
   bool isNull() const {
   bool isNull() const {
-    return getVariantImpl().isNull();
+    return getImpl().isNull();
   }
   }
 
 
   // Returns true if the reference is unbound.
   // Returns true if the reference is unbound.
   bool isUnbound() const {
   bool isUnbound() const {
-    return !getData();
+    return !getImpl().getData();
   }
   }
 
 
   // Casts the value to the specified type.
   // Casts the value to the specified type.
@@ -93,13 +93,13 @@ class VariantRefBase : public VariantTag {
   // Returns the size of the array or object.
   // Returns the size of the array or object.
   // https://arduinojson.org/v7/api/jsonvariant/size/
   // https://arduinojson.org/v7/api/jsonvariant/size/
   size_t size() const {
   size_t size() const {
-    return getVariantImpl().size();
+    return getImpl().size();
   }
   }
 
 
   // Returns the depth (nesting level) of the value.
   // Returns the depth (nesting level) of the value.
   // https://arduinojson.org/v7/api/jsonvariant/nesting/
   // https://arduinojson.org/v7/api/jsonvariant/nesting/
   size_t nesting() const {
   size_t nesting() const {
-    return getVariantImpl().nesting();
+    return getImpl().nesting();
   }
   }
 
 
   // Appends a new (empty) element to the array.
   // Appends a new (empty) element to the array.
@@ -120,34 +120,34 @@ class VariantRefBase : public VariantTag {
   // https://arduinojson.org/v7/api/jsonvariant/add/
   // https://arduinojson.org/v7/api/jsonvariant/add/
   template <typename T>
   template <typename T>
   bool add(const T& value) const {
   bool add(const T& value) const {
-    return getOrCreateOrCreateArray().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
   }
 
 
   // Appends a value to the array.
   // Appends a value to the array.
   // https://arduinojson.org/v7/api/jsonvariant/add/
   // https://arduinojson.org/v7/api/jsonvariant/add/
   template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
   template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
   bool add(T* value) const {
   bool add(T* value) const {
-    return getOrCreateOrCreateArray().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
   }
 
 
   // Removes an element of the array.
   // Removes an element of the array.
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   void remove(size_t index) const {
   void remove(size_t index) const {
-    getVariantImpl().removeElement(index);
+    getImpl().removeElement(index);
   }
   }
 
 
   // Removes a member of the object.
   // Removes a member of the object.
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   template <typename TChar, enable_if_t<IsString<TChar*>::value, int> = 0>
   template <typename TChar, enable_if_t<IsString<TChar*>::value, int> = 0>
   void remove(TChar* key) const {
   void remove(TChar* key) const {
-    getVariantImpl().removeMember(adaptString(key));
+    getImpl().removeMember(adaptString(key));
   }
   }
 
 
   // Removes a member of the object.
   // Removes a member of the object.
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   template <typename TString, enable_if_t<IsString<TString>::value, int> = 0>
   template <typename TString, enable_if_t<IsString<TString>::value, int> = 0>
   void remove(const TString& key) const {
   void remove(const TString& key) const {
-    getVariantImpl().removeMember(adaptString(key));
+    getImpl().removeMember(adaptString(key));
   }
   }
 
 
   // Removes a member of the object or an element of the array.
   // Removes a member of the object or an element of the array.
@@ -259,42 +259,26 @@ class VariantRefBase : public VariantTag {
     return static_cast<const TDerived&>(*this);
     return static_cast<const TDerived&>(*this);
   }
   }
 
 
-  ResourceManager* getResourceManager() const {
-    return VariantAttorney::getResourceManager(derived());
+  VariantImpl getImpl() const {
+    return VariantAttorney::getImpl(derived());
   }
   }
 
 
-  VariantData* getData() const {
-    return VariantAttorney::getData(derived());
+  VariantImpl getOrCreateImpl() const {
+    return VariantAttorney::getOrCreateImpl(derived());
   }
   }
 
 
-  VariantData* getOrCreateData() const {
-    return VariantAttorney::getOrCreateData(derived());
-  }
-
-  VariantImpl getVariantImpl() const {
-    return VariantImpl(getData(), getResourceManager());
-  }
-
-  VariantImpl getOrCreateVariantImpl() const {
-    return VariantImpl(getOrCreateData(), getResourceManager());
-  }
-
-  VariantImpl getOrCreateOrCreateArray() const {
-    auto data = getOrCreateData();
-    return VariantImpl(data ? data->getOrCreateArray() : nullptr,
-                       getResourceManager());
-  }
-
-  VariantImpl getOrCreateOrCreateObject() const {
-    auto data = getOrCreateData();
-    return VariantImpl(data ? data->getOrCreateObject() : nullptr,
-                       getResourceManager());
+  VariantImpl getOrCreateArray() const {
+    auto impl = getOrCreateImpl();
+    auto data = impl.getData();
+    if (data)
+      data->getOrCreateArray();
+    return impl;
   }
   }
 
 
   FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
   FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
 
 
   FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {
   FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {
-    return ArduinoJson::JsonVariantConst(getData(), getResourceManager());
+    return ArduinoJson::JsonVariantConst(getImpl());
   }
   }
 
 
   template <typename T>
   template <typename T>
@@ -322,8 +306,6 @@ class VariantRefBase : public VariantTag {
 
 
   template <typename TConverter, typename T>
   template <typename TConverter, typename T>
   bool doSet(const T& value, true_type) const;
   bool doSet(const T& value, true_type) const;
-
-  ArduinoJson::JsonVariant getOrCreateVariant() const;
 };
 };
 
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 21 - 24
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

@@ -69,20 +69,20 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
 template <typename TDerived>
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
 template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
 inline T VariantRefBase<TDerived>::add() const {
 inline T VariantRefBase<TDerived>::add() const {
-  return JsonVariant(getOrCreateOrCreateArray().addElement(),
-                     getResourceManager());
+  auto impl = getOrCreateArray();
+  return JsonVariant(impl.addElement(), impl.getResourceManager());
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename TString, enable_if_t<IsString<TString>::value, int>>
 template <typename TString, enable_if_t<IsString<TString>::value, int>>
 inline bool VariantRefBase<TDerived>::containsKey(const TString& key) const {
 inline bool VariantRefBase<TDerived>::containsKey(const TString& key) const {
-  return getVariantImpl().getMember(adaptString(key)) != 0;
+  return getImpl().getMember(adaptString(key)) != 0;
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename TChar, enable_if_t<IsString<TChar*>::value, int>>
 template <typename TChar, enable_if_t<IsString<TChar*>::value, int>>
 inline bool VariantRefBase<TDerived>::containsKey(TChar* key) const {
 inline bool VariantRefBase<TDerived>::containsKey(TChar* key) const {
-  return getVariantImpl().getMember(adaptString(key)) != 0;
+  return getImpl().getMember(adaptString(key)) != 0;
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
@@ -93,12 +93,7 @@ inline bool VariantRefBase<TDerived>::containsKey(const TVariant& key) const {
 
 
 template <typename TDerived>
 template <typename TDerived>
 inline JsonVariant VariantRefBase<TDerived>::getVariant() const {
 inline JsonVariant VariantRefBase<TDerived>::getVariant() const {
-  return JsonVariant(getData(), getResourceManager());
-}
-
-template <typename TDerived>
-inline JsonVariant VariantRefBase<TDerived>::getOrCreateVariant() const {
-  return JsonVariant(getOrCreateData(), getResourceManager());
+  return JsonVariant(getImpl());
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
@@ -133,43 +128,45 @@ VariantRefBase<TDerived>::operator[](const TString& key) const {
 template <typename TDerived>
 template <typename TDerived>
 template <typename TConverter, typename T>
 template <typename TConverter, typename T>
 inline bool VariantRefBase<TDerived>::doSet(const T& value, false_type) const {
 inline bool VariantRefBase<TDerived>::doSet(const T& value, false_type) const {
-  TConverter::toJson(value, getOrCreateVariant());
-  auto resources = getResourceManager();
+  auto impl = getOrCreateImpl();
+  TConverter::toJson(value, JsonVariant(impl));
+  auto resources = impl.getResourceManager();
   return resources && !resources->overflowed();
   return resources && !resources->overflowed();
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename TConverter, typename T>
 template <typename TConverter, typename T>
 inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
 inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
-  return TConverter::toJson(value, getOrCreateVariant());
+  auto impl = getOrCreateImpl();
+  return TConverter::toJson(value, JsonVariant(impl));
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
 template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
 inline JsonArray VariantRefBase<TDerived>::to() const {
 inline JsonArray VariantRefBase<TDerived>::to() const {
-  auto data = getOrCreateData();
-  if (!data)
+  auto impl = getOrCreateImpl();
+  if (!impl.getData())
     return JsonArray();
     return JsonArray();
-  auto resources = getResourceManager();
-  VariantImpl(data, resources).clear();
-  return JsonArray(data->toArray(), resources);
+  impl.clear();
+  impl.getData()->toArray();
+  return JsonArray(impl);
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonObject>::value, int>>
 template <typename T, enable_if_t<is_same<T, JsonObject>::value, int>>
 JsonObject VariantRefBase<TDerived>::to() const {
 JsonObject VariantRefBase<TDerived>::to() const {
-  auto data = getOrCreateData();
-  if (!data)
+  auto impl = getOrCreateImpl();
+  if (!impl.getData())
     return JsonObject();
     return JsonObject();
-  auto resources = getResourceManager();
-  VariantImpl(data, resources).clear();
-  return JsonObject(data->toObject(), resources);
+  impl.clear();
+  impl.getData()->toObject();
+  return JsonObject(impl);
 }
 }
 
 
 template <typename TDerived>
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
 template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
 JsonVariant VariantRefBase<TDerived>::to() const {
 JsonVariant VariantRefBase<TDerived>::to() const {
-  detail::VariantImpl impl(getOrCreateData(), getResourceManager());
+  auto impl = getOrCreateImpl();
   impl.clear();
   impl.clear();
   return JsonVariant(impl);
   return JsonVariant(impl);
 }
 }