The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
charconv.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2024 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
15#include "utils/charconv.hpp"
16
17#include <cassert>
18#include <cctype>
19#include <clocale>
20#include <cstdlib>
21#include <string>
22
23#ifdef USE_FALLBACK_CHARCONV
24
25namespace
26{
27 template<typename T>
28 T string_to_floating_point(const char* str, char** str_end) = delete;
29 template<>
30 float string_to_floating_point(const char* str, char** str_end)
31 {
32 return std::strtof(str, str_end);
33 }
34 template<>
35 double string_to_floating_point(const char* str, char** str_end)
36 {
37 return std::strtod(str, str_end);
38 }
39 template<>
40 long double string_to_floating_point(const char* str, char** str_end)
41 {
42 return std::strtold(str, str_end);
43 }
44}
45namespace utils::charconv
46{
47 template<typename T>
48 std::enable_if_t<std::is_same_v<T, double> || std::is_same_v<T, float> || std::is_same_v<T, long double>, from_chars_result> from_chars(const char* first, const char* last, T& value, chars_format fmt)
49 {
50 // We don't need the other formats.
51 assert(fmt == chars_format::general);
52
53 // Make a copy to make sure its null terminated.
54 std::string buffer = std::string(first, last);
55 // from_chars doesnt support leading whitespace or plus signs.
56 if(buffer.empty() || std::isspace(buffer.front()) || buffer.front() == '+' ) {
57 return { first, std::errc::invalid_argument };
58 }
59
60
61 locale_t l = newlocale(LC_ALL, "C", static_cast<locale_t>(0));
62 locale_t l_prev = uselocale(l);
63
64 //initilize this to silence a warning.
65 char* str_end = nullptr;
66 value = string_to_floating_point<T>( buffer.data(), &str_end );
67
68 uselocale(l_prev);
69 freelocale(l);
70
71 if(str_end == buffer.data()) {
72 return { first, std::errc::invalid_argument };
73 }
74 return { first + (str_end - buffer.data()), std::errc() };
75 }
76 template from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt);
77 template from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt);
78 template from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt);
79}
80
81#endif
std::enable_if_t< std::is_integral_v< T >, std::from_chars_result > from_chars(const char *first, const char *last, T &value, int base=10)
Definition charconv.hpp:62
charconv_impl::from_chars_result from_chars_result
Definition charconv.hpp:52
charconv_impl::chars_format chars_format
Definition charconv.hpp:51
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139