1- // Copyright 2023 Matt Borland
1+ // Copyright 2023 - 2024 Matt Borland
22// Distributed under the Boost Software License, Version 1.0.
33// https://www.boost.org/LICENSE_1_0.txt
44
1010#include < boost/decimal/decimal32.hpp>
1111#include < boost/decimal/decimal64.hpp>
1212#include < boost/decimal/decimal128.hpp>
13+ #include < boost/decimal/charconv.hpp>
14+ #include < algorithm>
1315#include < format>
1416#include < iostream>
1517#include < iomanip>
1618#include < string>
1719#include < tuple>
1820
19- // See for general impl
20- // https://en.cppreference.com/w/cpp/utility/format/formatter
21+ // Default :g
22+ // Fixed :f
23+ // Scientific :3
24+ // Hex :a
25+ //
26+ // Capital letter for any of the above leads to all characters being uppercase
2127
2228namespace boost ::decimal::detail {
2329
2430template <typename ParseContext>
2531constexpr auto parse_impl (ParseContext& ctx)
2632{
2733 auto it {ctx.begin ()};
28- int precision = 5 ;
34+ int precision = 6 ;
35+ boost::decimal::chars_format fmt = boost::decimal::chars_format::general;
2936
3037 if (it == ctx.end ())
3138 {
32- return std::make_tuple (precision, it);
39+ return std::make_tuple (precision, fmt, it);
3340 }
3441
3542 if (*it == ' .' )
@@ -54,80 +61,36 @@ constexpr auto parse_impl(ParseContext& ctx)
5461 throw std::format_error (" Invalid format" );
5562 }
5663
57- return std::make_tuple (precision, it);
64+ return std::make_tuple (precision, fmt, it);
5865};
5966};
6067
6168template <>
6269struct std ::formatter<boost::decimal::decimal32>
63- {
64- int precision {};
65-
66- template <typename ParseContext>
67- constexpr auto parse (ParseContext& ctx)
68- {
69- auto res {boost::decimal::detail::parse_impl (ctx)};
70- precision = std::get<0 >(res);
71- return std::get<1 >(res);
72- }
73-
74- template <typename FormatContext>
75- auto format (const boost::decimal::decimal32& v, FormatContext& ctx)
76- {
77- std::ostringstream out;
78- out << std::setprecision (precision) << v;
79-
80- return std::ranges::copy (std::move (out).str (), ctx.out ()).out ;
81- }
82- };
83-
84- template <>
85- struct std ::formatter<boost::decimal::decimal64>
8670{
8771 int precision;
72+ boost::decimal::chars_format fmt;
8873
89- template <typename ParseContext>
90- constexpr auto parse (ParseContext& ctx)
74+ constexpr auto parse (const std::basic_format_parse_context<char >& context)
9175 {
92- auto res {boost::decimal::detail::parse_impl (ctx )};
76+ auto res {boost::decimal::detail::parse_impl (context )};
9377 precision = std::get<0 >(res);
94- return std::get<1 >(res);
78+ fmt = std::get<1 >(res);
79+ return std::get<2 >(res);
9580 }
9681
97- template <typename FormatContext >
98- auto format (const boost::decimal::decimal32& v, FormatContext& ctx)
82+ template <typename OutputIterator >
83+ auto format (const boost::decimal::decimal32& v, std::basic_format_context<OutputIterator, char >& context) const
9984 {
100- std::ostringstream out;
101- out << std::setprecision (precision) << v;
102-
103- return std::ranges::copy (std::move (out).str (), ctx.out ()).out ;
85+ auto && out = context.out ();
86+ char buffer[128U ];
87+ const auto r = to_chars (buffer, buffer + sizeof (buffer), v, fmt, precision);
88+ *r.ptr = ' \0 ' ;
89+ out = std::copy (buffer, r.ptr , out);
90+ return out;
10491 }
10592};
10693
107- template <>
108- struct std ::formatter<boost::decimal::decimal128>
109- {
110- int precision;
111-
112- template <typename ParseContext>
113- constexpr auto parse (ParseContext& ctx)
114- {
115- auto res {boost::decimal::detail::parse_impl (ctx)};
116- precision = std::get<0 >(res);
117- return std::get<1 >(res);
118- }
119-
120- template <typename FormatContext>
121- auto format (const boost::decimal::decimal32& v, FormatContext& ctx)
122- {
123- std::ostringstream out;
124- out << std::setprecision (precision) << v;
125-
126- return std::ranges::copy (std::move (out).str (), ctx.out ()).out ;
127- }
128- };
129-
130-
13194#endif
13295
13396#endif // BOOST_DECIMAL_FORMAT_HPP
0 commit comments