diff --git a/benchmark/util/args.h b/benchmark/util/args.h index d7a8eb2c..e17f70af 100644 --- a/benchmark/util/args.h +++ b/benchmark/util/args.h @@ -7,96 +7,105 @@ namespace details { - template - bool extract(const char *, T &); + inline bool extract(const char * p, size_t & t) + { + char * e; + long long ll = std::strtoll(p, &e, 0); + if (*e || ll < 0) + { + return false; + } + t = static_cast(ll); + return true; + } - template - int parse(int todo, char ** p, ARGS & ... args); + inline bool extract(const char * p, unsigned short & t) + { + char * e; + long long ll = std::strtoll(p, &e, 0); + if (*e + || ll < static_cast(std::numeric_limits::min()) + || ll > static_cast(std::numeric_limits::max()) + ) + { + return false; + } + t = static_cast(ll); + return true; + } - template <> - int parse(int todo, char ** p) - { - return 0; - } + inline bool extract(const char * p, std::string & t) + { + t = p; + return true; + } - template - int parse(int todo, char ** p, T & t, ARGS & ... args) - { - if (todo != 0 && extract(*p, t)) - { - return parse(todo - 1, p + 1, args ...) + 1; - } - return 0; - } + inline bool extract(const char * p, const char *& t) + { + t = p; + return true; + } - template - int parse_args(int & argc, char ** argv, ARGS & ... args) - { - if (argc <= 1) - { - return 0; - } + template + inline bool extract_impl(size_t todo, int& index, bool& r, char**& p, Arg& arg){ + if(!r||index>=todo){ + return false; + } - int length = argc - 1; - char ** begin = argv + 1; - char ** end = begin + length; + r = extract(*p, arg); - int done = parse(length, begin, args ...); - std::rotate(begin, begin + done, end); - std::reverse(end - done, end); + if(!r){ + return false; + } - argc -= done; - return done; - } + index++; + p++; - template <> - bool extract(const char * p, size_t & t) - { - char * e; - long long ll = std::strtoll(p, &e, 0); - if (*e || ll < 0) - { - return false; - } - t = static_cast(ll); - return true; - } + return true; + } - template <> - bool extract(const char * p, unsigned short & t) - { - char * e; - long long ll = std::strtoll(p, &e, 0); - if (*e - || ll < static_cast(std::numeric_limits::min()) - || ll > static_cast(std::numeric_limits::max()) - ) - { - return false; - } - t = static_cast(ll); - return true; - } + template + inline int parse(size_t todo, char ** p, ARGS & ... args) + { + int index = 0; + bool r = true; + (void)std::initializer_list{(extract_impl(todo, index, r, p, args), 0)...}; + return index; + } - template <> - bool extract(const char * p, std::string & t) - { - t = p; - return true; - } + template + inline int parse(int todo, char ** p, ARGS & ... args) + { + int index = 0; + (void)std::initializer_list{(index+=extract(*p, args), p++, 0)...}; + return index; + } - template <> - bool extract(const char * p, const char *& t) - { - t = p; - return true; - } + template + inline int parse_args(int & argc, char ** argv, ARGS & ... args) + { + if (argc <= 1) + { + return 0; + } + + int length = argc - 1; + char ** begin = argv + 1; + char ** end = begin + length; + + int done = parse(length, begin, args ...); + std::rotate(begin, begin + done, end); + std::reverse(end - done, end); + + argc -= done; + return done; + } } template -static int parse_args(int & argc, char ** argv, ARGS & ... args) +inline static int parse_args(int & argc, char ** argv, ARGS & ... args) { - return details::parse_args(argc, argv, args ...); + return details::parse_args(argc, argv, args ...); } #endif //_BENCHMARK_ARGS_H_