Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-06-21 16:30:02


after lots of re-thinking and fixing several flaws my sketch-pad update seems final.

It includes an attempt to rewrite the tags section of the documentation for the
proposed tag handling. I tried my best to make it clearly understandable and
hope no flwas crept in so it works for you.

The updated interface seems quite smooth to me, now. And even the names feel
satisfactory (and after replacing that 'pof' placeholder used in the previous

Thanks again to Jonathan Turkanis for his suggestion to split the tags -- it
really makes things a lot easier to use (and hopefully explain) and even brings
more flexiblity to the library.

The term "function type" (which conflicts with the standard) in the current
documentation will be worked around with some: "optionally decorated function
[type]" or just "type" where the context allows it.

Any proof-reading is very very much welcome!



TODO List:

> Documentation:
> - revise text in respect to the reviewer's notes
> - inline examples, add short examples of typical use cases
> - add a tutorial
> - port to BoostBook on the fly
> Library:
> - wrap interface in namespace, shorten/improve identifier names
> - cv-qualify class types of member function pointer
> - add unary (TypeTraits-style) traits for classification for most common cases
> - decorate member function pointers' class type in 'signature' with a reference
> by default
> - allow a placeholder name in calling conventions configuration to allow
> "explicitly empty" cc-attributation to address MSVC's '__thiscall' which
> cannot be specified explicity.
> - tag becomes the second (template-) parameter for tag-based metafunctions
> - improve tag logic by allowing combination of orthogonal aspects
> - simplify 'signature' by hiding most type members

- extend portability and test-sute, add V2 Jamfiles on the fly

Synopsis (draft):
> (lazy notation, all are class templates)
   (brackets denote optional parts, single slashes denote variations)
> // Classification
> is_function_pointer
> is_function_reference
> is_member_function_pointer_

        is_function_<Type,QueryTag = undecorated> // previously: is_function_type
        kind_of<T> // returns tag of arbitrary type

> // Decomposition
> arity // number of parameters of the function
> parameter[_c] // get a single parameter type
> class_of // class type of member function pointers (undecorated)
                       // (but cv-qualified)

> parameters // MPL sequence of paramters
> signature<T, ClassDecoration = add_reference<_> > // Seq. of all types
> effective_parameter[s/_c] // includes "this reference" (hard-wired)
                                   // except for the sequence: ^
> // Synthesis
> function_type<Signature_or_Seq_or_T // (*1)
> ,Tag = unspecified,ClassDecoration = add_reference<_> >

        tag[n]<Tag_or_Signature // combined tag (*2)
           ,Tag1 [[= nil_t], Tag2 = [[nil_t], ...]] >

        represents<Tag_Or_Signature,QueryTag> // predicate to query a tag

> (*1)
> function_type< signature<T> >
> replaces
> typename function_type_signature<T>::representee
> (*2)
> tag< signature<T> >
> replaces
> typename function_type_signature<T>::kind

Tag types:

The kinds of a type to be synthesised and complex classification queries are
described by *tags types*.

A tag encapsulates one or more aspects of the kind of type (see the reference
section below for examples).
Tags which only encapsulate a single aspect are called *aspect tags* in the
following text.

These can be used to query, whether a type's kind reflects this aspect:

     is_function_type< T, pointer >
     is_function_type< T, variadic >

Aspects can be *abstract* : In this case several non-abstract possibilities of
the same aspect are matched for querying:

     is_function_type< T, unbound >

   is equivalent to:

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

When an aspect tag is used to specify the kind of type to be synthesized, only a
single aspect is specified explicitly:

     function_type< mpl::single_view<void>, variadic >::type is void(...)
     function_type< void(), pointer >::type is void(*)()

Abstract tag aspects are concretized to a default (see refernce below) when used
for type synthesis:

     function_type<void(my_class::*)(), unbound>::type is void()

When a tag is taken from a type, the resulting tag explicitly describes all
aspects and none of them has abstract state:

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

When classifying or synthesising types there are situations where it is
neccessary to describe more than one aspect. Therefore tags can be combined.

E.g. for synthesising a both variadic and pointer-decorated function:

     function_type< mpl::vector<int,int>, tag<pointer,variadic> >::type

In classification context all aspects in the query tag must match:

     is_function_type< void(...), tag<unbound,variadic> >::value == true

     is_function_type< void(my_class::*)(...), tag<unbound,variadic> >::value
       == false

When the 'tag' metafunction is used to combine tags, which describe different
possibiltiies of the same aspects, the right hand side tag's aspect is used --
it *overrides* the aspect:

     tag<unbound,reference>'s decoration aspect is 'reference'
     tag<reference,undecorated>'s decoration aspect is 'undecorated'
     tag<unbound,reference,unbound>'s decoration aspect is 'unbound'

Tag combination occurs either explicitly by using the 'tag' metafunction or
implicitly when using 'function_type' with an optionally decorated function type
or a specialization of 'signature' as its first template argument:

    function_type<void __cdecl(my_class::*)(),tag<undecorated,unspecified_call> >

overrides the decoration and calling convention aspect of the
'void __cdecl(my_class*)()'s kind and thus returns 'void(my_class&)'.

Aspect tag reference:

     // Decoration aspect
     unspecified_decoration (*) (default)
     unbound (*) (matches the next three)
     (*) abstract - same as 'undecorated' when used for synthesis

     // Variadic aspect
     unspecified_variadic (*) (default)
     (*) abstract - same as 'non_variadic' when used for synthesis

     // Const aspect
     unspecified_constness (*) (default)
     (*) abstract - same qualfication as the class type when used for synthesis

     // Volatile aspect
     unspecified_volatility (*) (default)
     (*) abstract - same qualfication as the class type when used for synthesis

     // Calling convention aspect
     unspecified_call (*) (default)
     cdecl, stdcall, etc. (depends on configuration)
     (*) abstract - uses the default calling convention when used for synthesis

Boost list run by bdawes at, gregod at, cpdaniel at, john at