diff --git a/benchmark/to_chars_floating.cpp b/benchmark/to_chars_floating.cpp index da8738d..e5809b8 100644 --- a/benchmark/to_chars_floating.cpp +++ b/benchmark/to_chars_floating.cpp @@ -1,7 +1,25 @@ // Copyright 2023 Peter Dimov +// Copyright 2023 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#include +#include + +#ifdef BOOST_CHARCONV_HAS_STDFLOAT128 +#include + +std::ostream& operator<<( std::ostream& os, std::float128_t v) +{ + char buffer [ 256 ] {}; + std::to_chars(buffer, buffer + sizeof(buffer), v); + os << buffer; + return os; +} + +#endif + + #include #include #include @@ -35,6 +53,28 @@ template static BOOST_NOINLINE void init_input_data( std::vector& da } } +#ifdef BOOST_CHARCONV_HAS_STDFLOAT128 +template<> BOOST_NOINLINE void init_input_data( std::vector& data ) +{ + data.reserve( N ); + + boost::detail::splitmix64 rng; + + for( unsigned i = 0; i < N; ++i ) + { + boost::charconv::detail::uint128 tmp {rng(), rng()}; + boost::uint128_type temp {tmp}; + + std::float128_t x; + std::memcpy( &x, &temp, sizeof(x) ); + + if( !std::isfinite(x) ) continue; + + data.push_back( x ); + } +} +#endif + using namespace std::chrono_literals; template static BOOST_NOINLINE void test_snprintf( std::vector const& data, bool general, char const* label, int precision ) @@ -89,8 +129,8 @@ template static BOOST_NOINLINE void test_std_to_chars( std::vector c std::chars_format fmt = general? std::chars_format::general: std::chars_format::scientific; auto r = precision == 0? - std::to_chars( buffer, buffer + sizeof( buffer ), x, fmt ): - std::to_chars( buffer, buffer + sizeof( buffer ), x, fmt, precision ); + std::to_chars( buffer, buffer + sizeof( buffer ), x, fmt ): + std::to_chars( buffer, buffer + sizeof( buffer ), x, fmt, precision ); s += static_cast( r.ptr - buffer ); s += static_cast( buffer[0] ); @@ -117,8 +157,8 @@ template static BOOST_NOINLINE void test_boost_to_chars( std::vector boost::charconv::chars_format fmt = general? boost::charconv::chars_format::general: boost::charconv::chars_format::scientific; auto r = precision == 0? - boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), x, fmt ): - boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), x, fmt, precision ); + boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), x, fmt ): + boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), x, fmt, precision ); s += static_cast( r.ptr - buffer ); s += static_cast( buffer[0] ); @@ -160,6 +200,34 @@ template static void test() std::cout << std::endl; } +#ifdef BOOST_CHARCONV_HAS_STDFLOAT128 +template<> void test() +{ + std::vector data; + init_input_data( data ); + + test_std_to_chars( data, false, "scientific", 0 ); + test_boost_to_chars( data, false, "scientific", 0 ); + + std::cout << std::endl; + + test_std_to_chars( data, false, "scientific", 6 ); + test_boost_to_chars( data, false, "scientific", 6 ); + + std::cout << std::endl; + + test_std_to_chars( data, true, "general", 0 ); + test_boost_to_chars( data, true, "general", 0 ); + + std::cout << std::endl; + + test_std_to_chars( data, true, "general", 6 ); + test_boost_to_chars( data, true, "general", 6 ); + + std::cout << std::endl; +} +#endif + int main() { std::cout << BOOST_COMPILER << "\n"; @@ -167,4 +235,7 @@ int main() test(); test(); + #ifdef BOOST_CHARCONV_HAS_STDFLOAT128 + test(); + #endif }