refactor: move to libtrbase: tr_num_pase()

This commit is contained in:
Charles Kerr
2026-02-11 21:03:36 -06:00
parent f15eeabd00
commit f64d69046e
10 changed files with 76 additions and 71 deletions

View File

@@ -57,6 +57,8 @@ target_include_directories(trbase
${CMAKE_SOURCE_DIR})
target_link_libraries(trbase
PRIVATE
FastFloat::fast_float
PUBLIC
transmission::fmt-header-only
utf8::cpp

View File

@@ -4,12 +4,16 @@
// License text can be found in the licenses/ folder.
#include <cctype>
#include <charconv> // std::from_chars()
#include <cstdint>
#include <cstring>
#include <iterator>
#include <optional>
#include <ranges>
#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>
#ifdef _WIN32
#include <windows.h>
@@ -17,6 +21,8 @@
#include <fmt/format.h>
#include <fast_float/fast_float.h>
#include <utf8.h>
#include <wildmat.h>
@@ -153,3 +159,58 @@ std::u8string tr_strv_to_u8string(std::string_view const sv)
auto const view = std::views::transform(u8str, [](char c) -> char8_t { return c; });
return { view.begin(), view.end() };
}
// --- tr_num_parse()
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* remainder, int base)
requires std::is_integral_v<T>
{
auto val = T{};
auto const* const begin_ch = std::data(str);
auto const* const end_ch = begin_ch + std::size(str);
auto const result = std::from_chars(begin_ch, end_ch, val, base);
if (result.ec != std::errc{})
{
return std::nullopt;
}
if (remainder != nullptr)
{
*remainder = str;
remainder->remove_prefix(result.ptr - std::data(str));
}
return val;
}
template std::optional<long long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<int> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<char> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned long long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned int> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned short> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned char> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* remainder)
requires std::is_floating_point_v<T>
{
auto const* const begin_ch = std::data(str);
auto const* const end_ch = begin_ch + std::size(str);
auto val = T{};
auto const result = fast_float::from_chars(begin_ch, end_ch, val);
if (result.ec != std::errc{})
{
return std::nullopt;
}
if (remainder != nullptr)
{
*remainder = str;
remainder->remove_prefix(result.ptr - std::data(str));
}
return val;
}
template std::optional<double> tr_num_parse(std::string_view sv, std::string_view* remainder);

View File

@@ -9,8 +9,10 @@
#include <cctype>
#include <cstdint>
#include <iterator>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#ifdef _WIN32
@@ -100,6 +102,14 @@ template <typename... Args> constexpr bool tr_strv_sep(std::string_view* sv, std
return true;
}
template <typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr, int base = 10)
requires std::is_integral_v<T>;
template <typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr)
requires std::is_floating_point_v<T>;
[[nodiscard]] std::string_view tr_strv_strip(std::string_view str);
[[nodiscard]] std::string tr_strv_to_utf8_string(std::string_view sv);

View File

@@ -227,7 +227,6 @@ target_link_libraries(${TR_NAME}
Threads::Threads
libdeflate::libdeflate
CURL::libcurl
FastFloat::fast_float
psl::psl
natpmp::natpmp
miniupnpc::miniupnpc

View File

@@ -18,9 +18,10 @@
#include <fmt/format.h>
#include "lib/base/string-utils.h"
#include "libtransmission/clients.h"
#include "libtransmission/types.h"
#include "libtransmission/utils.h"
using namespace std::literals;

View File

@@ -6,7 +6,6 @@
#include <algorithm> // for std::sort, std::transform
#include <array> // std::array
#include <cfloat> // DBL_DIG
#include <charconv> // std::from_chars()
#include <chrono>
#include <cstdint> // SIZE_MAX
#include <cstdlib> // getenv()
@@ -38,8 +37,6 @@
#include <fmt/format.h>
#include <fast_float/fast_float.h>
#include "lib/base/env.h"
#include "lib/base/string-utils.h"
#include "lib/base/tr-assert.h"
@@ -469,58 +466,3 @@ std::string_view tr_get_mime_type_for_filename(std::string_view filename)
auto constexpr Fallback = "application/octet-stream"sv;
return Fallback;
}
// --- tr_num_parse()
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* remainder, int base)
requires std::is_integral_v<T>
{
auto val = T{};
auto const* const begin_ch = std::data(str);
auto const* const end_ch = begin_ch + std::size(str);
auto const result = std::from_chars(begin_ch, end_ch, val, base);
if (result.ec != std::errc{})
{
return std::nullopt;
}
if (remainder != nullptr)
{
*remainder = str;
remainder->remove_prefix(result.ptr - std::data(str));
}
return val;
}
template std::optional<long long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<int> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<char> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned long long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned long> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned int> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned short> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template std::optional<unsigned char> tr_num_parse(std::string_view str, std::string_view* remainder, int base);
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* remainder)
requires std::is_floating_point_v<T>
{
auto const* const begin_ch = std::data(str);
auto const* const end_ch = begin_ch + std::size(str);
auto val = T{};
auto const result = fast_float::from_chars(begin_ch, end_ch, val);
if (result.ec != std::errc{})
{
return std::nullopt;
}
if (remainder != nullptr)
{
*remainder = str;
remainder->remove_prefix(result.ptr - std::data(str));
}
return val;
}
template std::optional<double> tr_num_parse(std::string_view sv, std::string_view* remainder);

View File

@@ -68,14 +68,6 @@ template<typename T>
// ---
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr, int base = 10)
requires std::is_integral_v<T>;
template<typename T>
[[nodiscard]] std::optional<T> tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr)
requires std::is_floating_point_v<T>;
/**
* @brief Given a string like "1-4" or "1-4,6,9,14-51", this returns a
* newly-allocated array of all the integers in the set.

View File

@@ -25,7 +25,6 @@
#include "libtransmission/benc.h"
#include "libtransmission/quark.h"
#include "libtransmission/utils.h"
#include "libtransmission/variant.h"
using namespace std::literals;

View File

@@ -35,7 +35,6 @@
#include "lib/base/i18n.h"
#include "libtransmission/quark.h"
#include "libtransmission/utils.h"
#include "libtransmission/variant.h"
namespace

View File

@@ -23,11 +23,11 @@
#include "lib/base/error.h"
#include "lib/base/file-utils.h"
#include "lib/base/i18n.h"
#include "lib/base/string-utils.h"
#include "lib/base/tr-assert.h"
#include "libtransmission/log.h"
#include "libtransmission/quark.h"
#include "libtransmission/utils.h"
#include "libtransmission/variant.h"
using namespace std::literals;