
Rob Stewart wrote:
From: Tobias Schwinger <tschwinger@neoscientists.org>
Tag types: ----------
The kinds of a type to be synthesised and complex classification queries are
Here's a typo: it should be either "kinds of types" or "kind of a type".
I don't understand "the kinds of a type." Is this a reference to something discussed elsewhere?
"Elsewhere" is work in progress ;-). Here's a (maybe still bad) defintion: A type supported by this library is completely described by its subtypes and its kind. The kind collectively refers to the following information: - decoration (none,pointer,reference,member pointer) - variadicity ^^^^^^^^^^^ ANNOTATION: is this a word? Is it "variadicness" (sounds even stranger)? - cv-qualification of member function pointers - the calling convention attribute
described by *tag* types.
No paragraph break here.
OK - but why?
A tag encapsulates one or more aspects of the kind of type.
s/kind/kinds/ to be consistent with the first sentence? (I still don't understand the phrase, though.)
Caused by that ^$% typo above, I guess...
Tags which only encapsulate variations of a single aspect are called
s/only encapsulate/represent the/ ?
OK.
*aspect tags* in the following text (see reference).
Strike "in the following text." You're creating the term for the library, not just the following text.
OK.
Aspect tags can be used to query, whether a type's kind reflects this aspect:
No comma. s/reflects/includes/ or s/reflects/is described by/ ?
OK. How about "contains"?
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*.
There are special tags that represent groups--or the union--of several variations of a single aspect.
Shouldn't "abstract variations" be "abstract tags?"
Don't think so: "aspects" and "variations" are semantics, the tags are their syntactical encapsulation.
I think, like John suggested, that "composite tags" works better than "abstract tags." The special variation you use represents a grouping or union of variations, not a generalization of them.
I'm afraid it /is/ in fact a generalization - see http://lists.boost.org/boost/2005/06/29472.php
is_function< T, free_or_static >
The free_or_static describes an abstract variation of the decoration aspect
^tag
and makes the above code is equivalent to:
s/is //
OK.
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
s/abstact variation/abstract tag/ (or "composite tag" ;0)
Noted. Not sure, yet.
(aspect) tag named "unspecified_" plus the aspect name.
Instead of "unspecified_" how about "any_?" It is shorter and fits the prose. Whenever you discuss this, you refer to matching *any* variation.
is_function< T, unspecified_decoration >::value // true for any type T the library can handle
Not sure here: function_type< mpl::single_view<int>, unspecified_call >::type == "give me a function type of the default calling convention (the one you get when you /don't specify/ it)" function_type< mpl::single_view<int>, any_call >::type == <just strange> I do like the shortening, though.
You said my version was incorrect because I suggested this query was only useful in combination with other queries. I don't see the point in asking whether a type fits any variation of an aspect while asking about no other aspects. In that case, you're asking about no aspects. The above suggests that one might have to choose an "any" aspect tag just to ask whether a type is a function type, but that just seems messy. So, what are the use cases for a query like the above in which nothing specific is queried?
If no second template argument is given, is_function asks for a "function type"; that is as defined by the standard, "undecorated": template<typename T, typename Tag = undecorated> struct is_function; Well, technically I could've used some "null tag" here, but it's more expressive to say what we want, isn't it? But this is not the only issue I had with that one of your versions (note btw. that the current version is also heavily inspired by a different one from you): typedef tag< some_query, unspecified_decoration > new_query; // widens a query but doesn't test anything
Each abstract variation of an aspect has a non-abstract semantical equivalence
s/semantical/semantic/
Whoops - this one crept in again...
I like the "non-abstract semantic equivalence" phrasing to explain the "concrete" usage of the tags.
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
That use of free_or_static seems just plain wrong. Why would you synthesize a type while giving a choice as to how it is decorated? Yes, you can document that free_or_static and undecorated are the same in this context, but it is confusing at best.
Imagine this case: function< typename function_type<MemFnPtr, free_or_static>::type > I think it does make sense to express 'free_or_static' (== "remove the member pointer, please") instead of 'undecorated', here. It's not about giving a choice to the library how things are done but giving a choice to the user to differently express things in different contexts. Further fail-safeness has some advantages. Remember btw. that the "_or_" in the name "free_or_static" does not reflect technical distinction but only exists in terminology. That's why I initially used "unbound" instead of "free_or_static". I know the "(default)" in the reference section is still very confusing. Please just ignore it, for now (it refers to the default of unset aspects *in a tag*, *not* to the template default arguments of the metafunctions).
When a tag is taken from a type, the resulting tag explicitly describes all aspects, none of them with an abstract variation:
When querying for a tag describing a type, the result is a nonabstract tag that describes all aspects of the type.
Yours was structured poorly, but more importantly, I didn't get the "taking" a tag from a type part. I'm sure mine doesn't capture the concept quite right, but hopefully it helps.
Inspired by "taking the address of an object" -- but you're right -- there is a serious flaw: the tag is not a property of the type. Either s/tag/kind/ or s/taking/creating/ fixes it. I prefer the former.
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
s/where/in which/ (situations aren't places)
OK.
combined.
combined in a single query using the tag metafunction.
OK. But s/in a single query// -- combination of tags does not imply querying.
E.g. for synthesising a both variadic and pointer-decorated function:
FWIW, I always find it appropriate to follow "for example" with a comma, so I consider it approprite to follow "e.g." with one.
OK. ... and probably spell it out. Looks nicer, I guess.
function_type< mpl::vector<int,int>, tag<pointer,variadic> >::type
In classification context all aspects in the query tag must match:
s/context/contexts/
OK.
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
No comma.
OK.
variations of the same aspect, the right hand side tag's variation is used -- it *overrides* the aspect:
Try this instead:
When using the tag metafunction to combine tags, it is possible to have different variations of the same aspect in the list. In that situation, the last (rightmost) variation
^^ "in the tags in the list" to be correct - note: syntax vs. semantics. After applying this correction I don't find it too appealing... What is wrong with the original in your opinion??
is used; the others are ignored.
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:
Tag combination occurs either explicitly, by using the tag metafunction, or implicitly. Implicit tag combination occurs when using function_type with a tag or a (possibly decorated) function type as its first template argument.
OK. Better. <snip reference> There's lots of valuable material in your post. Thank you, Tobias