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

View File

@ -79,12 +79,16 @@ class VariantRefBase : public VariantTag {
// Copies the specified value. // Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/ // https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T> 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. // Copies the specified value.
// https://arduinojson.org/v7/api/jsonvariant/set/ // https://arduinojson.org/v7/api/jsonvariant/set/
template <typename T> 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. // Returns the size of the array or object.
// https://arduinojson.org/v7/api/jsonvariant/size/ // https://arduinojson.org/v7/api/jsonvariant/size/
@ -290,6 +294,21 @@ class VariantRefBase : public VariantTag {
return getVariant(); 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; ArduinoJson::JsonVariant getOrCreateVariant() const;
}; };

View File

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