Determine compile-time existence of include files in C++
Asked Answered
I

4

8

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. :)

Incomputable answered 25/7, 2009 at 8:53 Comment(0)
G
10

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.

Glimmering answered 25/7, 2009 at 8:57 Comment(0)
B
6

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.

Bubaline answered 25/7, 2009 at 8:55 Comment(2)
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)Incomputable
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.Bubaline
A
4

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
Arched answered 25/7, 2009 at 19:51 Comment(0)
A
4

Update for this topic in case you are having this issue recently: Now this IS possible with C++17, use the preprocessor macro __has_include()

#if __has_include("MyInclude")
#  include "MyInclude"
#  define MY_INCLUDE 1
#else
#  define MY_INCLUDE 0
#endif

details here:

https://en.cppreference.com/w/cpp/preprocessor/include

Aultman answered 12/12, 2019 at 17:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.