Allow Converter<T>::toJson() to return a boolean as an optimization

This commit is contained in:
Benoit Blanchon
2024-05-22 09:22:53 +02:00
parent 9e0c56acc3
commit 04326d2655
3 changed files with 44 additions and 22 deletions

View File

@ -59,11 +59,13 @@ struct Converter<
!detail::is_same<bool, T>::value &&
!detail::is_same<char, T>::value>::type>
: private detail::VariantAttorney {
static void toJson(T src, JsonVariant dst) {
static bool toJson(T src, JsonVariant dst) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
auto data = getData(dst);
if (data)
data->setInteger(src, getResourceManager(dst));
if (!data)
return false;
data->setInteger(src, getResourceManager(dst));
return true;
}
static T fromJson(JsonVariantConst src) {
@ -81,8 +83,8 @@ struct Converter<
template <typename T>
struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
: private detail::VariantAttorney {
static void toJson(T src, JsonVariant dst) {
dst.set(static_cast<JsonInteger>(src));
static bool toJson(T src, JsonVariant dst) {
return dst.set(static_cast<JsonInteger>(src));
}
static T fromJson(JsonVariantConst src) {
@ -98,10 +100,12 @@ struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
template <>
struct Converter<bool> : private detail::VariantAttorney {
static void toJson(bool src, JsonVariant dst) {
static bool toJson(bool src, JsonVariant dst) {
auto data = getData(dst);
if (data)
data->setBoolean(src, getResourceManager(dst));
if (!data)
return false;
data->setBoolean(src, getResourceManager(dst));
return true;
}
static bool fromJson(JsonVariantConst src) {
@ -119,10 +123,12 @@ template <typename T>
struct Converter<
T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
: private detail::VariantAttorney {
static void toJson(T src, JsonVariant dst) {
static bool toJson(T src, JsonVariant dst) {
auto data = getData(dst);
if (data)
data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
if (!data)
return false;
data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
return true;
}
static T fromJson(JsonVariantConst src) {

View File

@ -79,12 +79,16 @@ class VariantRefBase : public VariantTag {
// Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T>
bool set(const T& value) const;
bool set(const T& value) const {
return doSet<Converter<typename remove_cv<T>::type>>(value);
}
// Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T>
bool set(T* value) const;
bool set(T* value) const {
return doSet<Converter<T*>>(value);
}
// Returns the size of the array or object.
// https://arduinojson.org/v7/api/jsonvariant/size/
@ -290,6 +294,21 @@ class VariantRefBase : public VariantTag {
return getVariant();
}
template <typename TConverter, typename T>
bool doSet(T&& value) const {
return doSet<TConverter>(
detail::forward<T>(value),
is_same<typename function_traits<
decltype(&TConverter::toJson)>::return_type,
bool>{});
}
template <typename TConverter, typename T>
bool doSet(T&& value, false_type) const;
template <typename TConverter, typename T>
bool doSet(T&& value, true_type) const;
ArduinoJson::JsonVariant getOrCreateVariant() const;
};

View File

@ -139,20 +139,17 @@ VariantRefBase<TDerived>::operator[](const TString& key) const {
}
template <typename TDerived>
template <typename T>
inline bool VariantRefBase<TDerived>::set(const T& value) const {
Converter<typename detail::remove_cv<T>::type>::toJson(value,
getOrCreateVariant());
template <typename TConverter, typename T>
inline bool VariantRefBase<TDerived>::doSet(T&& value, false_type) const {
TConverter::toJson(value, getOrCreateVariant());
auto resources = getResourceManager();
return resources && !resources->overflowed();
}
template <typename TDerived>
template <typename T>
inline bool VariantRefBase<TDerived>::set(T* value) const {
Converter<T*>::toJson(value, getOrCreateVariant());
auto resources = getResourceManager();
return resources && !resources->overflowed();
template <typename TConverter, typename T>
inline bool VariantRefBase<TDerived>::doSet(T&& value, true_type) const {
return TConverter::toJson(value, getOrCreateVariant());
}
template <typename TDerived>