5#if !defined(__XTD_CORE_INTERNAL__)
6#error "Do not include this file: Internal use only"
10#include "../helpers/throw_helper.hpp"
11#include "../number_styles.hpp"
12#include "../types.hpp"
20inline std::basic_string<char_t> __parse_remove_decorations(
const std::basic_string<char_t>& s,
xtd::number_styles styles) {
21 std::basic_string<char_t> str(s);
23 while (str.size() > 0 && (str[0] == 9 || str[0] == 10 || str[0] == 11 || str[0] == 12 || str[0] == 13 || str[0] == 32))
27 while (str.size() > 0 && (str[str.size() - 1] == 9 || str[str.size() - 1] == 10 || str[str.size() - 1] == 11 || str[str.size() - 1] == 12 || str[str.size() - 1] == 13 || str[str.size() - 1] == 32))
28 str.erase(str.size() - 1, 1);
39inline int __parse_remove_signs(std::basic_string<char_t>& str,
xtd::number_styles styles) {
44 str = str.substr(1, str.size() - 1);
50 str = str.substr(1, str.size() - 1);
67 str = str.substr(1, str.size() - 2);
75inline void __parse_check_valid_characters(
const std::basic_string<char_t>& str,
xtd::number_styles styles) {
76 std::basic_string<char_t> valid_characters = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'};
79 if ((styles &
xtd::number_styles::allow_hex_specifier) ==
xtd::number_styles::allow_hex_specifier) valid_characters += std::basic_string<char_t> {
'A',
'B',
'C',
'D',
'E',
'F',
'a',
'b',
'c',
'd',
'e',
'f'};
85 if (valid_characters.find(c) == std::basic_string<char_t>::npos)
90 size_t index = str.find(std::use_facet<std::numpunct<char_t>>(std::locale()).decimal_point());
91 if (index != std::basic_string<char_t>::npos && str.find(std::use_facet<std::numpunct<char_t>>(std::locale()).decimal_point(), index + 1) != std::basic_string<char_t>::npos)
97 while ((index = str.find(std::use_facet<std::numpunct<char_t>>(std::locale()).thousands_sep(), index)) != std::basic_string<char_t>::npos) {
98 if (str[index - 1] == std::use_facet<std::numpunct<char_t>>(std::locale()).thousands_sep())
105 size_t index = str.find(
'+');
106 if (index == std::basic_string<char_t>::npos) index = str.find(
'-');
107 if (index != std::basic_string<char_t>::npos && str[index - 1] !=
'e' && str[index - 1] !=
'E')
112template<
class value_t,
class char_t>
113inline value_t __parse_floating_point(
const std::basic_string<char_t>& str,
int sign,
xtd::number_styles styles) {
116 result = std::stold(str,
nullptr);
118 std::stringstream ss(str);
119 ss.imbue(std::locale());
123 result = sign < 0 ? -result : result;
125 return static_cast<value_t
>(result);
128template<
class value_t,
class char_t>
129inline value_t __parse_signed(
const std::basic_string<char_t>& str,
int base,
int sign,
xtd::number_styles styles) {
132 result = std::stoll(str,
nullptr, base);
134 std::stringstream ss(str);
135 ss.imbue(std::locale());
139 result = sign < 0 ? -result : result;
141 return static_cast<value_t
>(result);
144template<
class value_t,
class char_t>
145inline value_t __parse_unsigned(
const std::basic_string<char_t>& str,
int base,
xtd::number_styles styles) {
146 unsigned long long result = 0;
148 result = std::stoull(str,
nullptr, base);
150 std::stringstream ss(str);
151 ss.imbue(std::locale());
156 return static_cast<value_t
>(result);
159template<
class value_t,
class char_t>
160inline value_t __parse_floating_point_number(
const std::basic_string<char_t>& s,
xtd::number_styles styles,
const std::locale& locale) {
166 for (
auto& c : lower_str)
167 c = static_cast<char>(std::tolower(
c));
168 if (s ==
"inf")
return std::numeric_limits<value_t>::infinity();
169 if (s ==
"-inf")
return -std::numeric_limits<value_t>::infinity();
170 if (s ==
"nan")
return std::numeric_limits<value_t>::quiet_NaN();
172 std::basic_string<char_t> str = __parse_remove_decorations(s, styles);
173 int sign = __parse_remove_signs(str, styles);
175 __parse_check_valid_characters(str, styles);
179 result = std::stold(str,
nullptr);
181 std::stringstream ss(str);
186 result = sign < 0 ? -result : result;
188 return static_cast<value_t
>(result);
191template<
class value_t,
class char_t>
192inline value_t __parse_number(
const std::basic_string<char_t>& s,
xtd::number_styles styles) {
202 std::basic_string<char_t> str = __parse_remove_decorations(s, styles);
203 int sign = __parse_remove_signs(str, styles);
205 __parse_check_valid_characters(str, styles);
208 return __parse_signed<value_t>(str, base, sign, styles);
211template<
class value_t,
class char_t>
212inline value_t __parse_unsigned_number(
const std::basic_string<char_t>& s,
xtd::number_styles styles) {
222 std::basic_string<char_t> str = __parse_remove_decorations(s, styles);
225 __parse_check_valid_characters(str, styles);
228 return __parse_unsigned<value_t>(str, base, styles);
231template<
class value_t>
232value_t __parse_enum(
const std::string& str);
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
Throws an exption with specified exception case.
@ overflow
Arithmetic overflow.
@ format
The format is not valid.
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
number_styles
Determines the styles permitted in numeric string arguments that are passed to the xtd::parse and xtd...
Definition number_styles.hpp:16
@ allow_thousands
Indicates that the numeric string can have group separators, such as symbols that separate hundreds f...
@ allow_decimal_point
Indicates that the numeric string can have a decimal point. If the number_styles value includes the a...
@ allow_trailing_sign
Indicates that the numeric string can have a trailing sign. Valid trailing sign characters are determ...
@ allow_leading_sign
Indicates that the numeric string can have a leading sign.
@ none
Indicates that no style elements, such as leading or trailing white space, thousands separators,...
@ allow_parentheses
Indicates that the numeric string can have one pair of parentheses enclosing the number....
@ binary_number
Indicates that the allow_leading_white, allow_trailing_white, and allow_binary_specifier styles are u...
@ allow_exponent
Indicates that the numeric string can be in exponential notation. The allow_exponent flag allows the ...
@ allow_hex_specifier
Indicates that the numeric string represents a hexadecimal value. Valid hexadecimal values include th...
@ allow_octal_specifier
Indicates that the numeric string represents a octal value. Valid octal values include the numeric di...
@ allow_leading_white
Indicates that leading white-space characters can be present in the parsed string....
@ octal_number
Indicates that the allow_leading_white, allow_trailing_white, and allow_octal_specifier styles are us...
@ allow_trailing_white
Indicates that trailing white-space characters can be present in the parsed string....
@ allow_currency_symbol
Indicates that the numeric string can contain a currency symbol. Valid currency symbols are determine...
@ hex_number
Indicates that the allow_leading_white, allow_trailing_white, and allow_hex_specifier styles are used...
@ allow_binary_specifier
Indicates that the numeric string represents a binary value. Valid binary values include the numeric ...