/**
\defgroup fcpptrecord fcppt.record
\ingroup fcpptmain
\brief A record class that holds named elements in a generic way.

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

<ul>
	<li>\ref record_motivation</li>
	<li>\ref record_init</li>
	<li>\ref record_label_arg</li>
	<li>\ref record_headers</li>
</ul>

\section record_motivation Motivation

A set of name-type pairs, for example <code>{ age : int, name : string
}</code>, is generally called a <em>record</em>. In C++, these are usually
declared using classes or structs:

\snippet record.cpp record_struct_person

The shortcoming is that such a struct provides no generic structure.
Imagine you would like to write a generic function that prints such a struct,
given you already know how to print ints and strings. A concrete implementation
would look like this:

\snippet record.cpp record_struct_person_print

This, however, only works for the concrete type <code>person</code>. To find a more abstract
representation, we need to specify which elements a struct has in a generic way. To this end, we first
of all need to create unique types that represent <em>element names</em> which we
call <em>labels</em>. Such a label together with a unique tag type is created by
#FCPPT_RECORD_MAKE_LABEL:

\snippet record.cpp record_make_label

A record <em>element</em> is represented by #fcppt::record::element. It
gets a label together with a type as its template parameters:

\snippet record.cpp record_elements

Finally, a <em>record object</em> consists of a list of elements:

\snippet record.cpp record_object

Before we continue, here is a small example of how to use such a record:

\snippet record.cpp record_get_set

The initialization syntax is further explained in \ref record_init. The
functions #fcppt::record::get and #fcppt::record::set
are used to read and write elements.

To return to our goal of creating a generic output function, we first create a
function <code>print_label</code> that given a record and a label prints the
element for the given label to a stream:

\snippet record.cpp record_output_label

The function #fcppt::record::element_vector returns an #fcppt::mpl::list::object of the elements of a record.
Such a list can be used by #fcppt::algorithm::loop, which will
call a function for every type in the sequence. We use this to call <code>print_label</code>
for every element of the record:

\snippet record.cpp record_output

Now, if we were to add another member to the person record, say <code>address</code>, we
wouldn't have to change our <code>print</code> function.

\section record_init Initialization

There are two ways to initialize a record: First, we can initialize every
element separately. This is done by the special syntax
\code
record{label_1{} = value_1, ..., label_n{} = value_n}
\endcode
Here, it is important that all labels of the record appear exactly once. Also,
the types of the values have to match the types of the record.

\code
person const test_person{
	age{} = 42
	// error: forgotten name
};

person const test_person{
	// error: age specified twice
	age{} = 42,
	age{} = 10
};

person const test_person{
	age{} = 42,
	name{} = 10 // error: wrong type for name
};
\endcode

The second way to initialize a record is via the #fcppt::record::init
function. It is a generic function that calls a function for every element of the
record (from first to last), which can be used to initialize a record in
a generic way. Assume that we have the values for our record in a stream:

\snippet record.cpp record_init_stream

We then read the corresponding elements of the record from the stream:

\snippet record.cpp record_init_generic

The lambda is first called for <code>age_element</code> and second for <code>name_element</code>
because of the order they appear in the declaration. So, in the example, <code>age</code> will be
<code>42</code> and <code>name</code> will be <code>"test"</code>.

\section record_label_arg Labels with an argument

Unlike normal labels, there are also labels that take an additional argument. Consider
a sprite that can have a fixed number of textures <code>t_1,...,t_n</code> which will
be rendered in order. To create a label that is parameterized, we use
#FCPPT_RECORD_MAKE_LABEL_ARG:

\snippet record.cpp make_label_arg

Next, we create a type function that takes an unsigned integer <code>I</code>
to the <code>I</code>'th texture element:

\snippet record.cpp sprite_element

Finally, to declare our sprite with N textures, we use
a <code>std::integer_sequence</code> to create a record
with types <code>sprite_element<0>, ..., sprite_element<N-1></code>.

\snippet record.cpp sprite_generic

Here is an example that shows how such a sprite can be initialized:

\snippet record.cpp sprite_example

\section record_headers Header files

<table>
<tr>
<th>Header file</th>
<th>Description</th>
</tr>
<tr>
<td><code>object_fwd.hpp</code></td>
<td>Contains #fcppt::record::object record's  declaration.</td>
</tr>
<tr>
<td><code>object_decl.hpp</code></td>
<td>Contains #fcppt::record::object record's  definition.</td>
</tr>
<tr>
<td><code>object_impl.hpp</code></td>
<td>Contains the definition of #fcppt::record::object record's  member functions.</td>
</tr>
<tr>
<td><code>object.hpp</code></td>
<td>Includes <code>object_impl.hpp</code> and <code>comparison.hpp</code>.</td>
</tr>
<tr>
<td><code>comparison.hpp</code></td>
<td>Contains <code>operator==</code> and <code>operator!=</code>.</td>
</tr>
<tr>
<td><code>element_fwd.hpp</code></td>
<td>Contains #fcppt::record::element element's  declaration.</td>
</tr>
<tr>
<td><code>element.hpp</code></td>
<td>Contains #fcppt::record::element element's  definition.</td>
</tr>
<tr>
<td><code>element_to_label.hpp</code></td>
<td>Contains #fcppt::record::element_to_label.</td>
</tr>
<tr>
<td><code>element_to_type.hpp</code></td>
<td>Contains #fcppt::record::element_to_type.</td>
</tr>
<tr>
<td><code>from_list_fwd.hpp</code></td>
<td>Contains #fcppt::record::from_list.</td>
</tr>
<tr>
<td><code>from_list.hpp</code></td>
<td>Includes <code>fcppt/record/from_list_fwd.hpp</code> and defines #fcppt::record::object.</td>
</tr>
<tr>
<td><code>get.hpp</code></td>
<td>Contains #fcppt::record::get.</td>
</tr>
<tr>
<td><code>init.hpp</code></td>
<td>Contains #fcppt::record::init.</td>
</tr>
<tr>
<td><code>label_fwd.hpp</code></td>
<td>Contains #fcppt::record::label label's  declaration.</td>
</tr>
<tr>
<td><code>label_decl.hpp</code></td>
<td>Contains #fcppt::record::label label's  definition.</td>
</tr>
<tr>
<td><code>label_impl.hpp</code></td>
<td>Contains the definition of #fcppt::record::label label's  member functions.</td>
</tr>
<tr>
<td><code>label.hpp</code></td>
<td>Includes <code>label_impl.hpp</code>.</td>
</tr>
<tr>
<td><code>label_name.hpp</code></td>
<td>Contains #fcppt::record::label_name.</td>
</tr>
<tr>
<td><code>label_value_type.hpp</code></td>
<td>Contains #fcppt::record::label_value_type.</td>
</tr>
<tr>
<td><code>make_label_fwd.hpp</code></td>
<td>Contains #FCPPT_RECORD_MAKE_LABEL and includes <code>label_fwd.hpp</code>.</td>
</tr>
<tr>
<td><code>make_label.hpp</code></td>
<td>Includes <code>make_label_fwd.hpp</code> and <code>label_impl.hpp</code>.</td>
</tr>
<tr>
<td><code>make_label_arg_fwd.hpp</code></td>
<td>Contains #FCPPT_RECORD_MAKE_LABEL_ARG and includes <code>label_fwd.hpp</code>.</td>
</tr>
<tr>
<td><code>make_label_arg.hpp</code></td>
<td>Includes <code>make_label_arg_fwd.hpp</code> and <code>label_impl.hpp</code>.</td>
</tr>
<tr>
<td><code>output.hpp</code></td>
<td>Contains <code>operator<< </code>.</td>
</tr>
<tr>
<td><code>set.hpp</code></td>
<td>Contains #fcppt::record::set.</td>
</tr>
</table>
*/
