## Variadic Templates

C++ long lacked a type-safe way to write variadic functions, which
would also be compatible with passing non-POD values. Variadic
templates are this mechanism, but in addition to function templates,
it is also available for class templates, which makes it much more
powerful. This is an essential part of what makes ‹std::tuple› and
‹std::variant› possible.

Besides the traditional ‹template› syntax with ‹typename...› or say
‹int...› or even ‹auto...› in the parameter list (the parameter with
an ellipsis in it is called a «parameter pack»), abbreviated generic
functions using ‹auto› parameters can be made variadic directly, by
writing their last argument as ‹auto... foo› (possibly decorated
with ‹const›, ‹&›, ‹&&› and so on).

However, the ‹template› syntax (besides being required for ‹class›
templates) has one additional advantage: it may contain «multiple»
such «parameter packs». Of course, instantiating such template is
only possible if all except the first pack are entirely deduced
(e.g. because they appear as template parameters in argument types:
‹std::tuple< args_t... >› in a parameter list will deduce the entire
pack ‹args_t›).

There are, besides direct expansion, 3 essential tools for working
with parameter packs:

 1. the simplest and most direct is recursion (with a helping of ‹if
    constexpr›) which is basically always possible but usually not
    very succinct,
 2. fold expressions, which work like direct expansion, but with
    operators interspersed between individual pack members (these
    can be used to great effect, e.g. folding with the comma
    operator can often replace the non-existent ‹for constexpr›),
 3. and finally index sequences, which are especially useful with
    tuples (or other compile-time indexable types).

Each of these techniques will be highlighted in one of the following
demos:

 1. ‹make›  – constructing a tuple from constructor argument tuples
 2. ‹xxx›
 3. ‹xxx›
 4. ‹trim›  – reduce the number of elements, recursively

Elementary:

 1. ‹max›   – pick a maximal value among arguments

Practice:

 1. ‹vfold›   – fold arguments using a function
 2. ‹tzip›    – zip a pair of tuples into a tuple of pairs
 3. ‹tdrop›   – copy of a tuple without first element
 4. ‹mvec›    - multi-type, multi-track vector
 5. ‹reverse› – reverse a tuple
 6. ‹tvec›    – type-indexed runtime values

Regular:

 1. ‹tcat›    – join arbitrary tuples, tuplify non-tuple args
 2. ‹flatten› – construct a tuple of non-tuple values
