// Copyright 2023 Matt Borland // Copyright 2023 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #ifdef BOOST_HAS_INT128 // We need to define these operator<< overloads before // including boost/core/lightweight_test.hpp, or they // won't be visible to BOOST_TEST_EQ #include static char* mini_to_chars( char (&buffer)[ 64 ], boost::uint128_type v ) { char* p = buffer + 64; *--p = '\0'; do { *--p = "0123456789"[ v % 10 ]; v /= 10; } while ( v != 0 ); return p; } std::ostream& operator<<( std::ostream& os, boost::uint128_type v ) { char buffer[ 64 ]; os << mini_to_chars( buffer, v ); return os; } std::ostream& operator<<( std::ostream& os, boost::int128_type v ) { char buffer[ 64 ]; char* p; if( v >= 0 ) { p = mini_to_chars( buffer, v ); } else { p = mini_to_chars( buffer, -(boost::uint128_type)v ); *--p = '-'; } os << p; return os; } #endif // #ifdef BOOST_HAS_INT128 #include #include #include #include #include #include void test_odr_use( int const* ); template void test_integral( T value ) { // no base { char buffer[ boost::charconv::limits::max_chars10 ]; auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), value ); BOOST_TEST(r.ec == std::errc()); T v2 = 0; auto r2 = boost::charconv::from_chars( buffer, r.ptr, v2 ); BOOST_TEST(r2.ec == std::errc()) && BOOST_TEST_EQ( v2, value ); } // base 10 { char buffer[ boost::charconv::limits::max_chars10 ]; auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), value, 10 ); BOOST_TEST(r.ec == std::errc()); T v2 = 0; auto r2 = boost::charconv::from_chars( buffer, r.ptr, v2, 10 ); BOOST_TEST(r2.ec == std::errc()) && BOOST_TEST_EQ( v2, value ); } // any base for( int base = 2; base <= 36; ++base ) { char buffer[ boost::charconv::limits::max_chars ]; auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), value, base ); BOOST_TEST(r.ec == std::errc()); T v2 = 0; auto r2 = boost::charconv::from_chars( buffer, r.ptr, v2, base ); BOOST_TEST(r2.ec == std::errc()) && BOOST_TEST_EQ( v2, value ); } } template void test_integral() { BOOST_TEST_GE( boost::charconv::limits::max_chars10, std::numeric_limits::digits10 ); BOOST_TEST_GE( boost::charconv::limits::max_chars, std::numeric_limits::digits ); test_odr_use( &boost::charconv::limits::max_chars10 ); test_odr_use( &boost::charconv::limits::max_chars ); test_integral( std::numeric_limits::min() ); test_integral( std::numeric_limits::max() ); } template void test_floating_point( T value ) { // no base, max_chars10 { char buffer[ boost::charconv::limits::max_chars10 ]; auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), value ); BOOST_TEST(r.ec == std::errc()); T v2 = 0; auto r2 = boost::charconv::from_chars( buffer, r.ptr, v2 ); BOOST_TEST(r2.ec == std::errc()) && BOOST_TEST_EQ( v2, value ); } // no base, max_chars { char buffer[ boost::charconv::limits::max_chars ]; auto r = boost::charconv::to_chars( buffer, buffer + sizeof( buffer ), value ); BOOST_TEST(r.ec == std::errc()); T v2 = 0; auto r2 = boost::charconv::from_chars( buffer, r.ptr, v2 ); BOOST_TEST(r2.ec == std::errc()) && BOOST_TEST_EQ( v2, value ); } } template void test_floating_point() { BOOST_TEST_GE( boost::charconv::limits::max_chars10, std::numeric_limits::max_digits10 ); BOOST_TEST_GE( boost::charconv::limits::max_chars, std::numeric_limits::max_digits10 ); test_odr_use( &boost::charconv::limits::max_chars10 ); test_odr_use( &boost::charconv::limits::max_chars ); test_floating_point( std::numeric_limits::min() ); test_floating_point( -std::numeric_limits::min() ); test_floating_point( std::numeric_limits::max() ); test_floating_point( -std::numeric_limits::max() ); } int main() { test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); test_integral(); #if !defined(__CYGWIN__) && !defined(__s390x__) && !((defined(__arm__) || defined(__aarch64__)) && !defined(__APPLE__)) && !(defined(__APPLE__) && (__clang_major__ == 12)) // the stub implementations fail under Cygwin, s390x, linux ARM, and Apple Clang w/Xcode 12.2; // re-enable these when we have real ones test_floating_point(); test_floating_point(); test_floating_point(); #endif // Broken Platforms #ifdef BOOST_CHARCONV_HAS_INT128 test_integral(); test_integral(); #endif return boost::report_errors(); } void test_odr_use( int const* ) { }