1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
The inverse operation of determining the index of a certain type in a
tt(TypeList) is retrieving the type given its index. This inverse operation is
the topic of this section.
The algorithm is implemented using a struct tt(TypeAt). tt(TypeAt) specifies a
using-declaration to define the type matching a given index. But the index
might be out of bounds. In that case we have several options:
itemization(
it() Use a link(static_assert)(STATICASSERT) to stop the compilation. This
is an appropriate action if the index should simply not be out of bounds;
it() Define a local type (e.g., tt(Null)) that should not be used as a
type in the tt(TypeList). This type is going to be returned when the index is
out of bounds. Using this local type as one of the types in a tt(TypeList) is
considered an error as its would conflict with the special meaning of tt(Null)
as the type returned at an invalid index.nl()
To prevent tt(Null) from being returned by tt(TypeAt) a tt(static_assert)
is used to catch the tt(Null) type when it is encountered while evaluating
tt(TypeAt);
it() The struct tt(TypeAt) may define an enum value tt(validIndex) set to
tt(true) if the index was valid and set to tt(false) if not.
)
The first alternative is implemented below. The other alternatives are not
difficult to implement and are left as exercises for the reader. Here's how
tt(TypeAt) works:
itemization(
it() The foundation consists of a variadic template struct tt(TypeAt),
expecting an index and a tt(TypeList):
verbinclude(//TYPEAT examples/typeat.h)
it() If the typelist is empty a tt(static_assert) ends the compilation
verbinclude(//INVALID examples/typeat.h)
it() If the search index equals 0, define tt(Type) as the first type in
the tt(TypeList):
verbinclude(//ZERO examples/typeat.h)
it() Otherwise, tt(Type) is defined as tt(Type) defined by tt(TypeAt<index
- 1>) operating on the tt(TypeList)'s tail:
verbinclude(//TYPELIST examples/typeat.h)
)
Here is how tt(typeAt) can be used. Uncommenting the first variable
definition causes a tt(TypeAt index out of bounds) compilation error:
verbinclude(//EXAMPLE examples/typeat.cc)
|