|
Boost : |
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2004-10-11 16:46:58
Jonathan Turkanis wrote:
> "Tobias Schwinger" <tschwinger_at_[hidden]> wrote in message
> news:ckdcqh$imj$1_at_sea.gmane.org...
>
>>Jonathan Turkanis wrote:
>>
>>>"Tobias Schwinger" <tschwinger_at_[hidden]> wrote in message
>>>news:ckbu5h$acq$1_at_sea.gmane.org...
>>>
>>>
>>>>Alexander Nasonov wrote:
>>>>
>>>>
>>>>>I have one addition to '[type_traits] "member_function_pointer_traits" ?'
>>>>>thread started long time ago (29 Jul 2004) by Tobias Schwinger.
>>>>>Is it makes sense to modify as_sequence to convert function type into a
>>>>>sequence? Eg:
>>>>>as_sequence<R (T0,T1)> ---> vector<R,T0,T1>
>>>>>as_sequence<R(*)(T0,T1)> ---> vector<R,T0,T1>
>>>>>as_sequence<R(&)(T0,T1)> ---> vector<R,T0,T1>
>>>>>
>>>>>as_sequence<R(C::*)(T0,T1)> ---> vector<R,C,T0,T1>
>>>>
>>>>as_sequence<R(T0,T1)> reads great, but this would add a lot to the
>>>>complexity of 'as_sequence':
>>>>
>>>>First we have to idenitify if T is some sort of function (ptr/ref) type.
>>>>Although there are ways to detect (not decompose, that is) functions and
>>>>even member function pointers without using an unrolled cascades of
>>>>specializations for different function arities, it requires a very
>>>>standard compliant compiler.
>>>>As we need to decompose the type and wrap its components into a vector
>>>>in case it turns out to be a function anyway, we will instantiate one of
>>>>these (more than 100) specializations.
>>>
>>>
>>>I don't understand why this would be hard. Here's how I would do it:
>>
>>I meant what has to happen _inside_ the function_arguments metafunction.
>>And the fact that it has to be defined at the point of this code:
>
>
> <snip>
>
>>However, I guess you are talking about another as_sequence distinct from
>>mpl::as_sequence...
>
>
> Yes, I misunderstood the question. I don't like the idea of 'overloading'
> mpl::as_sequence this way, but generating sequences from function types vice
> versa seems like a legitimate request. I'm still not sure I see the difficulty,
> though.
>
Yes, indeed. I was takling about the possiblilty of an
'mpl::as_sequence' "feature injection"...
>
>>>Last night I realized I needed the ability to manipulate function types as
>>>sequences, so I wrote a small library to do it. I just finished documenting
>
> it:
>
>>> http://home.comcast.net/~jturkanis/function_traits/
>>>
>>>It differs from your library as follows:
>>>
>>>- it splits up the metafunction signature into several metafunctions
>>>- it allows function types to be constructed from sequences
>>>- it doesn't handle volatility.
>
>
> I should add to this:
>
> - it contains (almost) no broken compiler workarounds
> - it doesn't allow arities above BOOST_MPL_LIMIT_VECTOR_SIZE
> - it doesn't use the native TT macros.
>
OK.
>
>>>It's not really meant to compete with your proposal -- I wrote it for a
Why not ?! If it's undoubtfully better it should be used instead.
I don't think it is that _clearly_ better, yet. Although it has some
advantages...
Feel free to read / use / change or just deprecate my code in order to
take it there ;+).
>
> project
That's about the same motivation which made me work on it...
>>>I am currently working on. However, I'd like to know your opinion about it.
>>
>>I'll have a closer look at it this evening.
>
I'll try to arrange my thoughts about it top down.
I'll also try to combine the ideas from this discussion and my proposal
with it, after the analysis:
JTFT:
-----
First of all: _very_ nice documentation (by the way: you do not manually
code the syntax highlighting, do you ? ;+).
The interface looks very well to me, too. It conforms to the concepts of
the Type Traits library (although it does not use the TT macros, as you
said - but this should not be too hard to change).
It is definitely an improvement compared to the current function_traits.
I very much like the ability to modify/synthesize function (pointer)
types. However, I am not fully convinced this interface is the best way
to archieve this, yet. I will discuss my suggestions below.
Looking at the implementation I think there is a lot of redundancy.
There is one cascade for references, one for pointers, one for function
(non ref/ptr) types and the same for synthesizing once again.
If you want to use more of them at the same time, the code which needs
to be processed sums up and takes its toll (consider for example using
it to automatically register event handlers within a GUI framework where
there are at least a few hundred translation units).
Comparsion (JTFT versus TSFT):
------------------------------
The JTFT separate function I/O signatures into result, arguments
and optionally class. TSFT only separates the input signature from the
result. I have no idea which approach is better as there are
applications where JTFT is more convenient (implementing closures) or
where TSFT is more convenient ((full) argument binding). Both interfaces
semantically make sense to me. While I read it now - I think I like the
JTFT interface better... What were your thoughts on this design ?
The JTFT introduce a new cascade of code for each kind of "signature
type" (used in the following text as defined in the JTFT docs). The TSFT
use one common backend for everything. The TSFT do not address function
types and function references. The idea behind it was: using add_pointer
/ remove_reference may be better.
The TSFT common backend comes with a price, too: It depends on
mpl::vector up to BOOST_TT_FUNCTION_MAX_ARITY to be included.
However, I think the backend part of TSFT is more simple and better.
Further suggestions:
--------------------
1. Merge the best of both of our approaches
1.1. Implement the classification/decomposition interface of JTFT with
the TSFT (or similar) backend.
1.1.1. The TSFT needs to be adjusted slightly to simplify the more fine
grained separation of result,args and class.
1.2. use the native TT macros to publish the traits classes
1.3. handle volatility
2. Strip out the synthesis part and replace it with an mpl-sequence
implemenation backed with (all) signature types.
3. Use this instead of mpl::vector in all cases.
Step 2 is not that new. Alexander brought it up (well at least the base)
when we started this discussion.
I did find it too complicated and tried to keep things "safe and simple"
in my proposal (it was meant as an extension to Type Traits rather than
MPL ;+). However, if you really want to go that far in terms of
modifying/synthesizing signature types, I believe this is the right way
to go.
One last note:
--------------
The imperative used in the previous section is not meant as harsh as it
may sound.
So the section should be read as my todo list for the project: "combine
the best parts of JTFT and TSFT into FT".
OK - enough for now...
Best regards,
Tobias
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk