|
7 | 7 |
|
8 | 8 | #include "4C_io_value_parser.hpp" |
9 | 9 |
|
| 10 | +#include <c4/charconv.hpp> |
| 11 | + |
10 | 12 | #include <algorithm> |
11 | 13 |
|
12 | 14 | FOUR_C_NAMESPACE_OPEN |
@@ -74,34 +76,36 @@ void Core::IO::ValueParser::read_internal(bool& value) |
74 | 76 |
|
75 | 77 | void Core::IO::ValueParser::read_internal(int& value) |
76 | 78 | { |
77 | | - std::string token(advance_token()); |
78 | | - std::size_t end; |
79 | | - try |
| 79 | + auto token(advance_token()); |
| 80 | + if (token.front() == '+') [[unlikely]] |
80 | 81 | { |
81 | | - value = std::stoi(token.data(), &end); |
| 82 | + token = token.substr(1); |
82 | 83 | } |
83 | | - catch (const std::logic_error&) |
| 84 | + |
| 85 | + c4::csubstr token_cstr = c4::csubstr{token.data(), token.size()}; |
| 86 | + // Note: this could use std::from_chars if clang fully supports it at some point. |
| 87 | + std::size_t n_chars_used = c4::from_chars_first(token_cstr, &value); |
| 88 | + if (n_chars_used != token.size()) |
84 | 89 | { |
85 | | - FOUR_C_THROW("Could not parse '{}' as an integer value.", token.c_str()); |
| 90 | + FOUR_C_THROW("Could not parse '{}' as an integer value.", token); |
86 | 91 | } |
87 | | - |
88 | | - if (end != token.size()) FOUR_C_THROW("Could not parse '{}' as an integer value.", token.c_str()); |
89 | 92 | } |
90 | 93 |
|
91 | 94 | void Core::IO::ValueParser::read_internal(double& value) |
92 | 95 | { |
93 | | - std::string token(advance_token()); |
94 | | - std::size_t end; |
95 | | - try |
| 96 | + auto token(advance_token()); |
| 97 | + if (token.front() == '+') [[unlikely]] |
96 | 98 | { |
97 | | - value = std::stod(token.data(), &end); |
| 99 | + token = token.substr(1); |
98 | 100 | } |
99 | | - catch (const std::logic_error&) |
| 101 | + |
| 102 | + c4::csubstr token_cstr = c4::csubstr{token.data(), token.size()}; |
| 103 | + // Note: this could use std::from_chars if clang fully supports it at some point. |
| 104 | + std::size_t n_chars_used = c4::from_chars_first(token_cstr, &value); |
| 105 | + if (n_chars_used != token.size()) |
100 | 106 | { |
101 | | - FOUR_C_THROW("Could not parse '{}' as a double value.", token.c_str()); |
| 107 | + FOUR_C_THROW("Could not parse '{}' as a double value.", token); |
102 | 108 | } |
103 | | - |
104 | | - if (end != token.size()) FOUR_C_THROW("Could not parse '{}' as a double value.", token.c_str()); |
105 | 109 | } |
106 | 110 |
|
107 | 111 | void Core::IO::ValueParser::read_internal(std::string& value) |
|
0 commit comments