Преглед изворни кода

Use helper functions for flags and options

Sam Jaffe пре 4 година
родитељ
комит
6d24e4c2be
2 измењених фајлова са 37 додато и 18 уклоњено
  1. 12 5
      include/program_args/arguments.h
  2. 25 13
      include/program_args/arguments_impl.hpp

+ 12 - 5
include/program_args/arguments.h

@@ -9,6 +9,7 @@ namespace program {
 
 template <typename Impl> class Arguments {
 private:
+  using option_id = std::string;
   struct Argument;
   struct Flag;
   struct Option;
@@ -33,15 +34,21 @@ private:
   void add_options(std::string const & name, char abbrev,
                    std::string const & description,
                    std::vector<std::string> aliases = {});
+  option_id id(std::string const & arg) const;
+  option_id id(char arg) const { return id({'-', arg}); }
+  bool is_option(std::string const & arg) const;
+  bool is_option(char arg) const { return is_option({'-', arg}); }
+  bool is_flag(std::string const & arg) const;
+  bool is_flag(char arg) const { return is_flag({'-', arg}); }
 
 private:
   // Metadata variables
   bool primed_{false};
-  std::map<std::string, std::string> argument_descriptions;
-  std::map<size_t, std::string> argument_names;
-  std::map<std::string, std::string> option_descriptions;
-  std::map<std::string, std::string> option_names;
-  std::set<std::string> flag_names;
+  std::map<option_id, std::string> argument_descriptions;
+  std::map<size_t, option_id> argument_names;
+  std::map<option_id, std::string> option_descriptions;
+  std::map<std::string, option_id> option_names;
+  std::set<option_id> flag_names;
 
   // Data/Output variables
   std::string program;

+ 25 - 13
include/program_args/arguments_impl.hpp

@@ -121,22 +121,18 @@ Arguments<Impl>::Arguments(int argc, char const * const * const argv) {
       // TODO: Special arguments store for passthroughs
       arguments.insert(arguments.end(), &argv[i + 1], &argv[argc]);
       break;
-    } else if (argv[i][0] == '-') {
-      auto it = option_names.find(argv[i]);
-      if (it == option_names.end()) { throw NotAnArgumentError(argv[i]); }
-      auto & name = it->second;
+    } else if (argv[i][0] != '-') {
+      arguments.emplace_back(argv[i]);
+    } else if (!is_flag(argv[i])) {
+      options[id(argv[i])].emplace_back(argv[i]);
+      ++i;
+    } else {
       // TODO: Flag handling for e.g. -v2 -vv
-      if (!flag_names.count(name)) {
-        options[name].emplace_back(argv[i + 1]);
-        // TODO: Arity
-        ++i;
-      } else if (arg_starts_with("--no-")) {
-        flags[name] = 0;
+      if (arg_starts_with("--no-")) {
+        flags[id(argv[i])] = 0;
       } else {
-        ++flags[name];
+        ++flags[id(argv[i])];
       }
-    } else {
-      arguments.emplace_back(argv[i]);
     }
   }
 }
@@ -174,6 +170,22 @@ void Arguments<Impl>::add_options(std::string const & name, char abbrev,
   option_descriptions.emplace(join(",", aliases), description);
 }
 
+template <typename Impl>
+auto Arguments<Impl>::id(std::string const & arg) const -> option_id {
+  if (!is_option(arg)) { throw NotAnArgumentError(arg); }
+  return option_names.at(arg);
+}
+
+template <typename Impl>
+bool Arguments<Impl>::is_option(std::string const & arg) const {
+  return option_names.count(arg);
+}
+
+template <typename Impl>
+bool Arguments<Impl>::is_flag(std::string const & arg) const {
+  return is_option(arg) && flag_names.count(id(arg));
+}
+
 template <typename Impl>
 auto Arguments<Impl>::argument(size_t index, std::string const & name,
                                std::string const & description) {