diff options
| author | Taylor C. Richberger <tcr@absolute-performance.com> | 2016-05-07 12:05:44 -0600 | 
|---|---|---|
| committer | Taylor C. Richberger <tcr@absolute-performance.com> | 2016-05-07 12:05:44 -0600 | 
| commit | 3a9c02aa7404e20a0c1126616ac86a61cc7f2d00 (patch) | |
| tree | a99a7e84a3bba4300cf7c013064d4bd5d4d4c12e | |
| parent | change README syntax (diff) | |
| download | args.hxx-3a9c02aa7404e20a0c1126616ac86a61cc7f2d00.tar.xz | |
fix ADL.  Add unified initializer list
| -rw-r--r-- | args.hxx | 50 | ||||
| -rw-r--r-- | test.cxx | 35 | 
2 files changed, 67 insertions, 18 deletions
| @@ -151,6 +151,42 @@ namespace args              }      }; +    struct EitherOpt +    { +        bool isShort; +        char shortOpt; +        std::string longOpt; +        EitherOpt(const std::string &opt) : isShort(false), longOpt(opt) {} +        EitherOpt(const char *opt) : isShort(false), longOpt(opt) {} +        EitherOpt(const char opt) : isShort(true), shortOpt(opt) {} +    }; + +    std::unordered_set<std::string> GetLong(std::initializer_list<EitherOpt> opts) +    { +        std::unordered_set<std::string>  longOpts; +        for (const EitherOpt &opt: opts) +        { +            if (!opt.isShort) +            { +                longOpts.insert(opt.longOpt); +            } +        } +        return longOpts; +    } + +    std::unordered_set<char> GetShort(std::initializer_list<EitherOpt> opts) +    { +        std::unordered_set<char>  shortOpts; +        for (const EitherOpt &opt: opts) +        { +            if (opt.isShort) +            { +                shortOpts.insert(opt.shortOpt); +            } +        } +        return shortOpts; +    } +      /** A class of "matchers", specifying short and long options that can possibly be matched       *       * This is supposed to be constructed and then passed in, not used directly from user code. @@ -179,20 +215,14 @@ namespace args              /** Specify short and long opts as initializer lists               */ -            Matcher(const std::initializer_list<char> &shortIn, const std::initializer_list<std::string> &longIn) : +            Matcher(std::initializer_list<char> shortIn, std::initializer_list<std::string> longIn) :                  shortOpts(std::begin(shortIn), std::end(shortIn)), longOpts(std::begin(longIn), std::end(longIn))              {} -            /** Specify short opts only as initializer lists -             */ -            Matcher(const std::initializer_list<char> &shortIn) : -                shortOpts(std::begin(shortIn), std::end(shortIn)) -            {} - -            /** Specify long opts only as initializer lists +            /** Specify a mixed single initializer-list of both short and long opts               */ -            Matcher(const std::initializer_list<std::string> &longIn) : -                longOpts(std::begin(longIn), std::end(longIn)) +            Matcher(std::initializer_list<EitherOpt> in) : +                shortOpts(GetShort(in)), longOpts(GetLong(in))              {}              Matcher(Matcher &&other) : shortOpts(std::move(other.shortOpts)), longOpts(std::move(other.longOpts)) @@ -4,6 +4,14 @@  #include <iostream> +std::istream& operator>>(std::istream& is, std::tuple<int, int>& ints) +{ +    is >> std::get<0>(ints); +    is.get(); +    is >> std::get<1>(ints); +    return is; +} +  #include <args.hxx>  #define CATCH_CONFIG_MAIN @@ -59,6 +67,25 @@ TEST_CASE("Argument flags work as expected, with clustering", "[args]")      REQUIRE_FALSE(bix);  } +TEST_CASE("Unified argument lists for match work", "[args]") +{ +    args::ArgumentParser parser("This is a test program.", "This goes after the options."); +    args::ArgFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); +    args::Flag bar(parser, "BAR", "test flag", args::Matcher{"bar", 'b'}); +    args::ArgFlag<double> baz(parser, "BAZ", "test flag", args::Matcher{'a', "baz"}); +    args::ArgFlag<char> bim(parser, "BAZ", "test flag", args::Matcher{'B', "bim"}); +    args::Flag bix(parser, "BAZ", "test flag", args::Matcher{"bix"}); +    parser.ParseArgs(std::vector<std::string>{"-bftest", "--baz=7.555e2", "--bim", "c"}); +    REQUIRE(foo); +    REQUIRE(foo.value == "test"); +    REQUIRE(bar); +    REQUIRE(baz); +    REQUIRE((baz.value > 755.49 && baz.value < 755.51)); +    REQUIRE(bim); +    REQUIRE(bim.value == 'c'); +    REQUIRE_FALSE(bix); +} +  TEST_CASE("Invalid argument parsing throws parsing exceptions", "[args]")  {      args::ArgumentParser parser("This is a test program.", "This goes after the options."); @@ -173,14 +200,6 @@ TEST_CASE("Argument groups should nest", "[args]")  #include <tuple> -std::istream& operator>>(std::istream& is, std::tuple<int, int>& ints) -{ -    is >> std::get<0>(ints); -    is.get(); -    is >> std::get<1>(ints); -    return is; -} -  void DoublesReader(const std::string &name, const std::string &value, std::tuple<double, double> &destination)  {      size_t commapos = 0; | 
