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

This commit is contained in:
Benoit Blanchon
2025-07-07 15:53:37 +02:00
parent f62d6f26e0
commit 0b9a8b6d2b
20 changed files with 168 additions and 267 deletions

View File

@ -50,21 +50,17 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
: upstream_(src.upstream_), index_(src.index_) {}
// 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_;

View File

@ -22,10 +22,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Constructs an unbound reference.
JsonArray() {}
// INTERNAL USE ONLY
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
: impl_(data, resources) {}
// INTERNAL USE ONLY
JsonArray(detail::VariantImpl impl) : impl_(impl) {}
@ -199,16 +195,12 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
}
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_;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,10 +22,6 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Creates an unbound reference.
JsonObject() {}
// INTERNAL USE ONLY
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
: impl_(data, resource) {}
// INTERNAL USE ONLY
JsonObject(detail::VariantImpl impl) : impl_(impl) {}
@ -222,16 +218,12 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
}
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_;

View File

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

View File

@ -51,21 +51,17 @@ class MemberProxy
: upstream_(src.upstream_), key_(src.key_) {}
// 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:

View File

@ -11,10 +11,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <template <typename> class TSerializer>
size_t measure(ArduinoJson::JsonVariantConst source) {
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

View File

@ -10,10 +10,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <template <typename> class TSerializer, typename TWriter>
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>

View File

@ -60,18 +60,18 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
: private detail::VariantAttorney {
static bool toJson(T src, JsonVariant dst) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
auto variant = getVariantImpl(dst);
auto variant = getImpl(dst);
variant.clear();
return variant.setInteger(src);
}
static T fromJson(JsonVariantConst src) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
return getVariantImpl(src).template asIntegral<T>();
return getImpl(src).template asIntegral<T>();
}
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) {
return static_cast<T>(getVariantImpl(src).template asIntegral<int>());
return static_cast<T>(getImpl(src).template asIntegral<int>());
}
static bool checkJson(JsonVariantConst src) {
return getVariantImpl(src).template isInteger<int>();
return getImpl(src).template isInteger<int>();
}
};
template <>
struct Converter<bool> : private detail::VariantAttorney {
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) {
return getVariantImpl(src).asBoolean();
return getImpl(src).asBoolean();
}
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>>
: private detail::VariantAttorney {
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) {
return getVariantImpl(src).template asFloat<T>();
return getImpl(src).template asFloat<T>();
}
static bool checkJson(JsonVariantConst src) {
auto data = getData(src);
return data && data->isFloat();
return getImpl(src).isFloat();
}
};
template <>
struct Converter<const char*> : private detail::VariantAttorney {
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) {
return getVariantImpl(src).asString().c_str();
return getImpl(src).asString().c_str();
}
static bool checkJson(JsonVariantConst src) {
auto data = getData(src);
return data && data->isString();
return getImpl(src).isString();
}
};
template <>
struct Converter<JsonString> : private detail::VariantAttorney {
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) {
return getVariantImpl(src).asString();
return getImpl(src).asString();
}
static bool checkJson(JsonVariantConst src) {
auto data = getData(src);
return data && data->isString();
return getImpl(src).isString();
}
};
template <typename T>
inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
const T& src, JsonVariant dst) {
auto variant = detail::VariantAttorney::getVariantImpl(dst);
auto variant = detail::VariantAttorney::getImpl(dst);
variant.clear();
variant.setString(detail::adaptString(src));
}
@ -178,7 +174,7 @@ inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
template <typename T>
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
static void toJson(SerializedValue<T> src, JsonVariant dst) {
auto variant = getVariantImpl(dst);
auto variant = getImpl(dst);
variant.clear();
variant.setRawString(src);
}
@ -187,14 +183,13 @@ struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
template <>
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
static void toJson(detail::nullptr_t, JsonVariant dst) {
getVariantImpl(dst).clear();
getImpl(dst).clear();
}
static detail::nullptr_t fromJson(JsonVariantConst) {
return nullptr;
}
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
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;
detail::VariantImpl(data, resources).clear();
detail::StringBuilderPrint print(resources);
impl.clear();
detail::StringBuilderPrint print(impl.getResourceManager());
src.printTo(print);
if (print.overflowed())
return;
print.save(data);
print.save(impl.getData());
}
#endif
@ -306,12 +300,11 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
}
static JsonArrayConst fromJson(JsonVariantConst src) {
return JsonArrayConst(getData(src), getResourceManager(src));
return JsonArrayConst(getImpl(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) {
return JsonArray(getData(src), getResourceManager(src));
return JsonArray(getImpl(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) {
return JsonObjectConst(getData(src), getResourceManager(src));
return JsonObjectConst(getImpl(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) {
return JsonObject(getData(src), getResourceManager(src));
return JsonObject(getImpl(src));
}
static bool checkJson(JsonVariant src) {
auto data = getData(src);
return data && data->type == detail::VariantType::Object;
return getImpl(src).type() == detail::VariantType::Object;
}
};

View File

@ -26,16 +26,12 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
JsonVariant(detail::VariantImpl impl) : impl_(impl) {}
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_;
@ -56,7 +52,7 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
}
static bool checkJson(JsonVariant src) {
auto data = getData(src);
auto data = getImpl(src).getData();
return !!data;
}
};
@ -68,11 +64,11 @@ struct Converter<JsonVariantConst> : private detail::VariantAttorney {
}
static JsonVariantConst fromJson(JsonVariantConst src) {
return JsonVariantConst(getData(src), getResourceManager(src));
return JsonVariantConst(getImpl(src));
}
static bool checkJson(JsonVariantConst src) {
auto data = getData(src);
auto data = getImpl(src).getData();
return !!data;
}
};

View File

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

View File

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

View File

@ -16,24 +16,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantAttorney {
public:
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>
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();
}
};

View File

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

View File

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

View File

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