Boost logo

Boost :

From: Andrei Alexandrescu (andrewalex_at_[hidden])
Date: 2001-11-24 21:30:04


I just uploaded typelist.zip for review. It contains three header files and
a cpp test file.

Background:

Typelists are useful collection of types which allow implementing repetitive
data and code structures with remarkable ease. This in turn enables reuse of
a higher level. Typelists are especially useful in implementing code that
looks similar but is applied to several types known at compile-time. Also,
typelists can have less obvious (and more powerful) uses in hierarchy
generators. Here's a list of generic components that typelists can help:

* Functors. Typelists can define the list of argument types.

* Double dispatch. If the types to dispatch on are known at compile time,
you can use typelists to express them and generate the dispatch code
automatically.

* Factories. You can use typelists to express and manipulate the types that
a factory can produce.

* The Visitor Pattern. A really cool application of typelists is automating
implementation of cyclic visitation in the Visitor pattern.

* Variant types. You can use typelist to express and manipulate the
collection of types that is stored in a variant type. Also, typelists are
helpful in implementing ancillary stuff such as computing alignment.

* Tuples. Tuples using a typelist facility as a back-end can have a simple,
terse implementation. Also, tuples can be made visitable, thus nicely
integrating with typelist-based visitors above.

If typelists make it into boost, then all the components above can benefit
of them - and can be later submitted to boost as well.

Synopsis (more documentation is interspersed with the code):

1. Header null_typelist.hpp

class null_typelist;

* Defines a class that is used by convention as a typelist terminator. I
didn't use boost::tuple's null_type because in the long haul, if typelists
will be accepted, it would be more logical that tuples depend on typelists,
and not vice versa.

2. Header type_manip.hpp

template <int v> struct int2type;

* Maps integral constants to values. As I'm sure you know, this little
template has a lot of uses. Exposes value which evaluates to the passed-in
constant.

template <typename T> struct type2type;

* Maps each type to a unique, insipid type. Exposes T as original_type.

template <bool flag, typename T, typename U> struct select;

* The well-known "compile-time if". It is present in mpl as well as in
detail/select_type.hpp. By this I am making a suggestion to give
"compile-time if" full boost citizenship - not as a member of a library or a
detail.

template <class T, class U, bool strict = false>
struct super_subclass;

* Exposes value which evaluates to nonzero if T is a superclass of U. If you
specify strict = true, then T and U also must be distinct types. The
cv-qualifiers are ignored.

3. Header typelist.hpp

#define TYPELIST_1(T1)
...
#define TYPELIST_50(T1, ..., T50)

* The dreaded macros that linearize typelist creation.

template <class T, class U> struct type_list;

* Guess what :o).

namespace tl
{
    template <class TList> struct tl::length;

    template <class TList, unsigned int index> struct type_at;

    template <class TList, unsigned int index, typename default_type>
    struct type_at_nonstrict;

    template <class TList, class T> struct index_of;

    template <class TList, class T> struct append;

    template <class TList, class T> struct erase;

    template <class TList, class T> struct erase_all;

    template <class TList> struct no_duplicates;

    template <class TList, class T, class U> struct replace;

    template <class TList, class T, class U> struct replace_all;

    template <class TList> struct reverse;

    template <class TList, class T> struct most_derived;

    template <class TList> struct derived_to_front;
}

* These are the typelist manipulation algorithms. They are defined an a
protecting namespace tl. Again, you can find detailed documentation for each
of these functions in the header.

4. File typelist.cpp

* Contains only main() and tests typelists. Note: I couldn't test
most_derived and derived_to_front because MWCW didn't work with them. By the
way, as of now the code has been tested with MWCW 7.0 only.

More comments:

I would like to make a couple of proposals, which again I will put in
bulleted format:

* Everything is now in namespace ::boost::loki. I propose in the future that
typelists are migrated to namespace boost because they are generic enough to
deserve boost visibility.

* I suggest we merge the exisiting boost header "type.hpp" with
"type_manip.hpp". The type.hpp header defines only:

template <class T> struct type {};

which is functionally equivalent with loki::type2type. The suggested name
for the merge is type_manip.hpp for the header and type2type because "type"
is too general to be of any informativeness.

* There is some controversy around the TYPELIST_nn macros. The best solution
uses an extralinguistic mechanism, which is sort of "cheating" but sounds
pretty good. I believe that the one true solution is to change the language.
I am eager to hear suggestions and I would love it if the ensuing discussion
would lead to a good solution.

Andrei


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk