alpaqa 1.0.0a17
Nonconvex constrained optimization
Loading...
Searching...
No Matches
duration-parse.hpp
Go to the documentation of this file.
1#pragma once
2
5#include <chrono>
6#include <string_view>
7
8namespace alpaqa::util {
9
10struct ALPAQA_EXPORT invalid_duration_value : std::invalid_argument {
11 explicit invalid_duration_value(const std::string &arg,
12 std::from_chars_result result)
13 : std::invalid_argument{arg}, result{result} {}
14 std::from_chars_result result;
15};
16
17struct ALPAQA_EXPORT invalid_duration_units : std::invalid_argument {
18 explicit invalid_duration_units(const std::string &arg,
19 std::string_view units)
20 : std::invalid_argument{arg}, units{units} {}
21 /// Points into original argument, beware lifetime issues.
22 std::string_view units;
23};
24
25/// Adds the first duration in the string @p s to the duration @p t.
26template <class Rep, class Period>
27std::string_view parse_single_duration(std::chrono::duration<Rep, Period> &t,
28 std::string_view s) {
29 using Duration = std::remove_cvref_t<decltype(t)>;
30 auto trim = s.find_first_not_of("+0 ");
31 if (trim == std::string_view::npos)
32 return {};
33 s.remove_prefix(trim);
34 const auto *val_end = s.data() + s.size();
35 double value;
36 auto res = from_chars(s.data(), val_end, value);
37 if (res.ec != std::errc())
39 "Invalid value '" + std::string(res.ptr, val_end) + "' for type '" +
41 "': " + std::make_error_code(res.ec).message(),
42 res);
43 std::string_view remainder{res.ptr, val_end};
44 auto end = remainder.find_first_of("+-0123456789. ");
45 std::string_view units = remainder.substr(0, end);
46 using std::chrono::duration;
47 auto cast = [](auto t) { return std::chrono::round<Duration>(t); };
48 if (units == "s" || units.empty())
49 t += cast(duration<double, std::ratio<1, 1>>{value});
50 else if (units == "ms")
51 t += cast(duration<double, std::ratio<1, 1'000>>{value});
52 else if (units == "us" || units == "µs")
53 t += cast(duration<double, std::ratio<1, 1'000'000>>{value});
54 else if (units == "ns")
55 t += cast(duration<double, std::ratio<1, 1'000'000'000>>{value});
56 else if (units == "min")
57 t += cast(duration<double, std::ratio<60, 1>>{value});
58 else if (units == "h")
59 t += cast(duration<double, std::ratio<3'600, 1>>{value});
60 else
62 "Invalid units '" + std::string(units) + "' for duration", units);
63 if (end == std::string_view::npos)
64 return {};
65 return remainder.substr(end);
66}
67
68/// Adds the sum of the durations in the string @p s to the duration @p t.
69template <class Rep, class Period>
70void parse_duration(std::chrono::duration<Rep, Period> &t, std::string_view s) {
71 while (!s.empty())
72 s = parse_single_duration(t, s);
73}
74
75} // namespace alpaqa::util
std::string demangled_typename(const std::type_info &t)
Get the pretty name of the given type as a string.
std::string_view parse_single_duration(std::chrono::duration< Rep, Period > &t, std::string_view s)
Adds the first duration in the string s to the duration t.
void parse_duration(std::chrono::duration< Rep, Period > &t, std::string_view s)
Adds the sum of the durations in the string s to the duration t.
std::from_chars_result from_chars(const char *first, const char *last, T &value, std::chars_format fmt=std::chars_format::general)
constexpr const auto inf
Definition config.hpp:112
std::string_view units
Points into original argument, beware lifetime issues.
invalid_duration_units(const std::string &arg, std::string_view units)
invalid_duration_value(const std::string &arg, std::from_chars_result result)