I wasn't suggesting making the library strictly C++03-compatible. My main point was that the library has to be compatible with _todays_ and even better - _yesterdays_ compilers to be actually useful. My choice of "reasonable" time frame is 3-5 years, as I mentioned. That includes VS 2008 and VS 2010, which already had some C++11 features, including rvalue references. Making VS 2013 absolute minimum is a no-go, IMHO.
I don't think anyone is making VS2013 an absolute minimum - rather they're making variadic templates an absolute minimum. Something which any other compiler than VS has had for years, and something which unlike many, if not most other C++11 language features is something which lets you write a ton of stuff you simply can't write without them. Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation. As proposed Boost.AFIO is also a closure execution engine where that closure can take arbitrary args and return arbitrary returns, that evil variadic template machinery was really useful because it lets you skip using std::function<> with its implied virtual function call. As proposed Boost.AFIO currently nests, in the worst case scenario, a fully bound std::function<> calling a partially bound std::function<> calling a partially bound std::function<>, that's three nested virtual indirect function calls. Recent Intel CPUs can prefetch and branch predict two nesting levels, but they can't cope with three, so performance takes a real nose dive and hence one of the reasons we currently see a peak 80k IOPS. That evil variadic template machinery gets rid of that problem. And its only replacement is std::function<> - you *cannot* implement that functionality (pure compile time std::function<>) without variadic templates because you can't properly unpack them without. None of this matters for proposed Boost.AFIO. But it certainly matters for the forthcoming C++11 only libraries coming soon to Boost, because they make /very/ heavy usage of functionality only possible with variadic templates. That means that they will require, as an absolute minimum for VS, VS2013 or Nov 2012 CTP. Other C++11 features one can make do without without too much cost, but losing variadic templates means a ton of extra source code complexity, much longer compile times and chopping out a lot of what C++11 enables which simply can't be done in C++03. I suspect that those libraries are probably going to force a new "variadic template support is mandatory" category of Boost libraries, probably sooner rather than later. I agree it's going to be frustrating for those stuck with older compilers: I pity those whose employers force MSVC6 on them to this very day. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
On Mon, Jun 17, 2013 at 11:54 PM, Niall Douglas
I wasn't suggesting making the library strictly C++03-compatible. My main point was that the library has to be compatible with _todays_ and even better - _yesterdays_ compilers to be actually useful. My choice of "reasonable" time frame is 3-5 years, as I mentioned. That includes VS 2008 and VS 2010, which already had some C++11 features, including rvalue references. Making VS 2013 absolute minimum is a no-go, IMHO.
I don't think anyone is making VS2013 an absolute minimum - rather they're making variadic templates an absolute minimum. Something which any other compiler than VS has had for years, and something which unlike many, if not most other C++11 language features is something which lets you write a ton of stuff you simply can't write without them.
Now that is quite a bold statement. I don't think it holds. For example how about compile time O(1) access to the passed parameters?
Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
That is *very* easily achievable with the preprocessor. The outstanding feature here, IMHO, is the perfect forwarding, which is of course not possible with C++03. In any case, I couldn't think of how you'd unpack the tuple to call the function without the preprocessor. Could you please show me a code snippet how this could be done? FWIW, i just very recently wrote an implementation of the very same features you are talking about, just using the preprocessor (See here: https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/lcos/local/dataflow.hpp). You might also want to take a look at Phoenix which does the very same thing (Granted, without perfect forwarding). I can already here you ranting about how variadic templates allows you to use an arbitrary number of parameters while the preprocessor solution can not. Unfortunately, that isn't true as well, the number of variadics is limited by the compiler. That number is of course higher than what you can do with the preprocessor (to overcome this limitation we make heavy use of wave to partially preprocess our headers), and you safe some time in parsing. If anything, variadics just make your life as a library author easier than if you wanted to achieve the same with Preprocessor meta programming.
As proposed Boost.AFIO is also a closure execution engine where that closure can take arbitrary args and return arbitrary returns, that evil variadic template machinery was really useful because it lets you skip using std::function<> with its implied virtual function call. As proposed Boost.AFIO currently nests, in the worst case scenario, a fully bound std::function<> calling a partially bound std::function<> calling a partially bound std::function<>, that's three nested virtual indirect function calls. Recent Intel CPUs can prefetch and branch predict two nesting levels, but they can't cope with three, so performance takes a real nose dive and hence one of the reasons we currently see a peak 80k IOPS. That evil variadic template machinery gets rid of that problem. And its only replacement is std::function<> - you *cannot* implement that functionality (pure compile time std::function<>) without variadic templates because you can't properly unpack them without.
See above. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 18 June 2013 08:33, Thomas Heller wrote:
On Mon, Jun 17, 2013 at 11:54 PM, Niall Douglas
wrote: Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
That is *very* easily achievable with the preprocessor. The outstanding feature here, IMHO, is the perfect forwarding, which is of course not possible with C++03. In any case, I couldn't think of how you'd unpack the tuple to call the function without the preprocessor. Could you please show me a code snippet how this could be done?
Very, very easily, see the apply() example in [intseq.general] in the C++14 draft, taken from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html Doing that with the preprocessor instead would be ... I don't have a polite way to say it.
On Tue, Jun 18, 2013 at 11:37 AM, Jonathan Wakely
On Mon, Jun 17, 2013 at 11:54 PM, Niall Douglas
Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
That is *very* easily achievable with the preprocessor. The outstanding feature here, IMHO, is the perfect forwarding, which is of course not possible with C++03. In any case, I couldn't think of how you'd unpack
On 18 June 2013 08:33, Thomas Heller wrote: the
tuple to call the function without the preprocessor. Could you please show me a code snippet how this could be done?
Very, very easily, see the apply() example in [intseq.general] in the C++14 draft, taken from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
Doing that with the preprocessor instead would be ... I don't have a polite way to say it.
Well, it has been done. Except for passing a variadic amount of parameters (which would need to be emulated with the PP), everything else is perfectly doable within C++03 (ok, perfect forwarding is kinda missing ... Boost.Move might help here). Examples of where this has been done is boost.fusion. With the help of cons lists and iterators over tuples, you wouldn't even need the preprocessor to emulate a variadic amount of parameters. Heck, there is even a boost::fusion::invoke as well as a boost::fusion::fused class template. The user of such code never ever gets in contact with the preprocessor based implementation. My point is that saying this is impossible without variadic templates is plainly wrong. Of course, and I said this in my previous message as well, variadics ease the way to write such code. A preprocessor (with the help of partial preprocessing) based solution might be more efficient though, because no template recursions are needed. To put in a nutshell, variadic templates are a great addition to the language, and together with perfect forwarding, you get a very nice and elegant solution to the problem we are discussing here. However, every author has to decide for his/her own sake what to use here. It is all a matter of what compilers are supposed to be supported. I for one do not want to maintain a variadic template based and a preprocessor based solution. As the preprocessor based solution is supported on much, much more compilers, the decision for me is clear to fall back to such a legacy solution. Especially because i have to regularly deal with such compilers. However, IMHO, boost should move to a 2.0 version to advocate plain C++-11 without looking back to legacy compilers. As soon as the compiler landscape evolves to support more an more C++11 features, everyone is able to benefit from such a solution. The Boost 1.X line however should remain C++03 compliant.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 06/18/13 05:21, Thomas Heller wrote:> On Tue, Jun 18, 2013 at 11:37 AM, Jonathan Wakely
wrote: On 18 June 2013 08:33, Thomas Heller wrote:
On Mon, Jun 17, 2013 at 11:54 PM, Niall Douglas
Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
Hmm... Pack into tuple, then unpack. Sounds similar to what: http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/composite_st... except before packing each element in the tuple, it "reifies" the element into its "concrete" (or most derived) type using single dispatch or Watanabe's switch. Then, when all the packing is done, it unpacks into a variadic concrete argument list using (a technique similar to Jonathan's n3658 method below) apply_unpack (from same location as reify_apply.hpp). However, because it uses recursive temples, it's slow to compile time.
That is *very* easily achievable with the preprocessor. The outstanding feature here, IMHO, is the perfect forwarding, which is of course not possible with C++03. In any case, I couldn't think of how you'd unpack the tuple to call the function without the preprocessor. Could you please show me a code snippet how this could be done?
Very, very easily, see the apply() example in [intseq.general] in the C++14 draft, taken from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
Doing that with the preprocessor instead would be ... I don't have a polite way to say it.
[snip]
My point is that saying this is impossible without variadic templates is plainly wrong. Of course, and I said this in my previous message as well, variadics ease the way to write such code. A preprocessor (with the help of partial preprocessing) based solution might be more efficient though, because no template recursions are needed.
Agreed(based on my experience), template recursions are slow and the boost PP as a solution has been mentioned before: http://article.gmane.org/gmane.comp.lib.boost.devel/189900 [snip] -regards, Larry
Creating a version 2 that assumes C++11 is likely the best route for end user experience, as it would create a clear boundary as to what they can use. However, it would need to be done so that library maintainers do not have to work on two versions unless they choose to do so. Perhaps once the move to Git is done a Boost 2 super project could be created, and libraries that require C++11 would only appear as sub modules for it. Then libraries that are not C++03 compatible (or depends on another that is not) would be easy to find during testing since they will not compile. -----Original Message----- However, IMHO, boost should move to a 2.0 version to advocate plain C++-11 without looking back to legacy compilers. As soon as the compiler landscape evolves to support more an more C++11 features, everyone is able to benefit from such a solution. The Boost 1.X line however should remain C++03 compliant.
Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
[snip] I can already here you ranting about how variadic templates allows you to use an arbitrary number of parameters while the preprocessor solution can not.
"Ranting"? That's a little harsh don't you think? I am plenty aware that variadic templates have similar limits in parameter depth as recursive templates. Actually that wasn't the problem I found. And yes, I am more than well aware of Boost's existing facilities in Phoenix et al. and thanks to everyone for pointing them out in depth.
That evil variadic template machinery gets rid of that problem. And its only replacement is std::function<> - you *cannot* implement that functionality (pure compile time std::function<>) without variadic templates because you can't properly unpack them without.
I'll quickly explain the problem I found just for the list's reference: I struggled to implement nested args-to-tuple => tuple-to-args expansion without variadic templates i.e. if I bind up a callable and a set of args into a compile time container, and then pass that itself as part of a set of unknown args, I kept running into instantiation limits in C++03 era compilers. I'll entirely grant you, before anyone comments, that it could be entirely my own shoddy metaprogramming skills. And yes, I know you can tell some compilers to increase their hard limits. Either way, with C++03 era compilers it just became easier to use a function<>, push the problem into the runtime and be done with it, especially as the preprocessor generated template specialisations are lengthy and substantially extend compile times, as other posts have mentioned. That was the basis of my "quite bold statement" which you don't think holds: an earlier failure of mine in C++03 which was fairly straightforward to implement in C++11, and something I probably would have moved ahead with in Boost.AFIO if it weren't that I'm pretty sure we'll need to drop the variadic templates requirement. I accept, given the list's response, that the cause is likely my incompetence as a programmer and others on this list can perform magic I cannot. I therefore retract my earlier assertion. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
On Tue, Jun 18, 2013 at 6:41 PM, Niall Douglas
Now, nothing in proposed Boost.AFIO uses variadic templates in a way not replaceable with preprocessor programming. However it very /nearly/ did: I had this neato bit of evil variadic instantiation which let you convert an unknown set of trailing args into a std::tuple<> for storage, then /unpack/ said std::tuple<> back into an unknown set of trailing args, all with perfect forwarding. Effectively it was a compile-time std::function<> implementation.
[snip] I can already here you ranting about how variadic templates allows you to use an arbitrary number of parameters while the preprocessor solution can not.
"Ranting"? That's a little harsh don't you think? I am plenty aware that variadic templates have similar limits in parameter depth as recursive templates.
Sorry, I didn't mean to offend you. English isn't my native language and i sometimes use inappropriate words when I am excited about something :P
Actually that wasn't the problem I found. And yes, I am more than well aware of Boost's existing facilities in Phoenix et al. and thanks to everyone for pointing them out in depth.
That evil variadic template machinery gets rid of that problem. And its only replacement is std::function<> - you *cannot* implement that functionality (pure compile time std::function<>) without variadic templates because you can't properly unpack them without.
I'll quickly explain the problem I found just for the list's reference: I struggled to implement nested args-to-tuple => tuple-to-args expansion without variadic templates i.e. if I bind up a callable and a set of args into a compile time container, and then pass that itself as part of a set of unknown args, I kept running into instantiation limits in C++03 era compilers.
I'll entirely grant you, before anyone comments, that it could be entirely my own shoddy metaprogramming skills. And yes, I know you can tell some compilers to increase their hard limits.
Either way, with C++03 era compilers it just became easier to use a function<>, push the problem into the runtime and be done with it, especially as the preprocessor generated template specialisations are lengthy and substantially extend compile times, as other posts have mentioned.
That was the basis of my "quite bold statement" which you don't think holds: an earlier failure of mine in C++03 which was fairly straightforward to implement in C++11, and something I probably would have moved ahead with in Boost.AFIO if it weren't that I'm pretty sure we'll need to drop the variadic templates requirement. I accept, given the list's response, that the cause is likely my incompetence as a programmer and others on this list can perform magic I cannot. I therefore retract my earlier assertion.
You shouldn't resort to so much humbleness. I think, as a takeaway from this discussion we should appreciate that variadic templates are indeed superior to a preprocessor based solution (at least from the codeability aspect). Furthermore i believe that pushing that feature is also a good idea. However, that has many implications and everyone involved needs to be aware of those. I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler. Maybe Boost.AFIO should be the library that advocates and pushes this breaking change.
Niall
--- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 18 June 2013 19:46, Thomas Heller wrote:
I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler. Maybe Boost.AFIO should be the library that advocates and pushes this breaking change.
Huh? You're suggesting deprecating C++11-only libraries before they're even added? What do you mean?
Am 18.06.2013 21:09 schrieb "Jonathan Wakely"
On 18 June 2013 19:46, Thomas Heller wrote:
I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler. Maybe
Boost.AFIO
should be the library that advocates and pushes this breaking change.
Huh? You're suggesting deprecating C++11-only libraries before they're even added?
The other way around. Move on with C++11 and get rid of the C++03 cruft.
What do you mean?
_______________________________________________ Unsubscribe & other changes:
On 2013-06-18 21:13, Thomas Heller wrote:
Am 18.06.2013 21:09 schrieb "Jonathan Wakely"
: On 18 June 2013 19:46, Thomas Heller wrote:
I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler.
Huh? You're suggesting deprecating C++11-only libraries before they're even added?
The other way around. Move on with C++11 and get rid of the C++03 cruft.
Ah, that makes more sense. Working on a C++11 library myself, I was trying to wrap my head around it and failed :-) The really interesting question is though: How about the next few years, when C++14 and C++17 enter the stage? For instance, I'd really love to use static_if as soon as it is available :-)
On 18 June 2013 20:26, Roland Bock wrote:
The really interesting question is though: How about the next few years, when C++14 and C++17 enter the stage? For instance, I'd really love to use static_if as soon as it is available :-)
There isn't going to be a static_if
On 2013-06-18 21:26, Jonathan Wakely wrote:
On 18 June 2013 20:26, Roland Bock wrote:
The really interesting question is though: How about the next few years, when C++14 and C++17 enter the stage? For instance, I'd really love to use static_if as soon as it is available :-) There isn't going to be a static_if
Oh, huh, missed that. Well, concepts-lite then, or whatever else might be new by then. My point was: What happens in the next years with boost? C++03 vs C++11 is just the beginning, I assume.
On 18 June 2013 20:13, Thomas Heller wrote:
Am 18.06.2013 21:09 schrieb "Jonathan Wakely":
On 18 June 2013 19:46, Thomas Heller wrote:
I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler. Maybe
Boost.AFIO
should be the library that advocates and pushes this breaking change.
Huh? You're suggesting deprecating C++11-only libraries before they're even added?
The other way around. Move on with C++11 and get rid of the C++03 cruft.
I'm still confused, now you're advocating making all libraries C++11-only? What libraries get deprecated? Do you mean deprecate C++03 *compilers*?
On Tue, Jun 18, 2013 at 9:26 PM, Jonathan Wakely
On 18 June 2013 20:13, Thomas Heller wrote:
Am 18.06.2013 21:09 schrieb "Jonathan Wakely":
On 18 June 2013 19:46, Thomas Heller wrote:
I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and
deprecate
all libraries that will be unusable with a C++03 compiler. Maybe Boost.AFIO should be the library that advocates and pushes this breaking change.
Huh? You're suggesting deprecating C++11-only libraries before they're even added?
The other way around. Move on with C++11 and get rid of the C++03 cruft.
I'm still confused, now you're advocating making all libraries C++11-only?
Depends. Some might not be needed anymore and most will probably look completely different in C++11
What libraries get deprecated?
Do you mean deprecate C++03 *compilers*?
I mean moving on to C++11, whatever that may mean. I obviously don't have a roadmap for that handy or any idea how such a change might look like. It was simply a statement saying "I would be totally OK to move on to C++11, whatever that means". This has to be properly discussed.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Sorry, I didn't mean to offend you. English isn't my native language and i sometimes use inappropriate words when I am excited about something :P
For the list's reference we sorted out misunderstandings off list. I should have chosen my own words more carefully as well, and I do apologise to the list for my earlier tone.
Furthermore i believe that pushing that feature is also a good idea. However, that has many implications and everyone involved needs to be aware of those. I will support you in your efforts for going for a C++11 based solution under the condition that boost will move on and deprecate all libraries that will be unusable with a C++03 compiler. Maybe Boost.AFIO should be the library that advocates and pushes this breaking change.
I'll paraphrase from that email discussion between myself and Thomas off-list here: in essence, we discussed the striking difference in cleanliness and tidiness of C++ code that can appear when it is written knowing that the main C++11 features are guaranteed to hand as against code knowing that C++03 compatibility is a must. We agreed that the difference can be in orders of magnitude, especially so for corner case scenarios such as the one I mentioned earlier where twenty lines of variadic templates in C++11 can require pages and pages of preprocessor generated specialisations and overloads in C++03. I think we may even have concluded that such can be the difference that in some ways, one could even consider that C++11 _is a different language_ entirely to C++03 rather than merely a different dialect. Sure, it depends on perspective and framing, and where you're coming from and going to. But I think it's safe to say that anyone who has pushed C++11 hard wouldn't choose to go back to C++03 willingly, and I think that emotional response is very good indicator as to what comes next for Boost. Anyway, as for proposed AFIO, my thanks to the list for such detailed feedback on what will be expected for peer review. I think myself and Paul now have a very good handle and what needs to be done between now and end of GSoC. We'll get to it so, and I'll remind the list that progress in four of the seven GSoC projects this year can be watched at https://github.com/BoostGSOC. Thanks, Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc.
participants (6)
-
Gwenio
-
Jonathan Wakely
-
Larry Evans
-
Niall Douglas
-
Roland Bock
-
Thomas Heller