Browse Source

Add safe bool idiom in `JsonString`

Benoit Blanchon 4 years ago
parent
commit
acfa174333

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@ HEAD
 * Change the default of `ARDUINOJSON_USE_DOUBLE` to `1`
 * Change the default of `ARDUINOJSON_USE_LONG_LONG` to `1` on 32-bit platforms
 * Add `as<JsonString>()` and `is<JsonString>()`
+* Add safe bool idiom in `JsonString`
 
 v6.18.5 (2021-09-28)
 -------

+ 17 - 0
extras/tests/Misc/JsonString.cpp

@@ -14,6 +14,23 @@ TEST_CASE("JsonString") {
     CHECK(s.isStatic() == true);
   }
 
+  SECTION("Compare null with boolean") {
+    JsonString s;
+
+    CHECK(bool(s) == false);
+    CHECK(false == bool(s));
+    CHECK(bool(s) != true);
+    CHECK(true != bool(s));
+  }
+
+  SECTION("Compare non-null with boolean") {
+    JsonString s("hello");
+    CHECK(bool(s) == true);
+    CHECK(true == bool(s));
+    CHECK(bool(s) != false);
+    CHECK(false != bool(s));
+  }
+
   SECTION("Compare null with null") {
     JsonString a, b;
 

+ 3 - 6
src/ArduinoJson/Deserialization/DeserializationError.hpp

@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <ArduinoJson/Misc/SafeBoolIdiom.hpp>
 #include <ArduinoJson/Namespace.hpp>
 #include <ArduinoJson/Polyfills/preprocessor.hpp>
 #include <ArduinoJson/Polyfills/static_array.hpp>
@@ -14,11 +15,7 @@
 
 namespace ARDUINOJSON_NAMESPACE {
 
-class DeserializationError {
-  // safe bool idiom
-  typedef void (DeserializationError::*bool_type)() const;
-  void safeBoolHelper() const {}
-
+class DeserializationError : public SafeBoolIdom<DeserializationError> {
  public:
   enum Code {
     Ok,
@@ -58,7 +55,7 @@ class DeserializationError {
 
   // Behaves like a bool
   operator bool_type() const {
-    return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
+    return _code != Ok ? safe_true() : safe_false();
   }
   friend bool operator==(bool value, const DeserializationError& err) {
     return static_cast<bool>(err) == value;

+ 26 - 0
src/ArduinoJson/Misc/SafeBoolIdiom.hpp

@@ -0,0 +1,26 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Polyfills/type_traits.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename T>
+class SafeBoolIdom {
+ protected:
+  typedef void (T::*bool_type)() const;
+  void safeBoolHelper() const {}
+
+  static bool_type safe_true() {
+    return &SafeBoolIdom::safeBoolHelper;
+  }
+
+  static bool_type safe_false() {
+    return 0;
+  }
+};
+
+}  // namespace ARDUINOJSON_NAMESPACE

+ 8 - 1
src/ArduinoJson/Strings/String.hpp

@@ -4,9 +4,11 @@
 
 #pragma once
 
+#include <ArduinoJson/Misc/SafeBoolIdiom.hpp>
+
 namespace ARDUINOJSON_NAMESPACE {
 
-class String {
+class String : public SafeBoolIdom<String> {
  public:
   String() : _data(0), _isStatic(true) {}
   String(const char* data, bool isStaticData = true)
@@ -24,6 +26,11 @@ class String {
     return _isStatic;
   }
 
+  // safe bool idiom
+  operator bool_type() const {
+    return _data ? safe_true() : safe_false();
+  }
+
   friend bool operator==(String lhs, String rhs) {
     if (lhs._data == rhs._data)
       return true;