#include #include #include #include #include #include template void test(std::chars_format fmt = std::chars_format{}) { std::array str1, str2; union U { unsigned short s; T f; } u, v; for (int i = 0; i <= (unsigned short) ~0; ++i) { u.s = i; auto [ptr1, ec1] = std::to_chars(str1.data(), str1.data() + str1.size(), u.f, fmt); auto [ptr2, ec2] = std::to_chars(str2.data(), str2.data() + str2.size(), std::float32_t(u.f), fmt); if (ec1 != std::errc()) { std::cout << std::make_error_code(ec1).message() << '\n'; continue; } else if (ec2 != std::errc()) { std::cout << std::make_error_code(ec2).message() << '\n'; continue; } std::cout << i << ' ' << std::string_view (str1.data(), ptr1) << '\t' << std::string_view (str2.data(), ptr2) << '\n'; if (fmt == std::chars_format::fixed) { auto [ptr3, ec3] = std::to_chars(str1.data(), ptr1, u.f, fmt); if (ec3 != std::errc() || ptr3 != ptr1) throw "Consistency failure"; else { auto [ptr4, ec4] = std::to_chars(str1.data(), ptr1 - 1, u.f, fmt); if (ec4 == std::errc()) throw "Consistency failure"; } } auto [ptr5, ec5] = std::to_chars(str1.data(), str1.data() + str1.size(), u.f, fmt); std::float32_t f; auto [ptr6, ec6] = std::from_chars(str1.data(), ptr5, f, fmt == std::chars_format{} ? std::chars_format::general : fmt); if (ec6 != std::errc()) { std::cout << std::make_error_code(ec6).message() << '\n'; continue; } v.f = T(f); if (u.s != v.s) { auto [ptr7, ec7] = std::to_chars(str2.data(), str2.data() + str1.size(), v.f, fmt); if (ec7 != std::errc()) { std::cout << std::make_error_code(ec7).message() << '\n'; continue; } std::cout << "Difference on " << i << ' ' << u.s << ' ' << v.s << ' ' << std::string_view (str1.data(), ptr5) << '\t' << std::string_view (str2.data(), ptr7) << '\n';; } } } int main() { #ifdef __STDCPP_FLOAT16_T__ std::cout << "float16_t" << '\n'; test(); std::cout << "float16_t fixed" << '\n'; test(std::chars_format::fixed); std::cout << "float16_t scientific" << '\n'; test(std::chars_format::scientific); std::cout << "float16_t general" << '\n'; test(std::chars_format::general); std::cout << "float16_t hex" << '\n'; test(std::chars_format::hex); #endif #ifdef __STDCPP_BFLOAT16_T__ std::cout << "bfloat16_t" << '\n'; test(); std::cout << "bfloat16_t fixed" << '\n'; test(std::chars_format::fixed); std::cout << "bfloat16_t scientific" << '\n'; test(std::chars_format::scientific); std::cout << "bfloat16_t general" << '\n'; test(std::chars_format::general); std::cout << "bfloat16_t hex" << '\n'; test(std::chars_format::hex); #endif }