Skip to content

Commit b9adb39

Browse files
authored
Merge pull request #768 from cppalliance/str_charconv
2 parents a3094df + 2cfee86 commit b9adb39

File tree

6 files changed

+133
-0
lines changed

6 files changed

+133
-0
lines changed

doc/decimal/charconv.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ namespace decimal {
8888
template <typename DecimalType>
8989
constexpr boost::decimal::from_chars_result from_chars(const char* first, const char* last, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept
9090
91+
#ifdef BOOST_DECIMAL_HAS_STD_STRING_VIEW
92+
93+
template <typename DecimalType>
94+
constexpr boost::decimal::from_chars_result from_chars(std::string_view str, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept
95+
96+
#else
97+
98+
template <typename DecimalType>
99+
constexpr boost::decimal::from_chars_result from_chars(const std::string& str, DecimalType& value, boost::decimal::chars_format fmt = boost::decimal::chars_format::general) noexcept
100+
101+
#endif
102+
91103
#ifdef BOOST_DECIMAL_HAS_STD_CHARCONV
92104
93105
template <typename DecimalType>

doc/decimal/config.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@ This flag increases the performance of the basis operations (e.g. add, sub, mul,
4646
- `BOOST_DECIMAL_HAS_STD_CHARCONV`: This macro is defined if header `<charconv>` exists and the language standard used is >= C++17
4747
* We only need the structs and enums out of the header so we are not concerned with being overly restrictive about the feature test macros.
4848
** Known compilers that support this lighter requirement are: GCC >= 10, Clang >= 13, and MSVC >= 14.2
49+
50+
- `BOOST_DECIMAL_HAS_STD_STRING_VIEW`: This macro is defined if header `<string_view>` exists and the langauge standard used is >= C++17

include/boost/decimal/charconv.hpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727

2828
#if !defined(BOOST_DECIMAL_DISABLE_CLIB)
2929

30+
#ifndef BOOST_DECIMAL_BUILD_MODULE
31+
#include <string>
32+
#endif
33+
3034
namespace boost {
3135
namespace decimal {
3236

@@ -94,31 +98,103 @@ BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* la
9498
return detail::from_chars_general_impl(first, last, value, fmt);
9599
}
96100

101+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
102+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal32& value, chars_format fmt = chars_format::general) noexcept
103+
{
104+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
105+
}
106+
#else
107+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal32& value, chars_format fmt = chars_format::general) noexcept
108+
{
109+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
110+
}
111+
#endif
112+
97113
BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* last, decimal32_fast& value, chars_format fmt = chars_format::general) noexcept
98114
{
99115
return detail::from_chars_general_impl(first, last, value, fmt);
100116
}
101117

118+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
119+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal32_fast& value, chars_format fmt = chars_format::general) noexcept
120+
{
121+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
122+
}
123+
#else
124+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal32_fast& value, chars_format fmt = chars_format::general) noexcept
125+
{
126+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
127+
}
128+
#endif
129+
102130
BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* last, decimal64& value, chars_format fmt = chars_format::general) noexcept
103131
{
104132
return detail::from_chars_general_impl(first, last, value, fmt);
105133
}
106134

135+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
136+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal64& value, chars_format fmt = chars_format::general) noexcept
137+
{
138+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
139+
}
140+
#else
141+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal64& value, chars_format fmt = chars_format::general) noexcept
142+
{
143+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
144+
}
145+
#endif
146+
107147
BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* last, decimal64_fast& value, chars_format fmt = chars_format::general) noexcept
108148
{
109149
return detail::from_chars_general_impl(first, last, value, fmt);
110150
}
111151

152+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
153+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal64_fast& value, chars_format fmt = chars_format::general) noexcept
154+
{
155+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
156+
}
157+
#else
158+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal64_fast& value, chars_format fmt = chars_format::general) noexcept
159+
{
160+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
161+
}
162+
#endif
163+
112164
BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* last, decimal128& value, chars_format fmt = chars_format::general) noexcept
113165
{
114166
return detail::from_chars_general_impl(first, last, value, fmt);
115167
}
116168

169+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
170+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal128& value, chars_format fmt = chars_format::general) noexcept
171+
{
172+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
173+
}
174+
#else
175+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal128& value, chars_format fmt = chars_format::general) noexcept
176+
{
177+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
178+
}
179+
#endif
180+
117181
BOOST_DECIMAL_EXPORT constexpr auto from_chars(const char* first, const char* last, decimal128_fast& value, chars_format fmt = chars_format::general) noexcept
118182
{
119183
return detail::from_chars_general_impl(first, last, value, fmt);
120184
}
121185

186+
#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
187+
BOOST_DECIMAL_EXPORT inline auto from_chars(const std::string& str, decimal128_fast& value, chars_format fmt = chars_format::general) noexcept
188+
{
189+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
190+
}
191+
#else
192+
BOOST_DECIMAL_EXPORT constexpr auto from_chars(std::string_view str, decimal128_fast& value, chars_format fmt = chars_format::general) noexcept
193+
{
194+
return detail::from_chars_general_impl(str.data(), str.data() + str.size(), value, fmt);
195+
}
196+
#endif
197+
122198
#ifdef BOOST_DECIMAL_HAS_STD_CHARCONV
123199
BOOST_DECIMAL_EXPORT template <typename DecimalType>
124200
constexpr auto from_chars(const char* first, const char* last, DecimalType& value, std::chars_format fmt) noexcept
@@ -147,6 +223,13 @@ constexpr auto from_chars(const char* first, const char* last, DecimalType& valu
147223

148224
return std::from_chars_result {boost_r.ptr, boost_r.ec};
149225
}
226+
227+
BOOST_DECIMAL_EXPORT template <typename DecimalType>
228+
constexpr auto from_chars(std::string_view str, DecimalType& value, std::chars_format fmt) noexcept
229+
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_decimal_floating_point_v, DecimalType, std::from_chars_result)
230+
{
231+
return from_chars(str.data(), str.data() + str.size(), value, fmt);
232+
}
150233
#endif
151234

152235
// ---------------------------------------------------------------------------------------------------------------------

include/boost/decimal/detail/config.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,16 @@ typedef unsigned __int128 uint128_t;
323323
# define BOOST_DECIMAL_HAS_STD_CHARCONV
324324
# endif
325325
# endif
326+
327+
# if __has_include(<string_view>)
328+
# ifndef BOOST_DECIMAL_BUILD_MODULE
329+
# include <string_view>
330+
# endif
331+
# if __cpp_lib_string_view >= 201606L
332+
# define BOOST_DECIMAL_HAS_STD_STRING_VIEW
333+
# endif
334+
# endif
335+
326336
#endif
327337

328338
// Since we should not be able to pull these in from the STL in module mode define them ourselves

modules/decimal.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module;
3030
#include <complex>
3131
#include <compare>
3232
#include <charconv>
33+
#include <string_view>
3334

3435
// <stdfloat> is a C++23 feature that is not everywhere yet
3536
#if __has_include(<stdfloat>)

test/test_from_chars.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ void test_non_finite_values()
162162

163163
const char* snan_str = "nan(snan)";
164164
auto r = from_chars(snan_str, snan_str + std::strlen(snan_str), val);
165+
BOOST_TEST(r);
165166
BOOST_TEST(isnan(val));
166167

167168
const char* qnan_str = "nan";
@@ -318,6 +319,17 @@ void test_from_chars_general_std()
318319

319320
#endif
320321

322+
template <typename T>
323+
void test_string_interface()
324+
{
325+
constexpr T correct_val {42};
326+
std::string str {"42"};
327+
T val;
328+
const auto r = from_chars(str, val);
329+
BOOST_TEST(r);
330+
BOOST_TEST_EQ(val, correct_val);
331+
}
332+
321333
int main()
322334
{
323335
test_from_chars_scientific<decimal32>();
@@ -362,12 +374,25 @@ int main()
362374
test_hex_values<decimal32_fast>();
363375
test_hex_values<decimal64_fast>();
364376

377+
test_string_interface<decimal32>();
378+
test_string_interface<decimal64>();
379+
test_string_interface<decimal32_fast>();
380+
test_string_interface<decimal64_fast>();
381+
365382
#if !defined(BOOST_DECIMAL_REDUCE_TEST_DEPTH)
366383
test_from_chars_scientific<decimal128>();
367384
test_from_chars_fixed<decimal128>();
368385
test_from_chars_general<decimal128>();
369386
test_non_finite_values<decimal128>();
370387
test_hex_values<decimal128>();
388+
test_string_interface<decimal128>();
389+
390+
test_from_chars_scientific<decimal128_fast>();
391+
test_from_chars_fixed<decimal128_fast>();
392+
test_from_chars_general<decimal128_fast>();
393+
test_non_finite_values<decimal128_fast>();
394+
test_hex_values<decimal128_fast>();
395+
test_string_interface<decimal128_fast>();
371396
#endif
372397

373398
return boost::report_errors();

0 commit comments

Comments
 (0)