How to check for TR1 while compiling?
Asked Answered
L

5

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.

Lyndel answered 7/4, 2009 at 7:19 Comment(0)
Y
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
Youthful answered 7/4, 2009 at 7:55 Comment(2)
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.Lyndel
I'm accepting this answer as it seems there is no way, and this seems to be the better way...Lyndel
R
2

GCC-4.3 has:

#define __GXX_EXPERIMENTAL_CXX0X__ 1

But, this is obviously not standard.

Reorganization answered 7/4, 2009 at 7:31 Comment(2)
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 <tr1/unordered_map> include and std::tr1::unordered_map class.Youthful
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.Reorganization
Y
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
Youthful answered 7/4, 2009 at 7:55 Comment(2)
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.Lyndel
I'm accepting this answer as it seems there is no way, and this seems to be the better way...Lyndel
L
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.

Leven answered 7/4, 2009 at 11:38 Comment(0)
P
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.

Portillo answered 7/4, 2009 at 7:48 Comment(0)
L
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?

Leff answered 14/3, 2011 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.