The Lean Mean C++ Option Parser
Classes | Typedefs | Enumerations | Functions
option Namespace Reference

Detailed Description

The namespace of The Lean Mean C++ Option Parser.


struct  Descriptor
 Describes an option, its help text (usage) and how it should be parsed. More...
class  Option
 A parsed option from the command line together with its argument if it has one. More...
struct  Arg
 Functions for checking the validity of option arguments. More...
struct  Stats
 Determines the minimum lengths of the buffer and options arrays used for Parser. More...
class  Parser
 Checks argument vectors for validity and parses them into data structures that are easier to work with. More...


typedef ArgStatus(* CheckArg )(const Option &option, bool msg)
 Signature of functions that check if an argument is valid for a certain type of option.


 Possible results when checking if an argument is valid for a certain option. More...


template<typename OStream >
void printUsage (OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.

Typedef Documentation

typedef ArgStatus(* CheckArg)(const Option &option, bool msg)

Signature of functions that check if an argument is valid for a certain type of option.

Every Option has such a function assigned in its Descriptor.

 Descriptor usage[] = { {UNKNOWN, 0, "", "", Arg::None, ""}, ... };

A CheckArg function has the following signature:

 ArgStatus CheckArg(const Option& option, bool msg); 

It is used to check if a potential argument would be acceptable for the option. It will even be called if there is no argument. In that case option.arg will be NULL.

If msg is true and the function determines that an argument is not acceptable and that this is a fatal error, it should output a message to the user before returning ARG_ILLEGAL. If msg is false the function should remain silent (or you will get duplicate messages).

See ArgStatus for the meaning of the return values.

While you can provide your own functions, often the following pre-defined checks (which never return ARG_ILLEGAL) will suffice:

  • Arg::None

    For options that don't take an argument: Returns ARG_NONE.

  • Arg::Optional

    Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.

Definition at line 286 of file optionparser.h.

Enumeration Type Documentation

enum ArgStatus

Possible results when checking if an argument is valid for a certain option.

In the case that no argument is provided for an option that takes an optional argument, return codes ARG_OK and ARG_IGNORE are equivalent.


The option does not take an argument.


The argument is acceptable for the option.


The argument is not acceptable but that's non-fatal because the option's argument is optional.


The argument is not acceptable and that's fatal.

Definition at line 246 of file optionparser.h.

Function Documentation

void option::printUsage ( OStream &  prn,
const Descriptor  usage[],
int  width = 80,
int  last_column_min_percent = 50,
int  last_column_own_line_max_percent = 75 

Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.

printUsage() takes the help texts of a Descriptor[] array and formats them into a usage message, wrapping lines to achieve the desired output width.

Table formatting:

Aside from plain strings which are simply line-wrapped, the usage may contain tables. Tables are used to align elements in the output.

 // Without a table. The explanatory texts are not aligned.
 -c, --create  |Creates something.
 -k, --kill  |Destroys something.

 // With table formatting. The explanatory texts are aligned.
 -c, --create  |Creates something.
 -k, --kill    |Destroys something.

Table formatting removes the need to pad help texts manually with spaces to achieve alignment. To create a table, simply insert \t (tab) characters to separate the cells within a row.

 const option::Descriptor usage[] = {
 {..., "-c, --create  \tCreates something." },
 {..., "-k, --kill  \tDestroys something." }, ...

Note that you must include the minimum amount of space desired between cells yourself. Table formatting will insert further spaces as needed to achieve alignment.

You can insert line breaks within cells by using \v (vertical tab).

 const option::Descriptor usage[] = {
 {..., "-c,\v--create  \tCreates\vsomething." },
 {..., "-k,\v--kill  \tDestroys\vsomething." }, ...

 // results in

 -c,       Creates
 --create  something.
 -k,       Destroys
 --kill    something.

You can mix lines that do not use \t or \v with those that do. The plain lines will not mess up the table layout. Alignment of the table columns will be maintained even across these interjections.

 const option::Descriptor usage[] = {
 {..., "-c, --create  \tCreates something." },
 {..., "----------------------------------" },
 {..., "-k, --kill  \tDestroys something." }, ...

 // results in

 -c, --create  Creates something.
 -k, --kill    Destroys something.

You can have multiple tables within the same usage whose columns are aligned independently. Simply insert a dummy Descriptor with help==0.

 const option::Descriptor usage[] = {
 {..., "Long options:" },
 {..., "--very-long-option  \tDoes something long." },
 {..., "--ultra-super-mega-long-option  \tTakes forever to complete." },
 {..., 0 }, // ---------- table break -----------
 {..., "Short options:" },
 {..., "-s  \tShort." },
 {..., "-q  \tQuick." }, ...

 // results in

 Long options:
 --very-long-option              Does something long.
 --ultra-super-mega-long-option  Takes forever to complete.
 Short options:
 -s  Short.
 -q  Quick.

 // Without the table break it would be

 Long options:
 --very-long-option              Does something long.
 --ultra-super-mega-long-option  Takes forever to complete.
 Short options:
 -s                              Short.
 -q                              Quick.

Output methods:

Because TheLeanMeanC++Option parser is freestanding, you have to provide the means for output in the first argument(s) to printUsage(). Because printUsage() is implemented as a set of template functions, you have great flexibility in your choice of output method. The following example demonstrates typical uses. Anything that's similar enough will work.

 #include <unistd.h>  // write()
 #include <iostream>  // cout
 #include <sstream>   // ostringstream
 #include <cstdio>    // fwrite()
 using namespace std;

 void my_write(const char* str, int size) {
   fwrite(str, size, 1, stdout);

 struct MyWriter {
   void write(const char* buf, size_t size) const {
      fwrite(str, size, 1, stdout);

 struct MyWriteFunctor {
   void operator()(const char* buf, size_t size) {
      fwrite(str, size, 1, stdout);
 printUsage(my_write, usage);    // custom write function
 printUsage(MyWriter(), usage);  // temporary of a custom class
 MyWriter writer;
 printUsage(writer, usage);      // custom class object
 MyWriteFunctor wfunctor;
 printUsage(&wfunctor, usage);   // custom functor
 printUsage(write, 1, usage);    // write() to file descriptor 1
 printUsage(cout, usage);        // an ostream&
 printUsage(fwrite, stdout, usage);  // fwrite() to stdout
 ostringstream sstr;
 printUsage(sstr, usage);        // an ostringstream&
  • the write() method of a class that is to be passed as a temporary as MyWriter() is in the example, must be a const method, because temporary objects are passed as const reference. This only applies to temporary objects that are created and destroyed in the same statement. If you create an object like writer in the example, this restriction does not apply.
  • a functor like MyWriteFunctor in the example must be passed as a pointer. This differs from the way functors are passed to e.g. the STL algorithms.
  • All printUsage() templates are tiny wrappers around a shared non-template implementation. So there's no penalty for using different versions in the same program.
  • printUsage() always interprets Descriptor::help as UTF-8 and always produces UTF-8-encoded output. If your system uses a different charset, you must do your own conversion. You may also need to change the font of the console to see non-ASCII characters properly. This is particularly true for Windows.
  • Security warning: Do not insert untrusted strings (such as user-supplied arguments) into the usage. printUsage() has no protection against malicious UTF-8 sequences.
prnThe output method to use. See the examples above.
usagethe Descriptor[] array whose help texts will be formatted.
widththe maximum number of characters per output line. Note that this number is in actual characters, not bytes. printUsage() supports UTF-8 in help and will count multi-byte UTF-8 sequences properly. Asian wide characters are counted as 2 characters.
last_column_min_percent(0-100) The minimum percentage of width that should be available for the last column (which typically contains the textual explanation of an option). If less space is available, the last column will be printed on its own line, indented according to last_column_own_line_max_percent.
last_column_own_line_max_percent(0-100) If the last column is printed on its own line due to less than last_column_min_percent of the width being available, then only last_column_own_line_max_percent of the extra line(s) will be used for the last column's text. This ensures an indentation. See example below.
 // width=20, last_column_min_percent=50 (i.e. last col. min. width=10)
 --3456789 1234567890

 // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
 // last_column_own_line_max_percent=75

 // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
 // last_column_own_line_max_percent=33 (i.e. max. 5)

Definition at line 2778 of file optionparser.h.

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator