namespace fcppt
{
/**
\brief Contains fcppt::variant::object and helper types/functions for it
*/
namespace variant
{
}
}

/**
\defgroup fcpptvariant fcppt.variant
\ingroup fcpptmain
\brief A class that can hold any object from a fixed set of types

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

<ul>
	<li>\ref variant_motivation</li>
	<li>\ref variant_visitation</li>
	<li>\ref variant_access</li>
	<li>\ref variant_design</li>
	<li>\ref variant_headers</li>
</ul>

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

\section variant_motivation Motivation

A variant is a type that can hold objects of a fixed set of types, which is
sometimes also called a <em>sum type</em>. The closest language feature in C++
are unions, which are very low-level and dangerous to use:
<ul>
<li>A union does not know which type of object it actually holds. This can also
be nothing at all when the union has not been initialized.</li>
<li>Accessing the wrong type is undefined behaviour.</li>
<li>A union also does not know how to call constructors or destructors.</li>
</ul>

\snippet variant/motivation.cpp variant_union

<code>%fcppt::variant</code> fixes the aforementioned problems in the following way:
<ul>
<li>It keeps track of which type it holds.</li>
<li>It is not default-constructible.</li>
<li>It calls constructors, assignment operators and destructors as needed.</li>
<li>Safe access is provided, similar to \ref fcpptoptional.</li>
</ul>

Consider a variant of an int and a string, for which we provide a print function:

\snippet variant/motivation.cpp variant_example

Notice that we do not query which type the variant holds. Instead, we make use
of #fcppt::variant::match and write out all cases explicitly.

\section variant_visitation Visitation

A more general way to access variants is called <em>visitation</em>, which is
similar to <em>pattern matching</em>. A visitor is a struct or class that uses
an <em>overloaded</em> <code>operator()</code> to distinguish between the
possible types of a variant.

Suppose we want to define a visitor that does something different for all
<em>integral types</em>. The easiest way this can be done is by using
<code>std::enable_if</code>.

\snippet variant/visitation.cpp variant_visitor

The following code shows how such a visitor is called:

\snippet variant/visitation.cpp variant_visitor_apply

Here is a small example for defining a binary visitor:

\snippet variant/binary_visitation.cpp variant_binary_visitation

Non-const visitation, which means that the visited variant can be modified, is
also supported.

\snippet variant/nonconst_visitation.cpp variant_nonconst_visitor
\snippet variant/nonconst_visitation.cpp variant_nonconst_visitation

\section variant_access Access

Visitation and matching are the most common ways to access a variant. The
other ways are:
<ul>
<li>#fcppt::variant::get_unsafe which does not check if the
variant actually holds the queried type. It is comparable to
<code>static_cast</code> to a derived class.</li>
<li>#fcppt::variant::to_optional returns an optional to
the queried type. Similarly, #fcppt::variant::to_optional_ref returns
an optional reference.</li>
</ul>

\section variant_design Design

While the design of <code>fcppt::variant</code> is similar to
<code>std::variant</code>, there are some key differences:

<ul>
<li>#fcppt::variant::object does not provide a default constructor.
<code>std::variant</code> default constructs the first type of all possible
types instead, which does not make any sense.</li>
<li>#fcppt::variant::object's constructor is explicit.</li>
<li>#fcppt::variant::object does not allow any implicit conversions in its
constructors.</li>
</ul>

\section variant_headers Header files
<table>
<tr>
<th>Header file</th>
<th>Description</th>
</tr>
<tr>
<td><code>object_fwd.hpp</code></td>
<td>Contains #fcppt::variant::object variants's  declaration.</td>
</tr>
<tr>
<td><code>object_decl.hpp</code></td>
<td>Contains #fcppt::variant::object variant's  definition.</td>
</tr>
<tr>
<td><code>object_impl.hpp</code></td>
<td>Contains the definition of #fcppt::variant::object variants's  member functions.</td>
</tr>
<tr>
<td><code>object.hpp</code></td>
<td>The same as <code>object_impl.hpp</code>.</td>
</tr>
<tr>
<td><code>apply.hpp</code></td>
<td>Contains #fcppt::variant::apply .</td>
</tr>
<tr>
<td><code>compare.hpp</code></td>
<td>Contains #fcppt::variant::compare .</td>
</tr>
<tr>
<td><code>comparison.hpp</code></td>
<td>Contains <code>operator<</code>, <code>operator==</code> and <code>operator!=</code>.</td>
</tr>
<tr>
<td><code>from_list_fwd.hpp</code></td>
<td>Contains #fcppt::variant::from_list.</td>
</tr>
<tr>
<td><code>from_list.hpp</code></td>
<td>Includes <code>fcppt/variant/object_fwd.hpp</code> and defines #fcppt::variant::object.</td>
</tr>
<tr>
<td><code>get_unsafe.hpp</code></td>
<td>Contains #fcppt::variant::get_unsafe  which does the same
thing as the #fcppt::variant::object::get_unsafe member
function.</td>
</tr>
<tr>
<td><code>holds_type.hpp</code></td>
<td>Contains the #fcppt::variant::holds_type  function to check if
a type is held by the variant.</td>
</tr>
<tr>
<td><code>match.hpp</code></td>
<td>Contains #fcppt::variant::match.</td>
</tr>
<tr>
<td><code>output.hpp</code></td>
<td>Contains <code>operator<<</code> for output.</td>
</tr>
<tr>
<td><code>to_optional.hpp</code></td>
<td>Contains #fcppt::variant::to_optional.</td>
</tr>
<tr>
<td><code>to_optional_ref.hpp</code></td>
<td>Contains #fcppt::variant::to_optional_ref.</td>
</tr>
<tr>
<td><code>type_info.hpp</code></td>
<td>Contains #fcppt::variant::type_info.</td>
</tr>
</table>
*/
