Raptor 4.0.0-rc.1
A fast and space-efficient pre-filter
Loading...
Searching...
No Matches
to_bytes.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <cmath>
13#include <cstddef>
14#include <stdexcept>
15#include <string_view>
16
17#include <seqan3/std/charconv>
18
19namespace raptor
20{
21
22namespace detail
23{
24
25template <typename number_t>
26[[nodiscard]] size_t to_bytes_impl(std::string_view const input)
27{
28 number_t value{};
29 auto [ptr, ec] = std::from_chars(input.data(), input.data() + input.size(), value);
30
31 if (ec == std::errc::invalid_argument)
32 throw std::invalid_argument{"Invalid number in \"" + std::string{input} + "\"."};
33 else if (ec == std::errc::result_out_of_range)
34 throw std::out_of_range{"Number in \"" + std::string{input} + "\" is out of range."};
35
36 std::string_view const unit{ptr, input.end()};
37
38 if (unit.empty())
39 {
41 {
42 double integral_part{};
43 double fractional_part = std::modf(value, std::addressof(integral_part));
44 if (fractional_part)
45 throw std::invalid_argument{"Fractional bytes are not allowed."};
46 }
47
48 return static_cast<size_t>(value);
49 }
50
51 if (unit == "K")
52 return static_cast<size_t>(value * 1000);
53 else if (unit == "Ki")
54 return static_cast<size_t>(value * 1024);
55 else if (unit == "M")
56 return static_cast<size_t>(value * 1000 * 1000);
57 else if (unit == "Mi")
58 return static_cast<size_t>(value * 1024 * 1024);
59 else if (unit == "G")
60 return static_cast<size_t>(value * 1000 * 1000 * 1000);
61 else if (unit == "Gi")
62 return static_cast<size_t>(value * 1024 * 1024 * 1024);
63 else if (unit == "T")
64 return static_cast<size_t>(value * 1000ULL * 1000ULL * 1000ULL * 1000ULL);
65 else if (unit == "Ti")
66 return static_cast<size_t>(value * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
67 else if (unit == "P")
68 return static_cast<size_t>(value * 1000ULL * 1000ULL * 1000ULL * 1000ULL * 1000ULL);
69 else if (unit == "Pi")
70 return static_cast<size_t>(value * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
71 else if (unit == "E")
72 return static_cast<size_t>(value * 1000ULL * 1000ULL * 1000ULL * 1000ULL * 1000ULL * 1000ULL);
73 else if (unit == "Ei")
74 return static_cast<size_t>(value * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
75
76 throw std::invalid_argument{"Unknown unit in \"" + std::string{input} + "\"."};
77}
78
79} // namespace detail
80
81[[nodiscard]] inline size_t to_bytes(std::string_view input)
82{
83 input.remove_prefix(std::min(input.find_first_not_of(' '), input.size()));
84 if (auto const pos = input.find_last_not_of(' '); pos != std::string_view::npos)
85 input.remove_suffix(input.size() - 1 - pos);
86
87 if (input.empty())
88 return 0;
89
90 if (input.starts_with('-'))
91 throw std::invalid_argument{"Negative numbers are not allowed."};
92
93 if (input.contains('.'))
94 return detail::to_bytes_impl<double>(input);
95 else
96 return detail::to_bytes_impl<size_t>(input);
97}
98
99} // namespace raptor
T addressof(T... args)
T data(T... args)
T empty(T... args)
T end(T... args)
T find_first_not_of(T... args)
T find_last_not_of(T... args)
T from_chars(T... args)
T min(T... args)
T modf(T... args)
T remove_prefix(T... args)
T remove_suffix(T... args)
T size(T... args)
T starts_with(T... args)
Hide me