Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal
diff options
context:
space:
mode:
authorMartin Hořeňovský2026-07-23 14:26:17 +0200
committerMartin Hořeňovský2026-07-23 14:26:26 +0200
commitc267251e709c52cda421e9490c5cbaf62914fa52 (patch)
treea1330c2158cd39ac376d05fca0960a58cda679d7 /src/catch2/internal
parent0cc833ea95bb7136c99be1b5b105780cae5766ff (diff)
downloadcatch3-c267251e709c52cda421e9490c5cbaf62914fa52.tar.gz
Better support for infs and NaNs in JSON writer
As the types and values sent into the writer are determined by Catch2, I do not expect to actually need this support, but it is better to have it and not be surprised in the future.
Diffstat (limited to 'src/catch2/internal')
-rw-r--r--src/catch2/internal/catch_jsonwriter.cpp22
-rw-r--r--src/catch2/internal/catch_jsonwriter.hpp8
2 files changed, 30 insertions, 0 deletions
diff --git a/src/catch2/internal/catch_jsonwriter.cpp b/src/catch2/internal/catch_jsonwriter.cpp
index 6a994f11..d5122dbc 100644
--- a/src/catch2/internal/catch_jsonwriter.cpp
+++ b/src/catch2/internal/catch_jsonwriter.cpp
@@ -7,8 +7,10 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_jsonwriter.hpp>
+#include <catch2/internal/catch_polyfills.hpp>
#include <catch2/internal/catch_unreachable.hpp>
+#include <cmath>
#include <locale>
namespace Catch {
@@ -145,10 +147,30 @@ namespace Catch {
writeImpl( value, true );
}
+ void JsonValueWriter::write( float value ) && {
+ writeFloatingPoint( value );
+ }
+
+ void JsonValueWriter::write( double value ) && {
+ writeFloatingPoint( value );
+ }
+
void JsonValueWriter::write( bool value ) && {
writeImpl( value ? "true"_sr : "false"_sr, false );
}
+ template <typename T>
+ void JsonValueWriter::writeFloatingPoint( T value ) {
+ if ( Catch::isnan( value ) ) {
+ writeImpl( "NaN"_sr, false );
+ } else if ( std::isinf( value ) ) {
+ writeImpl( value < 0 ? "-Infinity"_sr : "Infinity"_sr, false );
+ } else {
+ m_sstream << value;
+ writeImpl( m_sstream.str(), false );
+ }
+ }
+
void JsonValueWriter::writeImpl( Catch::StringRef value, bool quote ) {
if ( quote ) { m_os << '"'; }
size_t current_start = 0;
diff --git a/src/catch2/internal/catch_jsonwriter.hpp b/src/catch2/internal/catch_jsonwriter.hpp
index 8b3d2bc1..c07d7d75 100644
--- a/src/catch2/internal/catch_jsonwriter.hpp
+++ b/src/catch2/internal/catch_jsonwriter.hpp
@@ -39,11 +39,19 @@ namespace Catch {
writeImpl( value, !std::is_arithmetic<T>::value );
}
void write( StringRef value ) &&;
+ void write( float value ) &&;
+ void write( double value ) &&;
void write( bool value ) &&;
private:
void writeImpl( StringRef value, bool quote );
+ // Helper to deal with non-finite floating point values, which
+ // are not standard JSON, but we use JS/Python/etc. approach of
+ // emitting `NaN`, `Infinity`, `-Infinity` as number(like).
+ template <typename T>
+ void writeFloatingPoint( T value );
+
// Without this SFINAE, this overload is a better match
// for `std::string`, `char const*`, `char const[N]` args.
// While it would still work, it would cause code bloat