
Tobias Schwinger <tschwinger@neoscientists.org> writes:
Tag Types ----------
The Function Types library uses *tag* types in order to represent or
Strike "in order."
query one or more aspects of a type's kind.
Such as...?
Tags that represent the variations of a single aspect are called *aspect tags*.
Strike "the."
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>
Why are these not just "aspects of the type?" "Aspect of the type's kind" seems needlessly complex.
When classifying types it is often necessary to match against several variations of one aspect.
Okay, now you've introduced "variations of an aspect of a type's kind??!" Help! I'm drowning in jargon!
Special, *abstract* variations allow this behaviour.
is_function< T, free_or_static >
What aspect are "free" and "static" variations of? Oh, of the decoration aspect? Let's try this again: Tag Types ---------- The Function Types library uses *tag* types to represent or query one or more properties of a type, such as its variadicness, or whether it is a pointer. Tags that represent the values of a single property are called *property tags*. These tags can be used to determine whether one property of the type has a particular value. is_function< T, variadic > is_function< T, pointer > // same as is_function_pointer<T> To match against several values of a property at once, you can use wildcard property tags: is_function< T, free_or_static > // the tag 'free_or_static' captures two values of the decoration // property and makes the above code equivalent to: mpl::or_< is_function_type< T, undecorated> , is_function_type< T, pointer > , is_function_type< T, reference > > [?? This example doesn't make any sense to me; what do "undecorated," "pointer," and "reference" have to do with whether a function is free or static?? If you really meant what you wrote, you had better explain -- at length!] Every property has a fully-general wildcard tag that can be used to indicate that /any/ value of the property should be matched. The tag's name is the same as that of the property, but with the prefix "unspecfied_". is_function< T, unspecified_decoration >::value // true for any type T that the library can handle [You need to say more clearly what "can handle" means. IMO the comment should really be expressed as the last sentence of the foregoing paragraph]
Each abstract variation of an aspect has a non-abstract semantic equivalence
Wha??? I don't know how to translate that into something simpler, because I can't tell what it means!
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
And the example doesn't help me tell what it means, mostly because of my confusion above, probably.
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, ...
A signature tag is a compound tag that precisely describes all of a specific type's properties, so it does not act as a wildcard. signature< void() > // describes all aspects: undecorated, non-variadic, ... [This example fails to illustrate your main point, which is that it doesn't act as a wildcard. That said, I'm not sure it's an important point to make -- it should be obvious! Anyway, if you use this section it should come after compound property tags are introduced below]
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...)
[That "tag" template is not obviously a metafunction from its usage. I believe calling it that here (even if it really is one) is confusing. ] A compound property tag describes a combination of possible values of different properties. The tag class template can be used to create a specific compound property tag. The specialization of tag used below matches all pointers to variadic functions, and the type vector further restricts the type matched to int(*)(int,...). function_type< mpl::vector<int,int>, tag<pointer,variadic> >::type
In the context of classification all aspects represented by the query tag must match:
A compound property tag matches a type only when all of its component properties 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.
[I don't know what "except for tag combination" is supposed to mean above, so I left it out below, but if it's important, you need to describe what _does_ happen when you use the fully-general wildcard in a "tag combination" (whatever that is)] The fully-general wildcard tag for any property not otherwise represented can be added to a tag specialization without changing its meaning. [Now that I read it I guess I don't know whether I am even saying what you were trying to say here. And I don't know what use the 2nd sentence (which needs an antecedent for "this") is without an example]
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.
When several tags for the same property appear in the argument list, only the last one is used; others are ignored. [I assume we are still on the topic of the "tag" class template here, so "the argument list" is sufficient. I wonder if there's a rationale for this behavior, as opposed to making it a compile-time error?]
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.
Tags can be combined either explicitly, by using the tag metafunction, or implicitly. Implicit tag combination takes place when function_type is used with a tag or function type as its first template argument. In the example below, any properties of the first argument to function_type not overridden by those in the tag specialization are turned into a tag and implicitly combined with the tag specialization to produce a new function type. [personally I don't believe it's important for users to know that implicit tag combination happens here, and I think saying so just complicates matters. It would be just as useful to say that "any properties represented in the tag specialization override those of the first argument to produce a new function type," and leave it at that.]
function_type<void __cdecl(X::*)(),tag<undecorated,unspecified_call> > // ::type member is 'void(my_class&)' // the decoration and calling convention aspect are overridden
-- Dave Abrahams Boost Consulting www.boost-consulting.com