diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 7e5c4fcce..503e28a73 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -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 diff --git a/lib/base/string-utils.cc b/lib/base/string-utils.cc index be976169c..97a3b1705 100644 --- a/lib/base/string-utils.cc +++ b/lib/base/string-utils.cc @@ -4,12 +4,16 @@ // License text can be found in the licenses/ folder. #include +#include // std::from_chars() #include #include #include +#include #include #include #include +#include +#include #ifdef _WIN32 #include @@ -17,6 +21,8 @@ #include +#include + #include #include @@ -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 +[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base) + requires std::is_integral_v +{ + 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 tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); + +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); +template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); + +template +[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* remainder) + requires std::is_floating_point_v +{ + 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 tr_num_parse(std::string_view sv, std::string_view* remainder); diff --git a/lib/base/string-utils.h b/lib/base/string-utils.h index 4724fd0d6..08e80e0c5 100644 --- a/lib/base/string-utils.h +++ b/lib/base/string-utils.h @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include #include #ifdef _WIN32 @@ -100,6 +102,14 @@ template constexpr bool tr_strv_sep(std::string_view* sv, std return true; } +template +[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr, int base = 10) + requires std::is_integral_v; + +template +[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr) + requires std::is_floating_point_v; + [[nodiscard]] std::string_view tr_strv_strip(std::string_view str); [[nodiscard]] std::string tr_strv_to_utf8_string(std::string_view sv); diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt index ae90caf75..212aac257 100644 --- a/libtransmission/CMakeLists.txt +++ b/libtransmission/CMakeLists.txt @@ -227,7 +227,6 @@ target_link_libraries(${TR_NAME} Threads::Threads libdeflate::libdeflate CURL::libcurl - FastFloat::fast_float psl::psl natpmp::natpmp miniupnpc::miniupnpc diff --git a/libtransmission/clients.cc b/libtransmission/clients.cc index ea5a1ed0e..b5d2c24c6 100644 --- a/libtransmission/clients.cc +++ b/libtransmission/clients.cc @@ -18,9 +18,10 @@ #include +#include "lib/base/string-utils.h" + #include "libtransmission/clients.h" #include "libtransmission/types.h" -#include "libtransmission/utils.h" using namespace std::literals; diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index b1ae8d5b4..e8b1852cc 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -6,7 +6,6 @@ #include // for std::sort, std::transform #include // std::array #include // DBL_DIG -#include // std::from_chars() #include #include // SIZE_MAX #include // getenv() @@ -38,8 +37,6 @@ #include -#include - #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 -[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base) - requires std::is_integral_v -{ - 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 tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); - -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); -template std::optional tr_num_parse(std::string_view str, std::string_view* remainder, int base); - -template -[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* remainder) - requires std::is_floating_point_v -{ - 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 tr_num_parse(std::string_view sv, std::string_view* remainder); diff --git a/libtransmission/utils.h b/libtransmission/utils.h index ca6d6c123..4f0a1da54 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -68,14 +68,6 @@ template // --- -template -[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr, int base = 10) - requires std::is_integral_v; - -template -[[nodiscard]] std::optional tr_num_parse(std::string_view str, std::string_view* setme_remainder = nullptr) - requires std::is_floating_point_v; - /** * @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. diff --git a/libtransmission/variant-benc.cc b/libtransmission/variant-benc.cc index 6071ce874..41f7af74c 100644 --- a/libtransmission/variant-benc.cc +++ b/libtransmission/variant-benc.cc @@ -25,7 +25,6 @@ #include "libtransmission/benc.h" #include "libtransmission/quark.h" -#include "libtransmission/utils.h" #include "libtransmission/variant.h" using namespace std::literals; diff --git a/libtransmission/variant-json.cc b/libtransmission/variant-json.cc index 3dfa91465..4254c41c4 100644 --- a/libtransmission/variant-json.cc +++ b/libtransmission/variant-json.cc @@ -35,7 +35,6 @@ #include "lib/base/i18n.h" #include "libtransmission/quark.h" -#include "libtransmission/utils.h" #include "libtransmission/variant.h" namespace diff --git a/libtransmission/variant.cc b/libtransmission/variant.cc index bda9f61c9..d9b3020bc 100644 --- a/libtransmission/variant.cc +++ b/libtransmission/variant.cc @@ -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;