parsepp  typelists

Typelists

Typelists are an idiom popularized by Andrei Alexandrescu in his amazing book entitled Modern C++ Design (that book triggered a re-awakening in my interest in C++).

In an ideal world we could pass an arbitrary number of arguments to a class or function template. In the current standard we can't do that, but in C++0x we can (gcc 4.3 already supports this). Typelists help us work around that by providing a partial workaround (albeit a slightly unsightly one). Typelists typically are made up of a very small struct type with two typedefs, then a whole boatload of generated code which implements specializations to allow variadic-like arguments (but there is an upper-limit to the number, typically set by the typelist implementor).

parsepp's older brother, parse0x, is essentially identical to parsepp but takes advantage of C++0x's variadic templates to provide a much small implementation than we can get with current typelists. To work around that missing feature, parsepp uses two core typelist-like types, called rule_list and char_list. (Normally referred to by the names RuleList and CharList.) The upper limit on the number of arguments is set at compile time, with some hard upper limit (whatever was generated by the code generator and build time). The default maximum is "some reasonable number" (e.g. 15, which "should" be suitable for most uses of this library).

A RuleList is a pseudo-variadic type which is used like this:

rule_list<Rule1,...RuleN>

All types passed to a RuleList must be Rules. That is, they must behave as described in the API documentation for the RuleConcept class.

Only a few of the core Rules expect a RuleList. Most expect a single Rule instead (a RuleList is not inherently a Rule). Rules which expect a RuleList conventionally use the template typename RuleList for that argument, whereas others conventionally use the name Rule (or <Rule1,Rule2>, or similar).

Aside from RuleList, some of the core Rules expect a list of character literals (e.g. match an 'A' or a 'z'). This feature is provided by the char_list pseudo-variadic type, which is used like this:

char_list<Char1,...CharN>

where each Char must be a character literal or an integer constant which is a legal character value. The framework reserves the null character to mark end-of-input, and reserves the integer value -1 to mark the end of CharLists.