Skip to content

Commit

Permalink
Merge pull request #863 from cppalliance/842
Browse files Browse the repository at this point in the history
  • Loading branch information
mborland authored Feb 18, 2025
2 parents aba2c7b + fb3c452 commit b1ec783
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 79 deletions.
22 changes: 16 additions & 6 deletions include/boost/decimal/charconv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ namespace detail {
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
constexpr auto from_chars_general_impl(const char* first, const char* last, TargetDecimalType& value, chars_format fmt) noexcept -> from_chars_result
{
using significand_type = std::conditional_t<std::is_same<typename TargetDecimalType::significand_type, uint128>::value, uint128, std::uint64_t>;
using significand_type = std::conditional_t<(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
std::numeric_limits<std::uint64_t>::digits),
detail::uint128, std::uint64_t>;

if (first >= last)
{
Expand Down Expand Up @@ -288,7 +290,10 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c
int exp {};
auto significand {frexp10(value, &exp)};

using uint_type = std::conditional_t<std::is_same<typename TargetDecimalType::significand_type, uint128>::value, uint128, std::uint64_t>;
using uint_type = std::conditional_t<(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
std::numeric_limits<std::uint64_t>::digits),
detail::uint128, std::uint64_t>;

auto significand_digits = num_digits(significand);
exp += significand_digits - 1;
bool append_zeros = false;
Expand Down Expand Up @@ -526,7 +531,10 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
}
}

using uint_type = std::conditional_t<std::is_same<typename TargetDecimalType::significand_type, uint128>::value, uint128, std::uint64_t>;
using uint_type = std::conditional_t<(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
std::numeric_limits<std::uint64_t>::digits),
detail::uint128, std::uint64_t>;

auto r = to_chars_integer_impl<uint_type, uint_type>(first, last, significand, 10);

if (BOOST_DECIMAL_UNLIKELY(!r))
Expand Down Expand Up @@ -637,7 +645,9 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const TargetDecimalType& value, int precision = -1) noexcept -> to_chars_result
{
using Unsigned_Integer = std::conditional_t<std::is_same<typename TargetDecimalType::significand_type, uint128>::value, uint128, std::uint64_t>;
using Unsigned_Integer = std::conditional_t<(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
std::numeric_limits<std::uint64_t>::digits),
detail::uint128, std::uint64_t>;

if (signbit(value))
{
Expand Down Expand Up @@ -780,8 +790,8 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_impl(char* first, char* last, TargetDecima
}

auto abs_value = abs(value);
constexpr auto max_fractional_value = impl::decimal_val_v<TargetDecimalType> < 64 ? TargetDecimalType{1, 7} :
impl::decimal_val_v<TargetDecimalType> < 128 ? TargetDecimalType{1, 16} :
constexpr auto max_fractional_value = decimal_val_v<TargetDecimalType> < 64 ? TargetDecimalType{1, 7} :
decimal_val_v<TargetDecimalType> < 128 ? TargetDecimalType{1, 16} :
TargetDecimalType{1, 34};

constexpr auto min_fractional_value = TargetDecimalType{1, -4};
Expand Down
5 changes: 3 additions & 2 deletions include/boost/decimal/cstdlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ namespace detail {
template <typename TargetDecimalType>
inline auto strtod_calculation(const char* str, char** endptr, char* buffer, std::size_t str_length) noexcept -> TargetDecimalType
{
using significand_type = std::conditional_t<std::is_same<TargetDecimalType, decimal128>::value ||
std::is_same<TargetDecimalType, decimal128_fast>::value, detail::uint128, std::uint64_t>;
using significand_type = std::conditional_t<(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
std::numeric_limits<std::uint64_t>::digits),
detail::uint128, std::uint64_t>;

std::memcpy(buffer, str, str_length);
convert_string_to_c_locale(buffer);
Expand Down
8 changes: 4 additions & 4 deletions include/boost/decimal/decimal128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,10 @@ BOOST_DECIMAL_EXPORT class decimal128 final
explicit constexpr operator std::bfloat16_t() const noexcept;
#endif

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal128>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal128>), bool> = true>
constexpr operator Decimal() const noexcept;

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal128>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal128>), bool> = true>
explicit constexpr operator Decimal() const noexcept;

// cmath functions that are easier as friends
Expand Down Expand Up @@ -1113,13 +1113,13 @@ constexpr decimal128::operator std::bfloat16_t() const noexcept
}
#endif

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal128>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal128>), bool>>
constexpr decimal128::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal128>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal128>), bool>>
constexpr decimal128::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
Expand Down
8 changes: 4 additions & 4 deletions include/boost/decimal/decimal32_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,10 @@ BOOST_DECIMAL_EXPORT class decimal32_fast final


// Conversion to other decimal type
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal32_fast>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal32_fast>), bool> = true>
constexpr operator Decimal() const noexcept;

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal32_fast>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal32_fast>), bool> = true>
explicit constexpr operator Decimal() const noexcept;

friend constexpr auto direct_init(std::uint_fast32_t significand, std::uint_fast8_t exponent, bool sign) noexcept -> decimal32_fast;
Expand Down Expand Up @@ -1334,13 +1334,13 @@ constexpr decimal32_fast::operator std::bfloat16_t() const noexcept
}
#endif

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal32_fast>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal32_fast>), bool>>
constexpr decimal32_fast::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal32_fast>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal32_fast>), bool>>
constexpr decimal32_fast::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
Expand Down
8 changes: 4 additions & 4 deletions include/boost/decimal/decimal64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,10 @@ BOOST_DECIMAL_EXPORT class decimal64 final


// Conversion to other decimal type
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal64>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal64>), bool> = true>
constexpr operator Decimal() const noexcept;

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal64>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal64>), bool> = true>
explicit constexpr operator Decimal() const noexcept;

// 3.2.6 Conversion to floating-point type
Expand Down Expand Up @@ -940,13 +940,13 @@ constexpr decimal64::operator detail::uint128_t() const noexcept

#endif

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal64>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal64>), bool>>
constexpr decimal64::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal64>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal64>), bool>>
constexpr decimal64::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
Expand Down
10 changes: 5 additions & 5 deletions include/boost/decimal/decimal64_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ BOOST_DECIMAL_EXPORT class decimal64_fast final
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::uint64_t);

template <typename ReturnType, typename T>
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> std::enable_if_t<!std::is_same<ReturnType, decimal64>::value, ReturnType>;
BOOST_DECIMAL_FORCE_INLINE friend constexpr auto detail::d64_mul_impl(const T& lhs, const T& rhs) noexcept -> std::enable_if_t<detail::is_fast_type_v<ReturnType>, ReturnType>;

public:
constexpr decimal64_fast() noexcept = default;
Expand Down Expand Up @@ -272,10 +272,10 @@ BOOST_DECIMAL_EXPORT class decimal64_fast final
#endif

// Conversion to other decimal type
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal64_fast>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal64_fast>), bool> = true>
constexpr operator Decimal() const noexcept;

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal64_fast>), bool> = true>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal64_fast>), bool> = true>
explicit constexpr operator Decimal() const noexcept;

// Unary Operators
Expand Down Expand Up @@ -935,13 +935,13 @@ constexpr decimal64_fast::operator std::bfloat16_t() const noexcept
}
#endif

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> > detail::impl::decimal_val_v<decimal64_fast>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> > detail::decimal_val_v<decimal64_fast>), bool>>
constexpr decimal64_fast::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::impl::decimal_val_v<Decimal> <= detail::impl::decimal_val_v<decimal64_fast>), bool>>
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE Decimal, std::enable_if_t<detail::is_decimal_floating_point_v<Decimal> && (detail::decimal_val_v<Decimal> <= detail::decimal_val_v<decimal64_fast>), bool>>
constexpr decimal64_fast::operator Decimal() const noexcept
{
return to_decimal<Decimal>(*this);
Expand Down
11 changes: 9 additions & 2 deletions include/boost/decimal/detail/attributes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ constexpr auto max_significand_v() noexcept
template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType, std::enable_if_t<decimal_val_v<DecimalType> >= 128, bool> = true>
constexpr auto max_significand_v() noexcept
{
return std::is_same<DecimalType, decimal128>::value ? uint128{UINT64_C(0b1111111111'1111111111'1111111111'1111111111'111111), UINT64_MAX} :
uint128{UINT64_C(542101086242752), UINT64_C(4003012203950112767)};
return decimal_val_v<DecimalType> == 128 ? uint128{UINT64_C(0b1111111111'1111111111'1111111111'1111111111'111111), UINT64_MAX} :
uint128{UINT64_C(542101086242752), UINT64_C(4003012203950112767)};
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType>
Expand All @@ -99,6 +99,13 @@ constexpr auto max_string_length_v() noexcept -> int
decimal_val_v<DecimalType> < 128 ? 25 : 41;
}

template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE DecimalType>
constexpr auto is_fast_type_v() noexcept -> bool
{
// The fast types all assign 1 additional bit over the regular types
return decimal_val_v<DecimalType> % 2 == 1;
}

} // namespace impl

template <typename Dec, std::enable_if_t<detail::is_decimal_floating_point_v<Dec>, bool> = true>
Expand Down
Loading

0 comments on commit b1ec783

Please sign in to comment.