diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-07-02 04:00:06 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-07-02 04:00:06 +0100 |
| commit | 5adeb648f74c1771164c0686d6e0fc584cf36d9e (patch) | |
| tree | 060cd918d3dd9e931a1541a43c9edff1a404ff47 /nihil.util/parse_size.ccm | |
| parent | 06fafff8e9e9c096cc39bde0306caa53ad3a2351 (diff) | |
| download | nihil-5adeb648f74c1771164c0686d6e0fc584cf36d9e.tar.gz nihil-5adeb648f74c1771164c0686d6e0fc584cf36d9e.tar.bz2 | |
move everything from util to core
Diffstat (limited to 'nihil.util/parse_size.ccm')
| -rw-r--r-- | nihil.util/parse_size.ccm | 90 |
1 files changed, 0 insertions, 90 deletions
diff --git a/nihil.util/parse_size.ccm b/nihil.util/parse_size.ccm deleted file mode 100644 index 51bfb4f..0000000 --- a/nihil.util/parse_size.ccm +++ /dev/null @@ -1,90 +0,0 @@ -// This source code is released into the public domain. -export module nihil.util:parse_size; - -import nihil.std; -import nihil.core; - -import :ctype; -import :error; -import :monad; - -namespace nihil { - -export template <typename Char> -auto get_multiplier(Char c) -> std::expected<std::uint64_t, error> -{ - auto ret = std::uint64_t{1}; - - // clang-format off - switch (c) { - case 'p': case 'P': ret *= 1024; // NOLINT - case 't': case 'T': ret *= 1024; // NOLINT - case 'g': case 'G': ret *= 1024; // NOLINT - case 'm': case 'M': ret *= 1024; // NOLINT - case 'k': case 'K': ret *= 1024; // NOLINT - return ret; - - default: - return error(errc::invalid_unit); - } - // clang-format on -} - -// Parse a string containing a human-formatted size, such as "1024" -// or "4g". Parsing is always done in the "C" locale and does not -// recognise thousands separators or negative numbers. -export template <typename T, typename Char> -[[nodiscard]] -auto parse_size(std::basic_string_view<Char> str) -> std::expected<T, error> -{ - // Extract the numeric part of the string. - auto it = std::ranges::find_if_not(str, is_c_digit); - auto num_str = std::basic_string_view<Char>(std::ranges::begin(str), it); - - if (num_str.empty()) - co_return error(errc::empty_string); - - auto ret = T{0}; - - for (auto c : num_str) { - if (ret > (std::numeric_limits<T>::max() / 10)) - co_return error(std::errc::result_out_of_range); - ret *= 10; - - auto digit = static_cast<T>(c - '0'); - if ((std::numeric_limits<T>::max() - digit) < ret) - co_return error(std::errc::result_out_of_range); - ret += digit; - } - - if (it == str.end()) - // No multiplier. - co_return ret; - - auto mchar = *it++; - - if (it != str.end()) - // Multiplier is more than one character. - co_return error(errc::invalid_unit); - - auto mult = co_await get_multiplier(mchar); - - if (std::cmp_greater(ret, std::numeric_limits<T>::max() / mult)) - co_return error(std::errc::result_out_of_range); - - co_return ret *mult; -} - -export template <typename T> -[[nodiscard]] auto parse_size(char const *s) -{ - return parse_size<T>(std::string_view(s)); -} - -export template <typename T> -[[nodiscard]] auto parse_size(wchar_t const *s) -{ - return parse_size<T>(std::wstring_view(s)); -} - -} // namespace nihil |
