/**
\defgroup fcpptoptions fcppt.options
\ingroup fcpptmain
\brief Library for command-line options

<b>Link to <code>${fcppt_options_TARGET}</code>,
or to <code>fcppt_options_interface</code> if you only need the headers.</b>

<table id="toc">
<tr>
<td>

<ul>
	<li>\ref fcpptoptions_introduction</li>
	<li>\ref fcpptoptions_simple</li>
	<li>\ref fcpptoptions_parsers</li>
	<li>\ref fcpptoptions_complex</li>
	<li>\ref fcpptoptions_commands</li>
	<li>\ref fcpptoptions_help</li>
	<li>\ref fcpptoptions_base</li>
	<li>\ref fcpptoptions_implementation</li>
</ul>

</td>
</tr>
</table>

\section fcpptoptions_introduction Introduction

Passing arguments to a program is done via the main function,
<code>int main(int argc, char **argv)</code>, where <code>argc</code> is
the number of arguments and <code>argv</code> points to the arguments themselves.
The first argument, <code>argv[0]</code>, is usually the name of the program,
but does not have to be.
Now, consider a program that expects a single
integer argument: It first has to check if <code>argc</code> is <code>2</code> and if
so, it has to convert <code>argv[1]</code> into an
integer. If any of these two steps fails, it should also print an appropriate
error message and exit. Handling arguments this way quickly gets out of
hand. For example, we might have to deal with optional arguments, flags or
arbitrary many arguments.

<code>fcppt.options</code> features declarative <em>parsers</em>.
Instead of writing parsing code by hand, we only write down the arguments
and their types that our program excepts. A parser (if it succeeds)
produces an #fcppt::record::object.
For example, a parser that expects a single integer with label
name <code>age</code> has type <code>{ age : int }</code>. Parsers can be combined
to yield more complicated parsers, so for example a parser that expects zero or
more strings with label name <code>first_names</code> has type <code>{ first_names :
std::vector<std::string> }</code>. Combining these two parsers yields
a parser of type <code>{ age : int, first_names : std::vector<std::string> }</code>.

\section fcpptoptions_simple A simple example

To start off, let us look at a simple example, where we expect a single argument of
type <code>int</code>. First, we declare the label to be used in the parser type:

\snippet options/simple.cpp options_label

Next, we declare the parser type that uses <code>age_label</code> to produce
a single value of type <code>int</code>.

\snippet options/simple.cpp options_arg_type

Such a parser parses a command-line like <code>./program 123</code>, yielding
the record <code>{ age_label = 123 }</code>, which is of type
<code>result_type = { age_label : int }</code>. Next, we define the
actual parser:

\snippet options/simple.cpp options_arg_object

Here, we see that an #fcppt::options::argument gets two parameters:
<ul>
<li>The <em>long name</em> which is used as a placeholder in help messages and</li>
<li>a text called <code>help_text</code> which can be used to explain the argument's purpose
to the user.</li>
</ul>

Instead of using <code>argc</code> and <code>argv</code> directly, we first use the
helper function #fcppt::args_from_second which copies every argument except the
first (which usually holds the program's name but does not have to) into a container:

\snippet options/simple.cpp options_args_from_second

Parsing the arguments using a parser is done by calling the #fcppt::options::parse function.
Its result is an #fcppt::options::result which is an #fcppt::either::object
that encapsulates the fact that a parser can fail.

\snippet options/simple.cpp options_parse

Now, all that needs to be done is to inspect <code>result</code>: First, we
define a function called <code>on_success</code> that receives <code>result_type</code>
(remember, this is a record of type <code>{ age_label : int }</code>) and prints it.

\snippet options/simple.cpp options_on_success

In case of failure we get an #fcppt::options::error, telling the user what went wrong.
In addition to that, we also print <code>parser.usage()</code> which
tells the user what the expected format is:

\snippet options/simple.cpp options_on_failure

Finally, we use #fcppt::either::match to call one of these functions:

\snippet options/simple.cpp options_match

Here are a few example invocations:

\code{.unparsed}
./fcppt_example_options_simple
Missing argument "age".
Usage: age : int - Your age
\endcode

\code{.unparsed}
./fcppt_example_options_simple 10 20
Leftover arguments [20].
Usage: age : int - Your age
\endcode

\code{.unparsed}
./fcppt_example_options_simple test
Failed to convert "test" to int for argument "age".
Usage: age : int - Your age
\endcode

\code{.unparsed}
./fcppt_example_options_simple 42
Your age is 42.
\endcode

\section fcpptoptions_parsers Parser types

Parser types are split into basic and combinator parsers.

\subsection fcpptoptions_parsers_basic Basic parser types

There are three different types of basic parsers:
<table>
<tr>
<th>
Type:
</th>
<th>
Description:
</th>
</tr>
<tr>
<td>
#fcppt::options::argument
</td>
<td>
Parses a single argument, e.g. <code>"arg"</code>. If there is no argument or
it cannot be converted to the parser's result type, an error occurs.
</td>
</tr>
<tr>
<td>
#fcppt::options::flag
</td>
<td>
Parses a flag, e.g. <code>"-f"</code> or <code>"--flag"</code>. Depending on
whether the flag was specified or not, the result type is either its
<em>inactive value</em> or its <em>active value</em>. Flags never produce an
error.
#fcppt::options::switch_ is a short-hand for a flag
of type <code>bool</code>.
</td>
</tr>
<tr>
<td>
#fcppt::options::option
</td>
<td>
Parses an option, e.g. <code>"-o val"</code> or <code>"--opt val"</code>.
Option parsers can have an optional <em>default value</em> which is used in
case the option has not been specified. If there is no such option and no
default value has been specified or the option's value cannot be converted to
the parser's result type, an error occurs.
</td>
</tr>
<tr>
<td>
#fcppt::options::unit
</td>
<td>
A parser that parses nothing. This is useful, for example, when you want a
sub-command that takes no arguments or options.
</td>
</tr>
<tr>
<td>
#fcppt::options::unit_switch
</td>
<td>
A flag that always has to be specified (e.g. if you want to parse <code>"--help"</code>).
</td>
</tr>
</table>

\subsection fcpptoptions_parsers_combinators Combinator parser types

The following parsers can be used to create more advanced parsers:
<table>
<tr>
<th>
Type:
</th>
<th>
Description:
</th>
</tr>

<tr>
<td>
#fcppt::options::product
</td>
<td>
A parser of type <code>fcppt::options::product<Left,Right></code> combines two
parsers of type <code>Left</code> and <code>Right</code>, which must have
<em>disjoint</em> records. The product parser first tries the left parser and
then the right parser. It only succeeds if both succeed. Its result type is the
<em>disjoint union</em> (see #fcppt::record::multiply_disjoint)
of Left's and Right's result types. To combine two or more parsers at once, use
#fcppt::options::apply.
</td>
</tr>
<tr>
<td>
#fcppt::options::sum
</td>
<td>
A parser of type <code>fcppt::options::sum<Label,Left,Right></code> first
tries <code>Left</code> and if that fails tries <code>Right</code>.
It returns the result of the first one that succeeded or an error
if both fail. Its result type is a record with a single element with label
<code>Label</code>. The type of this element is an <code>fcppt::variant::object</code> of
<code>fcppt::options::left<LeftResult></code> and <code>fcppt::options::right<RightResult></code>,
where <code>LeftResult</code> is the result type of <code>Left</code>
and <code>RightResult</code> is the result type of <code>Right</code>.
</td>
</tr>

<tr>
<td>
#fcppt::options::optional
</td>
<td>
A parser of type <code>fcppt::options::optional<Parser></code> turns a parser
of type <code>Parser</code> into a parser that may fail. Its result type has
the same labels as Parser's result type, but with an extra #fcppt::optional::object layer added on top.
See #fcppt::options::make_optional.
</td>
</tr>

<tr>
<td>
#fcppt::options::many
</td>
<td>
A parser of type <code>fcppt::options::many<Parser></code> turns a parser of
type <code>Parser</code> into a parser that parsers zero or more occurrences.
Its result type has the same labels as Parser's result type, but with an extra
<code>std::vector</code> layer added on top. See #fcppt::options::make_many.
</td>
</tr>

<tr>
<td>
#fcppt::options::commands
</td>
<td>
A commands parser combines several sub-commands into a single parser.
It gets a parser that parses options common to all sub-commands
and for each sub-command, it gets a parser plus the name of the sub-command.

For parsers <code>O,S_1,...,S_n</code> (<code>n >= 1</code>),
a parser of type <code>fcppt::options::commands<O,S_1,...,S_n></code>
gets a list of <em>sub-command names</em> <code>C_1,...,C_n</code>
in its constructor, passed as
<code>fcppt::options::sub_command<S_1>,...,fcppt::options::sub_command<S_n></code>.
Here, <code>O</code> is the common options parser and <code>S_1,...,S_n</code>
are the sub-parsers.
Its result is a record with
<ul>
<li>
the result of <code>O</code> with label name <code>fcppt::options::options_label</code> and
</li>
<li>
a variant of the result types of <code>S_1,...,S_n</code> with label name <code>fcppt::options::sub_command_label</code>.
</li>
</ul>

See #fcppt::options::make_sub_command and #fcppt::options::make_commands.

\warning A commands parser looks for the first argument (i.e. a parameter that is not a flag or an option)
which it uses as the name of the sub-command.
Therefore, you should not include
anything other than flags or options in <code>O</code>.
</td>
</tr>
</table>

Passing a parser to another can be done in three different ways:
<ul>
<li>By moving. In this case, the parser must be an rvalue.
Use #fcppt::copy to create an explicit copy if needed.</li>
<li>By reference. Use #fcppt::make_cref in this case.
Be careful to keep all parsers alive that are passed this way.</li>
<li>By moving an #fcppt::unique_ptr. This is useful
if you want to pass an #fcppt::options::base_unique_ptr.</li>
</ul>

\section fcpptoptions_complex A more complex example

Imagine a program that copies an input file to an output file,
with the following requirements:
<ul>
<li>
The input filename always needs to be specified.
</li>
<li>
The output filename is optional. If it is not specified, it defaults to the
name of the input file plus <code>".bak"</code>.
</li>
<li>
The program should by default be in <em>pretend mode</em> in which it does
nothing. Actually executing the copy operation requires to specify a flag.
</li>
<li>
It should have the ability to append to the result file instead of overwriting
it. The append behavior will be activated using a flag.
</li>
<li>
It uses a log framework to output certain messages during its run. The log
level, which dictates which log messages get printed, should be an optional
option to the program. If it is not specified, a default log level is used.
</li>
</ul>

We first start by declaring the labels the parsers are going to use:

\snippet options/complex.cpp options_labels

The input filename is an argument parser of type #fcppt::string.

\snippet options/complex.cpp options_input_file_option

The output filename is an <em>optional</em> argument parser. Its type is
<code>fcppt::optional::object<fcppt::string></code>.

\snippet options/complex.cpp options_output_file_option

The execute flag is just a switch. It can be activated using <code>"-e"</code>
or <code>"--execute"</code>.

\snippet options/complex.cpp options_execute_switch

To handle whether to append to the output file, we use a flag parser of type
<code>std::ios_base::openmode</code>. Its inactive value is the empty openmode,
while its active value is <code>std::ios_base::trunc</code>.

\snippet options/complex.cpp options_openmode_option

The log level is an option parser of type #fcppt::log::level. It
can be set using <code>"-l level"</code> or <code>"--loglevel level"</code>,
where <code>level</code> has to be one of #fcppt::log::level's
values. The parser also gets a default value of <code>fcppt::log::level::warning</code>.

\snippet options/complex.cpp options_log_level_option

Finally, the actual parser is created using #fcppt::options::apply. Its type is complicated, so it is shortened
using <code>auto</code> here. See \ref fcpptoptions_base on how to hide a
parser's actual type.

\snippet options/complex.cpp options_parser

We also check what the result type of the parser is to make sure we did not miss anything.

\snippet options/complex.cpp options_result_type

The main program is a lambda function that gets <code>result_type</code> as its
parameter. This is a record that contains all the options of the parsers
combined.

\snippet options/complex.cpp options_main_program

First, we check if the execute flag has been specified. If not, the executing stops.

\snippet options/complex.cpp options_read_execute

Next, we create a log context that uses the log-level specified. Notice how the
string specified on the command-line has already been converted to a value of
#fcppt::log::level.

\snippet options/complex.cpp options_log_context

We then open the input file using the input filename.

\snippet options/complex.cpp options_open_input

Opening the output file consists of two things: First, we need to check whether
the output filename has been specified. If not, we use the default of
<code>input_file.bak</code>.

\snippet options/complex.cpp options_output_filename

Secondly, the openmode needs to be passed as well.

\snippet options/complex.cpp options_open_output

Here is the output of the parser's usage:

\code{.unparsed}
Input filename : string - The name of the input file to copy
[ Output filename : string - The name of the output file. Defaults to input_file.bak ]
[ --execute|-e ] - Whether to actually execute the actions
[ --trunc ] - Whether to truncate the output file
[ --loglevel|-l : [verbose,debug,info,warning,error,fatal] / warning ] - The log level to use
\endcode

\section fcpptoptions_commands Commands

Instead of creating one program per command, it is useful to combine several
commands into a single parser, where the sub-command is chosen by a specific name.
Examples of this are found in several programs, namely <code>git</code>.
For example, <code>git clone</code> and <code>git pull</code> are
different commands that take different arguments and options themselves.
However, the <code>git</code> program itself can also take options
common to all sub-commands, for example <code>"--git-dir"</code> which
specifies the directory of the repository.
In fcppt, this is handled by #fcppt::options::commands.
First, we declare the parser for the common options:

\snippet options/commands.cpp common_options

This parser can optionally take a <code>"--git-dir"</code> option.

Then, we declare two parsers, one for each sub-command.
We want the <code>clone</code> command to take exactly one argument,
which is the path to clone from. The pull command, on the other hand,
should take no arguments, for which we make use of the unit parser.

\snippet options/commands.cpp sub_parsers

Next, we turn each of the parsers into a sub-command, giving it a name,
a label and an optional help text. The label is important to make
the types of the sub-commands disjoint.

\snippet options/commands.cpp sub_commands

Finally, we combine everything into a commands parser.

\snippet options/commands.cpp commands

Here is an example showing how to use the parser's result.
We first check if the optional git directory has been specified.

\snippet options/commands.cpp usage_git_dir

We then match on the two different sub-commands.

\snippet options/commands.cpp usage_sub_commands

The main program prints the parser's usage in case of an error.

\snippet options/commands.cpp main

Here are some example invocations:

\code{.unparsed}
./fcppt_example_options_commands
No command specified from [clone,pull].
Usage:
[ --git-dir : string - The path to the repository ]
  clone:  (Clone from another repository)
    path : string - The path to clone from
  pull:  (Pull all changes)
\endcode

\code{.unparsed}
./fcppt_example_options_commands bar
Invalid command "bar".
Usage:
[ --git-dir : string - The path to the repository ]
  clone:  (Clone from another repository)
    path : string - The path to clone from
  pull:  (Pull all changes)
\endcode

\code{.unparsed}
./fcppt_example_options_commands clone
Missing argument "path".
Usage:
[ --git-dir : string - The path to the repository ]
  clone:  (Clone from another repository)
    path : string - The path to clone from
  pull:  (Pull all changes)
\endcode

\code{.unparsed}
./fcppt_example_options_commands clone dir
Clone from dir.
\endcode

\code{.unparsed}
./fcppt_example_options_commands --git-dir x clone dir
Git directory is x.
Clone from dir.
\endcode

\code{.unparsed}
./fcppt_example_options_commands pull
Pull.
\endcode

\section fcpptoptions_help Help option

A help option is a special flag like <code>"--help"</code>. If specified, the
program should print its help text and not accept any other arguments. This
layering of two parsers is implemented by #fcppt::options::parse_help.
It gets a parser of type #fcppt::options::help_switch as its first argument, and a regular parser
as its second argument. #fcppt::options::default_help_switch is
a switch that accepts <code>"--help"</code>:

\snippet options/help.cpp options_parse_help

If the help switch matches, the function returns an #fcppt::options::usage,
otherwise it returns a regular #fcppt::options::result.

\snippet options/help.cpp options_help_match

In this example, <code>parser</code> is a simple parser that parses an int:

\snippet options/help.cpp options_help_int

Here are a few example invocations:

\code{.unparsed}
./fcppt_example_options_help
  Missing flag --help.
|
  Missing argument "arg1".
\endcode

\code{.unparsed}
./fcppt_example_options_help --help
arg1 : int - The main argument
\endcode

\section fcpptoptions_base Hiding parser implementation

As seen in \ref fcpptoptions_complex, the type of a parser can get very
complex, because it carries the exact types of all the parsers used to build
it. In order to hide this, the base class #fcppt::options::base
can be used. Its only type parameter is the parser's result type, which means
that we need to know the result type in advance. In the following example,
we are going to expect a parser that returns an int and a bool:

\snippet options/base.cpp options_base_record

Next, we define a function that creates such a parser. In a real program, this
can be hidden away inside another translation unit:

\snippet options/base.cpp options_create_base

The parser can then be used like any other parser:

\snippet options/base.cpp options_use_base

It is also possible to use such an #fcppt::options::base_unique_ptr as an argument to another parser:

\snippet options/base.cpp options_base_combine

\section fcpptoptions_implementation Implementation

The implementation of a parser consists of the following functions and types:
<table>
<tr>
<th>
Type/Function:
</th>
<th>
Description
</th>
</tr>

<tr>
<td>
<code>result_type</code>
</td>
<td>
The type returned by a successful parse.
</td>
</tr>

<tr>
<td>
<code>fcppt::options::flag_name_set flag_names() const</code>
</td>
<td>
A set of flag names (parameters without an argument) this parser recognizes.
</td>
</tr>

<tr>
<td>
<code>fcppt::options::option_name_set option_names() const</code>
</td>
<td>
A set of option names (parameters with an argument) this parser recognizes.
</td>
</tr>

<tr>
<td>
<code>fcppt::options::usage usage() const</code>
</td>
<td>
A description on how to use this parser.
</td>
</tr>

<tr>
<td>
<code>fcppt::options::parse_result<result_type> parse(fcppt::options::state &&, fcppt::options::parse_context const &) const</code>
</td>
<td>
This is the main parsing function. An #fcppt::options::state
contains the current command-line and an #fcppt::options::parse_context
contains information about the surrounding parsers.
An #fcppt::options::parse_result contains either an error or a result
together with the remaining state.
</td>
</tr>
</table>

The function #fcppt::options::deref dereferences a parser,
which currently can be a copy, an #fcppt::reference or an #fcppt::unique_ptr.
This is used internally by a parser to access its sub-parsers.
*/

namespace fcppt
{
/// Library for command-line options
namespace options{}
}
