1- // Copyright 2024 Matt Borland
1+ // Copyright 2024 - 2025 Matt Borland
22// Distributed under the Boost Software License, Version 1.0.
33// https://www.boost.org/LICENSE_1_0.txt
44
2828#include < boost/decimal/detail/promotion.hpp>
2929#include < boost/decimal/detail/write_payload.hpp>
3030#include < boost/decimal/detail/formatting_limits.hpp>
31+ #include < boost/decimal/detail/from_chars_impl.hpp>
3132
3233#ifndef BOOST_DECIMAL_BUILD_MODULE
3334#include < cstdint>
@@ -43,111 +44,11 @@ namespace boost {
4344namespace decimal {
4445
4546// ---------------------------------------------------------------------------------------------------------------------
46- // from_chars and implementation
47+ // from_chars
4748// ---------------------------------------------------------------------------------------------------------------------
4849
49- namespace detail {
50-
51- #ifdef _MSC_VER
52- # pragma warning(push)
53- # pragma warning(disable:4127)
54- #endif
55-
56- template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
57- constexpr auto from_chars_general_impl (const char * first, const char * last, TargetDecimalType& value, const chars_format fmt) noexcept -> from_chars_result
58- {
59- using significand_type = std::conditional_t <(std::numeric_limits<typename TargetDecimalType::significand_type>::digits >
60- std::numeric_limits<std::uint64_t >::digits),
61- int128::uint128_t , std::uint64_t >;
62-
63- BOOST_DECIMAL_IF_CONSTEXPR (is_fast_type_v<TargetDecimalType>)
64- {
65- if (fmt == chars_format::cohort_preserving_scientific)
66- {
67- return {first, std::errc::invalid_argument};
68- }
69- }
70-
71- if (BOOST_DECIMAL_UNLIKELY (first >= last))
72- {
73- return {first, std::errc::invalid_argument};
74- }
75-
76- bool sign {};
77- significand_type significand {};
78- std::int32_t expval {};
79-
80- auto r {detail::parser (first, last, sign, significand, expval, fmt)};
81-
82- if (!r)
83- {
84- if (r.ec == std::errc::not_supported)
85- {
86- using resultant_sig_type = typename TargetDecimalType::significand_type;
87-
88- resultant_sig_type payload_value {};
89- if (significand < std::numeric_limits<resultant_sig_type>::max ())
90- {
91- payload_value = static_cast <resultant_sig_type>(significand);
92- }
93-
94- if (expval > 0 )
95- {
96- value = write_payload<TargetDecimalType, true >(payload_value);
97- }
98- else
99- {
100- value = write_payload<TargetDecimalType, false >(payload_value);
101- }
102-
103- if (sign)
104- {
105- value = -value;
106- }
107-
108- r.ec = std::errc ();
109- }
110- else if (r.ec == std::errc::value_too_large)
111- {
112- value = sign ? -std::numeric_limits<TargetDecimalType>::infinity () :
113- std::numeric_limits<TargetDecimalType>::infinity ();
114- r.ec = std::errc ();
115- }
116- else
117- {
118- value = std::numeric_limits<TargetDecimalType>::signaling_NaN ();
119- errno = static_cast <int >(r.ec );
120- }
121- }
122- else
123- {
124- BOOST_DECIMAL_IF_CONSTEXPR (!is_fast_type_v<TargetDecimalType>)
125- {
126- if (fmt == chars_format::cohort_preserving_scientific)
127- {
128- const auto sig_digs {detail::num_digits (significand)};
129- if (sig_digs > precision_v<TargetDecimalType>)
130- {
131- // If we are parsing more digits than are representable there's no concept of cohorts
132- return {last, std::errc::value_too_large};
133- }
134- }
135- }
136-
137- value = TargetDecimalType (significand, expval, sign);
138- }
139-
140- return r;
141- }
142-
143- #ifdef _MSC_VER
144- # pragma warning(pop)
145- #endif
146-
147- } // namespace detail
148-
149- template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
150- constexpr auto from_chars (const char * first, const char * last, TargetDecimalType& value, const chars_format fmt) noexcept -> from_chars_result
50+ BOOST_DECIMAL_EXPORT template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE TargetDecimalType>
51+ constexpr auto from_chars (const char * first, const char * last, TargetDecimalType& value, const chars_format fmt = chars_format::general) noexcept -> from_chars_result
15152{
15253 return detail::from_chars_general_impl (first, last, value, fmt);
15354}
0 commit comments