| 271 | |
| 272 | template<typename... Args> |
| 273 | bool argparse_withargs(std::vector<const char*> &args, |
| 274 | std::vector<const char*>::iterator& i, |
| 275 | std::ostream& oss, |
| 276 | const char* opt, |
| 277 | Args*... opts) |
| 278 | { |
| 279 | if (!ceph_argparse_flag(args, i, opt, nullptr)) { |
| 280 | return false; |
| 281 | } |
| 282 | auto parse = [&](auto& opt) { |
| 283 | if (i == args.end()) { |
| 284 | oss << "expecting additional argument to " << opt; |
| 285 | return false; |
| 286 | } |
| 287 | using opt_t = std::remove_pointer_t<decay_t<decltype(opt)>>; |
| 288 | string err; |
| 289 | if constexpr (std::is_same_v<opt_t, string>) { |
| 290 | opt->assign(*i); |
| 291 | } else if constexpr (is_same_v<opt_t, int>) { |
| 292 | *opt = strict_strtol(*i, 10, &err); |
| 293 | } else if constexpr (is_same_v<opt_t, float>) { |
| 294 | *opt = strict_strtof(*i, &err); |
| 295 | } |
| 296 | i = args.erase(i); |
| 297 | if (err.empty()) |
| 298 | return true; |
| 299 | else { |
| 300 | oss << err; |
| 301 | return false; |
| 302 | } |
| 303 | }; |
| 304 | (... && parse(opts)); |
| 305 | return true; |
| 306 | } |
| 307 | |
| 308 | int do_add_bucket(CephContext* cct, |
| 309 | const char* me, |
no test coverage detected