66#include < sstream>
77#include < utility>
88
9- template <typename T>
10- struct bounds {
11- T lower;
12- T upper;
13- bool contains (T x) const {
14- return (x >= lower && x <= upper);
15- }
16- };
17-
18- namespace std {
19-
20- template <typename T, typename Char>
21- requires std::formattable<T, Char>
22- struct formatter <bounds<T>, Char> {
23- std::formatter<T, Char> underlying_;
24-
25- constexpr auto parse (std::basic_format_parse_context<Char> &ctx) {
26- return underlying_.parse (ctx);
27- }
28-
29- template <typename FormatContext>
30- auto format (const bounds<T> &b, FormatContext &ctx) const {
31- auto out = ctx.out ();
32- out = underlying_.format (b.lower , ctx);
33- for (const char &c : std::string (" .. " )) {
34- *out++ = Char (c);
35- }
36- out = underlying_.format (b.upper , ctx);
37- return out;
38- }
39- };
40-
41- } // namespace std
42-
439namespace partdiff {
4410
4511 template <typename T, typename U = std::underlying_type_t <T>>
@@ -139,43 +105,40 @@ namespace partdiff {
139105 };
140106
141107 auto number = &(this ->options .number );
142- this ->add_argument_description (" num" , number, std::format (" number of threads ({:d})" , num_bounds),
143- [number] { return num_bounds.contains (*number); });
108+ this ->add_argument_description (" num" , number, std::format (" number of threads ({:d})" , num_bounds), num_bounds);
144109
145110 auto method = &(this ->options .method );
146111 this ->add_argument_description (
147112 " method" , method, std::format (" calculation method ({:d})\n {}" , method_bounds, display_enum (method_bounds)),
148- [method] { return method_bounds. contains (*method); } );
113+ method_bounds);
149114
150115 auto interlines = &(this ->options .interlines );
151116 this ->add_argument_description (" lines" , interlines,
152117 std::format (" number of interlines ({1:d})\n "
153118 " {0}matrixsize = (interlines * 8) + 9" ,
154119 indent, lines_bounds),
155- [interlines] { return lines_bounds. contains (*interlines); } );
120+ lines_bounds);
156121
157122 auto pert_func = &(this ->options .pert_func );
158123 this ->add_argument_description (
159124 " func" , pert_func, std::format (" perturbation function ({:d})\n {}" , func_bounds, display_enum (func_bounds)),
160- [pert_func] { return func_bounds. contains (*pert_func); } );
125+ func_bounds);
161126
162127 auto termination = &(this ->options .termination );
163128 this ->add_argument_description (
164129 " term" , termination, std::format (" termination condition ({:d})\n {}" , term_bounds, display_enum (term_bounds)),
165- [termination] { return term_bounds. contains (*termination); } );
130+ term_bounds);
166131
167132 this ->add_argument_description (" acc/iter" , std::format (" depending on term:\n "
168133 " {0}accuracy: {1:.0e}\n "
169134 " {0}iterations: {2:d}\n " ,
170135 indent, accuracy_bounds, iteration_bounds));
171136
172137 auto term_accuracy = &(this ->options .term_accuracy );
173- this ->add_argument_description (" acc" , term_accuracy, std::nullopt ,
174- [term_accuracy] { return accuracy_bounds.contains (*term_accuracy); });
138+ this ->add_argument_description (" acc" , term_accuracy, std::nullopt , accuracy_bounds);
175139
176140 auto term_iteration = &(this ->options .term_iteration );
177- this ->add_argument_description (" iter" , term_iteration, std::nullopt ,
178- [term_iteration] { return iteration_bounds.contains (*term_iteration); });
141+ this ->add_argument_description (" iter" , term_iteration, std::nullopt , iteration_bounds);
179142 }
180143
181144 void argument_parser::add_argument_description (std::string name, std::optional<std::string> description_for_usage) {
@@ -188,11 +151,11 @@ namespace partdiff {
188151 template <class T >
189152 void argument_parser::add_argument_description (std::string name, T *target,
190153 std::optional<std::string> description_for_usage,
191- std::function< bool ()> check ) {
154+ bounds<T> target_bounds ) {
192155 argument_description arg_desc;
193156 arg_desc.name = name;
194157 arg_desc.target = target;
195- arg_desc.read_from_string = [target = arg_desc.target , check ](const std::string &input) {
158+ arg_desc.read_from_string = [target = arg_desc.target , target_bounds ](const std::string &input) {
196159 T *casted_ptr = std::any_cast<T *>(target);
197160 bool valid_input = false ;
198161 std::istringstream iss (input);
@@ -203,7 +166,7 @@ namespace partdiff {
203166 } else {
204167 valid_input = static_cast <bool >(iss >> *casted_ptr);
205168 }
206- valid_input &= check ( );
169+ valid_input &= target_bounds. contains (*casted_ptr );
207170 return valid_input;
208171 };
209172 arg_desc.description_for_usage = description_for_usage;
0 commit comments