ReUseX
0.0.5
3D Point Cloud Processing for Building Reuse
Toggle main menu visibility
Loading...
Searching...
No Matches
parse_number.hpp
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: 2026 Povl Filip Sonne-Frederiksen
2
//
3
// SPDX-License-Identifier: GPL-3.0-or-later
4
5
#pragma once
6
7
// Locale-independent text -> number. std::stod / strtod / std::stof follow
8
// the C locale's LC_NUMERIC: a process that calls setlocale(LC_ALL, "") —
9
// every QApplication does — reads "799.85" as 799 under da_DK, and stops a
10
// strtod loop dead at the '.' (Q2 review: the Qt client's intrinsics). These
11
// use std::from_chars, which never consults the locale.
12
13
#include <charconv>
14
#include <cstddef>
15
#include <optional>
16
#include <stdexcept>
17
#include <string>
18
#include <string_view>
19
#include <system_error>
20
21
namespace
reusex::utils
{
22
27
template
<
typename
T>
28
std::optional<T>
parse_number
(std::string_view s,
29
std::size_t *consumed =
nullptr
) {
30
std::size_t i = 0;
31
while
(i < s.size() && (s[i] ==
' '
|| s[i] ==
'\t'
|| s[i] ==
'\n'
||
32
s[i] ==
'\r'
|| s[i] ==
'\f'
|| s[i] ==
'\v'
))
33
++i;
34
if
(i < s.size() && s[i] ==
'+'
&&
35
!(i + 1 < s.size() && (s[i + 1] ==
'-'
|| s[i + 1] ==
'+'
)))
36
++i;
37
T value{};
38
const
auto
r = std::from_chars(s.data() + i, s.data() + s.size(), value);
39
if
(r.ec != std::errc{}) {
40
if
(consumed)
41
*consumed = 0;
42
return
std::nullopt;
43
}
44
if
(consumed)
45
*consumed =
static_cast<
std::size_t
>
(r.ptr - s.data());
46
return
value;
47
}
48
51
inline
double
to_double
(std::string_view s, std::size_t *pos =
nullptr
) {
52
std::size_t used = 0;
53
const
auto
v =
parse_number<double>
(s, &used);
54
if
(!v)
55
throw
std::invalid_argument(
"not a number: '"
+ std::string(s) +
"'"
);
56
if
(pos)
57
*pos = used;
58
return
*v;
59
}
60
62
inline
float
to_float
(std::string_view s, std::size_t *pos =
nullptr
) {
63
std::size_t used = 0;
64
const
auto
v =
parse_number<float>
(s, &used);
65
if
(!v)
66
throw
std::invalid_argument(
"not a number: '"
+ std::string(s) +
"'"
);
67
if
(pos)
68
*pos = used;
69
return
*v;
70
}
71
72
}
// namespace reusex::utils
reusex::utils
Definition
cv.hpp:8
reusex::utils::to_float
float to_float(std::string_view s, std::size_t *pos=nullptr)
std::stof's contract without its locale.
Definition
parse_number.hpp:62
reusex::utils::parse_number
std::optional< T > parse_number(std::string_view s, std::size_t *consumed=nullptr)
Parse a number at the start of s, after optional whitespace and a '+' (strtod accepts both; from_char...
Definition
parse_number.hpp:28
reusex::utils::to_double
double to_double(std::string_view s, std::size_t *pos=nullptr)
std::stod's contract without its locale: throws std::invalid_argument when s does not start with a nu...
Definition
parse_number.hpp:51
libs
reusex
include
utils
parse_number.hpp
Generated by
1.18.0