|
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