Skip to content

Commit

Permalink
Move public facing SFINAEs to template declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed Dec 20, 2024
1 parent e33e78d commit 81f7e93
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 260 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ HEAD
* `JsonString` is now stored by copy, unless specified otherwise
* Replace undocumented `JsonString::Ownership` with `bool`
* Rename undocumented `JsonString::isLinked()` to `isStatic()`
* Move public facing SFINAEs to template declarations

> ### BREAKING CHANGES
>
Expand Down
30 changes: 15 additions & 15 deletions src/ArduinoJson/Array/JsonArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,18 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Appends a new (empty) element to the array.
// Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonarray/add/
template <typename T>
detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() const {
template <typename T, detail::enable_if_t<
!detail::is_same<T, JsonVariant>::value, int> = 0>
T add() const {
return add<JsonVariant>().to<T>();
}

// Appends a new (null) element to the array.
// Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonarray/add/
template <typename T>
detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() const {
template <typename T, detail::enable_if_t<
detail::is_same<T, JsonVariant>::value, short> = 0>
JsonVariant add() const {
return JsonVariant(detail::ArrayData::addElement(data_, resources_),
resources_);
}
Expand Down Expand Up @@ -115,9 +117,9 @@ class JsonArray : public detail::VariantOperators<JsonArray> {

// Removes the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/remove/
template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
const TVariant& variant) const {
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, int> = 0>
void remove(const TVariant& variant) const {
if (variant.template is<size_t>())
remove(variant.template as<size_t>());
}
Expand All @@ -130,19 +132,17 @@ class JsonArray : public detail::VariantOperators<JsonArray> {

// Gets or sets the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/subscript/
template <typename T>
detail::enable_if_t<detail::is_integral<T>::value,
detail::ElementProxy<JsonArray>>
operator[](T index) const {
template <typename T,
detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
detail::ElementProxy<JsonArray> operator[](T index) const {
return {*this, size_t(index)};
}

// Gets or sets the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/subscript/
template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value,
detail::ElementProxy<JsonArray>>
operator[](const TVariant& variant) const {
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, short> = 0>
detail::ElementProxy<JsonArray> operator[](const TVariant& variant) const {
if (variant.template is<size_t>())
return {*this, variant.template as<size_t>()};
else
Expand Down
12 changes: 6 additions & 6 deletions src/ArduinoJson/Array/JsonArrayConst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {

// Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
template <typename T>
detail::enable_if_t<detail::is_integral<T>::value, JsonVariantConst>
operator[](T index) const {
template <typename T,
detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
JsonVariantConst operator[](T index) const {
return JsonVariantConst(
detail::ArrayData::getElement(data_, size_t(index), resources_),
resources_);
}

// Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& variant) const {
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, short> = 0>
JsonVariantConst operator[](const TVariant& variant) const {
if (variant.template is<size_t>())
return operator[](variant.template as<size_t>());
else
Expand Down
38 changes: 19 additions & 19 deletions src/ArduinoJson/Array/Utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE

// Copies a value to a JsonVariant.
// This is a degenerated form of copyArray() to stop the recursion.
template <typename T>
inline detail::enable_if_t<!detail::is_array<T>::value, bool> copyArray(
const T& src, JsonVariant dst) {
template <typename T,
typename = detail::enable_if_t<!detail::is_array<T>::value>>
inline bool copyArray(const T& src, JsonVariant dst) {
return dst.set(src);
}

// Copies values from an array to a JsonArray or a JsonVariant.
// https://arduinojson.org/v7/api/misc/copyarray/
template <typename T, size_t N, typename TDestination>
inline detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value, bool>
copyArray(T (&src)[N], const TDestination& dst) {
template <typename T, size_t N, typename TDestination,
typename = detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value>>
inline bool copyArray(T (&src)[N], const TDestination& dst) {
return copyArray(src, N, dst);
}

// Copies values from an array to a JsonArray or a JsonVariant.
// https://arduinojson.org/v7/api/misc/copyarray/
template <typename T, typename TDestination>
inline detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value, bool>
copyArray(const T* src, size_t len, const TDestination& dst) {
template <typename T, typename TDestination,
typename = detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value>>
inline bool copyArray(const T* src, size_t len, const TDestination& dst) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= copyArray(src[i], dst.template add<JsonVariant>());
Expand Down Expand Up @@ -62,9 +62,9 @@ inline bool copyArray(const T* src, size_t len, JsonDocument& dst) {

// Copies a value from a JsonVariant.
// This is a degenerated form of copyArray() to stop the recursion.
template <typename T>
inline detail::enable_if_t<!detail::is_array<T>::value, size_t> copyArray(
JsonVariantConst src, T& dst) {
template <typename T,
typename = detail::enable_if_t<!detail::is_array<T>::value>>
inline size_t copyArray(JsonVariantConst src, T& dst) {
dst = src.as<T>();
return 1;
}
Expand Down Expand Up @@ -102,11 +102,11 @@ inline size_t copyArray(JsonVariantConst src, char (&dst)[N]) {

// Copies values from a JsonDocument to an array.
// https://arduinojson.org/v7/api/misc/copyarray/
template <typename TSource, typename T>
inline detail::enable_if_t<detail::is_array<T>::value &&
detail::is_base_of<JsonDocument, TSource>::value,
size_t>
copyArray(const TSource& src, T& dst) {
template <typename TSource, typename T,
typename = detail::enable_if_t<
detail::is_array<T>::value &&
detail::is_base_of<JsonDocument, TSource>::value>>
inline size_t copyArray(const TSource& src, T& dst) {
return copyArray(src.template as<JsonArrayConst>(), dst);
}

Expand Down
116 changes: 58 additions & 58 deletions src/ArduinoJson/Document/JsonDocument.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
}

// Construct from variant, array, or object
template <typename T>
JsonDocument(
const T& src, Allocator* alloc = detail::DefaultAllocator::instance(),
detail::enable_if_t<detail::IsVariant<T>::value ||
detail::is_same<T, JsonArray>::value ||
detail::is_same<T, JsonArrayConst>::value ||
detail::is_same<T, JsonObject>::value ||
detail::is_same<T, JsonObjectConst>::value>* = 0)
template <typename T, typename = detail::enable_if_t<
detail::IsVariant<T>::value ||
detail::is_same<T, JsonArray>::value ||
detail::is_same<T, JsonArrayConst>::value ||
detail::is_same<T, JsonObject>::value ||
detail::is_same<T, JsonObjectConst>::value>>
JsonDocument(const T& src,
Allocator* alloc = detail::DefaultAllocator::instance())
: JsonDocument(alloc) {
set(src);
}
Expand Down Expand Up @@ -136,9 +136,9 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {

// Replaces the root with the specified value.
// https://arduinojson.org/v7/api/jsondocument/set/
template <typename T>
detail::enable_if_t<!detail::is_base_of<JsonDocument, T>::value, bool> set(
const T& src) {
template <typename T, typename = detail::enable_if_t<
!detail::is_base_of<JsonDocument, T>::value>>
bool set(const T& src) {
return to<JsonVariant>().set(src);
}

Expand Down Expand Up @@ -168,68 +168,65 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {

// DEPRECATED: use obj[key].is<T>() instead
// https://arduinojson.org/v7/api/jsondocument/containskey/
template <typename TString>
template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead")
detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
const TString& key) const {
bool containsKey(const TString& key) const {
return data_.getMember(detail::adaptString(key), &resources_) != 0;
}

// DEPRECATED: use obj[key].is<T>() instead
// https://arduinojson.org/v7/api/jsondocument/containskey/
template <typename TVariant>
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, short> = 0>
ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead")
detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
const TVariant& key) const {
bool containsKey(const TVariant& key) const {
return containsKey(key.template as<const char*>());
}

// Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString>
detail::enable_if_t<
detail::IsString<TString>::value,
detail::MemberProxy<JsonDocument&, detail::AdaptedString<TString>>>
operator[](const TString& key) {
template <typename TString,
typename = detail::enable_if_t<detail::IsString<TString>::value>>
detail::MemberProxy<JsonDocument&, detail::AdaptedString<TString>> operator[](
const TString& key) {
return {*this, detail::adaptString(key)};
}

// Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar>
detail::enable_if_t<
detail::IsString<TChar*>::value && !detail::is_const<TChar>::value,
detail::MemberProxy<JsonDocument&, detail::AdaptedString<TChar*>>>
operator[](TChar* key) {
template <typename TChar,
typename = detail::enable_if_t<detail::IsString<TChar*>::value &&
!detail::is_const<TChar>::value>>
detail::MemberProxy<JsonDocument&, detail::AdaptedString<TChar*>> operator[](
TChar* key) {
return {*this, detail::adaptString(key)};
}

// Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString>
detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
operator[](const TString& key) const {
template <typename TString,
typename = detail::enable_if_t<detail::IsString<TString>::value>>
JsonVariantConst operator[](const TString& key) const {
return JsonVariantConst(
data_.getMember(detail::adaptString(key), &resources_), &resources_);
}

// Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar>
detail::enable_if_t<detail::IsString<TChar*>::value &&
!detail::is_const<TChar>::value,
JsonVariantConst>
operator[](TChar* key) const {
template <typename TChar,
typename = detail::enable_if_t<detail::IsString<TChar*>::value &&
!detail::is_const<TChar>::value>>
JsonVariantConst operator[](TChar* key) const {
return JsonVariantConst(
data_.getMember(detail::adaptString(key), &resources_), &resources_);
}

// Gets or sets a root array's element.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename T>
detail::enable_if_t<detail::is_integral<T>::value,
detail::ElementProxy<JsonDocument&>>
operator[](T index) {
template <typename T,
detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
detail::ElementProxy<JsonDocument&> operator[](T index) {
return {*this, size_t(index)};
}

Expand All @@ -241,9 +238,9 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {

// Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
operator[](const TVariant& key) const {
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, short> = 0>
JsonVariantConst operator[](const TVariant& key) const {
if (key.template is<JsonString>())
return operator[](key.template as<JsonString>());
if (key.template is<size_t>())
Expand All @@ -254,16 +251,18 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Appends a new (empty) element to the root array.
// Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsondocument/add/
template <typename T>
detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() {
template <typename T, detail::enable_if_t<
!detail::is_same<T, JsonVariant>::value, int> = 0>
T add() {
return add<JsonVariant>().to<T>();
}

// Appends a new (null) element to the root array.
// Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsondocument/add/
template <typename T>
detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() {
template <typename T, detail::enable_if_t<
detail::is_same<T, JsonVariant>::value, short> = 0>
JsonVariant add() {
return JsonVariant(data_.addElement(&resources_), &resources_);
}

Expand All @@ -284,36 +283,37 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {

// Removes an element of the root array.
// https://arduinojson.org/v7/api/jsondocument/remove/
template <typename T>
detail::enable_if_t<detail::is_integral<T>::value> remove(T index) {
template <typename T,
typename = detail::enable_if_t<detail::is_integral<T>::value>>
void remove(T index) {
detail::VariantData::removeElement(getData(), size_t(index),
getResourceManager());
}

// Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TChar>
detail::enable_if_t<detail::IsString<TChar*>::value &&
!detail::is_const<TChar>::value>
remove(TChar* key) {
template <typename TChar,
typename = detail::enable_if_t<detail::IsString<TChar*>::value &&
!detail::is_const<TChar>::value>>
void remove(TChar* key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager());
}

// Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TString>
detail::enable_if_t<detail::IsString<TString>::value> remove(
const TString& key) {
template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
void remove(const TString& key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager());
}

// Removes a member of the root object or an element of the root array.
// https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TVariant>
detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
const TVariant& key) {
template <typename TVariant,
detail::enable_if_t<detail::IsVariant<TVariant>::value, short> = 0>
void remove(const TVariant& key) {
if (key.template is<const char*>())
remove(key.template as<const char*>());
if (key.template is<size_t>())
Expand Down
Loading

0 comments on commit 81f7e93

Please sign in to comment.