A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/kongaskristjan/fire-hpp below:

kongaskristjan/fire-hpp: A C++ library that uses clever tricks to create super low-code, yet fully functional CLIs

Fire for C++ is a single header library that creates a command line interface from a function signature. Here's the whole program for adding two numbers with command line:

#include <iostream>
#include <fire-hpp/fire.hpp>

int fired_main(int x = fire::arg("-x"), int y = fire::arg("-y")) {
    std::cout << x + y << std::endl;
    return 0;
}

FIRE(fired_main)

That's all. Usage:

As you likely expect,

Why yet another CLI library?!

With most libraries, creating a CLI roughly follows this pattern:

  1. define arguments
  2. call parse(argc, argv);
  3. check whether errors are detected by parse(), print them and return (optional)
  4. check for -h and --help, print the help message and return (optional)
  5. for each argument:
    1. get argument from the map and if necessary convert to the right type
    2. try/catch for errors in conversion and return (optional)

That's a non-trivial amount of boilerplate, especially for simple scripts. Because of that, programmers (and a lot of library examples) tend to skip the optional parts, however this incurs a significant usability cost. Also, many libraries don't help at all with the conversion step.

With fire-hpp, you only call FIRE(fired_main) and define arguments as function parameters. When fired_main() scope begins, all steps have already been completed.

Steps to run examples:

Let's go through each part of the following example.

int fired_main(int x = fire::arg("-x"), int y = fire::arg("-y")) { // Define and convert arguments
    std::cout << x + y << std::endl; // Use x and y, they're ints!
    return 0;
}

FIRE(fired_main) // call fired_main()
D.1 FIRE(fired_main[, program_description]) and variants

Program description can be supplied as the second argument:

FIRE(fired_main, "Hello there")
D.2 fire::arg(identifiers[, default_value]])

Identifiers are used to find arguments from command line and provide a description. In general, it's a brace enclosed list of elements (braces can be omitted for a single element):

D.2.2 Default value (optional)

Default value if no value is provided through command line. Can be either std::string, integral or floating-point type and fire::arg must be converted to that same type. This default is also displayed on the help page.

For an optional argument without a default, see fire::optional.

Constraints can be applied to arguments by calling fire:arg's constraint methods:

These methods

  1. check whether user supplied value fits the constraint and emit a proper error message if condition is not met
  2. append the constraint to argument's help message
D.3 fire::arg conversions

To conveniently obtain arguments with the right type and automatically check the validity of input, fire::arg class defines several implicit conversions.

D.3.1 std::string, integral, or floating point

Converts the argument value on command line to the respective type. Displays an error if the conversion is impossible or default value has wrong type.

Used for optional arguments without a reasonable default value. This way the default value doesn't get printed in a help message. The underlying type can be std::string, integral or floating-point.

fire::optional is a tear-down version of std::optional, with compatible implementations for has_value(), value_or() and value().

For an optional argument with a sensible default value, see default value.

D.3.3 bool: flag argument

Boolean flags are true when they exist on command line and false when they don't. Multiple single-character flags can be packed on command line by prefixing with a single hyphen: -abc <=> -a -b -c

D.3.4 std::vector: variadic argument

A method for getting all positional arguments as a vector. The fire::arg object can be converted to std::vector<std::string>, std::vector<integral type> or std::vector<floating-point type>. Using variadic argument forbids extracting positional arguments with fire::arg(index).

In this case, identifier should be fire::variadic(). Description can be supplied in the usual way.

D.4 Post fired_main() functions D.4.1.1 Print help or error message with fire formatting D.4.1.2 Helper function for getting named argument names in assert messages:

std::string fire::helpful_name(const string &name) - return user called name of the specified argument (given by one name) if it exists, otherwise return empty string.

std::string fire::helpful_name(int pos) - return correctly formatted positional argument number

D.4.2 Accessing raw arguments

Some third party libraries require access to raw argc/argv. This is gained through fire::raw_args (of type fire::c_args), which has argc() and argv() methods for accessing the arguments.

Examples:

int argc = fire::raw_args.argc();
char ** argv = fire::raw_args.argv();
non_modifying_call(argc, argv);
fire::c_args raw_args_copy = fire::raw_args; 
int& argc = raw_args_copy.argc();
char ** argv = raw_args_copy.argv();
modifying_call(argc, argv);
// Once out of scope, raw_args_copy releases argv strings

You also need FIRE_ALLOW_UNUSED(...) if the third party library processes it's own arguments.

Other libraries you might find useful:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4