5

We are programming a logging library that keeps itself in a .hpp file. We would like to include <tr1/unordered_map> (if the compiler supports TR1,) or the standard <map> otherwise. Is there a standard way of checking at compile time if tr1 is available or not?

I was thinking that the same way that the "__cplusplus" define symbol is present, there could have been defined a "__cxx__tr1" or something like that. I haven't seen that in the drafts for TR1, so I assume it is not present, but I wanted to ask first just in case.

As a note, if those defines don't exist, it wouldn't be a bad idea to include them in proposals themselves.

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87

5 Answers5

2

GCC-4.3 has:

#define __GXX_EXPERIMENTAL_CXX0X__ 1

But, this is obviously not standard.

greyfade
  • 24,948
  • 7
  • 64
  • 80
  • This macro is defined if you use g++ -std=c++0x and then you have unordered_map in std::unordered_map. Otherwise (no -std=c++0x) you do not have this define but you still can use include and std::tr1::unordered_map class. – Artyom Apr 07 '09 at 08:05
  • Yes, but as others have pointed out, this is something that can only be tested for during configure. All other versions of GCC prior to 4.3 throw an error when that -std switch is given. – greyfade Apr 07 '09 at 16:57
2

If you are using any configuration tools like autotools you may try to write a test like:

AC_CHECK_HEADER(tr1/unordered_map,[AC_DEFINE([HAVE_TR1],[],["Have tr1"])],[])
AC_CHECK_HEADER(unordered_map,[AC_DEFINE([HAVE_CXX0X],[],["Have C++0x"])],[])

And then use these defines in your code.

Generally speaking __cplusplus macro should give you standard version number, but there is no compiler that gives you 100% standard implementation... Thus write configure macros.

Unfortunately this is only quite reliable way to check such things unless you want to write 1001 #ifdef for each compiler (what boost does)

And then:

#include "config.h"
#ifdef  HAVE_CXX0X
#  include <unordered_map>
   typedef std::unordered_map<foo,bar> my_map;
#elif HAVE_TR1
#  include <tr1/unordered_map>
   typedef std::tr1::unordered_map<foo,bar> my_map;
#else
#  include <map>
   typedef std::map<foo,bar> my_map;
#endif
Artyom
  • 31,019
  • 21
  • 127
  • 215
  • OK, that was an option I wanted to avoid, as I want just to release a .hpp file and run. For these "almost standard" things, I would prefer a simple comparison rather than having to run a full-fledged configure. – Diego Sevilla Apr 15 '09 at 22:06
  • I'm accepting this answer as it seems there is no way, and this seems to be the better way... – Diego Sevilla Apr 15 '09 at 22:08
2

See ISO C++ (WG21) paper N1575. This paper has been dropped from TR1, with no replacement. So there is no official way to detect TR1.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

One library I deal with needs to use some classes that got added to TR1 from Boost, preferring TR1 if available. The solution (being a Unix-based library) is to shove the checks into the configure script.

So in other words, no, nothing portable that I know of. That said, if you're on Unix, the configure script checks work well enough.

C Pirate
  • 444
  • 3
  • 7
0

Assuming one is using VS2010, or any suite that has TR1 available, what would happen if one were to do

#include "boost/tr1/unordered_map.hpp"
...
std::tr1::unordered_map< ... > uMap;

What would be the type of uMap be?

Mohamed Bana
  • 1,251
  • 2
  • 17
  • 27