add --target-duration option
[benchmarks.git] / src / main.cpp
index f9bde51eea3437d63f615c18096e8a4cae070b39..c49029f427bbef1f5d2b1f57295d4153c94105c3 100644 (file)
@@ -11,6 +11,7 @@
 #include <map>
 #include <optional>
 #include <ostream>
+#include <sstream>
 #include <string_view>
 #include <system_error>
 #include <type_traits>
@@ -390,6 +391,35 @@ class OptionsParser final
         i_value.emplace();
         this->parse_int(value, i_value.value(), limits);
     }
+    template <typename Float>
+    std::enable_if_t<std::is_floating_point_v<Float>, void> parse_float(
+        std::optional<std::string_view> value, Float &f_value)
+    {
+        f_value = Float();
+        if (!value)
+        {
+            help_and_exit("missing value for ", current_option());
+        }
+        auto str = *value;
+        std::istringstream is{std::string(str)};
+        if (!(is >> f_value))
+        {
+            help_and_exit("invalid value for: ", current_option());
+        }
+    }
+    template <typename Float>
+    std::enable_if_t<std::is_floating_point_v<Float>, void> parse_float(
+        std::optional<std::string_view> value, std::optional<Float> &f_value,
+        bool required = true)
+    {
+        if (!required && !value)
+        {
+            f_value = std::nullopt;
+            return;
+        }
+        f_value.emplace();
+        this->parse_float(value, f_value.value());
+    }
 };
 
 inline std::vector<std::string_view> Options::parse(
@@ -479,6 +509,23 @@ int main(int, char **argv)
                        config.use_json = true;
                        json_pretty = true;
                    }},
+        Option{.short_name = 'd',
+               .long_name = "target-duration",
+               .description =
+                   "target duration for a single benchmark in seconds",
+               .value_kind = OptionValueKind::Required,
+               .parse_value =
+                   [&](OptionsParser &parser, auto value) {
+                       parser.parse_float(value, config.target_duration);
+                       if (config.target_duration &&
+                           (!std::isfinite(*config.target_duration) ||
+                            *config.target_duration < 0))
+                       {
+                           parser.help_and_exit(
+                               "value out of range: target-duration=",
+                               *config.target_duration);
+                       }
+                   }},
     };
     OptionsParser parser(options, argv);
     auto args = parser.parse();