Boost logo

Boost :

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


Rob Stewart wrote:
> From: Tobias Schwinger <tschwinger_at_[hidden]>
>
>> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk