Skip to content

Commit 685b337

Browse files
authored
Merge pull request #562 from cppalliance/charconv_limits
Add buffer sizing for charconv
2 parents 3ebfb24 + 38f6249 commit 685b337

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

doc/decimal/charconv.adoc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,44 @@ NOTE: `BOOST_DECIMAL_CONSTEXPR` is defined if:
6767
- `\\__GNUC__` >= 9
6868
- Compiler has: `__builtin_is_constant_evaluated()`
6969
- C++20 support with: `std::is_constant_evaluated()`
70+
71+
The library offers an additional feature for sizing buffers without specified precision and in general format
72+
[source, c++]
73+
----
74+
namespace boost {
75+
namespace decimal {
76+
77+
template <typename T>
78+
struct limits
79+
{
80+
static constexpr int max_chars;
81+
}
82+
83+
} //namespace decimal
84+
} //namespace boost
85+
----
86+
87+
The member can then be used to size buffers such as:
88+
89+
[source, c++]
90+
----
91+
#include <boost/decimal.hpp>
92+
#include <iostream>
93+
94+
int main()
95+
{
96+
using namespace boost::decimal;
97+
98+
decimal32 val {5, -1};
99+
100+
char buffer[limits<T>::max_chars];
101+
102+
auto r_to = to_chars(buffer, buffer + sizeof(buffer), val);
103+
*r_to.ptr = '\0';
104+
105+
std::cout << buffer << std::endl;
106+
107+
return 0;
108+
}
109+
110+
----

include/boost/decimal/charconv.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,18 @@ BOOST_DECIMAL_EXPORT BOOST_DECIMAL_CONSTEXPR auto to_chars(char* first, char* la
812812
return detail::to_chars_impl(first, last, value, fmt, precision);
813813
}
814814

815+
template <typename T>
816+
struct limits
817+
{
818+
BOOST_DECIMAL_ATTRIBUTE_UNUSED static constexpr int max_chars = boost::decimal::detail::max_string_length_v<T>;
819+
};
820+
821+
#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900)
822+
823+
template <typename T> BOOST_DECIMAL_ATTRIBUTE_UNUSED constexpr int limits<T>::max_chars;
824+
825+
#endif
826+
815827
} //namespace decimal
816828
} //namespace boost
817829

include/boost/decimal/detail/attributes.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ template <>
7878
BOOST_DECIMAL_CONSTEXPR_VARIABLE_SPECIALIZATION auto max_significand_v<decimal128> =
7979
uint128{UINT64_C(0b1111111111'1111111111'1111111111'1111111111'111111), UINT64_MAX};
8080

81+
// sign + decimal digits + '.' + 'e' + '+/-' + max digits of exponent + null term
8182
template <typename Dec, std::enable_if_t<detail::is_decimal_floating_point_v<Dec>, bool> = true>
8283
BOOST_DECIMAL_ATTRIBUTE_UNUSED BOOST_DECIMAL_CONSTEXPR_VARIABLE auto max_string_length_v = std::is_same<Dec, decimal32>::value ? 15 : 25;
8384

test/test_to_chars.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static constexpr auto N = static_cast<std::size_t>(1024U >> 4U); // Number of tr
2323
#if !defined(BOOST_DECIMAL_DISABLE_CLIB) && !(defined(__GNUC__) && __GNUC__ >= 13 && !defined(__aarch64__))
2424

2525
template <typename T>
26-
void test_value(T val, const char* result, chars_format fmt = boost::decimal::chars_format::general, int precision = -1)
26+
void test_value(T val, const char* result, chars_format fmt, int precision = -1)
2727
{
2828
char buffer[256] {};
2929
auto r = to_chars(buffer, buffer + sizeof(buffer), val, fmt, precision);
@@ -32,6 +32,16 @@ void test_value(T val, const char* result, chars_format fmt = boost::decimal::ch
3232
BOOST_TEST_CSTR_EQ(result, buffer);
3333
}
3434

35+
template <typename T>
36+
void test_value(T val, const char* result)
37+
{
38+
char buffer[boost::decimal::limits<T>::max_chars] {};
39+
auto r = to_chars(buffer, buffer + sizeof(buffer), val, chars_format::general);
40+
*r.ptr = '\0';
41+
BOOST_TEST(r);
42+
BOOST_TEST_CSTR_EQ(result, buffer);
43+
}
44+
3545
template <typename T>
3646
void test_non_finite_values()
3747
{

0 commit comments

Comments
 (0)