Sfoglia il codice sorgente

Add helpers for type traits, such as `enable_if_t`

Benoit Blanchon 1 anno fa
parent
commit
1db803bcd3
58 ha cambiato i file con 376 aggiunte e 430 eliminazioni
  1. 7 9
      src/ArduinoJson/Array/JsonArray.hpp
  2. 2 4
      src/ArduinoJson/Array/JsonArrayConst.hpp
  3. 11 12
      src/ArduinoJson/Array/Utilities.hpp
  4. 2 3
      src/ArduinoJson/Deserialization/Reader.hpp
  5. 1 2
      src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp
  6. 1 2
      src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp
  7. 3 6
      src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp
  8. 2 4
      src/ArduinoJson/Deserialization/Readers/RamReader.hpp
  9. 1 2
      src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp
  10. 1 1
      src/ArduinoJson/Deserialization/Readers/VariantReader.hpp
  11. 6 7
      src/ArduinoJson/Deserialization/deserialize.hpp
  12. 26 34
      src/ArduinoJson/Document/JsonDocument.hpp
  13. 4 6
      src/ArduinoJson/Json/JsonDeserializer.hpp
  14. 2 2
      src/ArduinoJson/Json/JsonSerializer.hpp
  15. 3 3
      src/ArduinoJson/Json/TextFormatter.hpp
  16. 2 2
      src/ArduinoJson/Memory/StringNode.hpp
  17. 1 1
      src/ArduinoJson/Memory/VariantPool.hpp
  18. 10 12
      src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
  19. 4 5
      src/ArduinoJson/MsgPack/MsgPackSerializer.hpp
  20. 18 18
      src/ArduinoJson/Numbers/FloatTraits.hpp
  21. 19 23
      src/ArduinoJson/Numbers/arithmeticCompare.hpp
  22. 29 30
      src/ArduinoJson/Numbers/convertNumber.hpp
  23. 2 2
      src/ArduinoJson/Numbers/parseNumber.hpp
  24. 14 14
      src/ArduinoJson/Object/JsonObject.hpp
  25. 7 10
      src/ArduinoJson/Object/JsonObjectConst.hpp
  26. 7 4
      src/ArduinoJson/Polyfills/integer.hpp
  27. 2 2
      src/ArduinoJson/Polyfills/limits.hpp
  28. 1 1
      src/ArduinoJson/Polyfills/type_traits.hpp
  29. 4 0
      src/ArduinoJson/Polyfills/type_traits/conditional.hpp
  30. 3 0
      src/ArduinoJson/Polyfills/type_traits/enable_if.hpp
  31. 2 2
      src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp
  32. 3 4
      src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp
  33. 12 12
      src/ArduinoJson/Polyfills/type_traits/is_integral.hpp
  34. 8 8
      src/ArduinoJson/Polyfills/type_traits/is_signed.hpp
  35. 6 6
      src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp
  36. 3 0
      src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp
  37. 0 14
      src/ArduinoJson/Polyfills/type_traits/make_void.hpp
  38. 3 0
      src/ArduinoJson/Polyfills/type_traits/remove_const.hpp
  39. 3 0
      src/ArduinoJson/Polyfills/type_traits/remove_cv.hpp
  40. 3 0
      src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp
  41. 20 0
      src/ArduinoJson/Polyfills/type_traits/void_t.hpp
  42. 3 3
      src/ArduinoJson/Polyfills/utility.hpp
  43. 2 3
      src/ArduinoJson/Serialization/Writers/PrintWriter.hpp
  44. 2 3
      src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp
  45. 4 5
      src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp
  46. 5 7
      src/ArduinoJson/Serialization/serialize.hpp
  47. 3 4
      src/ArduinoJson/Strings/Adapters/RamString.hpp
  48. 8 11
      src/ArduinoJson/Strings/Adapters/StringObject.hpp
  49. 1 2
      src/ArduinoJson/Strings/IsString.hpp
  50. 4 8
      src/ArduinoJson/Strings/StringAdapters.hpp
  51. 7 12
      src/ArduinoJson/Strings/StringTraits.hpp
  52. 7 9
      src/ArduinoJson/Variant/ConverterImpl.hpp
  53. 15 23
      src/ArduinoJson/Variant/JsonVariantConst.hpp
  54. 5 6
      src/ArduinoJson/Variant/VariantCompare.hpp
  55. 2 2
      src/ArduinoJson/Variant/VariantData.hpp
  56. 16 23
      src/ArduinoJson/Variant/VariantOperators.hpp
  57. 25 31
      src/ArduinoJson/Variant/VariantRefBase.hpp
  58. 9 11
      src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

+ 7 - 9
src/ArduinoJson/Array/JsonArray.hpp

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

+ 2 - 4
src/ArduinoJson/Array/JsonArrayConst.hpp

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

+ 11 - 12
src/ArduinoJson/Array/Utilities.hpp

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

+ 2 - 3
src/ArduinoJson/Deserialization/Reader.hpp

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

+ 1 - 2
src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp

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

+ 1 - 2
src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp

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

+ 3 - 6
src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp

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

+ 2 - 4
src/ArduinoJson/Deserialization/Readers/RamReader.hpp

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

+ 1 - 2
src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp

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

+ 1 - 1
src/ArduinoJson/Deserialization/Readers/VariantReader.hpp

@@ -10,7 +10,7 @@
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
 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> {
   explicit Reader(const TVariant& x)
       : Reader<char*, void>(x.template as<const char*>()) {}

+ 6 - 7
src/ArduinoJson/Deserialization/deserialize.hpp

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

+ 26 - 34
src/ArduinoJson/Document/JsonDocument.hpp

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

+ 4 - 6
src/ArduinoJson/Json/JsonDeserializer.hpp

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

+ 2 - 2
src/ArduinoJson/Json/JsonSerializer.hpp

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

+ 3 - 3
src/ArduinoJson/Json/TextFormatter.hpp

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

+ 2 - 2
src/ArduinoJson/Memory/StringNode.hpp

@@ -17,9 +17,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 struct StringNode {
   // Use the same type as SlotId to store the reference count
   // (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;
   references_type references;

+ 1 - 1
src/ArduinoJson/Memory/VariantPool.hpp

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

+ 10 - 12
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp

@@ -291,8 +291,8 @@ class MsgPackDeserializer {
   }
 
   template <typename T>
-  typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
-  readFloat(VariantData* variant) {
+  enable_if_t<sizeof(T) == 4, DeserializationError::Code> readFloat(
+      VariantData* variant) {
     DeserializationError::Code err;
     T value;
 
@@ -307,8 +307,8 @@ class MsgPackDeserializer {
   }
 
   template <typename T>
-  typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type
-  readDouble(VariantData* variant) {
+  enable_if_t<sizeof(T) == 8, DeserializationError::Code> readDouble(
+      VariantData* variant) {
     DeserializationError::Code err;
     T value;
 
@@ -323,8 +323,8 @@ class MsgPackDeserializer {
   }
 
   template <typename T>
-  typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
-  readDouble(VariantData* variant) {
+  enable_if_t<sizeof(T) == 4, DeserializationError::Code> readDouble(
+      VariantData* variant) {
     DeserializationError::Code err;
     uint8_t i[8];  // input is 8 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.
 // https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
 template <typename TDestination, typename... Args>
-typename detail::enable_if<
-    detail::is_deserialize_destination<TDestination>::value,
-    DeserializationError>::type
+detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
+                    DeserializationError>
 deserializeMsgPack(TDestination&& dst, Args&&... args) {
   using namespace detail;
   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.
 // https://arduinojson.org/v7/api/msgpack/deserializemsgpack/
 template <typename TDestination, typename TChar, typename... Args>
-typename detail::enable_if<
-    detail::is_deserialize_destination<TDestination>::value,
-    DeserializationError>::type
+detail::enable_if_t<detail::is_deserialize_destination<TDestination>::value,
+                    DeserializationError>
 deserializeMsgPack(TDestination&& dst, TChar* input, Args&&... args) {
   using namespace detail;
   return deserialize<MsgPackDeserializer>(detail::forward<TDestination>(dst),

+ 4 - 5
src/ArduinoJson/MsgPack/MsgPackSerializer.hpp

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

+ 18 - 18
src/ArduinoJson/Numbers/FloatTraits.hpp

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

+ 19 - 23
src/ArduinoJson/Numbers/arithmeticCompare.hpp

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

+ 29 - 30
src/ArduinoJson/Numbers/convertNumber.hpp

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

+ 2 - 2
src/ArduinoJson/Numbers/parseNumber.hpp

@@ -16,11 +16,11 @@
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
 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) {
   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;
 
   ARDUINOJSON_ASSERT(s != 0);

+ 14 - 14
src/ArduinoJson/Object/JsonObject.hpp

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

+ 7 - 10
src/ArduinoJson/Object/JsonObjectConst.hpp

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

+ 7 - 4
src/ArduinoJson/Polyfills/integer.hpp

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

+ 2 - 2
src/ArduinoJson/Polyfills/limits.hpp

@@ -18,7 +18,7 @@ template <typename T, typename Enable = void>
 struct numeric_limits;
 
 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() {
     return 0;
   }
@@ -29,7 +29,7 @@ struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
 
 template <typename T>
 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() {
     return T(T(1) << (sizeof(T) * 8 - 1));
   }

+ 1 - 1
src/ArduinoJson/Polyfills/type_traits.hpp

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

+ 4 - 0
src/ArduinoJson/Polyfills/type_traits/conditional.hpp

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

+ 3 - 0
src/ArduinoJson/Polyfills/type_traits/enable_if.hpp

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

+ 2 - 2
src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp

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

+ 3 - 4
src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp

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

+ 12 - 12
src/ArduinoJson/Polyfills/type_traits/is_integral.hpp

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

+ 8 - 8
src/ArduinoJson/Polyfills/type_traits/is_signed.hpp

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

+ 6 - 6
src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp

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

+ 3 - 0
src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp

@@ -38,4 +38,7 @@ struct make_unsigned<signed long long> : type_identity<unsigned long long> {};
 template <>
 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

+ 0 - 14
src/ArduinoJson/Polyfills/type_traits/make_void.hpp

@@ -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

+ 3 - 0
src/ArduinoJson/Polyfills/type_traits/remove_const.hpp

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

+ 3 - 0
src/ArduinoJson/Polyfills/type_traits/remove_cv.hpp

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

+ 3 - 0
src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp

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

+ 20 - 0
src/ArduinoJson/Polyfills/type_traits/void_t.hpp

@@ -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

+ 3 - 3
src/ArduinoJson/Polyfills/utility.hpp

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

+ 2 - 3
src/ArduinoJson/Serialization/Writers/PrintWriter.hpp

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

+ 2 - 3
src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp

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

+ 4 - 5
src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp

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

+ 5 - 7
src/ArduinoJson/Serialization/serialize.hpp

@@ -23,17 +23,15 @@ size_t serialize(ArduinoJson::JsonVariantConst source,
 }
 
 template <template <typename> class TSerializer>
-typename enable_if<!TSerializer<StaticStringWriter>::producesText, size_t>::type
-serialize(ArduinoJson::JsonVariantConst source, void* buffer,
-          size_t bufferSize) {
+enable_if_t<!TSerializer<StaticStringWriter>::producesText, size_t> serialize(
+    ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
   StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
   return doSerialize<TSerializer>(source, writer);
 }
 
 template <template <typename> class TSerializer>
-typename enable_if<TSerializer<StaticStringWriter>::producesText, size_t>::type
-serialize(ArduinoJson::JsonVariantConst source, void* buffer,
-          size_t bufferSize) {
+enable_if_t<TSerializer<StaticStringWriter>::producesText, size_t> serialize(
+    ArduinoJson::JsonVariantConst source, void* buffer, size_t bufferSize) {
   StaticStringWriter writer(reinterpret_cast<char*>(buffer), bufferSize);
   size_t n = doSerialize<TSerializer>(source, writer);
   // 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>
-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]) {
   return serialize<TSerializer>(source, buffer, N);
 }

+ 3 - 4
src/ArduinoJson/Strings/Adapters/RamString.hpp

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

+ 8 - 11
src/ArduinoJson/Strings/Adapters/StringObject.hpp

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

+ 1 - 2
src/ArduinoJson/Strings/IsString.hpp

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

+ 4 - 8
src/ArduinoJson/Strings/StringAdapters.hpp

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

+ 7 - 12
src/ArduinoJson/Strings/StringTraits.hpp

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

+ 7 - 9
src/ArduinoJson/Variant/ConverterImpl.hpp

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

+ 15 - 23
src/ArduinoJson/Variant/JsonVariantConst.hpp

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

+ 5 - 6
src/ArduinoJson/Variant/VariantCompare.hpp

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

+ 2 - 2
src/ArduinoJson/Variant/VariantData.hpp

@@ -338,13 +338,13 @@ class VariantData {
   }
 
   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);
     content_.asSignedInteger = value;
   }
 
   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);
     content_.asUnsignedInteger = static_cast<JsonUInt>(value);
   }

+ 16 - 23
src/ArduinoJson/Variant/VariantOperators.hpp

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

+ 25 - 31
src/ArduinoJson/Variant/VariantRefBase.hpp

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

+ 9 - 11
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

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