Add helpers for type traits, such as enable_if_t

This commit is contained in:
Benoit Blanchon
2024-05-22 09:59:12 +02:00
parent 04326d2655
commit 1db803bcd3
58 changed files with 376 additions and 430 deletions

View File

@@ -44,8 +44,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonarray/add/ // https://arduinojson.org/v7/api/jsonarray/add/
template <typename T> template <typename T>
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() const {
add() const {
return add<JsonVariant>().to<T>(); return add<JsonVariant>().to<T>();
} }
@@ -53,8 +52,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonarray/add/ // https://arduinojson.org/v7/api/jsonarray/add/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() const {
add() const {
return JsonVariant(detail::ArrayData::addElement(data_, resources_), return JsonVariant(detail::ArrayData::addElement(data_, resources_),
resources_); resources_);
} }
@@ -117,7 +115,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Removes the element at the specified index. // Removes the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/remove/ // https://arduinojson.org/v7/api/jsonarray/remove/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value>::type remove( detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
TVariant variant) const { TVariant variant) const {
if (variant.template is<size_t>()) if (variant.template is<size_t>())
remove(variant.template as<size_t>()); remove(variant.template as<size_t>());
@@ -132,8 +130,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Gets or sets the element at the specified index. // Gets or sets the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/subscript/ // https://arduinojson.org/v7/api/jsonarray/subscript/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_integral<T>::value, detail::enable_if_t<detail::is_integral<T>::value,
detail::ElementProxy<JsonArray>>::type detail::ElementProxy<JsonArray>>
operator[](T index) const { operator[](T index) const {
return {*this, size_t(index)}; return {*this, size_t(index)};
} }
@@ -141,8 +139,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Gets or sets the element at the specified index. // Gets or sets the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/subscript/ // https://arduinojson.org/v7/api/jsonarray/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value,
detail::ElementProxy<JsonArray>>::type detail::ElementProxy<JsonArray>>
operator[](const TVariant& variant) const { operator[](const TVariant& variant) const {
if (variant.template is<size_t>()) if (variant.template is<size_t>())
return operator[](variant.template as<size_t>()); return operator[](variant.template as<size_t>());

View File

@@ -46,8 +46,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns the element at the specified index. // Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/ // https://arduinojson.org/v7/api/jsonarrayconst/subscript/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_integral<T>::value, detail::enable_if_t<detail::is_integral<T>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](T index) const { operator[](T index) const {
return JsonVariantConst( return JsonVariantConst(
detail::ArrayData::getElement(data_, size_t(index), resources_), detail::ArrayData::getElement(data_, size_t(index), resources_),
@@ -57,8 +56,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns the element at the specified index. // Returns the element at the specified index.
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/ // https://arduinojson.org/v7/api/jsonarrayconst/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TVariant& variant) const { operator[](const TVariant& variant) const {
if (variant.template is<size_t>()) if (variant.template is<size_t>())
return operator[](variant.template as<size_t>()); return operator[](variant.template as<size_t>());

View File

@@ -12,16 +12,16 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
// Copies a value to a JsonVariant. // Copies a value to a JsonVariant.
// This is a degenerated form of copyArray() to stop the recursion. // This is a degenerated form of copyArray() to stop the recursion.
template <typename T> template <typename T>
inline typename detail::enable_if<!detail::is_array<T>::value, bool>::type inline detail::enable_if_t<!detail::is_array<T>::value, bool> copyArray(
copyArray(const T& src, JsonVariant dst) { const T& src, JsonVariant dst) {
return dst.set(src); return dst.set(src);
} }
// Copies values from an array to a JsonArray or a JsonVariant. // Copies values from an array to a JsonArray or a JsonVariant.
// https://arduinojson.org/v7/api/misc/copyarray/ // https://arduinojson.org/v7/api/misc/copyarray/
template <typename T, size_t N, typename TDestination> template <typename T, size_t N, typename TDestination>
inline typename detail::enable_if< inline detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value, bool>::type !detail::is_base_of<JsonDocument, TDestination>::value, bool>
copyArray(T (&src)[N], const TDestination& dst) { copyArray(T (&src)[N], const TDestination& dst) {
return copyArray(src, N, dst); return copyArray(src, N, dst);
} }
@@ -29,8 +29,8 @@ copyArray(T (&src)[N], const TDestination& dst) {
// Copies values from an array to a JsonArray or a JsonVariant. // Copies values from an array to a JsonArray or a JsonVariant.
// https://arduinojson.org/v7/api/misc/copyarray/ // https://arduinojson.org/v7/api/misc/copyarray/
template <typename T, typename TDestination> template <typename T, typename TDestination>
inline typename detail::enable_if< inline detail::enable_if_t<
!detail::is_base_of<JsonDocument, TDestination>::value, bool>::type !detail::is_base_of<JsonDocument, TDestination>::value, bool>
copyArray(const T* src, size_t len, const TDestination& dst) { copyArray(const T* src, size_t len, const TDestination& dst) {
bool ok = true; bool ok = true;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
@@ -63,8 +63,8 @@ inline bool copyArray(const T* src, size_t len, JsonDocument& dst) {
// Copies a value from a JsonVariant. // Copies a value from a JsonVariant.
// This is a degenerated form of copyArray() to stop the recursion. // This is a degenerated form of copyArray() to stop the recursion.
template <typename T> template <typename T>
inline typename detail::enable_if<!detail::is_array<T>::value, size_t>::type inline detail::enable_if_t<!detail::is_array<T>::value, size_t> copyArray(
copyArray(JsonVariantConst src, T& dst) { JsonVariantConst src, T& dst) {
dst = src.as<T>(); dst = src.as<T>();
return 1; return 1;
} }
@@ -103,10 +103,9 @@ inline size_t copyArray(JsonVariantConst src, char (&dst)[N]) {
// Copies values from a JsonDocument to an array. // Copies values from a JsonDocument to an array.
// https://arduinojson.org/v7/api/misc/copyarray/ // https://arduinojson.org/v7/api/misc/copyarray/
template <typename TSource, typename T> template <typename TSource, typename T>
inline typename detail::enable_if< inline detail::enable_if_t<detail::is_array<T>::value &&
detail::is_array<T>::value && detail::is_base_of<JsonDocument, TSource>::value,
detail::is_base_of<JsonDocument, TSource>::value, size_t>
size_t>::type
copyArray(const TSource& src, T& dst) { copyArray(const TSource& src, T& dst) {
return copyArray(src.template as<JsonArrayConst>(), dst); return copyArray(src.template as<JsonArrayConst>(), dst);
} }

View File

@@ -62,9 +62,8 @@ ARDUINOJSON_END_PRIVATE_NAMESPACE
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TInput> template <typename TInput>
Reader<typename remove_reference<TInput>::type> makeReader(TInput&& input) { Reader<remove_reference_t<TInput>> makeReader(TInput&& input) {
return Reader<typename remove_reference<TInput>::type>{ return Reader<remove_reference_t<TInput>>{detail::forward<TInput>(input)};
detail::forward<TInput>(input)};
} }
template <typename TChar> template <typename TChar>

View File

@@ -9,8 +9,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TSource> template <typename TSource>
struct Reader<TSource, struct Reader<TSource, enable_if_t<is_base_of<Stream, TSource>::value>> {
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
public: public:
explicit Reader(Stream& stream) : stream_(&stream) {} explicit Reader(Stream& stream) : stream_(&stream) {}

View File

@@ -9,8 +9,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TSource> template <typename TSource>
struct Reader<TSource, struct Reader<TSource, enable_if_t<is_base_of<::String, TSource>::value>>
typename enable_if<is_base_of<::String, TSource>::value>::type>
: BoundedReader<const char*> { : BoundedReader<const char*> {
explicit Reader(const ::String& s) explicit Reader(const ::String& s)
: BoundedReader<const char*>(s.c_str(), s.length()) {} : BoundedReader<const char*>(s.c_str(), s.length()) {}

View File

@@ -4,6 +4,8 @@
#pragma once #pragma once
#include <ArduinoJson/Polyfills/type_traits.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TIterator> template <typename TIterator>
@@ -29,13 +31,8 @@ class IteratorReader {
} }
}; };
template <typename T>
struct void_ {
typedef void type;
};
template <typename TSource> template <typename TSource>
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type> struct Reader<TSource, void_t<typename TSource::const_iterator>>
: IteratorReader<typename TSource::const_iterator> { : IteratorReader<typename TSource::const_iterator> {
explicit Reader(const TSource& source) explicit Reader(const TSource& source)
: IteratorReader<typename TSource::const_iterator>(source.begin(), : IteratorReader<typename TSource::const_iterator>(source.begin(),

View File

@@ -19,8 +19,7 @@ template <typename T>
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {}; struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
template <typename TSource> template <typename TSource>
struct Reader<TSource*, struct Reader<TSource*, enable_if_t<IsCharOrVoid<TSource>::value>> {
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
const char* ptr_; const char* ptr_;
public: public:
@@ -39,8 +38,7 @@ struct Reader<TSource*,
}; };
template <typename TSource> template <typename TSource>
struct BoundedReader<TSource*, struct BoundedReader<TSource*, enable_if_t<IsCharOrVoid<TSource>::value>>
typename enable_if<IsCharOrVoid<TSource>::value>::type>
: public IteratorReader<const char*> { : public IteratorReader<const char*> {
public: public:
explicit BoundedReader(const void* ptr, size_t len) explicit BoundedReader(const void* ptr, size_t len)

View File

@@ -9,8 +9,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TSource> template <typename TSource>
struct Reader<TSource, typename enable_if< struct Reader<TSource, enable_if_t<is_base_of<std::istream, TSource>::value>> {
is_base_of<std::istream, TSource>::value>::type> {
public: public:
explicit Reader(std::istream& stream) : stream_(&stream) {} explicit Reader(std::istream& stream) : stream_(&stream) {}

View File

@@ -10,7 +10,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TVariant> template <typename TVariant>
struct Reader<TVariant, typename enable_if<IsVariant<TVariant>::value>::type> struct Reader<TVariant, enable_if_t<IsVariant<TVariant>::value>>
: Reader<char*, void> { : Reader<char*, void> {
explicit Reader(const TVariant& x) explicit Reader(const TVariant& x)
: Reader<char*, void>(x.template as<const char*>()) {} : Reader<char*, void>(x.template as<const char*>()) {}

View File

@@ -29,10 +29,9 @@ struct is_deserialize_destination : false_type {};
template <class T> template <class T>
struct is_deserialize_destination< struct is_deserialize_destination<
T, typename enable_if<is_same<decltype(VariantAttorney::getResourceManager( T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager(
detail::declval<T&>())), detail::declval<T&>())),
ResourceManager*>::value>::type> : true_type { ResourceManager*>::value>> : true_type {};
};
template <typename TDestination> template <typename TDestination>
inline void shrinkJsonDocument(TDestination&) { inline void shrinkJsonDocument(TDestination&) {
@@ -62,8 +61,8 @@ DeserializationError doDeserialize(TDestination&& dst, TReader reader,
template <template <typename> class TDeserializer, typename TDestination, template <template <typename> class TDeserializer, typename TDestination,
typename TStream, typename... Args, typename TStream, typename... Args,
typename = typename enable_if< // issue #1897 typename = enable_if_t< // issue #1897
!is_integral<typename first_or_void<Args...>::type>::value>::type> !is_integral<typename first_or_void<Args...>::type>::value>>
DeserializationError deserialize(TDestination&& dst, TStream&& input, DeserializationError deserialize(TDestination&& dst, TStream&& input,
Args... args) { Args... args) {
return doDeserialize<TDeserializer>( return doDeserialize<TDeserializer>(
@@ -73,7 +72,7 @@ DeserializationError deserialize(TDestination&& dst, TStream&& input,
template <template <typename> class TDeserializer, typename TDestination, template <template <typename> class TDeserializer, typename TDestination,
typename TChar, typename Size, typename... Args, typename TChar, typename Size, typename... Args,
typename = typename enable_if<is_integral<Size>::value>::type> typename = enable_if_t<is_integral<Size>::value>>
DeserializationError deserialize(TDestination&& dst, TChar* input, DeserializationError deserialize(TDestination&& dst, TChar* input,
Size inputSize, Args... args) { Size inputSize, Args... args) {
return doDeserialize<TDeserializer>(dst, makeReader(input, size_t(inputSize)), return doDeserialize<TDeserializer>(dst, makeReader(input, size_t(inputSize)),

View File

@@ -39,11 +39,11 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename T> template <typename T>
JsonDocument( JsonDocument(
const T& src, Allocator* alloc = detail::DefaultAllocator::instance(), const T& src, Allocator* alloc = detail::DefaultAllocator::instance(),
typename detail::enable_if< detail::enable_if_t<detail::IsVariant<T>::value ||
detail::IsVariant<T>::value || detail::is_same<T, JsonArray>::value || detail::is_same<T, JsonArray>::value ||
detail::is_same<T, JsonArrayConst>::value || detail::is_same<T, JsonArrayConst>::value ||
detail::is_same<T, JsonObject>::value || detail::is_same<T, JsonObject>::value ||
detail::is_same<T, JsonObjectConst>::value>::type* = 0) detail::is_same<T, JsonObjectConst>::value>* = 0)
: JsonDocument(alloc) { : JsonDocument(alloc) {
set(src); set(src);
} }
@@ -137,9 +137,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Replaces the root with the specified value. // Replaces the root with the specified value.
// https://arduinojson.org/v7/api/jsondocument/set/ // https://arduinojson.org/v7/api/jsondocument/set/
template <typename T> template <typename T>
typename detail::enable_if<!detail::is_base_of<JsonDocument, T>::value, detail::enable_if_t<!detail::is_base_of<JsonDocument, T>::value, bool> set(
bool>::type const T& src) {
set(const T& src) {
return to<JsonVariant>().set(src); return to<JsonVariant>().set(src);
} }
@@ -161,24 +160,24 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns true if the root object contains the specified key. // Returns true if the root object contains the specified key.
// https://arduinojson.org/v7/api/jsondocument/containskey/ // https://arduinojson.org/v7/api/jsondocument/containskey/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, bool>::type detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
containsKey(const TString& key) const { const TString& key) const {
return data_.getMember(detail::adaptString(key), &resources_) != 0; return data_.getMember(detail::adaptString(key), &resources_) != 0;
} }
// Returns true if the root object contains the specified key. // Returns true if the root object contains the specified key.
// https://arduinojson.org/v7/api/jsondocument/containskey/ // https://arduinojson.org/v7/api/jsondocument/containskey/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, bool>::type detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
containsKey(const TVariant& key) const { const TVariant& key) const {
return containsKey(key.template as<const char*>()); return containsKey(key.template as<const char*>());
} }
// Gets or sets a root object's member. // Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, detail::enable_if_t<detail::IsString<TString>::value,
detail::MemberProxy<JsonDocument&, TString>>::type detail::MemberProxy<JsonDocument&, TString>>
operator[](const TString& key) { operator[](const TString& key) {
return {*this, key}; return {*this, key};
} }
@@ -186,8 +185,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root object's member. // Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, detail::enable_if_t<detail::IsString<TChar*>::value,
detail::MemberProxy<JsonDocument&, TChar*>>::type detail::MemberProxy<JsonDocument&, TChar*>>
operator[](TChar* key) { operator[](TChar* key) {
return {*this, key}; return {*this, key};
} }
@@ -195,8 +194,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root object's member. // Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst( return JsonVariantConst(
data_.getMember(detail::adaptString(key), &resources_), &resources_); data_.getMember(detail::adaptString(key), &resources_), &resources_);
@@ -205,8 +203,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root object's member. // Gets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst( return JsonVariantConst(
data_.getMember(detail::adaptString(key), &resources_), &resources_); data_.getMember(detail::adaptString(key), &resources_), &resources_);
@@ -215,8 +212,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root array's element. // Gets or sets a root array's element.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_integral<T>::value, detail::enable_if_t<detail::is_integral<T>::value,
detail::ElementProxy<JsonDocument&>>::type detail::ElementProxy<JsonDocument&>>
operator[](T index) { operator[](T index) {
return {*this, size_t(index)}; return {*this, size_t(index)};
} }
@@ -230,8 +227,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets or sets a root object's member. // Gets or sets a root object's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<const char*>())
return operator[](key.template as<const char*>()); return operator[](key.template as<const char*>());
@@ -244,8 +240,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsondocument/add/ // https://arduinojson.org/v7/api/jsondocument/add/
template <typename T> template <typename T>
typename detail::enable_if<!detail::is_same<T, JsonVariant>::value, T>::type detail::enable_if_t<!detail::is_same<T, JsonVariant>::value, T> add() {
add() {
return add<JsonVariant>().to<T>(); return add<JsonVariant>().to<T>();
} }
@@ -253,8 +248,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsondocument/add/ // https://arduinojson.org/v7/api/jsondocument/add/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_same<T, JsonVariant>::value, T>::type detail::enable_if_t<detail::is_same<T, JsonVariant>::value, T> add() {
add() {
return JsonVariant(data_.addElement(&resources_), &resources_); return JsonVariant(data_.addElement(&resources_), &resources_);
} }
@@ -275,8 +269,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Removes an element of the root array. // Removes an element of the root array.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_integral<T>::value>::type remove( detail::enable_if_t<detail::is_integral<T>::value> remove(T index) {
T index) {
detail::VariantData::removeElement(getData(), size_t(index), detail::VariantData::removeElement(getData(), size_t(index),
getResourceManager()); getResourceManager());
} }
@@ -284,8 +277,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Removes a member of the root object. // Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value>::type remove( detail::enable_if_t<detail::IsString<TChar*>::value> remove(TChar* key) {
TChar* key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key), detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager()); getResourceManager());
} }
@@ -293,7 +285,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Removes a member of the root object. // Removes a member of the root object.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value>::type remove( detail::enable_if_t<detail::IsString<TString>::value> remove(
const TString& key) { const TString& key) {
detail::VariantData::removeMember(getData(), detail::adaptString(key), detail::VariantData::removeMember(getData(), detail::adaptString(key),
getResourceManager()); getResourceManager());
@@ -302,7 +294,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// 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.
// https://arduinojson.org/v7/api/jsondocument/remove/ // https://arduinojson.org/v7/api/jsondocument/remove/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value>::type remove( detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
const TVariant& key) { const TVariant& key) {
if (key.template is<const char*>()) if (key.template is<const char*>())
remove(key.template as<const char*>()); remove(key.template as<const char*>());

View File

@@ -671,9 +671,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
// Parses a JSON input, filters, and puts the result in a JsonDocument. // Parses a JSON input, filters, and puts the result in a JsonDocument.
// https://arduinojson.org/v7/api/json/deserializejson/ // https://arduinojson.org/v7/api/json/deserializejson/
template <typename TDestination, typename... Args> template <typename TDestination, typename... Args>
typename detail::enable_if< detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
detail::is_deserialize_destination<TDestination>::value, DeserializationError>
DeserializationError>::type
deserializeJson(TDestination&& dst, Args&&... args) { deserializeJson(TDestination&& dst, Args&&... args) {
using namespace detail; using namespace detail;
return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst), return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst),
@@ -683,9 +682,8 @@ deserializeJson(TDestination&& dst, Args&&... args) {
// Parses a JSON input, filters, and puts the result in a JsonDocument. // Parses a JSON input, filters, and puts the result in a JsonDocument.
// https://arduinojson.org/v7/api/json/deserializejson/ // https://arduinojson.org/v7/api/json/deserializejson/
template <typename TDestination, typename TChar, typename... Args> template <typename TDestination, typename TChar, typename... Args>
typename detail::enable_if< detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
detail::is_deserialize_destination<TDestination>::value, DeserializationError>
DeserializationError>::type
deserializeJson(TDestination&& dst, TChar* input, Args&&... args) { deserializeJson(TDestination&& dst, TChar* input, Args&&... args) {
using namespace detail; using namespace detail;
return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst), return deserialize<JsonDeserializer>(detail::forward<TDestination>(dst),

View File

@@ -150,8 +150,8 @@ inline size_t measureJson(JsonVariantConst source) {
#if ARDUINOJSON_ENABLE_STD_STREAM #if ARDUINOJSON_ENABLE_STD_STREAM
template <typename T> template <typename T>
inline typename detail::enable_if< inline detail::enable_if_t<detail::is_convertible<T, JsonVariantConst>::value,
detail::is_convertible<T, JsonVariantConst>::value, std::ostream&>::type std::ostream&>
operator<<(std::ostream& os, const T& source) { operator<<(std::ostream& os, const T& source) {
serializeJson(source, os); serializeJson(source, os);
return os; return os;

View File

@@ -100,8 +100,8 @@ class TextFormatter {
} }
template <typename T> template <typename T>
typename enable_if<is_signed<T>::value>::type writeInteger(T value) { enable_if_t<is_signed<T>::value> writeInteger(T value) {
typedef typename make_unsigned<T>::type unsigned_type; typedef make_unsigned_t<T> unsigned_type;
unsigned_type unsigned_value; unsigned_type unsigned_value;
if (value < 0) { if (value < 0) {
writeRaw('-'); writeRaw('-');
@@ -113,7 +113,7 @@ class TextFormatter {
} }
template <typename T> template <typename T>
typename enable_if<is_unsigned<T>::value>::type writeInteger(T value) { enable_if_t<is_unsigned<T>::value> writeInteger(T value) {
char buffer[22]; char buffer[22];
char* end = buffer + sizeof(buffer); char* end = buffer + sizeof(buffer);
char* begin = end; char* begin = end;

View File

@@ -17,9 +17,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
struct StringNode { struct StringNode {
// Use the same type as SlotId to store the reference count // Use the same type as SlotId to store the reference count
// (there can never be more references than slots) // (there can never be more references than slots)
using references_type = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>::type; using references_type = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
using length_type = uint_t<ARDUINOJSON_STRING_LENGTH_SIZE * 8>::type; using length_type = uint_t<ARDUINOJSON_STRING_LENGTH_SIZE * 8>;
struct StringNode* next; struct StringNode* next;
references_type references; references_type references;

View File

@@ -11,7 +11,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantSlot; class VariantSlot;
using SlotId = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>::type; using SlotId = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
using SlotCount = SlotId; using SlotCount = SlotId;
const SlotId NULL_SLOT = SlotId(-1); const SlotId NULL_SLOT = SlotId(-1);

View File

@@ -291,8 +291,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type enable_if_t<sizeof(T) == 4, DeserializationError::Code> readFloat(
readFloat(VariantData* variant) { VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
T value; T value;
@@ -307,8 +307,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type enable_if_t<sizeof(T) == 8, DeserializationError::Code> readDouble(
readDouble(VariantData* variant) { VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
T value; T value;
@@ -323,8 +323,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type enable_if_t<sizeof(T) == 4, DeserializationError::Code> readDouble(
readDouble(VariantData* variant) { VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
uint8_t i[8]; // input is 8 bytes uint8_t i[8]; // input is 8 bytes
T value; // output is 4 bytes T value; // output is 4 bytes
@@ -547,9 +547,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
// Parses a MessagePack input and puts the result in a JsonDocument. // Parses a MessagePack input and puts the result in a JsonDocument.
// https://arduinojson.org/v7/api/msgpack/deserializemsgpack/ // https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
template <typename TDestination, typename... Args> template <typename TDestination, typename... Args>
typename detail::enable_if< detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
detail::is_deserialize_destination<TDestination>::value, DeserializationError>
DeserializationError>::type
deserializeMsgPack(TDestination&& dst, Args&&... args) { deserializeMsgPack(TDestination&& dst, Args&&... args) {
using namespace detail; using namespace detail;
return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst), return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst),
@@ -559,9 +558,8 @@ deserializeMsgPack(TDestination&& dst, Args&&... args) {
// Parses a MessagePack input and puts the result in a JsonDocument. // Parses a MessagePack input and puts the result in a JsonDocument.
// https://arduinojson.org/v7/api/msgpack/deserializemsgpack/ // https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
template <typename TDestination, typename TChar, typename... Args> template <typename TDestination, typename TChar, typename... Args>
typename detail::enable_if< detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
detail::is_deserialize_destination<TDestination>::value, DeserializationError>
DeserializationError>::type
deserializeMsgPack(TDestination&& dst, TChar* input, Args&&... args) { deserializeMsgPack(TDestination&& dst, TChar* input, Args&&... args) {
using namespace detail; using namespace detail;
return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst), return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst),

View File

@@ -23,9 +23,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
: writer_(writer), resources_(resources) {} : writer_(writer), resources_(resources) {}
template <typename T> template <typename T>
typename enable_if<is_floating_point<T>::value && sizeof(T) == 4, enable_if_t<is_floating_point<T>::value && sizeof(T) == 4, size_t> visit(
size_t>::type T value32) {
visit(T value32) {
if (canConvertNumber<JsonInteger>(value32)) { if (canConvertNumber<JsonInteger>(value32)) {
JsonInteger truncatedValue = JsonInteger(value32); JsonInteger truncatedValue = JsonInteger(value32);
if (value32 == T(truncatedValue)) if (value32 == T(truncatedValue))
@@ -38,8 +37,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
template <typename T> template <typename T>
ARDUINOJSON_NO_SANITIZE("float-cast-overflow") ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
typename enable_if<is_floating_point<T>::value && sizeof(T) == 8, enable_if_t<is_floating_point<T>::value && sizeof(T) == 8, size_t> visit(
size_t>::type visit(T value64) { T value64) {
float value32 = float(value64); float value32 = float(value64);
if (value32 == value64) if (value32 == value64)
return visit(value32); return visit(value32);

View File

@@ -77,17 +77,17 @@ struct FloatTraits<T, 8 /*64bits*/> {
template <typename TOut> // int64_t template <typename TOut> // int64_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value && enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TOut) == 8, sizeof(TOut) == 8,
signed>::type* = 0) { signed>* = 0) {
return forge(0x43DFFFFFFFFFFFFF); // 9.2233720368547748e+18 return forge(0x43DFFFFFFFFFFFFF); // 9.2233720368547748e+18
} }
template <typename TOut> // uint64_t template <typename TOut> // uint64_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value && enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) == 8, sizeof(TOut) == 8,
unsigned>::type* = 0) { unsigned>* = 0) {
return forge(0x43EFFFFFFFFFFFFF); // 1.8446744073709549568e+19 return forge(0x43EFFFFFFFFFFFFF); // 1.8446744073709549568e+19
} }
@@ -157,33 +157,33 @@ struct FloatTraits<T, 4 /*32bits*/> {
template <typename TOut> // int32_t template <typename TOut> // int32_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value && enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TOut) == 4, sizeof(TOut) == 4,
signed>::type* = 0) { signed>* = 0) {
return forge(0x4EFFFFFF); // 2.14748352E9 return forge(0x4EFFFFFF); // 2.14748352E9
} }
template <typename TOut> // uint32_t template <typename TOut> // uint32_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value && enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) == 4, sizeof(TOut) == 4,
unsigned>::type* = 0) { unsigned>* = 0) {
return forge(0x4F7FFFFF); // 4.29496704E9 return forge(0x4F7FFFFF); // 4.29496704E9
} }
template <typename TOut> // int64_t template <typename TOut> // int64_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value && enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TOut) == 8, sizeof(TOut) == 8,
signed>::type* = 0) { signed>* = 0) {
return forge(0x5EFFFFFF); // 9.22337148709896192E18 return forge(0x5EFFFFFF); // 9.22337148709896192E18
} }
template <typename TOut> // uint64_t template <typename TOut> // uint64_t
static T highest_for( static T highest_for(
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value && enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) == 8, sizeof(TOut) == 8,
unsigned>::type* = 0) { unsigned>* = 0) {
return forge(0x5F7FFFFF); // 1.844674297419792384E19 return forge(0x5F7FFFFF); // 1.844674297419792384E19
} }

View File

@@ -32,34 +32,34 @@ CompareResult arithmeticCompare(const T& lhs, const T& rhs) {
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value && enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
sizeof(T1) < sizeof(T2)>::type* = 0) { sizeof(T1) < sizeof(T2)>* = 0) {
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs); return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value && enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
sizeof(T2) < sizeof(T1)>::type* = 0) { sizeof(T2) < sizeof(T1)>* = 0) {
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs)); return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
} }
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value && enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
is_signed<T1>::value == is_signed<T2>::value && is_signed<T1>::value == is_signed<T2>::value &&
sizeof(T2) == sizeof(T1)>::type* = 0) { sizeof(T2) == sizeof(T1)>* = 0) {
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs)); return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
} }
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value && enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
is_unsigned<T1>::value && is_signed<T2>::value && is_unsigned<T1>::value && is_signed<T2>::value &&
sizeof(T2) == sizeof(T1)>::type* = 0) { sizeof(T2) == sizeof(T1)>* = 0) {
if (rhs < 0) if (rhs < 0)
return COMPARE_RESULT_GREATER; return COMPARE_RESULT_GREATER;
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs)); return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
@@ -68,9 +68,9 @@ CompareResult arithmeticCompare(
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_integral<T1>::value && is_integral<T2>::value && enable_if_t<is_integral<T1>::value && is_integral<T2>::value &&
is_signed<T1>::value && is_unsigned<T2>::value && is_signed<T1>::value && is_unsigned<T2>::value &&
sizeof(T2) == sizeof(T1)>::type* = 0) { sizeof(T2) == sizeof(T1)>* = 0) {
if (lhs < 0) if (lhs < 0)
return COMPARE_RESULT_LESS; return COMPARE_RESULT_LESS;
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs); return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
@@ -79,23 +79,21 @@ CompareResult arithmeticCompare(
template <typename T1, typename T2> template <typename T1, typename T2>
CompareResult arithmeticCompare( CompareResult arithmeticCompare(
const T1& lhs, const T2& rhs, const T1& lhs, const T2& rhs,
typename enable_if<is_floating_point<T1>::value || enable_if_t<is_floating_point<T1>::value || is_floating_point<T2>::value>* =
is_floating_point<T2>::value>::type* = 0) { 0) {
return arithmeticCompare<double>(static_cast<double>(lhs), return arithmeticCompare<double>(static_cast<double>(lhs),
static_cast<double>(rhs)); static_cast<double>(rhs));
} }
template <typename T2> template <typename T2>
CompareResult arithmeticCompareNegateLeft( CompareResult arithmeticCompareNegateLeft(
JsonUInt, const T2&, JsonUInt, const T2&, enable_if_t<is_unsigned<T2>::value>* = 0) {
typename enable_if<is_unsigned<T2>::value>::type* = 0) {
return COMPARE_RESULT_LESS; return COMPARE_RESULT_LESS;
} }
template <typename T2> template <typename T2>
CompareResult arithmeticCompareNegateLeft( CompareResult arithmeticCompareNegateLeft(
JsonUInt lhs, const T2& rhs, JsonUInt lhs, const T2& rhs, enable_if_t<is_signed<T2>::value>* = 0) {
typename enable_if<is_signed<T2>::value>::type* = 0) {
if (rhs > 0) if (rhs > 0)
return COMPARE_RESULT_LESS; return COMPARE_RESULT_LESS;
return arithmeticCompare(-rhs, static_cast<T2>(lhs)); return arithmeticCompare(-rhs, static_cast<T2>(lhs));
@@ -103,15 +101,13 @@ CompareResult arithmeticCompareNegateLeft(
template <typename T1> template <typename T1>
CompareResult arithmeticCompareNegateRight( CompareResult arithmeticCompareNegateRight(
const T1&, JsonUInt, const T1&, JsonUInt, enable_if_t<is_unsigned<T1>::value>* = 0) {
typename enable_if<is_unsigned<T1>::value>::type* = 0) {
return COMPARE_RESULT_GREATER; return COMPARE_RESULT_GREATER;
} }
template <typename T1> template <typename T1>
CompareResult arithmeticCompareNegateRight( CompareResult arithmeticCompareNegateRight(
const T1& lhs, JsonUInt rhs, const T1& lhs, JsonUInt rhs, enable_if_t<is_signed<T1>::value>* = 0) {
typename enable_if<is_signed<T1>::value>::type* = 0) {
if (lhs > 0) if (lhs > 0)
return COMPARE_RESULT_GREATER; return COMPARE_RESULT_GREATER;
return arithmeticCompare(static_cast<T1>(rhs), -lhs); return arithmeticCompare(static_cast<T1>(rhs), -lhs);

View File

@@ -22,18 +22,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// uint32 -> int32 // uint32 -> int32
// uint64 -> int32 // uint64 -> int32
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value && enable_if_t<is_integral<TIn>::value && is_unsigned<TIn>::value &&
is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn), is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
return value <= TIn(numeric_limits<TOut>::highest()); return value <= TIn(numeric_limits<TOut>::highest());
} }
// uint32 -> int64 // uint32 -> int64
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value && enable_if_t<is_integral<TIn>::value && is_unsigned<TIn>::value &&
is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut), is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
bool>::type bool>
canConvertNumber(TIn) { canConvertNumber(TIn) {
return true; return true;
} }
@@ -41,18 +41,17 @@ canConvertNumber(TIn) {
// uint32 -> float // uint32 -> float
// int32 -> float // int32 -> float
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_floating_point<TOut>::value, enable_if_t<is_integral<TIn>::value && is_floating_point<TOut>::value, bool>
bool>::type
canConvertNumber(TIn) { canConvertNumber(TIn) {
return true; return true;
} }
// int64 -> int32 // int64 -> int32
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value && enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_signed<TOut>::value && is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TOut) < sizeof(TIn), sizeof(TOut) < sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
return value >= TIn(numeric_limits<TOut>::lowest()) && return value >= TIn(numeric_limits<TOut>::lowest()) &&
value <= TIn(numeric_limits<TOut>::highest()); value <= TIn(numeric_limits<TOut>::highest());
@@ -61,10 +60,10 @@ canConvertNumber(TIn value) {
// int32 -> int32 // int32 -> int32
// int32 -> int64 // int32 -> int64
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value && enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_signed<TOut>::value && is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TIn) <= sizeof(TOut), sizeof(TIn) <= sizeof(TOut),
bool>::type bool>
canConvertNumber(TIn) { canConvertNumber(TIn) {
return true; return true;
} }
@@ -72,10 +71,10 @@ canConvertNumber(TIn) {
// int32 -> uint32 // int32 -> uint32
// int32 -> uint64 // int32 -> uint64
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value && enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_unsigned<TOut>::value && is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) >= sizeof(TIn), sizeof(TOut) >= sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
if (value < 0) if (value < 0)
return false; return false;
@@ -84,10 +83,10 @@ canConvertNumber(TIn value) {
// int32 -> uint16 // int32 -> uint16
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value && enable_if_t<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_unsigned<TOut>::value && is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) < sizeof(TIn), sizeof(TOut) < sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
if (value < 0) if (value < 0)
return false; return false;
@@ -97,9 +96,9 @@ canConvertNumber(TIn value) {
// float32 -> int16 // float32 -> int16
// float64 -> int32 // float64 -> int32
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value && enable_if_t<is_floating_point<TIn>::value && is_integral<TOut>::value &&
sizeof(TOut) < sizeof(TIn), sizeof(TOut) < sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
return value >= numeric_limits<TOut>::lowest() && return value >= numeric_limits<TOut>::lowest() &&
value <= numeric_limits<TOut>::highest(); value <= numeric_limits<TOut>::highest();
@@ -112,9 +111,9 @@ canConvertNumber(TIn value) {
// float64 -> int64 // float64 -> int64
// float64 -> uint64 // float64 -> uint64
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value && enable_if_t<is_floating_point<TIn>::value && is_integral<TOut>::value &&
sizeof(TOut) >= sizeof(TIn), sizeof(TOut) >= sizeof(TIn),
bool>::type bool>
canConvertNumber(TIn value) { canConvertNumber(TIn value) {
// Avoid error "9.22337e+18 is outside the range of representable values of // Avoid error "9.22337e+18 is outside the range of representable values of
// type 'long'" // type 'long'"

View File

@@ -16,11 +16,11 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename A, typename B> template <typename A, typename B>
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {}; using largest_type = conditional_t<(sizeof(A) > sizeof(B)), A, B>;
inline bool parseNumber(const char* s, VariantData& result) { inline bool parseNumber(const char* s, VariantData& result) {
typedef FloatTraits<JsonFloat> traits; typedef FloatTraits<JsonFloat> traits;
typedef choose_largest<traits::mantissa_type, JsonUInt>::type mantissa_t; typedef largest_type<traits::mantissa_type, JsonUInt> mantissa_t;
typedef traits::exponent_type exponent_t; typedef traits::exponent_type exponent_t;
ARDUINOJSON_ASSERT(s != 0); ARDUINOJSON_ASSERT(s != 0);

View File

@@ -102,8 +102,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, detail::enable_if_t<detail::IsString<TString>::value,
detail::MemberProxy<JsonObject, TString>>::type detail::MemberProxy<JsonObject, TString>>
operator[](const TString& key) const { operator[](const TString& key) const {
return {*this, key}; return {*this, key};
} }
@@ -111,8 +111,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, detail::enable_if_t<detail::IsString<TChar*>::value,
detail::MemberProxy<JsonObject, TChar*>>::type detail::MemberProxy<JsonObject, TChar*>>
operator[](TChar* key) const { operator[](TChar* key) const {
return {*this, key}; return {*this, key};
} }
@@ -120,8 +120,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
// https://arduinojson.org/v7/api/jsonobject/subscript/ // https://arduinojson.org/v7/api/jsonobject/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value,
detail::MemberProxy<JsonObject, const char*>>::type detail::MemberProxy<JsonObject, const char*>>
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<const char*>())
return {*this, key.template as<const char*>()}; return {*this, key.template as<const char*>()};
@@ -138,7 +138,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Removes the member with the specified key. // Removes the member with the specified key.
// https://arduinojson.org/v7/api/jsonobject/remove/ // https://arduinojson.org/v7/api/jsonobject/remove/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value>::type remove( detail::enable_if_t<detail::IsString<TString>::value> remove(
const TString& key) const { const TString& key) const {
detail::ObjectData::removeMember(data_, detail::adaptString(key), detail::ObjectData::removeMember(data_, detail::adaptString(key),
resources_); resources_);
@@ -147,7 +147,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Removes the member with the specified key. // Removes the member with the specified key.
// https://arduinojson.org/v7/api/jsonobject/remove/ // https://arduinojson.org/v7/api/jsonobject/remove/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value>::type remove( detail::enable_if_t<detail::IsVariant<TVariant>::value> remove(
const TVariant& key) const { const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<const char*>())
remove(key.template as<const char*>()); remove(key.template as<const char*>());
@@ -164,8 +164,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobject/containskey/ // https://arduinojson.org/v7/api/jsonobject/containskey/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, bool>::type detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
containsKey(const TString& key) const { const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@@ -173,8 +173,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobject/containskey/ // https://arduinojson.org/v7/api/jsonobject/containskey/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
containsKey(TChar* key) const { TChar* key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@@ -182,8 +182,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobject/containskey/ // https://arduinojson.org/v7/api/jsonobject/containskey/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, bool>::type detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
containsKey(const TVariant& key) const { const TVariant& key) const {
return containsKey(key.template as<const char*>()); return containsKey(key.template as<const char*>());
} }

View File

@@ -71,8 +71,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/ // https://arduinojson.org/v7/api/jsonobjectconst/containskey/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, bool>::type detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
containsKey(const TString& key) const { const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::ObjectData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@@ -88,16 +88,15 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/containskey/ // https://arduinojson.org/v7/api/jsonobjectconst/containskey/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, bool>::type detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
containsKey(const TVariant& key) const { const TVariant& key) const {
return containsKey(key.template as<const char*>()); return containsKey(key.template as<const char*>());
} }
// Gets the member with specified key. // Gets the member with specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/ // https://arduinojson.org/v7/api/jsonobjectconst/subscript/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::ObjectData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
@@ -107,8 +106,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Gets the member with specified key. // Gets the member with specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/ // https://arduinojson.org/v7/api/jsonobjectconst/subscript/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::ObjectData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
@@ -118,8 +116,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Gets the member with specified key. // Gets the member with specified key.
// https://arduinojson.org/v7/api/jsonobjectconst/subscript/ // https://arduinojson.org/v7/api/jsonobjectconst/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<const char*>()) if (key.template is<const char*>())
return operator[](key.template as<const char*>()); return operator[](key.template as<const char*>());

View File

@@ -11,21 +11,24 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <int Bits> template <int Bits>
struct uint_t; struct uint_;
template <> template <>
struct uint_t<8> { struct uint_<8> {
typedef uint8_t type; typedef uint8_t type;
}; };
template <> template <>
struct uint_t<16> { struct uint_<16> {
typedef uint16_t type; typedef uint16_t type;
}; };
template <> template <>
struct uint_t<32> { struct uint_<32> {
typedef uint32_t type; typedef uint32_t type;
}; };
template <int Bits>
using uint_t = typename uint_<Bits>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -18,7 +18,7 @@ template <typename T, typename Enable = void>
struct numeric_limits; struct numeric_limits;
template <typename T> template <typename T>
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> { struct numeric_limits<T, enable_if_t<is_unsigned<T>::value>> {
static constexpr T lowest() { static constexpr T lowest() {
return 0; return 0;
} }
@@ -29,7 +29,7 @@ struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
template <typename T> template <typename T>
struct numeric_limits< struct numeric_limits<
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> { T, enable_if_t<is_integral<T>::value && is_signed<T>::value>> {
static constexpr T lowest() { static constexpr T lowest() {
return T(T(1) << (sizeof(T) * 8 - 1)); return T(T(1) << (sizeof(T) * 8 - 1));
} }

View File

@@ -21,6 +21,6 @@
#include "type_traits/is_signed.hpp" #include "type_traits/is_signed.hpp"
#include "type_traits/is_unsigned.hpp" #include "type_traits/is_unsigned.hpp"
#include "type_traits/make_unsigned.hpp" #include "type_traits/make_unsigned.hpp"
#include "type_traits/make_void.hpp"
#include "type_traits/remove_const.hpp" #include "type_traits/remove_const.hpp"
#include "type_traits/remove_reference.hpp" #include "type_traits/remove_reference.hpp"
#include "type_traits/void_t.hpp"

View File

@@ -18,4 +18,8 @@ struct conditional<false, TrueType, FalseType> {
typedef FalseType type; typedef FalseType type;
}; };
template <bool Condition, class TrueType, class FalseType>
using conditional_t =
typename conditional<Condition, TrueType, FalseType>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -17,4 +17,7 @@ struct enable_if<true, T> {
typedef T type; typedef T type;
}; };
template <bool Condition, typename T = void>
using enable_if_t = typename enable_if<Condition, T>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -20,8 +20,8 @@ class is_base_of {
public: public:
static const bool value = static const bool value =
sizeof(probe(reinterpret_cast<typename remove_reference<TDerived>::type*>( sizeof(probe(reinterpret_cast<remove_reference_t<TDerived>*>(0))) ==
0))) == sizeof(int); sizeof(int);
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -12,9 +12,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <class T> template <class T>
struct is_floating_point struct is_floating_point
: integral_constant< : integral_constant<bool, //
bool, // is_same<float, remove_cv_t<T>>::value ||
is_same<float, typename remove_cv<T>::type>::value || is_same<double, remove_cv_t<T>>::value> {};
is_same<double, typename remove_cv<T>::type>::value> {};
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -15,18 +15,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// clang-format off // clang-format off
template <typename T> template <typename T>
struct is_integral : integral_constant<bool, struct is_integral : integral_constant<bool,
is_same<typename remove_cv<T>::type, signed char>::value || is_same<remove_cv_t<T>, signed char>::value ||
is_same<typename remove_cv<T>::type, unsigned char>::value || is_same<remove_cv_t<T>, unsigned char>::value ||
is_same<typename remove_cv<T>::type, signed short>::value || is_same<remove_cv_t<T>, signed short>::value ||
is_same<typename remove_cv<T>::type, unsigned short>::value || is_same<remove_cv_t<T>, unsigned short>::value ||
is_same<typename remove_cv<T>::type, signed int>::value || is_same<remove_cv_t<T>, signed int>::value ||
is_same<typename remove_cv<T>::type, unsigned int>::value || is_same<remove_cv_t<T>, unsigned int>::value ||
is_same<typename remove_cv<T>::type, signed long>::value || is_same<remove_cv_t<T>, signed long>::value ||
is_same<typename remove_cv<T>::type, unsigned long>::value || is_same<remove_cv_t<T>, unsigned long>::value ||
is_same<typename remove_cv<T>::type, signed long long>::value || is_same<remove_cv_t<T>, signed long long>::value ||
is_same<typename remove_cv<T>::type, unsigned long long>::value || is_same<remove_cv_t<T>, unsigned long long>::value ||
is_same<typename remove_cv<T>::type, char>::value || is_same<remove_cv_t<T>, char>::value ||
is_same<typename remove_cv<T>::type, bool>::value> {}; is_same<remove_cv_t<T>, bool>::value> {};
// clang-format on // clang-format on
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -13,14 +13,14 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// clang-format off // clang-format off
template <typename T> template <typename T>
struct is_signed : integral_constant<bool, struct is_signed : integral_constant<bool,
is_same<typename remove_cv<T>::type, char>::value || is_same<remove_cv_t<T>, char>::value ||
is_same<typename remove_cv<T>::type, signed char>::value || is_same<remove_cv_t<T>, signed char>::value ||
is_same<typename remove_cv<T>::type, signed short>::value || is_same<remove_cv_t<T>, signed short>::value ||
is_same<typename remove_cv<T>::type, signed int>::value || is_same<remove_cv_t<T>, signed int>::value ||
is_same<typename remove_cv<T>::type, signed long>::value || is_same<remove_cv_t<T>, signed long>::value ||
is_same<typename remove_cv<T>::type, signed long long>::value || is_same<remove_cv_t<T>, signed long long>::value ||
is_same<typename remove_cv<T>::type, float>::value || is_same<remove_cv_t<T>, float>::value ||
is_same<typename remove_cv<T>::type, double>::value> {}; is_same<remove_cv_t<T>, double>::value> {};
// clang-format on // clang-format on
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -13,12 +13,12 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// clang-format off // clang-format off
template <typename T> template <typename T>
struct is_unsigned : integral_constant<bool, struct is_unsigned : integral_constant<bool,
is_same<typename remove_cv<T>::type, unsigned char>::value || is_same<remove_cv_t<T>, unsigned char>::value ||
is_same<typename remove_cv<T>::type, unsigned short>::value || is_same<remove_cv_t<T>, unsigned short>::value ||
is_same<typename remove_cv<T>::type, unsigned int>::value || is_same<remove_cv_t<T>, unsigned int>::value ||
is_same<typename remove_cv<T>::type, unsigned long>::value || is_same<remove_cv_t<T>, unsigned long>::value ||
is_same<typename remove_cv<T>::type, unsigned long long>::value || is_same<remove_cv_t<T>, unsigned long long>::value ||
is_same<typename remove_cv<T>::type, bool>::value> {}; is_same<remove_cv_t<T>, bool>::value> {};
// clang-format on // clang-format on
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -38,4 +38,7 @@ struct make_unsigned<signed long long> : type_identity<unsigned long long> {};
template <> template <>
struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {}; struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
template <typename T>
using make_unsigned_t = typename make_unsigned<T>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -1,14 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#pragma once
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <class = void>
struct make_void {
typedef void type;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -18,4 +18,7 @@ struct remove_const<const T> {
typedef T type; typedef T type;
}; };
template <typename T>
using remove_const_t = typename remove_const<T>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -25,4 +25,7 @@ struct remove_cv<const volatile T> {
typedef T type; typedef T type;
}; };
template <typename T>
using remove_cv_t = typename remove_cv<T>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -18,4 +18,7 @@ struct remove_reference<T&> {
typedef T type; typedef T type;
}; };
template <typename T>
using remove_reference_t = typename remove_reference<T>::type;
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -0,0 +1,20 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename...>
struct make_void {
using type = void;
};
template <typename... Args>
using void_t = typename make_void<Args...>::type;
// NOTE: using void_t = void; doesn't work on GCC 4.8
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -11,13 +11,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
using nullptr_t = decltype(nullptr); using nullptr_t = decltype(nullptr);
template <class T> template <class T>
T&& forward(typename remove_reference<T>::type& t) noexcept { T&& forward(remove_reference_t<T>& t) noexcept {
return static_cast<T&&>(t); return static_cast<T&&>(t);
} }
template <class T> template <class T>
typename remove_reference<T>::type&& move(T&& t) { remove_reference_t<T>&& move(T&& t) {
return static_cast<typename remove_reference<T>::type&&>(t); return static_cast<remove_reference_t<T>&&>(t);
} }
// Polyfull for std::swap // Polyfull for std::swap

View File

@@ -9,9 +9,8 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDestination> template <typename TDestination>
class Writer< class Writer<TDestination,
TDestination, enable_if_t<is_base_of<::Print, TDestination>::value>> {
typename enable_if<is_base_of<::Print, TDestination>::value>::type> {
public: public:
explicit Writer(::Print& print) : print_(&print) {} explicit Writer(::Print& print) : print_(&print) {}

View File

@@ -9,9 +9,8 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDestination> template <typename TDestination>
class Writer< class Writer<TDestination,
TDestination, enable_if_t<is_base_of<std::ostream, TDestination>::value>> {
typename enable_if<is_base_of<std::ostream, TDestination>::value>::type> {
public: public:
explicit Writer(std::ostream& os) : os_(&os) {} explicit Writer(std::ostream& os) : os_(&os) {}

View File

@@ -14,13 +14,12 @@ struct is_std_string : false_type {};
template <class T> template <class T>
struct is_std_string< struct is_std_string<
T, typename enable_if<is_same<void, decltype(T().push_back('a'))>::value && T, enable_if_t<is_same<void, decltype(T().push_back('a'))>::value &&
is_same<T&, decltype(T().append(""))>::value>::type> is_same<T&, decltype(T().append(""))>::value>> : true_type {
: true_type {}; };
template <typename TDestination> template <typename TDestination>
class Writer<TDestination, class Writer<TDestination, enable_if_t<is_std_string<TDestination>::value>> {
typename enable_if<is_std_string<TDestination>::value>::type> {
public: public:
Writer(TDestination& str) : str_(&str) { Writer(TDestination& str) : str_(&str) {
str.clear(); str.clear();

View File

@@ -23,17 +23,15 @@ size_t serialize(ArduinoJson::JsonVariantConst source,
} }
template <template <typename> class TSerializer> template <template <typename> class TSerializer>
typename enable_if<!TSerializer<StaticStringWriter>::producesText, size_t>::type enable_if_t<!TSerializer<StaticStringWriter>::producesText, size_t> serialize(
serialize(ArduinoJson::JsonVariantConst source, void* buffer, ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
size_t bufferSize) {
StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize); StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
return doSerialize<TSerializer>(source, writer); return doSerialize<TSerializer>(source, writer);
} }
template <template <typename> class TSerializer> template <template <typename> class TSerializer>
typename enable_if<TSerializer<StaticStringWriter>::producesText, size_t>::type enable_if_t<TSerializer<StaticStringWriter>::producesText, size_t> serialize(
serialize(ArduinoJson::JsonVariantConst source, void* buffer, ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
size_t bufferSize) {
StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize); StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
size_t n = doSerialize<TSerializer>(source, writer); size_t n = doSerialize<TSerializer>(source, writer);
// add null-terminator for text output (not counted in the size) // add null-terminator for text output (not counted in the size)
@@ -43,7 +41,7 @@ serialize(ArduinoJson::JsonVariantConst source, void* buffer,
} }
template <template <typename> class TSerializer, typename TChar, size_t N> template <template <typename> class TSerializer, typename TChar, size_t N>
typename enable_if<IsChar<TChar>::value, size_t>::type serialize( enable_if_t<IsChar<TChar>::value, size_t> serialize(
ArduinoJson::JsonVariantConst source, TChar (&buffer)[N]) { ArduinoJson::JsonVariantConst source, TChar (&buffer)[N]) {
return serialize<TSerializer>(source, buffer, N); return serialize<TSerializer>(source, buffer, N);
} }

View File

@@ -62,7 +62,7 @@ class ZeroTerminatedRamString {
}; };
template <typename TChar> template <typename TChar>
struct StringAdapter<TChar*, typename enable_if<IsChar<TChar>::value>::type> { struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; typedef ZeroTerminatedRamString AdaptedString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
@@ -71,7 +71,7 @@ struct StringAdapter<TChar*, typename enable_if<IsChar<TChar>::value>::type> {
}; };
template <typename TChar, size_t N> template <typename TChar, size_t N>
struct StringAdapter<TChar[N], typename enable_if<IsChar<TChar>::value>::type> { struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
typedef ZeroTerminatedRamString AdaptedString; typedef ZeroTerminatedRamString AdaptedString;
static AdaptedString adapt(const TChar* p) { static AdaptedString adapt(const TChar* p) {
@@ -131,8 +131,7 @@ class SizedRamString {
}; };
template <typename TChar> template <typename TChar>
struct SizedStringAdapter<TChar*, struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
typename enable_if<IsChar<TChar>::value>::type> {
typedef SizedRamString AdaptedString; typedef SizedRamString AdaptedString;
static AdaptedString adapt(const TChar* p, size_t n) { static AdaptedString adapt(const TChar* p, size_t n) {

View File

@@ -13,9 +13,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename T> template <typename T>
struct StringAdapter< struct StringAdapter<
T, T,
typename enable_if< enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
(string_traits<T>::has_cstr || string_traits<T>::has_data) && (string_traits<T>::has_length || string_traits<T>::has_size)>> {
(string_traits<T>::has_length || string_traits<T>::has_size)>::type> {
typedef SizedRamString AdaptedString; typedef SizedRamString AdaptedString;
static AdaptedString adapt(const T& s) { static AdaptedString adapt(const T& s) {
@@ -24,26 +23,24 @@ struct StringAdapter<
private: private:
template <typename U> template <typename U>
static typename enable_if<string_traits<U>::has_size, size_t>::type get_size( static enable_if_t<string_traits<U>::has_size, size_t> get_size(const U& s) {
const U& s) {
return s.size(); return s.size();
} }
template <typename U> template <typename U>
static typename enable_if<!string_traits<U>::has_size, size_t>::type get_size( static enable_if_t<!string_traits<U>::has_size, size_t> get_size(const U& s) {
const U& s) {
return s.length(); return s.length();
} }
template <typename U> template <typename U>
static typename enable_if<string_traits<U>::has_data, const char*>::type static enable_if_t<string_traits<U>::has_data, const char*> get_data(
get_data(const U& s) { const U& s) {
return s.data(); return s.data();
} }
template <typename U> template <typename U>
static typename enable_if<!string_traits<U>::has_data, const char*>::type static enable_if_t<!string_traits<U>::has_data, const char*> get_data(
get_data(const U& s) { const U& s) {
return s.c_str(); return s.c_str();
} }
}; };

View File

@@ -13,8 +13,7 @@ template <typename T, typename Enable = void>
struct IsString : false_type {}; struct IsString : false_type {};
template <typename T> template <typename T>
struct IsString< struct IsString<T, void_t<typename StringAdapter<T>::AdaptedString>>
T, typename make_void<typename StringAdapter<T>::AdaptedString>::type>
: true_type {}; : true_type {};
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -16,8 +16,7 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TAdaptedString1, typename TAdaptedString2> template <typename TAdaptedString1, typename TAdaptedString2>
typename enable_if<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, enable_if_t<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, int>
int>::type
stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
ARDUINOJSON_ASSERT(!s1.isNull()); ARDUINOJSON_ASSERT(!s1.isNull());
ARDUINOJSON_ASSERT(!s2.isNull()); ARDUINOJSON_ASSERT(!s2.isNull());
@@ -36,15 +35,13 @@ stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
} }
template <typename TAdaptedString1, typename TAdaptedString2> template <typename TAdaptedString1, typename TAdaptedString2>
typename enable_if< enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int>
(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int>::type
stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) {
return -stringCompare(s2, s1); return -stringCompare(s2, s1);
} }
template <typename TAdaptedString1, typename TAdaptedString2> template <typename TAdaptedString1, typename TAdaptedString2>
typename enable_if<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, enable_if_t<TAdaptedString1::typeSortKey <= TAdaptedString2::typeSortKey, bool>
bool>::type
stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
ARDUINOJSON_ASSERT(!s1.isNull()); ARDUINOJSON_ASSERT(!s1.isNull());
ARDUINOJSON_ASSERT(!s2.isNull()); ARDUINOJSON_ASSERT(!s2.isNull());
@@ -60,8 +57,7 @@ stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
} }
template <typename TAdaptedString1, typename TAdaptedString2> template <typename TAdaptedString1, typename TAdaptedString2>
typename enable_if< enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool>
(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool>::type
stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) {
return stringEquals(s2, s1); return stringEquals(s2, s1);
} }

View File

@@ -19,10 +19,8 @@ template <class T, class = void>
struct has_cstr : false_type {}; struct has_cstr : false_type {};
template <class T> template <class T>
struct has_cstr<T, struct has_cstr<T, enable_if_t<is_same<decltype(declval<const T>().c_str()),
typename enable_if<is_same<decltype(declval<const T>().c_str()), const char*>::value>> : true_type {};
const char*>::value>::type>
: true_type {};
// const char* data() const // const char* data() const
// - std::string // - std::string
@@ -33,10 +31,8 @@ template <class T, class = void>
struct has_data : false_type {}; struct has_data : false_type {};
template <class T> template <class T>
struct has_data<T, struct has_data<T, enable_if_t<is_same<decltype(declval<const T>().data()),
typename enable_if<is_same<decltype(declval<const T>().data()), const char*>::value>> : true_type {};
const char*>::value>::type>
: true_type {};
// unsigned int length() const // unsigned int length() const
// - String // - String
@@ -45,8 +41,8 @@ template <class T, class = void>
struct has_length : false_type {}; struct has_length : false_type {};
template <class T> template <class T>
struct has_length<T, typename enable_if<is_unsigned< struct has_length<
decltype(declval<const T>().length())>::value>::type> T, enable_if_t<is_unsigned<decltype(declval<const T>().length())>::value>>
: true_type {}; : true_type {};
// size_t size() const // size_t size() const
@@ -59,8 +55,7 @@ struct has_size : false_type {};
template <class T> template <class T>
struct has_size< struct has_size<
T, typename enable_if< T, enable_if_t<is_same<decltype(declval<const T>().size()), size_t>::value>>
is_same<decltype(declval<const T>().size()), size_t>::value>::type>
: true_type {}; : true_type {};
} // namespace string_traits_impl } // namespace string_traits_impl

View File

@@ -54,10 +54,9 @@ struct Converter {
}; };
template <typename T> template <typename T>
struct Converter< struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
T, typename detail::enable_if<detail::is_integral<T>::value && !detail::is_same<bool, T>::value &&
!detail::is_same<bool, T>::value && !detail::is_same<char, T>::value>>
!detail::is_same<char, T>::value>::type>
: 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);
@@ -81,7 +80,7 @@ struct Converter<
}; };
template <typename T> template <typename T>
struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type> struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
: private detail::VariantAttorney { : private detail::VariantAttorney {
static bool toJson(T src, JsonVariant dst) { static bool toJson(T src, JsonVariant dst) {
return dst.set(static_cast<JsonInteger>(src)); return dst.set(static_cast<JsonInteger>(src));
@@ -120,8 +119,7 @@ struct Converter<bool> : private detail::VariantAttorney {
}; };
template <typename T> template <typename T>
struct Converter< struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
: private detail::VariantAttorney { : private detail::VariantAttorney {
static bool toJson(T src, JsonVariant dst) { static bool toJson(T src, JsonVariant dst) {
auto data = getData(dst); auto data = getData(dst);
@@ -179,8 +177,8 @@ struct Converter<JsonString> : private detail::VariantAttorney {
}; };
template <typename T> template <typename T>
inline typename detail::enable_if<detail::IsString<T>::value>::type inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
convertToJson(const T& src, JsonVariant dst) { const T& src, JsonVariant dst) {
using namespace detail; using namespace detail;
auto data = VariantAttorney::getData(dst); auto data = VariantAttorney::getData(dst);
auto resources = VariantAttorney::getResourceManager(dst); auto resources = VariantAttorney::getResourceManager(dst);

View File

@@ -68,32 +68,28 @@ class JsonVariantConst : public detail::VariantTag,
// Casts the value to the specified type. // Casts the value to the specified type.
// https://arduinojson.org/v7/api/jsonvariantconst/as/ // https://arduinojson.org/v7/api/jsonvariantconst/as/
template <typename T> template <typename T>
typename detail::enable_if<ConversionSupported<T>::value, T>::type as() detail::enable_if_t<ConversionSupported<T>::value, T> as() const {
const {
return Converter<T>::fromJson(*this); return Converter<T>::fromJson(*this);
} }
// Casts the value to the specified type. // Casts the value to the specified type.
// https://arduinojson.org/v7/api/jsonvariantconst/as/ // https://arduinojson.org/v7/api/jsonvariantconst/as/
template <typename T> template <typename T>
typename detail::enable_if< detail::enable_if_t<!ConversionSupported<T>::value,
!ConversionSupported<T>::value, detail::InvalidConversion<JsonVariantConst, T>>
detail::InvalidConversion<JsonVariantConst, T>>::type
as() const; as() const;
// Returns true if the value is of the specified type. // Returns true if the value is of the specified type.
// https://arduinojson.org/v7/api/jsonvariantconst/is/ // https://arduinojson.org/v7/api/jsonvariantconst/is/
template <typename T> template <typename T>
typename detail::enable_if<ConversionSupported<T>::value, bool>::type is() detail::enable_if_t<ConversionSupported<T>::value, bool> is() const {
const {
return Converter<T>::checkJson(*this); return Converter<T>::checkJson(*this);
} }
// Always returns false for the unsupported types. // Always returns false for the unsupported types.
// https://arduinojson.org/v7/api/jsonvariantconst/is/ // https://arduinojson.org/v7/api/jsonvariantconst/is/
template <typename T> template <typename T>
typename detail::enable_if<!ConversionSupported<T>::value, bool>::type is() detail::enable_if_t<!ConversionSupported<T>::value, bool> is() const {
const {
return false; return false;
} }
@@ -105,8 +101,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets array's element at specified index. // Gets array's element at specified index.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename T> template <typename T>
typename detail::enable_if<detail::is_integral<T>::value, detail::enable_if_t<detail::is_integral<T>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](T index) const { operator[](T index) const {
return JsonVariantConst( return JsonVariantConst(
detail::VariantData::getElement(data_, size_t(index), resources_), detail::VariantData::getElement(data_, size_t(index), resources_),
@@ -116,8 +111,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets object's member with specified key. // Gets object's member with specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, detail::enable_if_t<detail::IsString<TString>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(detail::VariantData::getMember( return JsonVariantConst(detail::VariantData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
@@ -127,8 +121,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets object's member with specified key. // Gets object's member with specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, detail::enable_if_t<detail::IsString<TChar*>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(detail::VariantData::getMember( return JsonVariantConst(detail::VariantData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
@@ -139,8 +132,7 @@ class JsonVariantConst : public detail::VariantTag,
// specified index. // specified index.
// https://arduinojson.org/v7/api/jsonvariantconst/subscript/ // https://arduinojson.org/v7/api/jsonvariantconst/subscript/
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
JsonVariantConst>::type
operator[](const TVariant& key) const { operator[](const TVariant& key) const {
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
@@ -151,8 +143,8 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if tge object contains the specified key. // Returns true if tge object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/ // https://arduinojson.org/v7/api/jsonvariantconst/containskey/
template <typename TString> template <typename TString>
typename detail::enable_if<detail::IsString<TString>::value, bool>::type detail::enable_if_t<detail::IsString<TString>::value, bool> containsKey(
containsKey(const TString& key) const { const TString& key) const {
return detail::VariantData::getMember(getData(), detail::adaptString(key), return detail::VariantData::getMember(getData(), detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
@@ -160,15 +152,15 @@ class JsonVariantConst : public detail::VariantTag,
// Returns true if tge object contains the specified key. // Returns true if tge object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariantconst/containskey/ // https://arduinojson.org/v7/api/jsonvariantconst/containskey/
template <typename TChar> template <typename TChar>
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type detail::enable_if_t<detail::IsString<TChar*>::value, bool> containsKey(
containsKey(TChar* key) const { TChar* key) const {
return detail::VariantData::getMember(getData(), detail::adaptString(key), return detail::VariantData::getMember(getData(), detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
template <typename TVariant> template <typename TVariant>
typename detail::enable_if<detail::IsVariant<TVariant>::value, bool>::type detail::enable_if_t<detail::IsVariant<TVariant>::value, bool> containsKey(
containsKey(const TVariant& key) const { const TVariant& key) const {
return containsKey(key.template as<const char*>()); return containsKey(key.template as<const char*>());
} }

View File

@@ -19,8 +19,7 @@ template <typename T, typename Enable = void>
struct Comparer; struct Comparer;
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<IsString<T>::value>::type> struct Comparer<T, enable_if_t<IsString<T>::value>> : ComparerBase {
: ComparerBase {
T rhs; // TODO: store adapted string? T rhs; // TODO: store adapted string?
explicit Comparer(T value) : rhs(value) {} explicit Comparer(T value) : rhs(value) {}
@@ -46,8 +45,8 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type>
}; };
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<is_integral<T>::value || struct Comparer<
is_floating_point<T>::value>::type> T, enable_if_t<is_integral<T>::value || is_floating_point<T>::value>>
: ComparerBase { : ComparerBase {
T rhs; T rhs;
@@ -200,8 +199,8 @@ struct VariantComparer : ComparerBase {
}; };
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<is_convertible< struct Comparer<
T, ArduinoJson::JsonVariantConst>::value>::type> 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(static_cast<JsonVariantConst>(value)) {}

View File

@@ -338,13 +338,13 @@ class VariantData {
} }
template <typename T> template <typename T>
typename enable_if<is_signed<T>::value>::type setInteger(T value) { enable_if_t<is_signed<T>::value> setInteger(T value) {
setType(VALUE_IS_SIGNED_INTEGER); setType(VALUE_IS_SIGNED_INTEGER);
content_.asSignedInteger = value; content_.asSignedInteger = value;
} }
template <typename T> template <typename T>
typename enable_if<is_unsigned<T>::value>::type setInteger(T value) { enable_if_t<is_unsigned<T>::value> setInteger(T value) {
setType(VALUE_IS_UNSIGNED_INTEGER); setType(VALUE_IS_UNSIGNED_INTEGER);
content_.asUnsignedInteger = static_cast<JsonUInt>(value); content_.asUnsignedInteger = static_cast<JsonUInt>(value);
} }

View File

@@ -31,9 +31,8 @@ struct VariantOperators : VariantOperatorTag {
// float operator|(JsonVariant, float) // float operator|(JsonVariant, float)
// bool operator|(JsonVariant, bool) // bool operator|(JsonVariant, bool)
template <typename T> template <typename T>
friend friend enable_if_t<!IsVariant<T>::value && !is_array<T>::value, T> operator|(
typename enable_if<!IsVariant<T>::value && !is_array<T>::value, T>::type const TVariant& variant, const T& defaultValue) {
operator|(const TVariant& variant, const T& defaultValue) {
if (variant.template is<T>()) if (variant.template is<T>())
return variant.template as<T>(); return variant.template as<T>();
else else
@@ -51,8 +50,8 @@ struct VariantOperators : VariantOperatorTag {
// //
// JsonVariant operator|(JsonVariant, JsonVariant) // JsonVariant operator|(JsonVariant, JsonVariant)
template <typename T> template <typename T>
friend typename enable_if<IsVariant<T>::value, JsonVariantConst>::type friend enable_if_t<IsVariant<T>::value, JsonVariantConst> operator|(
operator|(const TVariant& variant, T defaultValue) { const TVariant& variant, T defaultValue) {
if (variant) if (variant)
return variant; return variant;
else else
@@ -75,9 +74,8 @@ struct VariantOperators : VariantOperatorTag {
return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; return compare(lhs, rhs) == COMPARE_RESULT_EQUAL;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type operator==(TVariant lhs, const T& rhs) {
operator==(TVariant lhs, const T& rhs) {
return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; return compare(lhs, rhs) == COMPARE_RESULT_EQUAL;
} }
@@ -97,9 +95,8 @@ struct VariantOperators : VariantOperatorTag {
return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; return compare(lhs, rhs) != COMPARE_RESULT_EQUAL;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type operator!=(TVariant lhs, const T& rhs) {
operator!=(TVariant lhs, const T& rhs) {
return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; return compare(lhs, rhs) != COMPARE_RESULT_EQUAL;
} }
@@ -119,9 +116,8 @@ struct VariantOperators : VariantOperatorTag {
return compare(lhs, rhs) == COMPARE_RESULT_LESS; return compare(lhs, rhs) == COMPARE_RESULT_LESS;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool> operator<(
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type TVariant lhs, const T& rhs) {
operator<(TVariant lhs, const T& rhs) {
return compare(lhs, rhs) == COMPARE_RESULT_LESS; return compare(lhs, rhs) == COMPARE_RESULT_LESS;
} }
@@ -141,9 +137,8 @@ struct VariantOperators : VariantOperatorTag {
return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type operator<=(TVariant lhs, const T& rhs) {
operator<=(TVariant lhs, const T& rhs) {
return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0;
} }
@@ -163,9 +158,8 @@ struct VariantOperators : VariantOperatorTag {
return compare(lhs, rhs) == COMPARE_RESULT_GREATER; return compare(lhs, rhs) == COMPARE_RESULT_GREATER;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool> operator>(
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type TVariant lhs, const T& rhs) {
operator>(TVariant lhs, const T& rhs) {
return compare(lhs, rhs) == COMPARE_RESULT_GREATER; return compare(lhs, rhs) == COMPARE_RESULT_GREATER;
} }
@@ -185,9 +179,8 @@ struct VariantOperators : VariantOperatorTag {
return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0;
} }
template <typename T> template <typename T>
friend friend enable_if_t<!is_base_of<VariantOperatorTag, T>::value, bool>
typename enable_if<!is_base_of<VariantOperatorTag, T>::value, bool>::type operator>=(TVariant lhs, const T& rhs) {
operator>=(TVariant lhs, const T& rhs) {
return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0;
} }
}; };

View File

@@ -48,8 +48,7 @@ class VariantRefBase : public VariantTag {
template <typename T> template <typename T>
T as() const; T as() const;
template <typename T, template <typename T, typename = enable_if_t<!is_same<T, TDerived>::value>>
typename = typename enable_if<!is_same<T, TDerived>::value>::type>
operator T() const { operator T() const {
return as<T>(); return as<T>();
} }
@@ -57,19 +56,17 @@ class VariantRefBase : public VariantTag {
// Sets the value to an empty array. // Sets the value to an empty array.
// https://arduinojson.org/v7/api/jsonvariant/to/ // https://arduinojson.org/v7/api/jsonvariant/to/
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type to() const; enable_if_t<is_same<T, JsonArray>::value, JsonArray> to() const;
// Sets the value to an empty object. // Sets the value to an empty object.
// https://arduinojson.org/v7/api/jsonvariant/to/ // https://arduinojson.org/v7/api/jsonvariant/to/
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type to() enable_if_t<is_same<T, JsonObject>::value, JsonObject> to() const;
const;
// Sets the value to null. // Sets the value to null.
// https://arduinojson.org/v7/api/jsonvariant/to/ // https://arduinojson.org/v7/api/jsonvariant/to/
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type to() enable_if_t<is_same<T, JsonVariant>::value, JsonVariant> to() const;
const;
// Returns true if the value is of the specified type. // Returns true if the value is of the specified type.
// https://arduinojson.org/v7/api/jsonvariant/is/ // https://arduinojson.org/v7/api/jsonvariant/is/
@@ -80,7 +77,7 @@ class VariantRefBase : public VariantTag {
// 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); return doSet<Converter<remove_cv_t<T>>>(value);
} }
// Copies the specified value. // Copies the specified value.
@@ -106,7 +103,7 @@ class VariantRefBase : public VariantTag {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonvariant/add/ // https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T> template <typename T>
typename enable_if<!is_same<T, JsonVariant>::value, T>::type add() const { enable_if_t<!is_same<T, JsonVariant>::value, T> add() const {
return add<JsonVariant>().template to<T>(); return add<JsonVariant>().template to<T>();
} }
@@ -114,7 +111,7 @@ class VariantRefBase : public VariantTag {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v7/api/jsonvariant/add/ // https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, T>::type add() const; enable_if_t<is_same<T, JsonVariant>::value, T> add() const;
// 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/
@@ -139,7 +136,7 @@ class VariantRefBase : public VariantTag {
// 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> template <typename TChar>
typename enable_if<IsString<TChar*>::value>::type remove(TChar* key) const { enable_if_t<IsString<TChar*>::value> remove(TChar* key) const {
VariantData::removeMember(getData(), adaptString(key), VariantData::removeMember(getData(), adaptString(key),
getResourceManager()); getResourceManager());
} }
@@ -147,8 +144,7 @@ class VariantRefBase : public VariantTag {
// 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> template <typename TString>
typename enable_if<IsString<TString>::value>::type remove( enable_if_t<IsString<TString>::value> remove(const TString& key) const {
const TString& key) const {
VariantData::removeMember(getData(), adaptString(key), VariantData::removeMember(getData(), adaptString(key),
getResourceManager()); getResourceManager());
} }
@@ -156,8 +152,7 @@ class VariantRefBase : public VariantTag {
// Removes a member of the object or an element of the array. // Removes a member of the object or an element of the array.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
template <typename TVariant> template <typename TVariant>
typename enable_if<IsVariant<TVariant>::value>::type remove( enable_if_t<IsVariant<TVariant>::value> remove(const TVariant& key) const {
const TVariant& key) const {
if (key.template is<size_t>()) if (key.template is<size_t>())
remove(key.template as<size_t>()); remove(key.template as<size_t>());
else else
@@ -171,40 +166,39 @@ class VariantRefBase : public VariantTag {
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariant/containskey/ // https://arduinojson.org/v7/api/jsonvariant/containskey/
template <typename TString> template <typename TString>
typename enable_if<IsString<TString>::value, bool>::type containsKey( enable_if_t<IsString<TString>::value, bool> containsKey(
const TString& key) const; const TString& key) const;
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariant/containskey/ // https://arduinojson.org/v7/api/jsonvariant/containskey/
template <typename TChar> template <typename TChar>
typename enable_if<IsString<TChar*>::value, bool>::type containsKey( enable_if_t<IsString<TChar*>::value, bool> containsKey(TChar* key) const;
TChar* key) const;
// Returns true if the object contains the specified key. // Returns true if the object contains the specified key.
// https://arduinojson.org/v7/api/jsonvariant/containskey/ // https://arduinojson.org/v7/api/jsonvariant/containskey/
template <typename TVariant> template <typename TVariant>
typename enable_if<IsVariant<TVariant>::value, bool>::type containsKey( enable_if_t<IsVariant<TVariant>::value, bool> containsKey(
const TVariant& key) const; const TVariant& key) const;
// Gets or sets an object member. // Gets or sets an object member.
// https://arduinojson.org/v7/api/jsonvariant/subscript/ // https://arduinojson.org/v7/api/jsonvariant/subscript/
template <typename TString> template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, FORCE_INLINE
MemberProxy<TDerived, TString>>::type enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
operator[](const TString& key) const; operator[](const TString& key) const;
// Gets or sets an object member. // Gets or sets an object member.
// https://arduinojson.org/v7/api/jsonvariant/subscript/ // https://arduinojson.org/v7/api/jsonvariant/subscript/
template <typename TChar> template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value, FORCE_INLINE
MemberProxy<TDerived, TChar*>>::type enable_if_t<IsString<TChar*>::value, MemberProxy<TDerived, TChar*>>
operator[](TChar* key) const; operator[](TChar* key) const;
// Gets an object member or an array element. // Gets an object member or an array element.
// https://arduinojson.org/v7/api/jsonvariant/subscript/ // https://arduinojson.org/v7/api/jsonvariant/subscript/
template <typename TVariant> template <typename TVariant>
typename enable_if<IsVariant<TVariant>::value, JsonVariantConst>::type enable_if_t<IsVariant<TVariant>::value, JsonVariantConst> operator[](
operator[](const TVariant& key) const { const TVariant& key) const {
if (key.template is<size_t>()) if (key.template is<size_t>())
return operator[](key.template as<size_t>()); return operator[](key.template as<size_t>());
else else
@@ -283,14 +277,14 @@ class VariantRefBase : public VariantTag {
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<is_same<T, JsonVariantConst>::value, T>::type FORCE_INLINE enable_if_t<is_same<T, JsonVariantConst>::value, T> getVariant()
getVariant() const { const {
return getVariantConst(); return getVariantConst();
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<is_same<T, JsonVariant>::value, T>::type FORCE_INLINE enable_if_t<is_same<T, JsonVariant>::value, T> getVariant()
getVariant() const { const {
return getVariant(); return getVariant();
} }

View File

@@ -68,7 +68,7 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
template <typename TDerived> template <typename TDerived>
template <typename T> template <typename T>
inline typename enable_if<is_same<T, JsonVariant>::value, T>::type inline enable_if_t<is_same<T, JsonVariant>::value, T>
VariantRefBase<TDerived>::add() const { VariantRefBase<TDerived>::add() const {
return JsonVariant( return JsonVariant(
detail::VariantData::addElement(getOrCreateData(), getResourceManager()), detail::VariantData::addElement(getOrCreateData(), getResourceManager()),
@@ -77,7 +77,7 @@ VariantRefBase<TDerived>::add() const {
template <typename TDerived> template <typename TDerived>
template <typename TString> template <typename TString>
inline typename enable_if<IsString<TString>::value, bool>::type inline enable_if_t<IsString<TString>::value, bool>
VariantRefBase<TDerived>::containsKey(const TString& key) const { VariantRefBase<TDerived>::containsKey(const TString& key) const {
return VariantData::getMember(getData(), adaptString(key), return VariantData::getMember(getData(), adaptString(key),
getResourceManager()) != 0; getResourceManager()) != 0;
@@ -85,7 +85,7 @@ VariantRefBase<TDerived>::containsKey(const TString& key) const {
template <typename TDerived> template <typename TDerived>
template <typename TChar> template <typename TChar>
inline typename enable_if<IsString<TChar*>::value, bool>::type inline enable_if_t<IsString<TChar*>::value, bool>
VariantRefBase<TDerived>::containsKey(TChar* key) const { VariantRefBase<TDerived>::containsKey(TChar* key) const {
return VariantData::getMember(getData(), adaptString(key), return VariantData::getMember(getData(), adaptString(key),
getResourceManager()) != 0; getResourceManager()) != 0;
@@ -93,7 +93,7 @@ VariantRefBase<TDerived>::containsKey(TChar* key) const {
template <typename TDerived> template <typename TDerived>
template <typename TVariant> template <typename TVariant>
inline typename enable_if<IsVariant<TVariant>::value, bool>::type inline enable_if_t<IsVariant<TVariant>::value, bool>
VariantRefBase<TDerived>::containsKey(const TVariant& key) const { VariantRefBase<TDerived>::containsKey(const TVariant& key) const {
return containsKey(key.template as<const char*>()); return containsKey(key.template as<const char*>());
} }
@@ -124,16 +124,14 @@ inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[](
template <typename TDerived> template <typename TDerived>
template <typename TString> template <typename TString>
inline typename enable_if<IsString<TString*>::value, inline enable_if_t<IsString<TString*>::value, MemberProxy<TDerived, TString*>>
MemberProxy<TDerived, TString*>>::type
VariantRefBase<TDerived>::operator[](TString* key) const { VariantRefBase<TDerived>::operator[](TString* key) const {
return MemberProxy<TDerived, TString*>(derived(), key); return MemberProxy<TDerived, TString*>(derived(), key);
} }
template <typename TDerived> template <typename TDerived>
template <typename TString> template <typename TString>
inline typename enable_if<IsString<TString>::value, inline enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
MemberProxy<TDerived, TString>>::type
VariantRefBase<TDerived>::operator[](const TString& key) const { VariantRefBase<TDerived>::operator[](const TString& key) const {
return MemberProxy<TDerived, TString>(derived(), key); return MemberProxy<TDerived, TString>(derived(), key);
} }
@@ -154,7 +152,7 @@ inline bool VariantRefBase<TDerived>::doSet(T&& value, true_type) const {
template <typename TDerived> template <typename TDerived>
template <typename T> template <typename T>
inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type inline enable_if_t<is_same<T, JsonArray>::value, JsonArray>
VariantRefBase<TDerived>::to() const { VariantRefBase<TDerived>::to() const {
return JsonArray( return JsonArray(
VariantData::toArray(getOrCreateData(), getResourceManager()), VariantData::toArray(getOrCreateData(), getResourceManager()),
@@ -163,7 +161,7 @@ VariantRefBase<TDerived>::to() const {
template <typename TDerived> template <typename TDerived>
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type enable_if_t<is_same<T, JsonObject>::value, JsonObject>
VariantRefBase<TDerived>::to() const { VariantRefBase<TDerived>::to() const {
return JsonObject( return JsonObject(
VariantData::toObject(getOrCreateData(), getResourceManager()), VariantData::toObject(getOrCreateData(), getResourceManager()),
@@ -172,7 +170,7 @@ VariantRefBase<TDerived>::to() const {
template <typename TDerived> template <typename TDerived>
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type enable_if_t<is_same<T, JsonVariant>::value, JsonVariant>
VariantRefBase<TDerived>::to() const { VariantRefBase<TDerived>::to() const {
auto data = getOrCreateData(); auto data = getOrCreateData();
auto resources = getResourceManager(); auto resources = getResourceManager();