Add additional compiler macro checks for checking float and double data formats conform to IEEE 754

Bug: 351170734

Change-Id: I2aab09a611136727d3662d1ec4a17562ef0c1bcc
diff --git a/include/cppbor/cppbor.h b/include/cppbor/cppbor.h
index acce184..271e0e6 100644
--- a/include/cppbor/cppbor.h
+++ b/include/cppbor/cppbor.h
@@ -943,7 +943,7 @@
     std::unique_ptr<Item> clone() const override { return std::make_unique<Null>(); }
 };
 
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 /**
  * Float is a concrete type that implements CBOR major type 7, with additional item value for
  * FLOAT.
@@ -977,7 +977,9 @@
   private:
     float mValue;
 };
+#endif  // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 /**
  * Double is a concrete type that implements CBOR major type 7, with additional item value for
  * DOUBLE.
@@ -1011,7 +1013,7 @@
   private:
     double mValue;
 };
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 
 /**
  * Returns pretty-printed CBOR for |item|
diff --git a/src/cppbor.cpp b/src/cppbor.cpp
index fbb71c6..bdb5559 100644
--- a/src/cppbor.cpp
+++ b/src/cppbor.cpp
@@ -245,23 +245,28 @@
                 case NULL_T:
                     out.append("null");
                     break;
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
                 case FLOAT:
                     snprintf(buf, sizeof(buf), "%f", item->asSimple()->asFloat()->value());
                     out.append(buf);
                     break;
+#ifndef __TRUSTY__
+                    LOG(ERROR) << "float not supported for this platform.";
+#endif  // __TRUSTY__
+                    return false;
+#endif  // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
                 case DOUBLE:
                     snprintf(buf, sizeof(buf), "%f", item->asSimple()->asDouble()->value());
                     out.append(buf);
                     break;
 #else
-                case FLOAT:
                 case DOUBLE:
 #ifndef __TRUSTY__
-                    LOG(ERROR) << "float/double not supported for this platform.";
+                    LOG(ERROR) << "double not supported for this platform.";
 #endif  // __TRUSTY__
                     return false;
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
                 default:
 #ifndef __TRUSTY__
                     LOG(ERROR) << "Only boolean/null/float/double is implemented for SIMPLE";
@@ -391,12 +396,14 @@
             return *asBool() == *(other.asBool());
         case NULL_T:
             return true;
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
         case FLOAT:
             return *asFloat() == *(other.asFloat());
+#endif  // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
         case DOUBLE:
             return *asDouble() == *(other.asDouble());
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
         default:
             CHECK(false);  // Impossible to get here.
             return false;
diff --git a/src/cppbor_parse.cpp b/src/cppbor_parse.cpp
index ddcc44b..de724db 100644
--- a/src/cppbor_parse.cpp
+++ b/src/cppbor_parse.cpp
@@ -104,7 +104,7 @@
             parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
 }
 
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 std::tuple<const uint8_t*, ParseClient*> handleFloat(uint32_t value, const uint8_t* hdrBegin,
                                                      const uint8_t* hdrEnd,
                                                      ParseClient* parseClient) {
@@ -114,7 +114,9 @@
     return {hdrEnd,
             parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
 }
+#endif  // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 std::tuple<const uint8_t*, ParseClient*> handleDouble(uint64_t value, const uint8_t* hdrBegin,
                                                       const uint8_t* hdrEnd,
                                                       ParseClient* parseClient) {
@@ -124,7 +126,7 @@
     return {hdrEnd,
             parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
 }
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 
 template <typename T>
 std::tuple<const uint8_t*, ParseClient*> handleString(uint64_t length, const uint8_t* hdrBegin,
@@ -471,17 +473,22 @@
                 case TRUE:
                 case FALSE:
                     return handleBool(*addlData, begin, pos, parseClient);
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
                 case FLOAT_V:
                     return handleFloat(*addlData, begin, pos, parseClient);
+#else
+                case FLOAT_V:
+                    parseClient->error(begin, "Value float is not supported for platform.");
+                    return {begin, nullptr};
+#endif  // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
                 case DOUBLE_V:
                     return handleDouble(*addlData, begin, pos, parseClient);
 #else
-                case FLOAT_V:
                 case DOUBLE_V:
-                    parseClient->error(begin, "Unsupported floating-point value for platform.");
+                    parseClient->error(begin, "Value double is not supported for platform.");
                     return {begin, nullptr};
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
                 case NULL_V:
                     return handleNull(begin, pos, parseClient);
                 default:
diff --git a/tests/cppbor_test.cpp b/tests/cppbor_test.cpp
index 7274a08..700c038 100644
--- a/tests/cppbor_test.cpp
+++ b/tests/cppbor_test.cpp
@@ -2022,7 +2022,7 @@
     EXPECT_EQ("Unsupported half-floating-point or simple value.", message);
 }
 
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 TEST(FullParserTest, FloatingPointValue) {
     vector<uint8_t> floatingPointValue = {0xFA, 0x12, 0x75, 0x34, 0x37};
     float f_val = 7.737272847557572e-28;
@@ -2094,7 +2094,9 @@
     Float f(f_val);
     EXPECT_EQ(f.encode(), floatingPointValue);
 }
+#endif  // defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
 
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 TEST(FullParserTest, DoubleValue) {
     vector<uint8_t> doubleValue = {0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A};
     double d_val = 3.1415926000000001;
@@ -2166,7 +2168,7 @@
     Double d(d_val);
     EXPECT_EQ(d.encode(), doubleValue);
 }
-#endif  // __STDC_IEC_559__
+#endif  // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
 
 TEST(MapGetValueByKeyTest, Map) {
     Array compoundItem(1, 2, 3, 4, 5, Map(4, 5, "a", "b"));