Commit 11df3becfb76971fb57a7ffc58ca3064205e0bd2

Authored by Henry Fredrick Schreiner
1 parent d24a5926

Show parse order is preserved

CHANGELOG.md
  1 +## Version 1.1 (in progress)
  2 +* Added `app.parse_order()` with original parse order
  3 +
1 ## Version 1.0 4 ## Version 1.0
2 * Cleanup using `clang-tidy` and `clang-format` 5 * Cleanup using `clang-tidy` and `clang-format`
3 * Small improvements to Timers, easier to subclass Error 6 * Small improvements to Timers, easier to subclass Error
README.md
@@ -164,7 +164,7 @@ On the command line, options can be given as: @@ -164,7 +164,7 @@ On the command line, options can be given as:
164 * `--file=filename` (equals) 164 * `--file=filename` (equals)
165 165
166 Extra positional arguments will cause the program to exit, so at least one positional option with a vector is recommended if you want to allow extraneous arguments. 166 Extra positional arguments will cause the program to exit, so at least one positional option with a vector is recommended if you want to allow extraneous arguments.
167 -If you set `.allow_extras()` on the main `App`, the parse function will return the left over arguments instead of throwing an error. 167 +If you set `.allow_extras()` on the main `App`, the parse function will return the left over arguments instead of throwing an error. You can access a vector of pointers to the parsed options in the original order using `parse_order()`.
168 If `--` is present in the command line, 168 If `--` is present in the command line,
169 everything after that is positional only. 169 everything after that is positional only.
170 170
examples/CMakeLists.txt
@@ -17,3 +17,4 @@ endfunction() @@ -17,3 +17,4 @@ endfunction()
17 add_cli_exe(simple simple.cpp) 17 add_cli_exe(simple simple.cpp)
18 add_cli_exe(subcommands subcommands.cpp) 18 add_cli_exe(subcommands subcommands.cpp)
19 add_cli_exe(groups groups.cpp) 19 add_cli_exe(groups groups.cpp)
  20 +add_cli_exe(inter_argument_order inter_argument_order.cpp)
examples/inter_argument_order.cpp 0 → 100644
  1 +#include <CLI/CLI.hpp>
  2 +#include <iostream>
  3 +#include <vector>
  4 +#include <tuple>
  5 +
  6 +int main(int argc, char **argv) {
  7 + CLI::App app;
  8 +
  9 + std::vector<int> foos;
  10 + auto foo = app.add_option("--foo,-f", foos);
  11 +
  12 + std::vector<int> bars;
  13 + auto bar = app.add_option("--bar", bars);
  14 +
  15 + app.add_flag("--z,--x"); // Random other flags
  16 +
  17 + // Standard parsing lines (copy and paste in)
  18 + try {
  19 + app.parse(argc, argv);
  20 + } catch (const CLI::ParseError &e) {
  21 + return app.exit(e);
  22 + }
  23 +
  24 + // I perfer using the back and popping
  25 + std::reverse(std::begin(foos), std::end(foos));
  26 + std::reverse(std::begin(bars), std::end(bars));
  27 +
  28 + std::vector<std::tuple<std::string,int>> keyval;
  29 + for(auto option : app.parse_order()) {
  30 + if(option == foo) {
  31 + keyval.emplace_back("foo", foos.back());
  32 + foos.pop_back();
  33 + }
  34 + if(option == bar) {
  35 + keyval.emplace_back("bar", bars.back());
  36 + bars.pop_back();
  37 + }
  38 + }
  39 +
  40 + // Prove the vector is correct
  41 + std::string name;
  42 + int value;
  43 +
  44 + for(auto& tuple : keyval) {
  45 + std::tie(name, value) = tuple;
  46 + std::cout << name << " : " << value << std::endl;
  47 + }
  48 +}
  49 +
  50 +
include/CLI/App.hpp
@@ -254,7 +254,7 @@ class App { @@ -254,7 +254,7 @@ class App {
254 variable.emplace_back(); 254 variable.emplace_back();
255 retval &= detail::lexical_cast(a, variable.back()); 255 retval &= detail::lexical_cast(a, variable.back());
256 } 256 }
257 - return variable.size() > 0 && retval; 257 + return (!variable.empty()) && retval;
258 }; 258 };
259 259
260 Option *opt = add_option(name, fun, description, defaulted); 260 Option *opt = add_option(name, fun, description, defaulted);