
Since the discussion seems to be drifting apart, I tried to bundle it by applying its results. Please try to reply to make suggestions based on this version, so we don't waste too much energy on redundant work. Thanks, Tobias Tag types: ---------- The kinds of a type to be synthesised and complex classification queries are described by *tag* types. A tag encapsulates one or more aspects of the kind of type. Tags which only encapsulate variations of a single aspect are called *aspect tags* in the following text (see reference). Aspect tags can be used to query, whether a type's kind reflects this aspect: 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. There are special variations which make this possible. These are called *abstract variations*. is_function< T, free_or_static > The free_or_static describes an abstract variation of the decoration aspect and makes the above code is equivalent to: mpl::or_< is_function_type< T, undecorated> , is_function_type< T, pointer> , is_function_type< T, reference> > An important use case for abstract variations is to match any variation of an aspect; that is, to ignore it in the context of type classification. Because of this, every aspect has at least one abstact variation, described by the (aspect) tag named "unspecified_" plus the aspect name. 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 semantical 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 When a tag is taken from a type, the resulting tag explicitly describes all aspects, none of them with an abstract variation: signature< void() > ANNOTATION: ^^^ will be a model of Tag (this is not yet documented) // describes all aspects: undecorated, non-variadic, ... When classifying and especially when 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<free_or_static,variadic> >::value // is true is_function_type< void(X::*)(...), tag<free_or_static,variadic> >::value // is false When the 'tag' metafunction is used to combine tags, which describe different variations of the same aspect, the right hand side tag's variation is used -- it *overrides* the aspect: tag<free_or_static,reference> // decoration aspect is 'reference' tag<reference,undecorated> // decoration aspect is 'undecorated' tag<undecorated,reference,undecorated> // decoration aspect is 'undecorated' Tag combination occurs either explicitly by using the 'tag' metafunction or implicitly when using 'function_type' with an optionally decorated function type or a tag 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 Aspect tag reference: --------------------- ANNOTATION: a proper explanation for "(default)" is still missing, please ignore it for now. // - decoration aspect typedef /.../ unspecified_decoration; // (*) (default) typedef /.../ unbound; // (*) (matches the next three) typedef /.../ undecorated; typedef /.../ pointer; typedef /.../ reference; typedef /.../ member_pointer; // (*) abstract - same as 'undecorated' when used for synthesis // - variadic aspect typedef /.../ unspecified_variadic; // (*) (default) typedef /.../ non_variadic; typedef /.../ variadic; // (*) abstract - same as 'non_variadic' when used for synthesis // - const aspect typedef /.../ unspecified_constness; // (*) (default) typedef /.../ const_; typedef /.../ non_const; // (*) abstract - same qualfication as the class type when used for synthesis // - volatile aspect typedef /.../ unspecified_volatility; // (*) (default) typedef /.../ volatile_; typedef /.../ non_volatile; // (*) abstract - same qualfication as the class type when used for synthesis // Calling convention aspect typedef /.../ unspecified_call; // (*) (default) typedef /.../ cdecl, stdcall, etc. (depends on configuration) // (*) abstract - uses the default calling convention when used for synthesis