Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add conversions for builtin 128-bit types #340

Merged
merged 5 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/boost/decimal/decimal128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ class decimal128 final
explicit constexpr operator std::int16_t() const noexcept;
explicit constexpr operator std::uint16_t() const noexcept;

#ifdef BOOST_DECIMAL_HAS_INT128
explicit constexpr operator detail::int128_t() const noexcept;
explicit constexpr operator detail::uint128_t() const noexcept;
#endif

// 3.2.6 Conversion to floating-point type
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept;
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept;
Expand Down Expand Up @@ -917,6 +922,20 @@ constexpr decimal128::operator std::uint16_t() const noexcept
return to_integral_128<decimal128, std::uint16_t>(*this);
}

#ifdef BOOST_DECIMAL_HAS_INT128

constexpr decimal128::operator detail::int128_t() const noexcept
{
return to_integral_128<decimal128, detail::int128_t>(*this);
}

constexpr decimal128::operator detail::uint128_t() const noexcept
{
return to_integral_128<decimal128, detail::uint128_t>(*this);
}

#endif //BOOST_DECIMAL_HAS_INT128

BOOST_DECIMAL_CXX20_CONSTEXPR decimal128::operator float() const noexcept
{
return to_float<decimal128, float>(*this);
Expand Down
19 changes: 19 additions & 0 deletions include/boost/decimal/decimal32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ class decimal32 final // NOLINT(cppcoreguidelines-special-member-functions,hicpp
explicit constexpr operator std::int16_t() const noexcept;
explicit constexpr operator std::uint16_t() const noexcept;

#ifdef BOOST_DECIMAL_HAS_INT128
explicit constexpr operator detail::int128_t() const noexcept;
explicit constexpr operator detail::uint128_t() const noexcept;
#endif

template <typename Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal>, bool> = true>
explicit constexpr operator Decimal() const noexcept;

Expand Down Expand Up @@ -1633,6 +1638,20 @@ constexpr decimal32::operator std::uint16_t() const noexcept
return to_integral<decimal32, std::uint16_t>(*this);
}

#ifdef BOOST_DECIMAL_HAS_INT128

constexpr decimal32::operator detail::int128_t() const noexcept
{
return to_integral<decimal32, detail::int128_t>(*this);
}

constexpr decimal32::operator detail::uint128_t() const noexcept
{
return to_integral<decimal32, detail::uint128_t>(*this);
}

#endif

template <typename Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal>, bool>>
constexpr decimal32::operator Decimal() const noexcept
{
Expand Down
21 changes: 21 additions & 0 deletions include/boost/decimal/decimal64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ class decimal64 final
explicit constexpr operator std::int16_t() const noexcept;
explicit constexpr operator std::uint16_t() const noexcept;

#ifdef BOOST_DECIMAL_HAS_INT128
explicit constexpr operator detail::int128_t() const noexcept;
explicit constexpr operator detail::uint128_t() const noexcept;
#endif


template <typename Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal>, bool> = true>
explicit constexpr operator Decimal() const noexcept;

Expand Down Expand Up @@ -807,6 +813,21 @@ constexpr decimal64::operator std::uint16_t() const noexcept
return to_integral<decimal64, std::uint16_t>(*this);
}

#ifdef BOOST_DECIMAL_HAS_INT128

constexpr decimal64::operator detail::int128_t() const noexcept
{
return to_integral<decimal64, detail::int128_t>(*this);
}

constexpr decimal64::operator detail::uint128_t() const noexcept
{
return to_integral<decimal64, detail::uint128_t>(*this);
}

#endif


template <typename Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal>, bool>>
constexpr decimal64::operator Decimal() const noexcept
{
Expand Down
4 changes: 2 additions & 2 deletions include/boost/decimal/detail/emulated128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ struct uint128
explicit constexpr operator bool() const noexcept { return high || low; }

#ifdef BOOST_DECIMAL_HAS_INT128
explicit constexpr operator boost::int128_type() const noexcept { return (static_cast<boost::int128_type>(high) << 64) + low; }
explicit constexpr operator boost::uint128_type() const noexcept { return (static_cast<boost::uint128_type>(high) << 64) + low; }
explicit constexpr operator int128_t() noexcept { return (static_cast<int128_t>(high) << 64) + low; }
explicit constexpr operator uint128_t() const noexcept { return (static_cast<uint128_t>(high) << 64) + low; }
#endif

#ifdef BOOST_DECIMAL_HAS_FLOAT128
Expand Down
5 changes: 5 additions & 0 deletions test/roundtrip_decimal32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ int main()
test_roundtrip_conversion_integer<std::int64_t>(-9'999'999, 9'999'999);
test_roundtrip_conversion_integer<std::uint64_t>(0, 9'999'999);

#if defined(BOOST_DECIMAL_HAS_INT128) && !defined(__STRICT_ANSI__)
test_roundtrip_conversion_integer<detail::int128_t>(-9'999'999, 9'999'999);
test_roundtrip_conversion_integer<detail::uint128_t>(0, 9'999'999);
#endif

test_conversion_to_float<float>();
test_conversion_to_float<double>();
test_conversion_to_float<long double>();
Expand Down
5 changes: 5 additions & 0 deletions test/roundtrip_decimal64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ int main()
test_roundtrip_conversion_integer<std::int64_t>(-9'999'999, 9'999'999);
test_roundtrip_conversion_integer<std::uint64_t>(0, 9'999'999);

#if defined(BOOST_DECIMAL_HAS_INT128) && !defined(__STRICT_ANSI__)
test_roundtrip_conversion_integer<detail::int128_t>(-9'999'999, 9'999'999);
test_roundtrip_conversion_integer<detail::uint128_t>(0, 9'999'999);
#endif

test_conversion_from_float<float>();
test_conversion_from_float<double>();
test_conversion_from_float<long double>();
Expand Down