Search code examples
c++dictionaryunordered-maptr1

How to check for TR1 while compiling?


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.


Solution

  • 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