Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-07-02 21:08:18


Tobias Schwinger <tschwinger_at_[hidden]> writes:

> David Abrahams wrote:
>
> <snip>
>> Subtypes? I think you mean argument, optional class target, and
>> return types. These are not (necessarily) "subtypes!" That word has
>> a very specific -- and different -- meaning in computer science.
>>
>
> I see. How about "Component types?"

That would be okay.

> This term should be close enough to common
> terminology since we are talking about "compound types." Works?
>
>> A type supported by this library is completely described by its
>> argument types, return type, class target (if the type is a
>> member pointer), and the following properties:
>>
>> - decoration (none,pointer,reference,member pointer)
>> - variadicity
>> - cv-qualification of member function pointers
>> - calling convention
>>
>
> Btw: "argument types" or "parameter types?"

Right, "parameter types."

>> You really don't intend to represent cv-qualification of member
>> function pointers as simply the cv-qualification attached to the class
>> type?
>>
>
> I do -- by default! Specifying these tags allows you to set/query either one of
> them explicitly.
>
> Because:
>
> ANNOTATION: I use const_member instead of const_ because it's its new name without
> trailing underscore. It will imply the 'member_pointer' decoration property then.
>
> a)
> is_const< typename class_of<T>::type >::value
> // precondition: T must be a member function pointer (decomposition)
>
> is_function<T,const_member>::value
> // no precondition (classification)
> b)
>
> mpl::not< is_const< typename class_of<T>::type > >::value
> // is lengthy
>
> is_function<T,non_const_member>::value
> // is not, plus it's more efficient
>
> c)
>
> function_type<MemFnPtr,[non_]const_member>::type
> // remove/add const from member function
>
> // NOTE: not specifying the const property in the context means keeping the
> // qualification of the original type (given the destination type will be a
> // member function pointer, that is).

Okay, not bad.

>>>> 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]
>>>
>>>s/type the library can handle/(possibly decorated) function type/
>>
>>
>> "(possibly decorated)" adds nothing. You have already made it clear
>> that function types can be decorated -- or if you haven't, you can't
>> just throw the term in here in parentheses and expect anyone to
>> understand what you mean.
>
> What 'decorated' means was already introduced (by the very first sentence of the
> documentation, see previous post).
>
> Generally I agree. However in this case it /should/ be mentioned because:
>
> template<typename T, typename Tag = undecorated> struct is_function;
> ^^^^^^^^^^^
>
> The default argument, if no tag is given, makes 'is_function' only match function
> types (standard definition, compatible with TypeTraits).
>
> The "code-to-English-mapping" is like this:
>
> is_function<T> // "is T a function (not decorated)?"
> is_function<T,pointer> // "is T a function pointer?"
> is_function<T,variadic> // "is the function _in_ T variadic?"

I am unsure that supporting this default is well-advised. We already
have is_function in the Type Traits library, no?

> However, if too confusing I can introduce a version of 'is_function'
> with a single template parameter, change the name of the current
> 'is_function' to something else (e.g. "is_function_of_kind" --
> better names are very welcome) and change its default argument.

   has_properties?

I assume you are in some nice nested namespace of Boost, with that suggestion.

> <snip>
>>> // Member function pointer -> function with default calling convention
>>> function_type<T, tag<undecorated,unspecified_call> >::type
>>
>>
>> Oh, wait. This use of "unspecified" is very bad, because it conflicts
>> with the very specific way the C++ standard (and many Boost libraries
>> as a result) use the word. The calling convention of the result isn't
>> unspecified -- that would mean "it will be something whose properties
>> we might describe but we're not going to tell you exactly what it is."
>
> This issue was already expressed and "any" was proposed instead.

"Any" is almost as bad as unspecified! You don't mean that it's some
abitrary calling convention, but that it is the default calling
convention.

>> In this case the calling convention is very much being specified to be
>> the default!
>>
>> For this purpose, the proper name is "default_call."
>
> Well "default_call" should not be a wildcard then.

No, it should not.

> In classification context
> "default_call" should mean "detect whether this has default calling convention" (I
> had to think a moment about if these semantics are implementable -- they are).
>
> OK -- STOP.
>
> Can we remove the fully-general wildcards for each property from the
> interface, then?

It seems like a good idea. In some sense you don't _have_
fully-general wildcards. I only thought you did because of the
misleading use of "unspecified."

> I believe we can:
>
> Classification:
>
> If you want to ignore a property just don't specify it in the query.

Yay!

> Requirements: one wildcard to match any decoration /or/ to change the default
> argument of the class template currently called 'is_function' (as described
> above)

Yes, that would be fine.

> Synthesis:
>
> You either override defaults or properties of an existing type.
>
> Requirements: there is a (in some ways special) 'default_call' calling
> convention.

Okay.

>>>Here the properties of the original types are overridden in an implicit tag
>>>combination with the tag representing the type.
>>>
>>>Well, we /could/ only allow it in this very context,
>>
>>
>> Allow what?
>>
>
> Sorry: "allow overriding of tag properties".

I'm lost, sorry. Too much context is gone.

>>>however, it maybe makes things more complicated to explain (see
>
> <- (because it has to be documented anyway)
>
>>>below) and involves more template instantiations - so I'm not sure
>>>it's really worth it.
>
>
> <snip>
>>>
>>> function_type< my_mpl_sequence, pointer > // no implicit tag combination
>>>VVVVV
>>> function_type< my_function , pointer > // implicit tag combination
>>> function_type< signature<F> , pointer > // implicit tag combination
>>>^^^^^
>>>
>>>I believe it is _very_ important to document this behaviour.
>>
>>
>> Yes, the behavior should be documented, but the way you are describing
>> it exposes implementation details and complicates understanding. If
>> you just say that "any properties of the first argument that are not
>> overridden by the second argument will be properties of the result"
>> then you don't need to introduce new jargon for "implicit tag
>> combination."
>>
>
> Very nice! I believe it makes sense move this sentence to the part of the
> reference section on 'function_type' or 'tag'.
>
> Thank you very much for these comments! I'll reassmeble our points to a piece of
> documentation and post them later.

You're welcome.

-- 
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