|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2005-07-01 09:23:13
Tobias Schwinger <tschwinger_at_[hidden]> 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk