2010-02-20 13:25:19 +01:00
|
|
|
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.
|
2007-06-06 17:03:01 +02:00
|
|
|
|
2010-02-20 13:25:19 +01:00
|
|
|
The algorithm is implemented using a struct tt(TypeAt). tt(TypeAt) uses a
|
|
|
|
tt(typedef) 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
|
2011-05-25 10:46:45 +02:00
|
|
|
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
|
2010-02-20 13:25:19 +01:00
|
|
|
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
|
2010-02-28 17:34:35 +01:00
|
|
|
tt(TypeAt) works:
|
2007-06-06 17:03:01 +02:00
|
|
|
itemization(
|
2010-02-20 13:25:19 +01:00
|
|
|
it() The foundation consists of a variadic template struct tt(TypeAt),
|
|
|
|
expecting an index and a tt(TypeList):
|
2010-11-06 16:47:24 +01:00
|
|
|
verbinsert(TYPEAT)(examples/typeat.h)
|
2007-06-13 11:20:59 +02:00
|
|
|
|
2010-02-20 13:25:19 +01:00
|
|
|
it() If the typelist is empty a tt(static_assert) ends the compilation
|
2010-11-06 16:47:24 +01:00
|
|
|
verbinsert(INVALID)(examples/typeat.h)
|
2007-06-13 11:20:59 +02:00
|
|
|
|
2010-02-20 13:25:19 +01:00
|
|
|
it() If the search index equals 0, define tt(Type) as the first type in
|
|
|
|
the tt(TypeList):
|
2010-11-06 16:47:24 +01:00
|
|
|
verbinsert(ZERO)(examples/typeat.h)
|
2007-06-13 11:20:59 +02:00
|
|
|
|
2010-02-20 13:25:19 +01:00
|
|
|
it() Otherwise, tt(Type) is defined as tt(Type) defined by tt(TypeAt<index
|
|
|
|
- 1>) operating on the tt(TypeList)'s tail:
|
2010-11-06 16:47:24 +01:00
|
|
|
verbinsert(TYPELIST)(examples/typeat.h)
|
2007-06-06 17:03:01 +02:00
|
|
|
)
|
2010-02-20 13:25:19 +01:00
|
|
|
Here is how tt(typeAt) can be used. Uncommenting the first variable
|
|
|
|
definition causes a tt(TypeAt index out of bounds) compilation error:
|
2010-11-06 16:47:24 +01:00
|
|
|
verbinsert(EXAMPLE)(examples/typeat.cc)
|