There are many places where libc++ want to use <atomic> internally in C++03 code. Unfortunately <atomic> currently only supports C++11 and later. This patch extends <atomic> so that everything except ATOMIC_VAR_INIT and ATOMIC_FLAG_INIT can be used in c++03 code.
This patch introduces the macros:
- _LIBCPP_HAS_C11_ATOMICS: Defined if __has_extension(c_atomic) is true.
- _LIBCPP_HAS_CXX_ATOMICS: Defined if we have C11 atomics from clang or the __atomic_* builtin family from GCC and libc++ is configured for threads. If _LIBCPP_HAS_CXX_ATOMICS is defined then the <atomic> header should be safe to include.
Other Misc changes:
- __gcc_atomic_t default constructs the stored value. This make it perform the same as _Atomic.
- constexpr -> _LIBCPP_CONSTEXPR
- noexcept -> TEST_NOEXCEPT in the tests.
- re-implement std::atomic::is_lock_free() to prevent needing libatomic with GCC.
Everything in atomic works in C++03 except for ATOMIC_VAR_INIT and ATOMIC_FLAG_INIT. These macros are required to allow:
std::atomic_flag f = ATOMIC_FLAG_INIT; // ATOMIC_VAR_INIT is defined as #define ATOMIC_VAR_INIT {false}
In c++11 f is aggregate-initialized but in C++03 f is copy-initialized. Since atomic types are not copy-able this results in a compile error in C++03. For this reason the macros are not defined in C++03 mode.
Furthermore initialization of static storage duration atomics using the macros takes place during constant-initialization.(http://en.cppreference.com/w/cpp/language/constant_initialization). This makes statically initialized atomic's safe and easy to use in other static initialization expressions.
There doesn't seem to be a way to implement these macros in C++03. For that reason they are simply removed when __cplusplus < 201103L.