Skip to content

Commit 7710013

Browse files
committed
Add bounds class to express the parameter bounds
1 parent 3239c71 commit 7710013

1 file changed

Lines changed: 56 additions & 40 deletions

File tree

argument_parser.cpp

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,41 @@
33
#include <format>
44
#include <print>
55
#include <sstream>
6+
#include <utility>
7+
8+
template <typename T>
9+
struct bounds {
10+
T lower;
11+
T upper;
12+
bool contains(T x) const {
13+
return (x >= lower && x <= upper);
14+
}
15+
};
16+
17+
namespace std {
18+
19+
template <typename T, typename Char>
20+
requires std::formattable<T, Char>
21+
struct formatter<bounds<T>, Char> {
22+
std::formatter<T, Char> underlying_;
23+
24+
constexpr auto parse(std::basic_format_parse_context<Char> &ctx) {
25+
return underlying_.parse(ctx);
26+
}
27+
28+
template <typename FormatContext>
29+
auto format(const bounds<T> &b, FormatContext &ctx) const {
30+
auto out = ctx.out();
31+
out = underlying_.format(b.lower, ctx);
32+
for (const char &c : std::string(" .. ")) {
33+
*out++ = Char(c);
34+
}
35+
out = underlying_.format(b.upper, ctx);
36+
return out;
37+
}
38+
};
39+
40+
} // namespace std
641

742
namespace partdiff {
843

@@ -11,19 +46,15 @@ namespace partdiff {
1146
return static_cast<U>(v);
1247
}
1348

14-
static constexpr uint64_t min_interlines = 0;
15-
static constexpr uint64_t max_interlines = 10240;
16-
static constexpr uint64_t min_iteration = 1;
17-
static constexpr uint64_t max_iteration = 200000;
18-
static constexpr uint64_t min_threads = 1;
19-
static constexpr uint64_t max_threads = 1024;
20-
static constexpr double min_accuracy = 1e-4;
21-
static constexpr double max_accuracy = 1e-20;
22-
2349
using calculation_method = calculation_options::calculation_method;
2450
using perturbation_function = calculation_options::perturbation_function;
2551
using termination_condition = calculation_options::termination_condition;
2652

53+
static constexpr bounds<uint64_t> interlines_bounds{0, 10240};
54+
static constexpr bounds<uint64_t> iteration_bounds{1, 200000};
55+
static constexpr bounds<uint64_t> thread_bounds{1, 1024};
56+
static constexpr bounds<double> accuracy_bounds{1e-20, 1e-4};
57+
2758
argument_parser::argument_parser(const int argc, char const *argv[])
2859
: app_name(argv[0]),
2960
args(argv + 1, argv + argc) {
@@ -69,7 +100,7 @@ namespace partdiff {
69100
}
70101
if (this->options.termination == termination_condition::accuracy) {
71102
parse_param(argument_index::term_accuracy, args[5]);
72-
this->options.term_iteration = max_iteration;
103+
this->options.term_iteration = iteration_bounds.upper;
73104
} else {
74105
parse_param(argument_index::term_iteration, args[5]);
75106
this->options.term_accuracy = 0.0;
@@ -89,22 +120,12 @@ namespace partdiff {
89120

90121
void argument_parser::fill_argument_descriptions() {
91122

92-
auto scientific_double = [](double val) {
93-
auto temp = std::format("{:.0e}", val);
94-
int epos = temp.find("e");
95-
std::string mantissa_str = temp.substr(0, epos);
96-
std::string exponent_str = temp.substr(epos + 1, temp.length() - epos - 1);
97-
int exponent = stoi(exponent_str);
98-
return mantissa_str + "e" + std::to_string(exponent);
99-
};
100-
101123
constexpr int indent_width = 17;
102124
const std::string indent = std::format("{:{}s}", "", indent_width);
103125

104126
auto number = &(this->options.number);
105-
this->add_argument_description("num", number,
106-
std::format("number of threads ({:d} .. {:d})", min_threads, max_threads),
107-
[number] { return (*number >= min_threads && *number <= max_threads); });
127+
this->add_argument_description("num", number, std::format("number of threads ({:d})", thread_bounds),
128+
[number] { return (thread_bounds.contains(*number)); });
108129

109130
auto method = &(this->options.method);
110131
this->add_argument_description(
@@ -116,12 +137,11 @@ namespace partdiff {
116137
[method] { return (*method == calculation_method::gauss_seidel || *method == calculation_method::jacobi); });
117138

118139
auto interlines = &(this->options.interlines);
119-
this->add_argument_description(
120-
"lines", interlines,
121-
std::format("number of interlines ({1:d} .. {2:d})\n"
122-
"{0}matrixsize = (interlines * 8) + 9",
123-
indent, min_interlines, max_interlines),
124-
[interlines] { return (*interlines >= min_interlines && *interlines <= max_interlines); });
140+
this->add_argument_description("lines", interlines,
141+
std::format("number of interlines ({1:d})\n"
142+
"{0}matrixsize = (interlines * 8) + 9",
143+
indent, interlines_bounds),
144+
[interlines] { return (interlines_bounds.contains(*interlines)); });
125145

126146
auto pert_func = &(this->options.pert_func);
127147
this->add_argument_description(
@@ -146,22 +166,18 @@ namespace partdiff {
146166
*termination == termination_condition::iterations);
147167
});
148168

149-
this->add_argument_description("acc/iter",
150-
std::format("depending on term:\n"
151-
"{0}accuracy: {1:s} .. {2:s}\n"
152-
"{0}iterations: {3:d} .. {4:d}\n",
153-
indent, scientific_double(min_accuracy), scientific_double(max_accuracy),
154-
min_iteration, max_iteration));
169+
this->add_argument_description("acc/iter", std::format("depending on term:\n"
170+
"{0}accuracy: {1:.0e}\n"
171+
"{0}iterations: {2:d}\n",
172+
indent, accuracy_bounds, iteration_bounds));
155173

156174
auto term_accuracy = &(this->options.term_accuracy);
157-
this->add_argument_description("acc", term_accuracy, std::nullopt, [term_accuracy] {
158-
return (*term_accuracy >= max_accuracy && *term_accuracy <= min_accuracy);
159-
});
175+
this->add_argument_description("acc", term_accuracy, std::nullopt,
176+
[term_accuracy] { return (accuracy_bounds.contains(*term_accuracy)); });
160177

161178
auto term_iteration = &(this->options.term_iteration);
162-
this->add_argument_description("iter", term_iteration, std::nullopt, [term_iteration] {
163-
return (*term_iteration >= min_iteration && *term_iteration <= max_iteration);
164-
});
179+
this->add_argument_description("iter", term_iteration, std::nullopt,
180+
[term_iteration] { return (iteration_bounds.contains(*term_iteration)); });
165181
}
166182

167183
void argument_parser::add_argument_description(std::string name, std::optional<std::string> description_for_usage) {

0 commit comments

Comments
 (0)