This patch implements the forwarding to frozen C++03 headers as discussed in https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc. In the RFC, we initially proposed selecting the right headers from the Clang driver, however consensus seemed to steer towards handling this in the library itself. This patch implements that direction. At a high level, the changes basically amount to making each public header look like this: ``` // inside <vector> #ifdef _LIBCPP_CXX03_LANG # include <__cxx03/vector> #else // normal <vector> content #endif ``` In most cases, public headers are simple umbrella headers so there isn't much code in the #else branch. In other cases, the #else branch contains the actual implementation of the header.
244 lines
11 KiB
C++
244 lines
11 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP_STDATOMIC_H
|
|
#define _LIBCPP_STDATOMIC_H
|
|
|
|
/*
|
|
stdatomic.h synopsis
|
|
|
|
template<class T>
|
|
using std-atomic = std::atomic<T>; // exposition only
|
|
|
|
#define _Atomic(T) std-atomic<T>
|
|
|
|
#define ATOMIC_BOOL_LOCK_FREE see below
|
|
#define ATOMIC_CHAR_LOCK_FREE see below
|
|
#define ATOMIC_CHAR16_T_LOCK_FREE see below
|
|
#define ATOMIC_CHAR32_T_LOCK_FREE see below
|
|
#define ATOMIC_WCHAR_T_LOCK_FREE see below
|
|
#define ATOMIC_SHORT_LOCK_FREE see below
|
|
#define ATOMIC_INT_LOCK_FREE see below
|
|
#define ATOMIC_LONG_LOCK_FREE see below
|
|
#define ATOMIC_LLONG_LOCK_FREE see below
|
|
#define ATOMIC_POINTER_LOCK_FREE see below
|
|
|
|
using std::memory_order // see below
|
|
using std::memory_order_relaxed // see below
|
|
using std::memory_order_consume // see below
|
|
using std::memory_order_acquire // see below
|
|
using std::memory_order_release // see below
|
|
using std::memory_order_acq_rel // see below
|
|
using std::memory_order_seq_cst // see below
|
|
|
|
using std::atomic_flag // see below
|
|
|
|
using std::atomic_bool // see below
|
|
using std::atomic_char // see below
|
|
using std::atomic_schar // see below
|
|
using std::atomic_uchar // see below
|
|
using std::atomic_short // see below
|
|
using std::atomic_ushort // see below
|
|
using std::atomic_int // see below
|
|
using std::atomic_uint // see below
|
|
using std::atomic_long // see below
|
|
using std::atomic_ulong // see below
|
|
using std::atomic_llong // see below
|
|
using std::atomic_ullong // see below
|
|
using std::atomic_char8_t // see below
|
|
using std::atomic_char16_t // see below
|
|
using std::atomic_char32_t // see below
|
|
using std::atomic_wchar_t // see below
|
|
using std::atomic_int8_t // see below
|
|
using std::atomic_uint8_t // see below
|
|
using std::atomic_int16_t // see below
|
|
using std::atomic_uint16_t // see below
|
|
using std::atomic_int32_t // see below
|
|
using std::atomic_uint32_t // see below
|
|
using std::atomic_int64_t // see below
|
|
using std::atomic_uint64_t // see below
|
|
using std::atomic_int_least8_t // see below
|
|
using std::atomic_uint_least8_t // see below
|
|
using std::atomic_int_least16_t // see below
|
|
using std::atomic_uint_least16_t // see below
|
|
using std::atomic_int_least32_t // see below
|
|
using std::atomic_uint_least32_t // see below
|
|
using std::atomic_int_least64_t // see below
|
|
using std::atomic_uint_least64_t // see below
|
|
using std::atomic_int_fast8_t // see below
|
|
using std::atomic_uint_fast8_t // see below
|
|
using std::atomic_int_fast16_t // see below
|
|
using std::atomic_uint_fast16_t // see below
|
|
using std::atomic_int_fast32_t // see below
|
|
using std::atomic_uint_fast32_t // see below
|
|
using std::atomic_int_fast64_t // see below
|
|
using std::atomic_uint_fast64_t // see below
|
|
using std::atomic_intptr_t // see below
|
|
using std::atomic_uintptr_t // see below
|
|
using std::atomic_size_t // see below
|
|
using std::atomic_ptrdiff_t // see below
|
|
using std::atomic_intmax_t // see below
|
|
using std::atomic_uintmax_t // see below
|
|
|
|
using std::atomic_is_lock_free // see below
|
|
using std::atomic_load // see below
|
|
using std::atomic_load_explicit // see below
|
|
using std::atomic_store // see below
|
|
using std::atomic_store_explicit // see below
|
|
using std::atomic_exchange // see below
|
|
using std::atomic_exchange_explicit // see below
|
|
using std::atomic_compare_exchange_strong // see below
|
|
using std::atomic_compare_exchange_strong_explicit // see below
|
|
using std::atomic_compare_exchange_weak // see below
|
|
using std::atomic_compare_exchange_weak_explicit // see below
|
|
using std::atomic_fetch_add // see below
|
|
using std::atomic_fetch_add_explicit // see below
|
|
using std::atomic_fetch_sub // see below
|
|
using std::atomic_fetch_sub_explicit // see below
|
|
using std::atomic_fetch_or // see below
|
|
using std::atomic_fetch_or_explicit // see below
|
|
using std::atomic_fetch_xor // see below
|
|
using std::atomic_fetch_xor_explicit // see below
|
|
using std::atomic_fetch_and // see below
|
|
using std::atomic_fetch_and_explicit // see below
|
|
using std::atomic_flag_test_and_set // see below
|
|
using std::atomic_flag_test_and_set_explicit // see below
|
|
using std::atomic_flag_clear // see below
|
|
using std::atomic_flag_clear_explicit // see below
|
|
|
|
using std::atomic_thread_fence // see below
|
|
using std::atomic_signal_fence // see below
|
|
|
|
*/
|
|
|
|
#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
|
# include <__cxx03/stdatomic.h>
|
|
#else
|
|
# include <__config>
|
|
|
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
# pragma GCC system_header
|
|
# endif
|
|
|
|
# if defined(__cplusplus)
|
|
|
|
# include <atomic>
|
|
# include <version>
|
|
|
|
# ifdef _Atomic
|
|
# undef _Atomic
|
|
# endif
|
|
|
|
# define _Atomic(_Tp) ::std::atomic<_Tp>
|
|
|
|
using std::memory_order _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_relaxed _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_consume _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_acquire _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_release _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_acq_rel _LIBCPP_USING_IF_EXISTS;
|
|
using std::memory_order_seq_cst _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_flag _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_bool _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_char _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_schar _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uchar _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_short _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_ushort _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_long _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_ulong _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_llong _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_ullong _LIBCPP_USING_IF_EXISTS;
|
|
# if _LIBCPP_HAS_CHAR8_T
|
|
using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS;
|
|
# endif
|
|
using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS;
|
|
# if _LIBCPP_HAS_WIDE_CHARACTERS
|
|
using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS;
|
|
# endif
|
|
|
|
using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int64_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint64_t _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_int_least8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_least8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_least16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_least16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_least32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_least32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_least64_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_least64_t _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_int_fast8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_fast8_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_fast16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_fast16_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_fast32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_fast32_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_int_fast64_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uint_fast64_t _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_intptr_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uintptr_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_size_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_ptrdiff_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_intmax_t _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_uintmax_t _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_compare_exchange_strong _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_compare_exchange_strong_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_compare_exchange_weak _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_compare_exchange_weak_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_exchange _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_exchange_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_add _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_add_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_and _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_and_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_or _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_xor_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_xor _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_or_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_sub _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_fetch_sub_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_flag_clear _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_flag_clear_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_flag_test_and_set _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_flag_test_and_set_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_is_lock_free _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_load _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_load_explicit _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_store _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS;
|
|
|
|
using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS;
|
|
using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
|
|
|
|
# else
|
|
|
|
# if __has_include_next(<stdatomic.h>)
|
|
# include_next <stdatomic.h>
|
|
# endif
|
|
|
|
# endif // defined(__cplusplus)
|
|
#endif // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
|
|
|
#endif // _LIBCPP_STDATOMIC_H
|