
Jonathan Turkanis wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote:
Jonathan Turkanis wrote:
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...
I just meant that it wasn't intended to supplant your proposal. I'm happy to work together with you, or to let you steal anything you like from my code ;-)
Feel free to read / use / change or just deprecate my code in order to take it there ;+).
Thanks. I'm feeling freer already.
First of all: _very_ nice documentation (by the way: you do not manually code the syntax highlighting, do you ? ;+).
I have keyboard shortcuts for the various categories.
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.
Right. For some reason it didn't occur to me to use add/remove pointer/reference, as you mention below. I wrote the implementation fast, and it's so easy to copy and paste ;-)
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 ?
To me it's more natural not to consider the implicit object pointer position to be part of the argument list, which is why I chose my design. Whichever is implemented from scratch, the other can be implemented easily as a wrapper.
Even though I thought quite a bit about separating them while writing it - and I decided not to do so. Your interface does seem more natural and thus preferable to me.
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.
I think you're clearly correct about only providing specializations for one of the three type/pointer/reference family. Otherwise, superficial differences asside, our implementations are very similar. The one key difference is that you use overload resolution and sizeof to implement the boolean metafunctions. Since this information is already available in decompose, I'm not sure why you do this. Is it for efficiency?
In fact, I don't. It's only done this way for compilers which won't allow these partial specializations otherwise. The naming of these files is probably confusing - "_fallback" could be more clear than "_classify"...
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.
Sounds good to me.
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
Good.
1.3. handle volatility
Also good. I'm interested to know, though, whether this is simply a matter of being comprehensive -- which is fine with me -- or whether you think there are important use cases.
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.
Just to make sure we're on the same page, are you refering to these comments:
"Alexander Nasonov" <alnsn@yandex.ru> wrote:
Conversion to mpl::vector and back to signature would slow down a compilation. Why waste your time if function_arguments can be made as fast as mpl::vector after applying similar optimization techniques?
?
No. It was in the thread I brought up that this is missing. Alexander suggested function_signature<T> could model an mpl sequence itself instead of having function_signature<T>::type be an mpl sequence.
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.
This is fine with me. Unfortunately, I'm probably not familiar enough with mpl optimization techniques to write a sequence type that will yield better performance than translating to and from mpl::vector. I hope you or Alexander have a better grasp of these issues then I do. I does sound fun, though.
A basic imlpementation could look just like 'vector' but with a few typedefs more... As you said: it sounds fun - and is likely to be slightly better. However, I don't think it's that very important - as the case of modifying signature types is not likely to happen that often (correct me if I'm wrong). I would vote for this even without a special sequence, that is...
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".
You don't have to worry about offending my sensibilities. I'm unflappable. ;-)
Good to hear ;+). Who's doing the megre, then ? I'll be quite busy until the middle of next week and won't get very much done before it... Regards, Tobias