Substituting Boost for C++0x Library Features - c++

I'm working on a library that makes heavy use of the latest C++0x language and library features. I'm mainly developing in Linux with gcc4.6, but would like to test in OS X (because Apple makes excellent profiling tools). Unfortunately all versions of libstdc++ that ship with any gcc4.6 for OS X I've found have their <thread> features disabled (see here for my question on SO on how to get this fixed).
In the meantime, does anyone have any ideas for a minimally invasive (for my library) way I can substitute boost's thread library for the standard one? I'd rather not resort to sed because I'm sharing this project over SVN and would like to check in my changes without forcing everyone else to switch to boost::thread, boost::mutex, etc as well.

This is not a standard complaint code because you're not allowed to change the inside of namespace std, but it should work on most compilers:
#include <boost/your_headers.hpp>
namespace std {
using boost::thread;
using boost::mutex;
// ...
}
the remaining code is unchanged.

Related

c++17 polyfills and boost

Some of the new features that have been added to the recent ISO C++ standards were originally part of boost.
This naturally raises the question of guidelines for writing portable code.
Is there a canonical way to portably use new language features when using an older version of the standard?
If you are already using boost should you continue to use the boost versions or the versions in C++17 or the experimental versions?
How far should you go in trying to be portable?
I am surprised not to find this question as a FAQ somewhere.
Shouldn't there be something about this in the core guidelines, the boost FAQ and or as an ISO committee paper?
There seem to be questions about individual features but less considering the wider view.
For example:
C++11 Polyfills
Aliasing boost::variant or std::variant not compilable
How to correctly shim functionality into std?
There are several projects that provide polyfills.
Boost is not the only option, though it may be the most common and comprehensive.
There are others, for example:
https://github.com/tcbrindle/cpp17_headers
https://www.reddit.com/r/cpp/comments/5oz3zj/c_shims_library/
https://abseil.io/about/philosophy
You can import the appropriate version with using clauses but this is risky as it masks semantic differences
see also:
From boost to std::experimental and furthermore c++17
You might consider using feature test macros
and create headers like "cxx17/optional.hpp" containing:
#ifdef __cpp_lib_experimental_optional
#include <experimental/optional>
namespace cxx17
{
using std::experimental::optional;
}
#elif __cpp_lib_optional
#include <optional>
namespace cxx17
{
using std::optional;
}
#else
#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}
#endif
However this still papers over semantic differences.
In some cases the boost libraries deliberately differ from the standard.
You also have to consider that there is no such thing as portable code
only code that has been ported. You cannot guarantee your code will work
unless you have actually tested it in each environment.
If you attempt to make your code portable like this and have no intention
of running it on those environments its just a YAGNI (you ain't gonna need it).
Using the feature test macros shows you're clever but it could be considered noise if they aren't used.
If you are using boost already it seems safe to assume you can continue using it
and leave it to boost (and the boost maintainers) to detect whether you are using C++17 or a TS
and act according. Unless you have a lot of resources you can assume that
the boost libraries are more portable than your code.
A good thing to do is to document intent.
If you just want to make life easier for future maintainers but you are stuck using
C++11 for now you might consider just doing (in cxx17/import_optional.hpp):
#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}
and using the cxx17 namespace to indicate that you wish to use C++17
but can't yet. This also implies that you consider deviations between boost and the ISO standard a bug
for your project. Other users may just prefer the boost version.
(consider for example What are the differences between std::variant and boost::variant?)
This applies mainly for pure library extensions.
For changes to the language itself you can sometimes emulate them using macros. This can be ugly so it may be better to stick to a given standard.
This should probably be a community wiki but I will wait in case a more learned guru comes up with a better answer.

Migrating from Boost to the Standard Library for C++11

I am new user of the boost library. I find my self thinking more about adopting boost for a number of reasons. From what I can tell, it seems that the boost library is a sort of skunkworks sandbox where various C++ TR features for upcoming standardization are tried out before being adopted by the C++ committee - think boost::filesystem and boost::regex,
As an example, I was trying out some of the C++11 regex features in visual studio via the #include header - this worked great until I ported to a target power pc platform, which, at the time used CodeSourcery's GCC 4.7.3. Unfortunately, I realized that at run-time, that much of the regex implementation was incomplete or empty (even thought it compiled) - With a bit of homework, I should have realized this beforehand, however now that GCC 4.8.x is out, the implementation is part of the v3 standard C++ library so it is a different story now.
In an ideal world, the standard library should be like developing for Java - write once, deploy everywhere - but that is not a reality. I would eventually like to move to the standard library implementation rather than Boost's regex and filesystem implementations.
My question given the above regex history, is how should developers use boost, is it possible to do a simple search and replace of the boost headers and namespaces when the features are adopted by the standard library or are there more many things to consider. I would like to use pure C++11 code without dependency on 3rd party libraries.
The amount of work required to move from a Boost library to its C++11 conterpart depends on the degree of C++11 conformance of a particular Boost library. In the simplest case it can be a matter of including another set of headers and using another namespace.
In a more complicated case, Boost library may have some subtle incompliancy with C++11 (eg. in Boost.Thread V1 ~thread used to call detach()) - such things might "silently" break the code correctness, but they are easy to fix.
Finally, Boost library may implement funcionality that doesn't exist in C++11 (eg. boost::bind can be extended using get_pointer function). Apparantly, porting such a code to C++11 would be quite not trivial.
Let's begin with your statement
I would like to use pure C++11 code without dependency on 3rd party
libraries.
It is clear that this is not possible now. You will have to use 3rd party libraries for any non-trivial program.
Unfortunately, C++ with Boost is not a platform also. You need 3rd party libraries to do things available out of the box in languages like Java, C#, Python etc.
So, you have to select libraries according to your requirements: performance, supported platforms, multithreading etc.
Again, Boost shouldn't be your default choice. It is not that useful now as it was 10 years ago. Most of must have stuff went into C++ standard library already.
If you support existing C++ codebase, find the best C++ library for your needs (e.g. re2 for regex). If you start a new project, I would suggest using Qt as a platform.
A "simple" way to migrate usage may be to use preprocessor defines to define a "Using Boost" directive. By putting all boost code in an #if-#else and carefully writing the code to not break (or at least have expected results) for sections that do not have a C++11 equivalent. You can simply not provide a definition for "Using Boost" before at the beginning of your code and C++11 features would be used instead.
See this and this
One link points to an old stackoverflow question, the other to an interesting talk performed by Stephan Lavavej

Using GCC's C++0x mode in production?

Is anyone using the GCC 4.4.0 C++0x support in production? I'm thinking about using it with the latest MinGW, but I'm not sure if it's mature enough.
I'm interested in:
TR1 support
auto
initializer lists
IMHO, TR1 support and auto are safe to use. In the case of auto it was one of the first features to be included into the standard and is a relatively small change to the language. I would therefore have no problem using it.
I would be a bit more hesitant about using initializer lists. On some other forums (eg. comp.lang.c++.moderated) there are questions about their behaviour and its possible that they may change closer to the release of the standard.
I'm not using GCC 4.4.0 C++0x support in production but I'm using the TR1 features with the help of the Boost Library http://www.boost.org/.
The Boost Library is well tested and often used in production environments. If you convert to the C++0x standard later the only thing you have to do is changing your include Directives http://www.boost.org/doc/libs/1_40_0/doc/html/boost_tr1.html.
In my opinion it's currently better to use the Boost Library until the standard is finished. It's a much more compiler independent way.
MinGW simply won't compile with '-std=c++0x'. Strange enough, '-std=gnu++0x' works. Anyway it seems buggy and I won't count on it.

Preparing for the next C++ standard

The spate of questions regarding BOOST_FOREACH prompts me to ask users of the Boost library what (if anything) they are doing to prepare their code for portability to the proposed new C++ standard (aka C++0x). For example, do you write code like this if you use shared_ptr:
#ifdef CPPOX
#include <memory>
#else
#include "boost/shared_ptr.hpp"
#endif
There is also the namespace issue - in the future, shared_ptr will be part of the std, namespace - how do you deal with that?
I'm interested in these questions because I've decided to bite the bullet and start learning boost seriously, and I'd like to use best practices in my code.
Not exactly a flood of answers - does this mean it's a non-issue? Anyway, thanks to those that replied; I'm accepting jalfs answer because I like being advised to do nothing!
The simple answer is "do nothing". Boost is not going to remove the libraries that got adopted into 0x. So boost::shared_ptr will still exist. So you don't need to do anything to maintain portability.
Of course, once 0x is here, a lot of code can be simplified, cleaned up and optimized, but since it's not yet here, that work can't really begin. All you can do is make sure your code will still compile when 0x hits... and it should, just like that. Boost isn't going to delete half their libraries. (I'm not guessing. They've stated this on their mailing list before)
(and if you want to switch to the standard shared_ptr, I'd say it's probably easier to just do a simple search/replace when the time comes. Replace #include <boost/shared_ptr.hpp> with #include <memory>, and boost::shared_ptr with std::shared_ptr)
Or of course, you can just decide on the project that you're going to keep using Boost's shared_ptr. Just because it's been added to the standard library doesn't mean you have to use it, after all.
Nothing will need to be done because of namespaces. If you want to use the boost implementation you will still use the boost namesapce.
I don't think they would venture into breaking compatibility in such a big way with a previous version.
See my previous similar question here: what will happen with the overlapping portion of boost once C++0x becomes mainstream?
But of course if you do using namespace a lot in your code you may have some overlapping definitions. You'll have to go back to specifying the namespace explicitly on each use.
The best way to use shared parts between C++0x and Boost is to use the Boost.TR1, i.e; the implementation if the Technical Report already accepted. Boost.TR1 will use the implementation provided by the compiler when it is available, and the provided by Boost otherwise. This was the main goal of Boost.TR1
"The TR1 library provides an implementation of the C++ Technical Report on Standard Library Extensions. This library does not itself implement the TR1 components, rather it's a thin wrapper that will include your standard library's TR1 implementation (if it has one), otherwise it will include the Boost Library equivalents, and import them into namespace std::tr1. "
No we don't, as of yet, given the facts that:
support for C++0x is not yet upto the mark across the various platforms (we need) and
that it is yet to be declared a standard officially
But yes, we do use Boost as and when required (but of course, only after a release has gone through a sanitation phase do we use it) just like any other third party library that we use. Also, we use the source form on a as-needed basis.
There is however an effort towards more stringent adoption of the driving principles in product design phase (e.g. move-ctor etc).
There is definitely going to be some work when C++0x gets standardised; but that will also require us to move on to some of newer compilers (vc10?) and moving on to a new compiler is always a task in it's own.
You may actually always prefer using the Boost version for a long time. Especially if you need to compile on multiple platforms.
The Boost libraries are ported and tested on multiple platforms and behave the same there (most of the time.)
The first vendor implementations of the new C++ libraries may still contain minor bugs and performance differences just like it was such a mess when STL and the std namespace were added.

what will happen with the overlapping portion of boost once C++0x becomes mainstream?

what will happen with the overlapping portion of boost once C++0x becomes mainstream?
Will boost still contain everything it used to, or will they adapt the library to update it with the new std:: stuff?
Will boost have both a normal c++ version and a c++0x version that they will maintain?
One would hope that Boost continues to support existing classes, for a couple of reasons.
First, there is a body of code that uses the overlapping features in Boost that needs to be supported, for some time.
Second, overlapping implementations allow me to select which one I'd prefer to use. There might be some difference between std::Frob and Boost::Frob that is important to my project, and having a choice is good.
In the long term, though, I would expect a migration toward the standard from both the application writers and the tools providers. That makes it a less risky choice to go with std::.
I am not affiliated with Boost and have no they idea what they will do but it seems like Boost will be left untouched.
There already has been released TR1 (VS 2008 feature pack) and Boost was left untouched. Since many users have not adopted Boost or TR1 yet, my prediction is that for at least next five years boost and c++0x libraries will exist in different namespaces and availaible for C++0x users as well as C++ users.
Namespaces make this somewhat of a non-issue for the Boost developers. There is no direct contention between the boost libraries and the standard libraries because they exist in separate namespaces. Therefore, changes to namespace std (for example the addition of std::tr1) have no direct impact on Boost.
Note however, that if you are importing both libraries (std and boost) into the global namespace, then you will have issues.
The following quote from the Boost TR1 documentation also sheds some light regarding Boost's implementation of TR1 components, suggesting that the corresponding Boost library will be maintained for the foreseeable future:
The TR1 library provides an
implementation of the C++ Technical
Report on Standard Library Extensions.
This library does not itself implement
the TR1 components, rather it's a thin
wrapper that will include your
standard library's TR1 implementation
(if it has one), otherwise it will
include the Boost Library equivalents,
and import them into namespace std::tr1.
Do you mean tr1?
Boost already supports tr1.
All the classes from boost that have been adopted into std::tr1 are available in this namespace from boost. See the following documentation.
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_tr1.html