views:

288

answers:

3

I'm trying to write some portable C++ library code that will initially rely on Boost.Regex, and then move to TR1 as compilers support it, and eventually to the C++0x specification after things get moved from the std::tr1 namespace to std. Here is some pseudo-code for what I'd like to do with the preprocessor:

if( exists(regex) )    // check if I can #include <regex>
{
    #include <regex>    // per TR1
    if( is_namespace(std::tr1) )   // are we on TR1 or C++0x?
    {
        using std::tr1::regex;
    } else
    {
        using std::regex;
    }
} else    // fall-back to boost
{
    #include <boost/regex.hpp>
    using boost::regex;
}

Granted, all of that would need to be in preprocessor directives, but if I knew how to accomplish that I wouldn't be asking here. :)

+5  A: 

You can't do it. The preprocessing phase of C++ happens before the compilation phase, so C++ language conditional constructs cannot usefully be placed around preprocessor directives like #include.

If you need conditional compilation, then the way to do it is to use #ifdef. Something like:

#ifdef BOOST_BUILD
  #include "somebooststuff.h"
  using namespace boost;
#else
  #include "somestdstuff.h"
  using namespace std;
#endif

where BOOST_BUILD is a preprocessor symbol you define in your makefile or whatever.

anon
I specifically said I wasn't trying to use C++ compiled conditional constructs. More specifically, I'm looking for something similar to an #ifdef directive that has the functionality of checking if the include file exists: #ifexists <regex> (or something to that effect)
Zac
There is no such preprocessor functionality. If you really need to do this 9and I doubt you do) you need to run your code through some sort of text processing script written in something like perl or python before you compile it.
anon
+8  A: 

You can't do it without relying on a third party thing before preprocessing. Generally, things like autoconf can be used to accomplish this.

They work by generating another header file with #define directives that indicate existence of headers/libraries you want to use.

Mehrdad Afshari
Thanks for the clarification! :)
Zac
+1  A: 

You can use the __cplusplus macro to see what version of C++ you're working with, in the next standard (C++1x, C++0x isn't meant to be) it will have a value larger than 199711L

#if __cplusplus > 199711
    using std::regex;
#else
    using std::tr1::regex;
#endif
Motti