2626using Benchmarks::arithmetic_float;
2727using Benchmarks::BenchArgs;
2828
29+ bool is_matched (const std::string &str, const std::span<std::string> filter) {
30+ if (filter.empty ()) {
31+ return true ;
32+ }
33+ for (const auto &f : filter) {
34+ if (str.find (f) != std::string::npos) {
35+ return true ;
36+ }
37+ }
38+ return false ;
39+ }
40+
2941template <arithmetic_float T>
3042void evaluateProperties (const std::vector<T> &lines,
31- const std::array<BenchArgs<T>, Benchmarks::COUNT> &args, const std::string& filter = " " ) {
43+ const std::array<BenchArgs<T>, Benchmarks::COUNT> &args, const std::span<std:: string> filter = {} ) {
3244 constexpr auto precision = std::numeric_limits<T>::digits10;
3345 fmt::println (" {:20} {:20}" , " Algorithm" , " Valid round-trip" );
3446
@@ -38,7 +50,7 @@ void evaluateProperties(const std::vector<T> &lines,
3850 continue ;
3951 }
4052 // Apply filter if provided
41- if (!filter. empty () && std::string (filter). find ( algo.name ) == std::string::npos ) {
53+ if (!is_matched ( algo.name , filter) ) {
4254 std::cout << " # filtered out " << algo.name << std::endl;
4355 continue ;
4456 }
@@ -73,14 +85,14 @@ void evaluateProperties(const std::vector<T> &lines,
7385
7486template <arithmetic_float T>
7587void process (const std::vector<T> &lines,
76- const std::array<BenchArgs<T>, Benchmarks::COUNT> &args, const std::string& filter = " " ) {
88+ const std::array<BenchArgs<T>, Benchmarks::COUNT> &args, const std::span<std:: string> filter = {} ) {
7789 for (const auto &algo : args) {
7890 if (!algo.used ) {
7991 std::cout << " # skipping " << algo.name << std::endl;
8092 continue ;
8193 }
8294 // Apply filter if provided
83- if (!filter. empty () && std::string (filter). find ( algo.name ) == std::string::npos ) {
95+ if (!is_matched ( algo.name , filter) ) {
8496 std::cout << " # filtered out " << algo.name << std::endl;
8597 continue ;
8698 }
@@ -155,18 +167,20 @@ int main(int argc, char **argv) {
155167 cxxopts::value<bool >()->default_value (" false" ))
156168 (" e,errol" , " Enable errol3 (current impl. returns invalid values, e.g., for 0)." ,
157169 cxxopts::value<bool >()->default_value (" false" ))
158- (" a,algo-filter" , " Filter algorithms by name substring." ,
159- cxxopts::value<std::string>()->default_value (" " ))
170+ (" a,algo-filter" , " Filter algorithms by name substring: you can use multiple filters separated by commas." ,
171+ cxxopts::value<std::vector<std::string>>()->default_value (" " ))
172+ (" r,repeat" , " Force a number of repetitions." ,
173+ cxxopts::value<size_t >()->default_value (" 0" ))
160174 (" h,help" , " Print usage." );
161175 const auto result = options.parse (argc, argv);
162176
163177 if (result[" help" ].as <bool >()) {
164178 std::cout << options.help () << std::endl;
165179 return EXIT_SUCCESS;
166180 }
167-
181+ const size_t repeat = result[ " repeat " ]. as < size_t >();
168182 const bool single = result[" single" ].as <bool >();
169- const std::string filter = result[" algo-filter" ].as <std::string>();
183+ std::vector<std:: string> filter = result[" algo-filter" ].as <std::vector<std:: string> >();
170184 std::cout << " number type: binary"
171185 << (single ? " 32 (float)" : " 64 (double)" ) << std::endl;
172186
@@ -198,6 +212,14 @@ int main(int argc, char **argv) {
198212 else
199213 algorithms = Benchmarks::initArgs<double >(errol);
200214
215+ if (repeat > 0 ) {
216+ std::cout << " # forcing repeat count to " << repeat << std::endl;
217+ std::visit ([repeat](auto &args) {
218+ for (auto &arg : args)
219+ arg.testRepeat = repeat;
220+ }, algorithms);
221+ }
222+
201223 const bool test = result[" test" ].as <bool >();
202224 std::visit ([test,&filter](const auto &lines, const auto &args) {
203225 using T1 = typename std::decay_t <decltype (lines)>::value_type;
0 commit comments