diff options
| author | Martin Hořeňovský | 2026-07-23 14:26:17 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2026-07-23 14:26:26 +0200 |
| commit | c267251e709c52cda421e9490c5cbaf62914fa52 (patch) | |
| tree | a1330c2158cd39ac376d05fca0960a58cda679d7 /src/catch2/internal | |
| parent | 0cc833ea95bb7136c99be1b5b105780cae5766ff (diff) | |
| download | catch3-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.cpp | 22 | ||||
| -rw-r--r-- | src/catch2/internal/catch_jsonwriter.hpp | 8 |
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 |