On 6/7/2015 1:04 PM, John Maddock wrote:
On 07/06/2015 15:36, Peter Dimov wrote:
Edward Diener wrote:
Most of the talk about the problems of my macro system presupposes that programmers using Boost will mistakenly try to use a C++11 version of a library during a C++03 mode build and vice versa, and therefore the system must be flawed.
This was some of the talk but I'm not sure about "most". A substantial part of the talk was about programmers wanting to use boost::regex even when the compiler happens to be in C++11 mode. In other words, talk that challenges your assumption that
If the end-user of my library is compiling in C++11 mode is it more likely that his use of regex will be std::regex or boost::regex ? IMO it is the former.
There are several good reasons to prefer boost::regex. First, the one I pointed out, you want to maintain a single code base that compiles under C++03 and C++11. Second, you want to use boost::regex's extensions that std::regex doesn't have. Third, you want predictable performance that is independent of the standard library in use.
Right. But if lib X prefers/needs to use the Boost version always, they don't have to use this mechanism.
Of course. The mechanism is completely optional.
On the other side of the coin, we have the desire to avoid use of Boost when use of standard facilities would suffice, which is real and legitimate. However, in my experience at least, this desire is only strong when you can avoid use of Boost _altogether_, which is not the case under discussion. Right, we're nowhere near having a package manager that's smart enough to avoid dependence on boost::whatever if the user tells it they have a C++11 compiler.
Boost doesn't have a package manager to begin with so I am not sure what the above means.
I guess my concerns are somewhat different from those already expressed:
* I'm not sure that this adds much over the existing macros BOOST_NO_CXX11_HDR_REGEX etc.
I am obviously using BOOST_NO_CXX11_HDR_REGEX for regex. I don't make any attempt to hide this. The current BOOST_CPP_HAS_REGEX is, I believe, a friendlier name of finding out if the C++ standard library regex is available than BOOST_NO_CXX11_HDR_REGEX but that is not the issue. On top of BOOST_NO_CXX11_HDR_REGEX I have built the simple BOOST_CPP_REGEX_HDR and BOOST_CPP_REGEX_NS macros and I seek to regularize this sort of naming for each library. It's not rocket science but I think it has value rather than everybody inventing this as a one-off situation for their own use. But of course that's my point of view as the inventor and I am biased.
* If this evolved into a more "complete" solution, then (a) It doesn't belong in Config (too many dependencies), and (b) I would worry that we repeat the mistake of Boost.TR1 - which is to say creating that particular unmaintainable monster it in the first place -just ask the author ;)
I don't think a more complete solution at the level I have specified is needed. if any further solution is needed it would be the ability, on demand, to name a non-header only library slightly differently whether or not that library is built in C++11 mode or not, and to link to the correct library name depending on C++11 mode. It seems the auto-link code in config could accomodate that for compilers that support auto-linking, but wouldn't any change have to be synced to changes in Boost Build ? For non-autolink compilers how is the library name generated ? Is it done in Boost Build or is it wholly decided by the programmer in a jam script ? I really don't know all these things but I suspect that you do and/or the Boost Build experts do.
* Folks are correct to be concerned about ABI issues: we not that long ago changed 'nix installs to install "one true binary" for each library as there was *very* strong user preference for that. Splitting into '03 and '11 binaries is IMO a significant retrograde step. If you do that expect endless newbie support requests wondering why things don't work.
First splitting binaries into C++03 and C++11 libs should only be done on demand for non-header only libraries that want to use my macro system. Secondly if the names are different the documentation explains what each variation is and it is up to the end-user to understand and use appropriately. If Boost Build automatically links the correct binary, as I believe it now does for our current naming scheme where we have different names for different variations of the same library, then the end-user should not have any problems. For any library program-wise I think it is fairly simple and I should have documented this better. If my own Boost library, called it EDS_LIB, uses my macro system for, let's say, regex, in one of its public interfaces, then any other module interfaces with EDS_LIB by hardcoding neither boost::regex or std::regex but BOOST_CPP_REGEX_NS::regex instead whenever it has to interact with my interface. Whatever compiler mode they are using, whether C++03 or C++11, it just works. Of course if they are using boost::regex everywhere else and they are forced by my macro system to use BOOST_CPP_REGEX_NS::regex and in C++11 mode that means std::regex, it's a real PITA. But that is no different than someone designing a library for C++11 use, using std::regex in a public interface, only to find out that another module compiling in C++11 mode is happily using boost::regex everywhere else but wants to use that library.
On the other hand:
* I can see a legitimate use for this as a library internal (rather like what Math does with std::tuple and boost::tuple). * The need to have different linking requirements in Boost.Build is a solved issue - just use check_target_builds to set the dependency.
So... I guess what I would like to see expressed, is what are the concrete use cases for this? What do *you* want to use it for?
I see these options realistically for Boost library developers: 1) We can continue to use public interfaces in our libraries that use other Boost libraries as the LCD, even if the C++ standard has a pretty close equivalent. Programmers compiling in C++11 mode, and inevitably there will be more as time goes on, who use the C++ standard library equivalents of Boost libraries, and inevitably there will be more using these equivalents as time goes on, may well be irritated about this situation. But if we view that as their problem and not ours, this is the obvious option. 2) We can design totally separate implementations of the same library, one to be used for C++11 and using C++ standard library equivalents in public interfaces, the other to be used for C++03 and using the equivalent Boost libraries in their public interfaces. 3) We can support our public interfaces with both the C++ standard library equivalent ( in C++11 mode ) and the Boost library equivalent, so as to accomodate end-users. 4) We can use the macro system I have created. Realistically 2) or 3) is an awful amount of work, which I as a developer would not want to do.
And finally, you are aware that there are 3 tuples available? boost::, fusion:: and std::, and they they all are slightly different? Oh and std::tr1::tuple too ;)
Yes I am aware. It is certainly permissible to say: this is my interface and if you want to use my library this is what you will use. We all do that as programmers. I just thought we could be a little more user friendly as C++11 becomes more of the norm for C++ programmers ( he ducks <g> ).
What I suspect we will see more of, is libraries becoming implementation agnostic - "give me something that looks like a tuple/thread/future/function and I'll go off and do the right thing". The latest Math code does that with tuple types, and it was a pain in the neck to get working (or possibly I was just being dense at the time), certainly the hoops you have to jump through to support that go way beyond the scope of this addition.
I hate to re-invent the wheel.