Best way to detect libc++ at compile time?

Hi all,

I am enabling libc++ in a library that was depending on boost for things such as mutex, thread, shared_ptr, etc., and I have not yet found a way to detect that we are compiling with the libc++ library unless I first include a header from it. I can do this:

// framework config.h:

#include

#if defined( _LIBCPP_VERSION )
#define USING_LIBCPP
#endif

but now every file that wanted to know if we are using libc++ has vector in it. This include is used to determine which standard library we should use, and many things depend on it. Is there a better solution, other than a -D flag to clang?

Cheers,
Rich

My solution is very similar to yours except I use <ciso646>. The C++ specification specifically says that #include <ciso646> has no effect. So it is very cheap to include.

The libc++ implementation of <ciso646> is:

#ifndef _LIBCPP_CISO646
#define _LIBCPP_CISO646

#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

#endif // _LIBCPP_CISO646

And <__config> will #define _LIBCPP_VERSION. All libc++ headers include <__config> as the first thing. Other implementations of <ciso646> will not (I hope) #define _LIBCPP_VERSION.

Howard

Rich E wrote:

I have not yet found a way to
detect that we are compiling with the libc++ library unless I first include
a header from it. I can do this:

// framework config.h:

#include <vector>

#if defined( _LIBCPP_VERSION )
    #define USING_LIBCPP
#endif

but now every file that wanted to know if we are using libc++ has vector in
it.

FYI, Boost.Config (boost/config/select_stdlib_config.hpp) determines the
standard library by including <cstddef> and checking vendor-specific macros.

Regards,
Michel

FWIW, I'm just testing for features I need:

#if __has_include(<thread>)
  #include <thread> // and assume libc++ or any other c++11 compliant library
#endif

Jean-Daniel

Thank you everyone for the great suggestions. After some consideration I think I’ll just include boost/config.hpp, and look for _LIBCPP_VERSION, since it is already included elsewhere.

It appears that boost is also using Howard’s method exactly (boost/config/stdlib/libcpp.hpp), wonder why that is. :slight_smile:

#if __has_include()
#include // and assume libc++ or any other c++11 compliant library
#endif

I was doing this for a while, but I decided it was cluttering up the includes section since you also need a check for clang

cheers,
Rich

You can do something like this so you don't need to guard every single
use of __has_include:

#if !__clang__
#define __has_include(x) 0
#endif

The recommended approach is

#ifndef __has_include
#define __has_include(x) 0
#endif

This would work correctly both in the presence of versions of clang which do not support __has_include, and for other compilers which do, but which don’t claim to be clang.