diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 94dbaf9..0acc094 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -69,6 +69,11 @@ throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))) #endif +#if (defined(BOOST_LCAST_HAS_INT128) && !defined(__GNUC__)) || GCC_VERSION > 40700 +#define BOOST_LCAST_HAS_INT128 +#endif + + namespace boost { // exception used to indicate runtime lexical_cast failure @@ -310,6 +315,11 @@ namespace boost { > {}; #endif +#ifdef BOOST_LCAST_HAS_INT128 + template <> struct stream_char_common< boost::int128_type >: public boost::mpl::identity< char > {}; + template <> struct stream_char_common< boost::uint128_type >: public boost::mpl::identity< char > {}; +#endif + #if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T) template <> struct stream_char_common< wchar_t > @@ -602,6 +612,10 @@ namespace boost { BOOST_LCAST_DEF(unsigned __int64) BOOST_LCAST_DEF( __int64) #endif +#ifdef BOOST_LCAST_HAS_INT128 + BOOST_LCAST_DEF(boost::int128_type) + BOOST_LCAST_DEF(boost::uint128_type) +#endif #undef BOOST_LCAST_DEF @@ -1723,6 +1737,12 @@ namespace boost { bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned(n, finish); return true; } bool operator<<( __int64 n) { return shl_signed(n); } #endif + +#ifdef BOOST_LCAST_HAS_INT128 + bool operator<<(const boost::uint128_type& n) { start = lcast_put_unsigned(n, finish); return true; } + bool operator<<(const boost::int128_type& n) { return shl_signed(n); } +#endif + bool operator<<(float val) { return shl_real_type(val, start, finish); } bool operator<<(double val) { return shl_real_type(val, start, finish); } bool operator<<(long double val) { @@ -1916,7 +1936,7 @@ namespace boost { } /************************************ OPERATORS >> ( ... ) ********************************/ - public: + public: bool operator>>(unsigned short& output) { return shr_unsigned(output); } bool operator>>(unsigned int& output) { return shr_unsigned(output); } bool operator>>(unsigned long int& output) { return shr_unsigned(output); } @@ -1930,6 +1950,12 @@ namespace boost { bool operator>>(unsigned __int64& output) { return shr_unsigned(output); } bool operator>>(__int64& output) { return shr_signed(output); } #endif + +#ifdef BOOST_LCAST_HAS_INT128 + bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); } + bool operator>>(boost::int128_type& output) { return shr_signed(output); } +#endif + bool operator>>(char& output) { return shr_xchar(output); } bool operator>>(unsigned char& output) { return shr_xchar(output); } bool operator>>(signed char& output) { return shr_xchar(output); } @@ -2563,6 +2589,7 @@ namespace boost { #undef BOOST_LCAST_THROW_BAD_CAST #undef BOOST_LCAST_NO_WCHAR_T +#undef BOOST_LCAST_HAS_INT128 #endif // BOOST_LEXICAL_CAST_INCLUDED diff --git a/test/lexical_cast_integral_types_test.cpp b/test/lexical_cast_integral_types_test.cpp index b34cdc4..96fc20e 100644 --- a/test/lexical_cast_integral_types_test.cpp +++ b/test/lexical_cast_integral_types_test.cpp @@ -47,6 +47,10 @@ #define BOOST_LCAST_NO_WCHAR_T #endif +#if (defined(BOOST_LCAST_HAS_INT128) && !defined(__GNUC__)) || GCC_VERSION > 40700 +#define BOOST_LCAST_HAS_INT128 +#endif + // Test all 65536 values if true: bool const lcast_test_small_integral_types_completely = false; @@ -56,6 +60,8 @@ int const lcast_integral_test_counter=500; using namespace boost; + + void test_conversion_from_to_short(); void test_conversion_from_to_ushort(); void test_conversion_from_to_int(); @@ -68,6 +74,10 @@ void test_conversion_from_to_uintmax_t(); void test_conversion_from_to_longlong(); void test_conversion_from_to_ulonglong(); #endif +#ifdef BOOST_LCAST_HAS_INT128 +void test_conversion_from_to_int128(); +void test_conversion_from_to_uint128(); +#endif void test_integral_conversions_on_min_max(); @@ -87,6 +97,10 @@ unit_test::test_suite *init_unit_test_suite(int, char *[]) #ifdef LCAST_TEST_LONGLONG suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong)); suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong)); +#endif +#ifdef BOOST_LCAST_HAS_INT128 + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int128)); + suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint128)); #endif suite->add(BOOST_TEST_CASE(&test_integral_conversions_on_min_max)); @@ -372,7 +386,7 @@ struct restore_oldloc }; template -void test_conversion_from_to_integral() +void test_conversion_from_to_integral_minimal() { char const zero = '0'; signed char const szero = '0'; @@ -438,7 +452,12 @@ void test_conversion_from_to_integral() must_owerflow_str += '0'; must_owerflow_negative_str += '0'; } +} +template +void test_conversion_from_to_integral() +{ + test_conversion_from_to_integral_minimal(); typedef std::numpunct numpunct; restore_oldloc guard; @@ -536,6 +555,19 @@ void test_conversion_from_to_ulonglong() #endif + +#ifdef BOOST_LCAST_HAS_INT128 +void test_conversion_from_to_int128() +{ + test_conversion_from_to_integral_minimal(); +} + +void test_conversion_from_to_uint128() +{ + test_conversion_from_to_integral_minimal(); +} +#endif + void test_integral_conversions_on_min_max() { typedef std::numeric_limits int_limits;