3
3
#include " doctest/doctest.h"
4
4
5
5
#include " fast_float/fast_float.h"
6
+ #include < cfenv>
6
7
#include < cmath>
7
8
#include < cstdio>
8
9
#include < iomanip>
9
10
#include < ios>
11
+ #include < iostream>
10
12
#include < limits>
13
+ #include < sstream>
11
14
#include < string>
12
15
#include < system_error>
13
16
#include < type_traits>
14
- #include < cfenv>
15
17
16
18
#if FASTFLOAT_IS_CONSTEXPR
17
19
#ifndef FASTFLOAT_CONSTEXPR_TESTS
54
56
#define FASTFLOAT_ODDPLATFORM 1
55
57
#endif
56
58
57
- #define iHexAndDec (v ) std::hex << " 0x" << (v) << " (" << std::dec << (v) << " )"
59
+ #define iHexAndDec (v ) \
60
+ (std::ostringstream{} << std::hex << " 0x" << (v) << " (" << std::dec << (v) \
61
+ << " )" ) \
62
+ .str()
58
63
#define fHexAndDec (v ) \
59
- std::hexfloat << (v) << " (" << std::defaultfloat << (v) << " )"
64
+ (std::ostringstream{} << std::hexfloat << (v) << " (" << std::defaultfloat \
65
+ << (v) << " )" ) \
66
+ .str()
60
67
61
68
char const *round_name (int d) {
62
69
switch (d) {
@@ -256,7 +263,6 @@ TEST_CASE("parse_negative_zero") {
256
263
#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && \
257
264
!defined(FASTFLOAT_ODDPLATFORM)
258
265
259
- #include < iostream>
260
266
#include < filesystem>
261
267
#include < charconv>
262
268
@@ -722,6 +728,38 @@ uint64_t get_mantissa(double f) {
722
728
return (m & ((uint64_t (1 ) << 57 ) - 1 ));
723
729
}
724
730
731
+ #ifdef __STDCPP_FLOAT64_T__
732
+ uint64_t get_mantissa (std::float64_t f) {
733
+ uint64_t m;
734
+ memcpy (&m, &f, sizeof (f));
735
+ return (m & ((uint64_t (1 ) << 10 ) - 1 ));
736
+ }
737
+ #endif
738
+
739
+ #ifdef __STDCPP_FLOAT32_T__
740
+ uint32_t get_mantissa (std::float32_t f) {
741
+ uint32_t m;
742
+ memcpy (&m, &f, sizeof (f));
743
+ return (m & ((uint32_t (1 ) << 10 ) - 1 ));
744
+ }
745
+ #endif
746
+
747
+ #ifdef __STDCPP_FLOAT16_T__
748
+ uint16_t get_mantissa (std::float16_t f) {
749
+ uint16_t m;
750
+ memcpy (&m, &f, sizeof (f));
751
+ return (m & ((uint16_t (1 ) << 10 ) - 1 ));
752
+ }
753
+ #endif
754
+
755
+ #ifdef __STDCPP_BFLOAT16_T__
756
+ uint16_t get_mantissa (std::bfloat16_t f) {
757
+ uint16_t m;
758
+ memcpy (&m, &f, sizeof (f));
759
+ return (m & ((uint16_t (1 ) << 7 ) - 1 ));
760
+ }
761
+ #endif
762
+
725
763
std::string append_zeros (std::string str, size_t number_of_zeros) {
726
764
std::string answer (str);
727
765
for (size_t i = 0 ; i < number_of_zeros; i++) {
@@ -736,26 +774,31 @@ enum class Diag { runtime, comptime };
736
774
737
775
} // anonymous namespace
738
776
777
+ constexpr size_t global_string_capacity = 2048 ;
778
+
739
779
template <Diag diag, class T , typename result_type, typename stringtype>
740
780
constexpr void check_basic_test_result (stringtype str, result_type result,
741
781
T actual, T expected,
742
782
std::errc expected_ec) {
743
- if constexpr (diag == Diag::runtime) {
744
- INFO (" str=" << str << " \n "
745
- << " expected=" << fHexAndDec (expected) << " \n "
746
- << " ..actual=" << fHexAndDec (actual) << " \n "
747
- << " expected mantissa=" << iHexAndDec (get_mantissa (expected))
748
- << " \n "
749
- << " ..actual mantissa=" << iHexAndDec (get_mantissa (actual)));
750
- }
751
-
752
783
struct ComptimeDiag {
753
784
// Purposely not constexpr
754
785
static void error_not_equal () {}
755
786
};
756
787
757
788
#define FASTFLOAT_CHECK_EQ (...) \
758
789
if constexpr (diag == Diag::runtime) { \
790
+ char narrow[global_string_capacity]{}; \
791
+ for (size_t i = 0 ; i < str.size (); i++) { \
792
+ narrow[i] = char (str[i]); \
793
+ } \
794
+ INFO (" str(char" << 8 * sizeof (typename stringtype::value_type) \
795
+ << " )=" << narrow << " \n " \
796
+ << " expected=" << fHexAndDec (expected) << " \n " \
797
+ << " ..actual=" << fHexAndDec (actual) << " \n " \
798
+ << " expected mantissa=" \
799
+ << iHexAndDec (get_mantissa (expected)) << " \n " \
800
+ << " ..actual mantissa=" \
801
+ << iHexAndDec (get_mantissa (actual))); \
759
802
CHECK_EQ (__VA_ARGS__); \
760
803
} else { \
761
804
if ([](auto const &lhs, auto const &rhs) { \
@@ -774,9 +817,9 @@ constexpr void check_basic_test_result(stringtype str, result_type result,
774
817
return -x;
775
818
}
776
819
return x;
777
- }
820
+ } else
778
821
#endif
779
- return std::copysign (x, y);
822
+ return std::copysign (x, y);
780
823
};
781
824
782
825
auto isnan = [](double x) -> bool { return x != x; };
@@ -797,26 +840,26 @@ constexpr void basic_test(std::string_view str, T expected,
797
840
auto result =
798
841
fast_float::from_chars (str.data (), str.data () + str.size (), actual);
799
842
check_basic_test_result<diag>(str, result, actual, expected, expected_ec);
800
- constexpr size_t global_string_capacity = 2048 ;
801
843
802
844
if (str.size () > global_string_capacity) {
803
845
return ;
804
846
}
847
+
805
848
// We give plenty of memory: 2048 characters.
806
849
char16_t u16 [global_string_capacity]{};
807
-
808
850
for (size_t i = 0 ; i < str.size (); i++) {
809
851
u16 [i] = char16_t (str[i]);
810
852
}
853
+
811
854
auto result16 = fast_float::from_chars (u16 , u16 + str.size (), actual);
812
855
check_basic_test_result<diag>(std::u16string_view (u16 , str.size ()), result16,
813
856
actual, expected, expected_ec);
814
857
815
858
char32_t u32 [global_string_capacity]{};
816
-
817
859
for (size_t i = 0 ; i < str.size (); i++) {
818
860
u32 [i] = char32_t (str[i]);
819
861
}
862
+
820
863
auto result32 = fast_float::from_chars (u32 , u32 + str.size (), actual);
821
864
check_basic_test_result<diag>(std::u32string_view (u32 , str.size ()), result32,
822
865
actual, expected, expected_ec);
@@ -906,7 +949,7 @@ void basic_test(float val) {
906
949
basic_test (val); \
907
950
}
908
951
909
- TEST_CASE (" 64bit .inf" ) {
952
+ TEST_CASE (" double .inf" ) {
910
953
verify (" INF" , std::numeric_limits<double >::infinity ());
911
954
verify (" -INF" , -std::numeric_limits<double >::infinity ());
912
955
verify (" INFINITY" , std::numeric_limits<double >::infinity ());
@@ -934,7 +977,7 @@ TEST_CASE("64bit.inf") {
934
977
std::errc::result_out_of_range);
935
978
}
936
979
937
- TEST_CASE (" 64bit .general" ) {
980
+ TEST_CASE (" double .general" ) {
938
981
verify (" 0.95000000000000000000" , 0.95 );
939
982
verify (" 22250738585072012e-324" ,
940
983
0x1p-1022 ); /* limit between normal and subnormal*/
@@ -1118,7 +1161,7 @@ TEST_CASE("64bit.general") {
1118
1161
-0x1 .f1660a65b00bfp +60 );
1119
1162
}
1120
1163
1121
- TEST_CASE (" 64bit .decimal_point" ) {
1164
+ TEST_CASE (" double .decimal_point" ) {
1122
1165
constexpr auto options = [] {
1123
1166
fast_float::parse_options ret{};
1124
1167
ret.decimal_point = ' ,' ;
@@ -1274,7 +1317,7 @@ TEST_CASE("64bit.decimal_point") {
1274
1317
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375);
1275
1318
}
1276
1319
1277
- TEST_CASE (" 32bit .inf" ) {
1320
+ TEST_CASE (" float .inf" ) {
1278
1321
verify (" INF" , std::numeric_limits<float >::infinity ());
1279
1322
verify (" -INF" , -std::numeric_limits<float >::infinity ());
1280
1323
verify (" INFINITY" , std::numeric_limits<float >::infinity ());
@@ -1292,7 +1335,7 @@ TEST_CASE("32bit.inf") {
1292
1335
std::errc::result_out_of_range);
1293
1336
}
1294
1337
1295
- TEST_CASE (" 32bit .general" ) {
1338
+ TEST_CASE (" float .general" ) {
1296
1339
verify (" -1e-999" , -0 .0f , std::errc::result_out_of_range);
1297
1340
verify (" 1."
1298
1341
" 175494140627517859246175898662808184331245864732796240031385942718174"
@@ -1432,7 +1475,7 @@ TEST_CASE("32bit.general") {
1432
1475
0 .00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875f );
1433
1476
}
1434
1477
1435
- TEST_CASE (" 32bit .decimal_point" ) {
1478
+ TEST_CASE (" float .decimal_point" ) {
1436
1479
constexpr auto options = [] {
1437
1480
fast_float::parse_options ret{};
1438
1481
ret.decimal_point = ' ,' ;
0 commit comments