Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-07-01 07:44:33


Tag Types
----------

The Function Types library uses *tag* types in order to represent or query one or
more aspects of a type's kind.

Tags that represent the variations of a single aspect are called *aspect tags*.
These tags can be used to determine whether one aspect of the type's kind matches
a particular variation.

     is_function< T, variadic >
     is_function< T, pointer > // same as is_function_pointer<T>

When classifying types it is often necessary to match against several variations
of one aspect. Special, *abstract* variations allow this behaviour.

is_function< T, free_or_static >

     // the tag 'free_or_static' describes an abstract variation of the decoration
     // aspect and makes the above code equivalent to:

     mpl::or_< is_function_type< T, undecorated>
             , is_function_type< T, pointer >
             , is_function_type< T, reference > >

Every aspect has at least one abstract variation, described by the (aspect)
tag named "unspecfied_" plus the aspect name. This variation's primary purpose
is to match any variation of an aspect; that is, to ignore that aspect in the
context of type classification.

     is_function< T, unspecified_decoration >::value
     // true for any type T the library can handle

Each abstract variation of an aspect has a non-abstract semantic equivalence when
used in the context of type synthesis (as defined in the reference section).

     function_type<void(X::*)(), free_or_static>::type

     // is equivalent to:

     function_type<void(X::*)(), undecorated>::type

A tag created from a type completely describes all aspects of the type's kind. The
aspect variations in the tag are never abstract.

     signature< void() >
     // describes all aspects: undecorated, non-variadic, ...

When classifying and especially when synthesising types, there are situations in
which it is neccessary to describe more than one aspect. Therefore tags can be
combined using the tag metafunction.

     function_type< mpl::vector<int,int>, tag<pointer,variadic> >::type
     // is int(*)(int...)

In the context of classification all aspects represented by the query tag must match:

     is_function_type< void(...), tag<free_or_static,variadic> >::value
     // is true

     is_function_type< void(X::*)(...), tag<free_or_static,variadic> >::value
     // is false

Except for tag combination, each aspect that is not represented by a tag is
similar to the abstract variation represented by the tag named "unspecified_" plus
that aspect's name. This is why these tags do not have to be specified in many
contexts.

When there are tags representing different variations of the same aspect in tag's
template argument list, the last variation is used; others are ignored.

     tag<free_or_static,reference>
     // decoration aspect is 'reference'

     tag<reference,undecorated>
     // decoration aspect is 'undecorated'

     tag<undecorated,reference,unspecified_decoration>
     // decoration aspect is 'unspecified_decoration'

     tag<undecorated,variadic,pointer>
     // two aspects are set: pointer decoration and variadic

Tag combination occurs either explicitly by using the tag metafunction or
implicitly. Implicit tag combination takes place when using function_type with a
tag or (possibly decorated) function type as its first template argument.

     function_type<void __cdecl(X::*)(),tag<undecorated,unspecified_call> >
     // ::type member is 'void(my_class&)'
     // the decoration and calling convention aspect are overridden


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