A simple to use, composable, command line parser for C++ 11 and beyond

Overview

Lyra

A simple to use, composing, header only, command line arguments parser for C++ 11 and beyond.

Obtain

GitHub All Releases

License

Boost Software License 1.0

Standards

Pitchfork Layout C\\ 11 C\\ 14 C\\ 17 C\\ 2a

Stats

GitHub code size in bytes GitHub issues GitHub stars

Tests

Azure DevOps Azure DevOps AppVeyor AppVeyor

License

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Features

  • Header only with no external dependencies (except the std library).

  • Define your interface once to get parsing, type conversions and usage strings with no redundancy.

  • Composing. Each opt or arg is an independent parser. Combine these to produce a composite parser — this can be done in stages across multiple function calls — or even projects.

  • Bind parsers directly to variables that will receive the results of the parse — no intermediate dictionaries to worry about.

  • Or can also bind parsers to lambdas for more custom handling.

  • Deduces types from bound variables or lambdas and performs type conversions (via ostream <<), with error handling, behind the scenes.

  • Bind parsers to vectors for args that can have multiple values.

  • Uses result types for error propagation, rather than exceptions (doesn’t yet build with exceptions disabled, but that will be coming later)

  • Models POSIX standards for short and long opt behavior.

  • Customizable option syntax.

  • Specify cardinality of arg-s from one to many.

  • Limit option values to a specified set of values.

  • Recursive argument groups with callback for detection. This allows for easy and generic sub-command specifications.

Using

To use, just #include <lyra/lyra.hpp>

A parser for a single option can be created like this:

int width = 0;
auto cli = lyra::cli()
    | lyra::opt( width, "width" )
        ["-w"]["--width"]
        ("How wide should it be?");

You can use this parser directly like this:

auto result = cli.parse( { argc, argv } );
if ( !result )
{
	std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
	exit(1);
}

// Everything was ok, width will have a value if supplied on command line.

Note that exceptions are not used for error handling.

You can combine parsers by composing with |, like this:

int width = 0;
std::string name;
bool doIt = false;
std::string command;
auto cli
    = lyra::opt( width, "width" )
        ["-w"]["--width"]
        ("How wide should it be?")
    | lyra::opt( name, "name" )
        ["-n"]["--name"]
        ("By what name should I be known")
    | lyra::opt( doIt )
        ["-d"]["--doit"]
        ("Do the thing" )
    | lyra::arg( command, "command" )
        ("which command to run");

opt specifies options that start with a short dash (-) or long dash (--). Options can be argument taking (such as -w 42), in which case the opt takes a second argument — a hint, or they are pure flags (such as -d), in which case the opt has only one argument — which must be a boolean. The option names are provided in one or more sets of square brackets, and a description string can be provided in parentheses. The first argument to an opt is any variable, local, global member, of any type that can be converted from a string using std::ostream.

arg specifies arguments that are not tied to options, and so have no square bracket names. They otherwise work just like opt.

A usage string can be obtained by inserting the parser into a stream. The usage string is built from the information supplied.

As a convenience, the standard help options (-h, --help and -?) can be specified using the help parser, which just takes a boolean to bind to.

More

There is a single-header version that is generated from the source files. You can find it at data/single_include/lyra/lyra.hpp. Some caveats for it:

  • It’s not the preferred method of using the library.

  • It’s not thoroughly tested.

  • It’s intended for use cases like Compiler Explorer. Where it allows for immediate experimentation.

  • Support for it will not be a priority.

  • Hence prefer to use the regular multi-file sources in your projects.

For more information and documentation see the web site.

Comments
  • Surprising behavior of lyra::group, is it a bug?

    Surprising behavior of lyra::group, is it a bug?

    Hi, I'm in the process of migrating my project to Lyra, and I've encountered some surprising behavior of the "group" feature where I'm not sure if it is intentional.

    Specifically, it seems that as soon as I specify an option belonging to a group, the very next subsequently given option will always be treated as a positional argument even if it should instead be matched by another option. This is easiest to explain by example. Consider the following program (ready for copy & paste and build):

    #include <lyra/lyra.hpp>
    
    #include <iostream>
    #include <string>
    
    int main(int argc, char** argv) {
      bool someFlag = false;
      std::string requiredArgInGroup;
      std::string optionalArgInGroup;
      std::string positionalArg;
    
      auto optionsParser =
        lyra::opt(someFlag).name("-f")
        | lyra::group([](const lyra::group&){})
          .add_argument(
            lyra::opt(requiredArgInGroup, "req")
            .name("--req-in-group")
            .required())
          .add_argument(
            lyra::opt(optionalArgInGroup, "opt")
            .name("--opt-in-group"))
        | lyra::arg(positionalArg, "positional");
    
      if (auto result = optionsParser.parse({argc, argv})) {
        std::cout << std::boolalpha << someFlag << ", " << positionalArg << '\n';
      } else {
        std::cout << result.errorMessage() << '\n';
      }
    }
    

    Expected behavior

    If I invoke the program and specify the -f option after --req-in-group, I would expect it to result in setting someFlag, and a subsequent positional argument to be assigned to positionalArg.

    Expected output:

    $ ./a.out --req-in-group test1 -f test2
    true, test2
    

    Expected output without positional arg:

    $ ./a.out --req-in-group test1 -f
    true, 
    

    Actual behavior

    What actually happens is that -f is assigned to positionalArg:

    $ ./a.out --req-in-group test1 -f
    false, -f
    

    And adding a subsequent positional argument (i.e. --req-in-group test1 -f test2) results in a parse error (unrecognized token: test2).

    Interestingly, specifying the positional argument first after the group argument results in the behavior I would expect:

    $ ./a.out --req-in-group test1 test2 -f
    true, test2
    

    This seems like a bug to me, but maybe I'm misunderstanding something about how groups work? Any clarification would be appreciated 🙂 I really like the groups feature and would love to use it!

    bug 
    opened by lethal-guitar 6
  • When building with -Wshadow on GCC there are many shadowing warnings.

    When building with -Wshadow on GCC there are many shadowing warnings.

    As Lyra is a header-only library it is affected by project build flags so there is no reasonable way for a project to work around this short of disabling the flag.

    Here is a sanitised log from my project:

    In file included from [PATH]/main.cpp:39:
    [PATH]/lyra.hpp: In constructor ‘lyra::detail::print::print(const char*)’:
    [PATH]/lyra.hpp:55:3: warning: declaration of ‘scope’ shadows a member of ‘lyra::detail::print’ [-Wshadow]
       55 |   : scope(scope)
          |   ^
    [PATH]/lyra.hpp:84:15: note: shadowed declaration is here
       84 |  const char * scope;
          |               ^~~~~
    [PATH]/lyra.hpp: In constructor ‘lyra::detail::print::print(const char*)’:
    [PATH]/lyra.hpp:59:2: warning: declaration of ‘scope’ shadows a member of ‘lyra::detail::print’ [-Wshadow]
       59 |  }
          |  ^
    [PATH]/lyra.hpp:84:15: note: shadowed declaration is here
       84 |  const char * scope;
          |               ^~~~~
    [PATH]/lyra.hpp: In constructor ‘lyra::detail::print::print(const char*)’:
    [PATH]/lyra.hpp:59:2: warning: declaration of ‘scope’ shadows a member of ‘lyra::detail::print’ [-Wshadow]
       59 |  }
          |  ^
    [PATH]/lyra.hpp:84:15: note: shadowed declaration is here
       84 |  const char * scope;
          |               ^~~~~
    In file included from [PATH]/main.cpp:39:
    [PATH]/lyra.hpp: In constructor ‘lyra::args::args(std::initializer_list<std::__cxx11::basic_string<char> >)’:
    [PATH]/lyra.hpp:136:3: warning: declaration of ‘args’ shadows a member of ‘lyra::args’ [-Wshadow]
      136 |   : m_exeName(*args.begin())
          |   ^
    [PATH]/lyra.hpp:128:1: note: shadowed declaration is here
      128 | {
          | ^
    [PATH]/lyra.hpp: In constructor ‘lyra::args::args(std::initializer_list<std::__cxx11::basic_string<char> >)’:
    [PATH]/lyra.hpp:138:3: warning: declaration of ‘args’ shadows a member of ‘lyra::args’ [-Wshadow]
      138 |  {}
          |   ^
    [PATH]/lyra.hpp:128:1: note: shadowed declaration is here
      128 | {
          | ^
    [PATH]/lyra.hpp: In constructor ‘lyra::args::args(std::initializer_list<std::__cxx11::basic_string<char> >)’:
    [PATH]/lyra.hpp:138:3: warning: declaration of ‘args’ shadows a member of ‘lyra::args’ [-Wshadow]
      138 |  {}
          |   ^
    [PATH]/lyra.hpp:128:1: note: shadowed declaration is here
      128 | {
          | ^
    	BUILD:		logger.cpp
    In file included from [PATH]/main.cpp:39:
    [PATH]/lyra.hpp: In constructor ‘lyra::detail::choices_check<Lambda>::choices_check(const Lambda&)’:
    [PATH]/lyra.hpp:984:3: warning: declaration of ‘checker’ shadows a member of ‘lyra::detail::choices_check<Lambda>’ [-Wshadow]
      984 |   : checker(checker)
          |   ^
    [PATH]/lyra.hpp:980:9: note: shadowed declaration is here
      980 |  Lambda checker;
          |         ^~~~~~~
    [PATH]/lyra.hpp: In constructor ‘lyra::option_style::option_style(std::string&&, std::string&&, std::size_t, std::string&&, std::size_t)’:
    [PATH]/lyra.hpp:1063:3: warning: declaration of ‘short_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1063 |   : value_delimiters(std::move(value_delimiters))
          |   ^
    [PATH]/lyra.hpp:1055:14: note: shadowed declaration is here
     1055 |  std::size_t short_option_size = 0;
          |              ^~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1063:3: warning: declaration of ‘short_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1063 |   : value_delimiters(std::move(value_delimiters))
          |   ^
    [PATH]/lyra.hpp:1054:14: note: shadowed declaration is here
     1054 |  std::string short_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1063:3: warning: declaration of ‘long_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1063 |   : value_delimiters(std::move(value_delimiters))
          |   ^
    [PATH]/lyra.hpp:1053:14: note: shadowed declaration is here
     1053 |  std::size_t long_option_size = 0;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1063:3: warning: declaration of ‘long_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1063 |   : value_delimiters(std::move(value_delimiters))
          |   ^
    [PATH]/lyra.hpp:1052:14: note: shadowed declaration is here
     1052 |  std::string long_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1063:3: warning: declaration of ‘value_delimiters’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1063 |   : value_delimiters(std::move(value_delimiters))
          |   ^
    [PATH]/lyra.hpp:1051:14: note: shadowed declaration is here
     1051 |  std::string value_delimiters;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp: In constructor ‘lyra::option_style::option_style(std::string&&, std::string&&, std::size_t, std::string&&, std::size_t)’:
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘short_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1055:14: note: shadowed declaration is here
     1055 |  std::size_t short_option_size = 0;
          |              ^~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘short_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1054:14: note: shadowed declaration is here
     1054 |  std::string short_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘long_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1053:14: note: shadowed declaration is here
     1053 |  std::size_t long_option_size = 0;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘long_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1052:14: note: shadowed declaration is here
     1052 |  std::string long_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘value_delimiters’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1051:14: note: shadowed declaration is here
     1051 |  std::string value_delimiters;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp: In constructor ‘lyra::option_style::option_style(std::string&&, std::string&&, std::size_t, std::string&&, std::size_t)’:
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘short_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1055:14: note: shadowed declaration is here
     1055 |  std::size_t short_option_size = 0;
          |              ^~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘short_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1054:14: note: shadowed declaration is here
     1054 |  std::string short_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘long_option_size’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1053:14: note: shadowed declaration is here
     1053 |  std::size_t long_option_size = 0;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘long_option_prefix’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1052:14: note: shadowed declaration is here
     1052 |  std::string long_option_prefix;
          |              ^~~~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp:1068:3: warning: declaration of ‘value_delimiters’ shadows a member of ‘lyra::option_style’ [-Wshadow]
     1068 |  {}
          |   ^
    [PATH]/lyra.hpp:1051:14: note: shadowed declaration is here
     1051 |  std::string value_delimiters;
          |              ^~~~~~~~~~~~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual lyra::parse_result lyra::arg::parse(const lyra::detail::token_iterator&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:2182:8: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2182 |   auto result = valueRef->setValue(token.name);
          |        ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual lyra::result lyra::arguments::validate() const’:
    [PATH]/lyra.hpp:2471:9: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2471 |    auto result = p->validate();
          |         ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::parse_result lyra::arguments::parse_any(const lyra::detail::token_iterator&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:2508:8: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2508 |   auto result = parse_result::ok(
          |        ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::parse_result lyra::arguments::parse_sequence(const lyra::detail::token_iterator&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:2589:8: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2589 |   auto result = parse_result::ok(
          |        ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual const lyra::parser* lyra::arguments::get_named(const string&) const’:
    [PATH]/lyra.hpp:2654:19: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2654 |    const parser * result = p->get_named(n);
          |                   ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual lyra::parse_result lyra::group::parse(const lyra::detail::token_iterator&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:2926:16: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     2926 |   parse_result result = arguments::parse(tokens, style);
          |                ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::cli::value_result::operator T() const’:
    [PATH]/lyra.hpp:3157:43: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3157 |    typename detail::remove_cvref<T>::type result {};
          |                                           ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::cli::value_result::operator std::vector<T>() const’:
    [PATH]/lyra.hpp:3168:19: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3168 |    std::vector<T> result;
          |                   ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::parse_result lyra::cli::parse(const lyra::args&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:3399:15: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3399 |  parse_result result = parse(args_tokens, style);
          |               ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::literal& lyra::literal::operator()(const string&)’:
    [PATH]/lyra.hpp:3589:69: warning: declaration of ‘description’ shadows a member of ‘lyra::literal’ [-Wshadow]
     3589 | inline literal & literal::operator()(std::string const & description)
          |                                                                     ^
    [PATH]/lyra.hpp:3535:14: note: shadowed declaration is here
     3535 |  std::string description;
          |              ^~~~~~~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual std::string lyra::opt::get_usage_text(const lyra::option_style&) const’:
    [PATH]/lyra.hpp:3825:15: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3825 |   std::string result;
          |               ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘virtual lyra::parser::help_text lyra::opt::get_help_text(const lyra::option_style&) const’:
    [PATH]/lyra.hpp:3839:21: warning: declaration of ‘opt’ shadows a member of ‘lyra::opt’ [-Wshadow]
     3839 |   for (auto const & opt : opt_names)
          |                     ^~~
    [PATH]/lyra.hpp:3773:1: note: shadowed declaration is here
     3773 | {
          | ^
    [PATH]/lyra.hpp: In member function ‘virtual lyra::parse_result lyra::opt::parse(const lyra::detail::token_iterator&, const lyra::option_style&) const’:
    [PATH]/lyra.hpp:3886:11: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3886 |      auto result = flagRef->setFlag(true);
          |           ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp:3910:11: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     3910 |      auto result = valueRef->setValue(argToken.name);
          |           ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    [PATH]/lyra.hpp: In member function ‘lyra::main& lyra::main::operator()(const T&)’:
    [PATH]/lyra.hpp:4273:41: warning: declaration of ‘parser’ shadows a member of ‘lyra::main’ [-Wshadow]
     4273 | main & main::operator()(const T & parser)
          |                                         ^
    [PATH]/lyra.hpp:1582:1: note: shadowed declaration is here
     1582 | {
          | ^
    [PATH]/lyra.hpp: In member function ‘lyra::main& lyra::main::add_argument(const T&)’:
    [PATH]/lyra.hpp:4279:43: warning: declaration of ‘parser’ shadows a member of ‘lyra::main’ [-Wshadow]
     4279 | main & main::add_argument(const T & parser)
          |                                           ^
    [PATH]/lyra.hpp:1582:1: note: shadowed declaration is here
     1582 | {
          | ^
    [PATH]/lyra.hpp: In member function ‘lyra::main& lyra::main::operator|=(const T&)’:
    [PATH]/lyra.hpp:4285:41: warning: declaration of ‘parser’ shadows a member of ‘lyra::main’ [-Wshadow]
     4285 | main & main::operator|=(const T & parser)
          |                                         ^
    [PATH]/lyra.hpp:1582:1: note: shadowed declaration is here
     1582 | {
          | ^
    [PATH]/lyra.hpp: In member function ‘int lyra::main::operator()(const lyra::args&, L)’:
    [PATH]/lyra.hpp:4391:7: warning: declaration of ‘result’ shadows a global declaration [-Wshadow]
     4391 |  auto result = cli::parse(argv);
          |       ^~~~~~
    [PATH]/lyra.hpp:603:7: note: shadowed declaration is here
      603 | using result = detail::basic_result<void>;
          |       ^~~~~~
    

    I'm using the single header version of 1.6.0 but this should still occur with the multi-header version.

    opened by SadieCat 5
  • Output formatting differs from clara

    Output formatting differs from clara

    I just started a new project using Lyra (after heeding the warning on the Clara repo, thanks for that!)

    Under clara my help cam out like this:

    usage:
      pt_three_ways <output> options
    
    where options are:
      -w, --width <width>           output image width
      -h, --height <height>         output image height
      --max-cpus <#cpus>            maximum number of CPUs to use (0 for all)
      --spp <samples>               number of samples per pixel
    

    etc

    In a new project using Lyra 1.1, the formatting of the help is very different:

    Usage:
      ticks2hdf5 [-?|-h|--help] <output> <input...>
    
    Options, arguments:
      -?, -h, --help
    
      Display usage information.
    
      <output>
    
      HDF5 output filename
    
      <input...>
    
      Input files, in gzip compressed CSV format
    

    Am I missing a changed configuration option somewhere? How might I get the nice formatting back?

    opened by mattgodbolt 5
  • cmake install option

    cmake install option

    I've added a simple cmake trick to detect if Lyra is "built" and installed directly or if it is used via the add_subdirectory directive.

    This allow the users of the latter not being polluted by Lyra install targets. It is also compatible with existing procedure as it automatically turns the install targets ON when used directly.

    Finally even when using it as a subdir, you can override that behaviour and still install Lyra by doing the following:

    set(LYRA_INSTALL ON CACHE BOOL "please install lyra anyway" FORCE)
    add_subdirectory(path/to/Lyra)
    

    Hope it is useful for others :)

    opened by NicoG60 4
  • Add CMake Support

    Add CMake Support

    This PR is intended to fix issue #29. It adds a installable target for CMake and makes it possible to use lyra by the standard CMake procedure of target_link_libraries(yourlib PUBLIC BFG::Lyra).

    enhancement 
    opened by jayeshbadwaik 4
  • cli_parser::parse overwrites exe_name

    cli_parser::parse overwrites exe_name

    when you call cli_parser::parse(), whatever value you set via lyra::exe_name is lost and replaced with the default executable name. If you constructed lyra::exe_name with a string in the stack, that string is also overwritten.

    An exemple:

    // my executable is called "myapp"
    bool show_help; std::string command;
    auto cli = lyra::cli_parser()
        | lyra::help(show_help)
        | lyra::arg(command, "command")("Command to perform.").required();
    
    std::string program_name = "different";
    cli.add_argument(lyra::exe_name(program_name)); // changes the name to "different"
    
    auto result = cli.parse({argc, argv});
    // exeName is is back to "myapp" at this point
    // the value of 'program_name' silently changes to "myapp"  😱 
    
    if (show_help) {
        // won't have the expected name
        std::cout << cli;
        exit(EXIT_SUCCESS);
    }
    
    opened by rehdi93 4
  • Help not working in sub-command example

    Help not working in sub-command example

    I was trying to get lyra::help to work with the add_argument interface and the sub-command example has just that. However, it looks like --help is not working in this case. I got it to work by moving the cli.parse invocation before the check for show_help - I believe that it's the right fix (parsing the command line for --help before checking the corresponding flag makes sense to me) but it's my first time trying Lyra so I can't really be sure.

    I believe that it was introduced when implementing the fix for #16.

    opened by Morwenn 4
  • optional option with container

    optional option with container

    It might be handy to be able to call a program with an [0;n] option. So you might be able to do the following: myprog -a foo -a bar stuff.txt or myprog stuff.txt

    In the current version of Lyra (using opt(std::vector, "foo")) I have two cases:

    • Default (seems to be required): [1; n] option when calling the program (using required(0) doesn't change that behavior)
    • .optional(): [0;1] option when calling the program.
    bug 
    opened by Thalamos 4
  • Unknown options are silently ignored and mixed with positional arguments

    Unknown options are silently ignored and mixed with positional arguments

    When there are options as well as positional arguments, some of which may be optional, there is a problem with unknown options. Consider this repro case:

    int foo = 0;
    std::string positional;
    std::string optional = "default";
    
    auto cli = lyra::cli();
    cli |= lyra::opt(foo, "foo")["--foo"];
    cli |= lyra::arg(positional, "positional");
    cli |= lyra::arg(optional, "optional").optional();
    
    auto result = cli.parse(lyra::args({ argv[0], "--foo", "1", "--bar", "a" }));
    if (!result) {
        std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
        std::cerr << cli << std::endl;
        return EXIT_FAILURE;
    }
    
    std::cout << "foo = " << foo << std::endl;
    std::cout << "positional = " << positional << std::endl;
    std::cout << "optional = " << optional << std::endl;
    

    which leads to this output:

    foo = 1
    positional = --bar
    optional = a
    

    This is a problem, because --bar as is not reported as unknown/invalid option, but passed to the next positional argument. It is pretty unlikely that the user intended to use --bar as a positional argument -- most likely they made a typo or another mistake and need to read the help page.

    bug 
    opened by lahwaacz 3
  • Named args with parameters' args don't appear in usage

    Named args with parameters' args don't appear in usage

    In the config:

    #include <lyra/lyra.hpp>
    #include <string>
    
    int main(int argc, const char *argv[]) {
      std::string named_required;
      std::string optional;
      auto cli = lyra::opt(named_required,
                      "required-arg")["--required"]("You must supply this arg")
                .required() |
            lyra::arg(optional, "optional")("This is an optional arg");
    
        std::cout << cli << "\n";
    }
    

    The output is:

    USAGE:
      <executable> --required [<optional>]
    
    OPTIONS, ARGUMENTS:
      --required <required-arg>
                              You must supply this arg
      <optional>              This is an optional arg
    

    The --required in the USAGE: line does not refer to the required parameter name. I'd expect to see:

    USAGE:
      <executable> --required <required-arg> [<optional>]
    
    OPTIONS, ARGUMENTS:
      --required <required-arg>
                              You must supply this arg
      <optional>              This is an optional arg
    
    bug 
    opened by mattgodbolt 3
  • Single header?

    Single header?

    Clara was a single header parser. That options seems to have been removed. Any chance it could be re-added? It is really handy to be able to drop in a single file to an app.

    opened by billyquith 3
  • Infinite loop when non-existent argument is specified

    Infinite loop when non-existent argument is specified

    I've been testing the proposed snippet from #51 showing how to have options with multiple arguments and so compiled and ran this simple example:

    #include <lyra/lyra.hpp>
    
    int main(int argc, const char** argv)
    {
      bool gotArgs = false;
      std::vector<std::string> args;
    
      auto cli = lyra::cli();
    
      cli.add_argument(lyra::group().sequential()
        | lyra::opt(gotArgs)["--args"]
        | lyra::arg(args, "args"));
    
      auto result = cli.parse({ argc, argv });
      if (!result) {
        std::cerr << "ERROR:" << cli << "\n";
        return EXIT_FAILURE;
      }
    
      std::cout << "got args = " << gotArgs << "\n";
      if(!args.empty()){
        for(auto const& a: args) {
          std::cout << "\targ: " << a << "\n";
        }
      }
    
      return EXIT_SUCCESS;
    }
    

    It works more or less as expected, but suffers from a fatal problem: running it with an unknown option or any arguments without using --args option simply hangs the program. I didn't have time to really debug this yet, but I see that it gets stuck in the do/while loop in lyra::arguments::parse_sequence and I don't really understand how is this supposed to work, i.e. why is p_result.value().have_tokens() always remains true.

    opened by vadz 0
  • Crash in lyra::args::args with zero arguments

    Crash in lyra::args::args with zero arguments

    While unusual, this can happen e.g. when execve invokes main without arguments and the calling program doesn't perform a check before calling lyra::args::args.

    opened by johnmcfarlane 0
  • lyra::group in

    lyra::group in "|" operator chain

    For lyra::group, I'd like to use the "|" operator chain way, but no example in the docs, and it seems that the callback passed into lyra::group isn't called.

    #include "lyra/lyra.hpp"
    
    #include "spdlog/fmt/fmt.h"
    #include "spdlog/fmt/ostr.h"
    
    int main(int argc, const char *argv[]) {
    
        bool show_help = false;
        auto name = std::string {};
        bool use_grade_id = false;
        int grade = 0;
        int id = 0;
    
        auto cli = lyra::help(show_help) | lyra::opt(name, "name")["-n"]["--name"].required()
                   | (lyra::group([&](const lyra::group &) {
                          use_grade_id = true;
                          fmt::print("{}\n", use_grade_id);
                      })
                      | lyra::opt(id, "id")["--id"].required()
                      | lyra::opt(grade, "grade")["--grade"].required());
    
        auto cli_result = cli.parse({argc, argv});
        if (!cli_result) {
            fmt::print(stderr, "Error in command line: {}\n{}", cli_result.message(), cli);
            return EXIT_FAILURE;
        }
    
        if (show_help) {
            fmt::print("{}\n", cli);
            return EXIT_SUCCESS;
        }
    
        fmt::print("name: {}\n", name);
        fmt::print("use_grade_id: {}\n", use_grade_id);
        fmt::print("grade: {}\n", grade);
        fmt::print("id: {}\n", id);
    
        return EXIT_SUCCESS;
    }
    

    Am I using it wrong? or is it a bug?

    Thanks!

    opened by elegracer 3
  • ignore help of subcommands

    ignore help of subcommands

    I have sub-commands with own arguments and I see them if I do app foo --help

    but I don't want to see those when I type foo --help I only want to see that sub-command itself exists, is it currently possible to do?

    opened by Miezhiko 0
  • Long text wrapping in the help output

    Long text wrapping in the help output

    The length of the "help" strings for options is not limited, but the implementation assumes that they are somewhat short, else the help output looks pretty ugly when it is wrapped in a terminal. For example (hard-wrapped manually to show the issue in HTML):

    ...
    
    OPTIONS, ARGUMENTS:
      -?, -h, --help
      --detect-features       Before mesh generation, detect sharp features and boundaries of the
    internal bounding polyhedron (and the potential internal polyhedron) and inserts them as features
    of the domain. Default value: 0.
      --features-angle-bound <SCALAR>
                              The maximum angle (in degrees) between the two normal vectors of adjacent
    triangles. For an edge of the polyhedron, if the angle between the two normal vectors of its
    incident facets is bigger than the given bound, then the edge is considered as a feature edge.
    Default value: 60.
      --edge-size <SCALAR>    A constant providing a uniform upper bound for the lengths of curve edges.
    This parameter has to be set to a positive value when 1-dimensional features protection is used.
    Default value: 1.
      --facet-angle <SCALAR>  A lower bound for the angles (in degrees) of the surface mesh facets.
    Default value: 25.
      --facet-size <SCALAR>   A constant describing a uniform upper-bound or for the radii of the
    surface Delaunay balls. Default value: 1.
      --facet-distance <SCALAR>
                              A constant describing a uniform upper bound for the distance between the
    facet circumcenter and the center of its surface Delaunay ball. Default value: 0.125.
    

    Instead, Lyra should do the wrapping and print something like this:

    OPTIONS, ARGUMENTS:
      -?, -h, --help
      --detect-features       Before mesh generation, detect sharp features and boundaries of the
                              internal bounding polyhedron (and the potential internal polyhedron) and
                              inserts them as features of the domain. Default value: 0.
      --features-angle-bound <SCALAR>
                              The maximum angle (in degrees) between the two normal vectors of adjacent
                              triangles. For an edge of the polyhedron, if the angle between the two
                              normal vectors of its incident facets is bigger than the given bound,
                              then the edge is considered as a feature edge.  Default value: 60.
      --edge-size <SCALAR>    A constant providing a uniform upper bound for the lengths of curve edges.
                              This parameter has to be set to a positive value when 1-dimensional
                              features protection is used.  Default value: 1.
      --facet-angle <SCALAR>  A lower bound for the angles (in degrees) of the surface mesh facets.
                              Default value: 25.
      --facet-size <SCALAR>   A constant describing a uniform upper-bound or for the radii of the
                              surface Delaunay balls. Default value: 1.
      --facet-distance <SCALAR>
                              A constant describing a uniform upper bound for the distance between the
                              facet circumcenter and the center of its surface Delaunay ball. Default
                              value: 0.125.
    
    enhancement 
    opened by lahwaacz 0
Releases(1.6.1)
  • 1.6.1(Nov 7, 2022)

    Only bug fixes for compile warnings and a pair of bad argument names. Changes:

    • Fix variable name shadowing warnings. -- Sadie Powell
    • Fix command::operator|= function signature. -- Henrik Gaßmann
    Source code(tar.gz)
    Source code(zip)
  • 1.6(Dec 10, 2021)

    Even though most of the changes for this release are to fix various reported bug fixes, fixing those bugs has meant dealing with some long standing internal parser inconsistencies. While I try to not break backwards compatibility, I likely can't catch all of the corner cases people have discovered.

    WARNING: This release has some internal cleanup of the parser result types. It also has an externally visible change to the parse function result type. It renames the errorMessage() function to message(). The errorMessage() function is marked deprecated and will be removed in a future release.

    Changes:

    • New: Add lyra::option_style type to better customize the syntax of options allowed. This replaces the "old" lyra::parser_customization as a better way. The lyra::parser_customization is now deprecated, and will be removed at some future release. -- René Ferdinand Rivera Morell
    • New: Add example to show how to count flags with cardinality greater than one (1). Shows how to handle increasing verbosity with -vvvv. -- René Ferdinand Rivera Morell
    • New: Add capability to control the cardinality of argument groups. -- René Ferdinand Rivera Morell
    • New: Allow setting hint after construction of lyra::bound_parser. -- Max Ferger
    • Fix virtual overload hiding of parse method. -- René Ferdinand Rivera Morell
    • Fix previously removed error for when expected option specifications do not have the required - prefix. -- René Ferdinand Rivera Morell
    • Fix inconsistencies in parsing arguments in a group followed by other arguments. (issue #49) -- René Ferdinand Rivera Morell
    • Fix incorrectly accepting negative values for unsigned integer arguments. The argument value conversion now checks the input for acceptable digits in the input before attempting to parse it. -- René Ferdinand Rivera Morell
    • Fix sub-command arguments being ignored even when they are marked as required. -- René Ferdinand Rivera Morell
    • Fix assigned values for flag options (--flag=no) being ignore. They now cause an error when specified. -- René Ferdinand Rivera Morell
    • Fix choices being allowed for for flag options, but ignored. Specifying choices on flag options now signal an error. -- René Ferdinand Rivera Morell
    • Tested with Visual Studio 2019, VS 2022, MinGW-64 (gcc 8.1.0), Linux ( clang 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; gcc 5, 6, 7, 8, 9, 10, 11), Xcode (11.2.1, 11.3.1, 11.4.1, 11.5, 11.6, 11.7, 12.0.1, 12.2, 12.3, 12.4, 13.0), on Azure Pipelines; and with VS 2015, VS 2017, MinGW-64 (gcc 6.3, 7.3) on AppVeyor.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.1(Aug 30, 2020)

  • 1.5(Aug 27, 2020)

    This release has some big changes in easy of use and functionality. There are now alternate interfaces for specifying and fetching arguments. Also the help output is now more compact and clearer. There is also new support for sub-commands.

    WARNING: The cli_parser type was renamed to cli. Both the cli_parser type and the lyra/cli_parser.hpp header are deprecated and will be removed in a future release.

    WARNING: Changed the install CMake target from BFG::Lyra to bfg::lyra.

    Changes:

    • New: Main encapsulation of common use case of help option handling. With shorthand specification of arguments. -- René Ferdinand Rivera Morell
    • New: Ability to specify argument values, with default, without specifying a local external to the parser variable. Making it easier to specify command lines. The values can be retrieved from the cli as a map from argument names to the value. -- René Ferdinand Rivera Morell
    • New: Support construction of lyra::args from iterators for cases where the arguments come from some existing container. -- René Ferdinand Rivera Morell
    • New: Add Cmake install support. -- Jayesh Vinay Badwaik
    • New: Command argument to make it easy to specify sub-commands. -- René Ferdinand Rivera Morell
    • New: Alternative sequential argument parsing mode. -- René Ferdinand Rivera Morell
    • New: Grouped arguments to specify and handle sub-command parsers. -- René Ferdinand Rivera Morell
    • New: literal parser to directly match an argument. -- René Ferdinand Rivera Morell
    • Fix missing hint text for optional, lyra::arg, arguments. -- René Ferdinand Rivera Morell
    • Bring back some cleaner and compact formatting of the help text. -- René Ferdinand Rivera Morell
    • Tested with Visual Studio 2017, VS 2019, MinGW-64 (gcc 8.1.0), Linux (clang 3.9, 4, 5, 6, 7, 8, 9, 10; gcc 4.9, 5, 6, 7, 8, 9, 10), Xcode ( 11.1, 11.2.1, 11.3.1, 11.4.1, 11.5, 11.6), on Azure Pipelines; and with VS 2015, MinGW-64 (gcc 6.3, 7.3) on AppVeyor.
    Source code(tar.gz)
    Source code(zip)
  • 1.4(May 24, 2020)

    Another round of small fixes and one new feature. Changes:

    • New Allow passing option value choices as an array. -- Rene Rivera
    • Fix sample code in README to be correctly namespaced. -- Jayesh Badwaik
    • Fix commands example to actually show help when specified. -- Shreyas Potnis
    • Tested with Visual Studio 2017, VS 2019, MinGW-64 (gcc 8.1.0), Linux (clang 3.8, 3.9, 4, 5, 6, 7, 8, 9, 10; gcc 4.8, 4.9, 5, 6, 7, 8, 9, 10), Xcode (10.1, 10.2.1, 10.3, 11.1, 11.2.1, 11.3.1, 11.4), on Azure Pipelines; and with VS 2015, MinGW-64 (gcc 6.3, 7.3) on AppVeyor.
    Source code(tar.gz)
    Source code(zip)
  • 1.3(Jan 19, 2020)

    A few small new features, bug fixes, and continued cleanup on the road to reducing memory allocations. Changes this time around:

    • New: Accept -o2 style option+value arguments. -- Rene Rivera
    • New: Accept -abc option name spelling as shorthand for -a, -b, -c. -- Rene Rivera
    • Fixed inconsistent handling of option values that look like options, like negative numbers. -- Rene Rivera
    • Rewrote argument token parsing for clarity, to avoid extra token buffer allocation, and to allow for more option & value variations. -- Rene Rivera
    • Fixed allowing junk extra characters after a non-string option value. -- Rene Rivera
    • Support specifying a single value for choices of an argument. -- Rene Rivera
    • Fix various problems with the commands example program. Also now the examples for the documentation are unit tested along with the regular unit tests. -- Rene Rivera
    • Tested with Visual Studio 2015, VS 2017, VS 2019, MinGW-64 (gcc 8.1), Linux (clang 3.5, 3.6, 3.7, 3.8, 3.9, 4, 5, 6, 7, 8, 9; gcc 4.8, 4.9, 5, 6, 7, 8, 9), Xcode (9.0, 9.0.1, 9.1, 9.2, 9.3, 9.3.1, 9.4, 9.4.1, 10.0, 10.1, 10.2, 10.2.1, 10.3, 11.0, 11.1, 11.2, 11.2.1), on Azure Pipelines.
    Source code(tar.gz)
    Source code(zip)
  • 1.2(Nov 25, 2019)

    Concentrated on new features. Many of them from old Clara requests. But also continued internal cleanup of code. The changes are:

    • New: One can now accept 1-or-more on bound container arguments by only specifying required() on such arguments. -- Rene Rivera
    • New: One can now define a description text to display as general command information with the help::description method. -- Rene Rivera
    • New: Add named methods as alternates for operators to add and specify arguments. They follow the familiar Python argparse nomenclature. -- Rene Rivera
    • New: Single header file alternative version of the library. For those that need or want such a thing. -- Rene Rivera
    • Improve help for arguments that specify a cardinality. -- Rene Rivera
    • Addition of more complicated use cases to demonstrate flexibility of library. -- Rene Rivera
    • Continued internal clean up of code for stability and easier future enhancements. -- Rene Rivera

    As mentioned above there is now a single header version of the library. It's included in the release archive as data/single_include/lyra/lyra.hpp. You can also get it directly from here.

    Source code(tar.gz)
    Source code(zip)
  • 1.1(Sep 29, 2019)

    This is mostly a maintenance release. Which means fixing bugs, more documentation changes, and more tested compilers. Thanks to people for pointing out problems. And, thanks to Matt Godbolt's suggestion, there is one new feature:

    • New: Add direct Meson Build use support. -- Rémi Gastaldi
    • New: Define argument value choices() as either a fixed set or checked by a custom lambda function. -- Rene Rivera
    • Fix being able to parse straight from args outside of cli_parser. Which resulted in misleading parsing behavior. Rene Rivera
    • Fix use of cardinality() to correctly constrain bounded cardinality ranges like [0,n], [n,m], [n,n], and [0,0] (unbounded). Rene Rivera
    • Fix use of required() arguments such that the parse errors if they are absent. -- girstsf
    • Remove uses of assert macro to avoid internal aborts and make it easier to use as a library. -- Rene Rivera
    • Many documentation improvements. -- Rene Rivera
    • Tested with Visual Studio 2015, VS 2017, VS 2019, MinGW-64 (gcc 8.1), Linux (clang 3.5, 3.6, 3.7, 3.8, 3.9, 4, 5, 6, 7, 8, 9; gcc 4.8, 4.9, 5, 6, 7, 8, 9), Xcode (9.0, 9.0.1, 9.1, 9.2, 9.3, 9.3.1, 9.4, 9.4.1, 10.0, 10.1, 10.2, 10.2.1, 10.3, 11.0), on Azure Pipelines.
    Source code(tar.gz)
    Source code(zip)
Owner
Build Frameworks Group
We create high quality frameworks and tools for build systems.
Build Frameworks Group
CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

CLI11: Command line parser for C++11 What's new • Documentation • API Reference CLI11 is a command line parser for C++11 and beyond that provides a ri

null 2.4k Dec 30, 2022
Lightweight C++ command line option parser

Release versions Note that master is generally a work in progress, and you probably want to use a tagged release version. Version 3 breaking changes I

null 3.3k Dec 30, 2022
Tiny command-line parser for C / C++

tinyargs Another commandline argument parser for C / C++. This one is tiny, source only, and builds cleanly with -Wall -pedantic under C99 and C++11 o

Erik Agsjö 7 Aug 22, 2022
led is a line-oriented text editor in command line

led is a line-oriented text editor in command line. This editor is similar to the standard program on unix systems - GNU ed. But i'm not going to make an exact clone of that program, it's just a pet project.

Artem Mironov 16 Dec 27, 2022
easy to use, powerful & expressive command line argument parsing for modern C++ / single header / usage & doc generation

clipp - command line interfaces for modern C++ Easy to use, powerful and expressive command line argument handling for C++11/14/17 contained in a sing

André Müller 977 Dec 29, 2022
Simple command line utilities for extracting data from Fallout 4 and 76 files

fo76utils Simple command line utilities for extracting data from Fallout 4 and 76 files. baunpack - list the contents of, or extract from .BA2 archive

null 15 Dec 6, 2022
Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

GPUOpen Effects 190 Dec 12, 2022
Simple, command line based player toolkit for the Ironsworn tabletop RPG

isscrolls - Command line based player toolkit for the Ironsworn tabletop RPG isscrolls is a simple toolkit for players of the Ironsworn tabletop RPG.

null 7 Sep 9, 2022
A simple command line application in order to create new Code workspaces.

mkcws Summary A simple command line application in order to create new Code workspaces. License This project's license is GPL 2. The whole license tex

Kevin Matthes 0 Apr 1, 2022
Simple command line tools to create/extract X4 .cat+.dat files

x4cat Simple command line tools to to create/extract X4 .cat+.dat files x4encat Usage: x4encat <archive name> Looks for a directory named <archive nam

Alexander Sago 1 Oct 31, 2021
Simple Driver loading command-line utility.

lddrv Simple Driver loading command-line utility. Command Line Load a driver: "lddrv.exe -operation create -binpath C:\Dev\TestDriver.sys -svcname Tes

Josh S. 3 Sep 8, 2022
udmp-parser: A Windows user minidump C++ parser library.

udmp-parser: A Windows user minidump C++ parser library. This is a cross-platform (Windows / Linux / OSX / x86 / x64) C++ library that parses Windows

Axel Souchet 95 Dec 13, 2022
A single header C++ library for parsing command line arguments and options with minimal amount of code

Quick Arg Parser Tired of unwieldy tools like getopt or argp? Quick Arg Parser is a single header C++ library for parsing command line arguments

null 47 Dec 21, 2022
null 77 Dec 27, 2022
Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin Organization 1.7k Dec 30, 2022
A command line tool for numerically computing Out-of-time-ordered correlations for N=4 supersymmetric Yang-Mills theory and Beta deformed N=4 SYM.

A command line tool to compute OTOC for N=4 supersymmetric Yang–Mills theory This is a command line tool to numerically compute Out-of-time-ordered co

Gaoli Chen 1 Oct 16, 2021
C++ Library for pulling system and hardware information, without hitting the command line.

infoware C++ Library for pulling system and hardware information, without hitting the command line. Requirements No non-built-in ones by default. Some

The Phantom Derpstorm 323 Dec 23, 2022
EAMain provides a multi-platform entry point used for platforms that don't support console output, return codes and command-line arguments.

EAMain provides a multi-platform entry point used for platforms that don't support console output, return codes and command-line arguments.

Electronic Arts 34 Oct 1, 2022
JSONes - c++ json parser & writer. Simple api. Easy to use.

JSONes Just another small json parser and writer. It has no reflection or fancy specs. It is tested with examples at json.org Only standart library. N

Enes Kaya ÖCAL 2 Dec 28, 2021