зеркало из https://github.com/microsoft/STL.git
Implement P0943R6 Supporting C Atomics In C++ (#2008)
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
46477a1152
Коммит
0680fabf17
|
@ -184,6 +184,7 @@ set(HEADERS
|
|||
${CMAKE_CURRENT_LIST_DIR}/inc/span
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/sstream
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/stack
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/stdatomic.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/stdexcept
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/stop_token
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc/streambuf
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
#include <barrier>
|
||||
#include <latch>
|
||||
#include <semaphore>
|
||||
#include <stdatomic.h>
|
||||
#include <stop_token>
|
||||
#endif // _M_CEE_PURE
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
"span",
|
||||
"sstream",
|
||||
"stack",
|
||||
"stdatomic.h",
|
||||
"stdexcept",
|
||||
"stop_token",
|
||||
"streambuf",
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
// stdatomic.h standard header
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#pragma once
|
||||
#ifndef _STDATOMIC_H_
|
||||
#define _STDATOMIC_H_
|
||||
#include <yvals.h>
|
||||
#if _STL_COMPILER_PREPROCESSOR
|
||||
|
||||
#ifdef _M_CEE_PURE
|
||||
#error <stdatomic.h> is not supported when compiling with /clr:pure.
|
||||
#endif // _M_CEE_PURE
|
||||
|
||||
#if !_HAS_CXX23
|
||||
#pragma message("The contents of <stdatomic.h> are available only with C++23 or later.")
|
||||
#else // ^^^ !_HAS_CXX23 / _HAS_CXX23 vvv
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#pragma pack(push, _CRT_PACKING)
|
||||
#pragma warning(push, _STL_WARNING_LEVEL)
|
||||
#pragma warning(disable : _STL_DISABLED_WARNINGS)
|
||||
_STL_DISABLE_CLANG_WARNINGS
|
||||
#pragma push_macro("new")
|
||||
#undef new
|
||||
|
||||
template <class _Ty>
|
||||
using _Std_atomic = _STD atomic<_Ty>;
|
||||
|
||||
#define _Atomic(T) _Std_atomic<T>
|
||||
|
||||
// clang-format off
|
||||
using _STD memory_order;
|
||||
using _STD memory_order_relaxed;
|
||||
using _STD memory_order_consume;
|
||||
using _STD memory_order_acquire;
|
||||
using _STD memory_order_release;
|
||||
using _STD memory_order_acq_rel;
|
||||
using _STD memory_order_seq_cst;
|
||||
|
||||
using _STD atomic_flag;
|
||||
|
||||
using _STD atomic_bool;
|
||||
using _STD atomic_char;
|
||||
using _STD atomic_schar;
|
||||
using _STD atomic_uchar;
|
||||
using _STD atomic_short;
|
||||
using _STD atomic_ushort;
|
||||
using _STD atomic_int;
|
||||
using _STD atomic_uint;
|
||||
using _STD atomic_long;
|
||||
using _STD atomic_ulong;
|
||||
using _STD atomic_llong;
|
||||
using _STD atomic_ullong;
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
using _STD atomic_char8_t;
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
using _STD atomic_char16_t;
|
||||
using _STD atomic_char32_t;
|
||||
using _STD atomic_wchar_t;
|
||||
using _STD atomic_int8_t;
|
||||
using _STD atomic_uint8_t;
|
||||
using _STD atomic_int16_t;
|
||||
using _STD atomic_uint16_t;
|
||||
using _STD atomic_int32_t;
|
||||
using _STD atomic_uint32_t;
|
||||
using _STD atomic_int64_t;
|
||||
using _STD atomic_uint64_t;
|
||||
using _STD atomic_int_least8_t;
|
||||
using _STD atomic_uint_least8_t;
|
||||
using _STD atomic_int_least16_t;
|
||||
using _STD atomic_uint_least16_t;
|
||||
using _STD atomic_int_least32_t;
|
||||
using _STD atomic_uint_least32_t;
|
||||
using _STD atomic_int_least64_t;
|
||||
using _STD atomic_uint_least64_t;
|
||||
using _STD atomic_int_fast8_t;
|
||||
using _STD atomic_uint_fast8_t;
|
||||
using _STD atomic_int_fast16_t;
|
||||
using _STD atomic_uint_fast16_t;
|
||||
using _STD atomic_int_fast32_t;
|
||||
using _STD atomic_uint_fast32_t;
|
||||
using _STD atomic_int_fast64_t;
|
||||
using _STD atomic_uint_fast64_t;
|
||||
using _STD atomic_intptr_t;
|
||||
using _STD atomic_uintptr_t;
|
||||
using _STD atomic_size_t;
|
||||
using _STD atomic_ptrdiff_t;
|
||||
using _STD atomic_intmax_t;
|
||||
using _STD atomic_uintmax_t;
|
||||
|
||||
using _STD atomic_is_lock_free;
|
||||
using _STD atomic_load;
|
||||
using _STD atomic_load_explicit;
|
||||
using _STD atomic_store;
|
||||
using _STD atomic_store_explicit;
|
||||
using _STD atomic_exchange;
|
||||
using _STD atomic_exchange_explicit;
|
||||
using _STD atomic_compare_exchange_strong;
|
||||
using _STD atomic_compare_exchange_strong_explicit;
|
||||
using _STD atomic_compare_exchange_weak;
|
||||
using _STD atomic_compare_exchange_weak_explicit;
|
||||
using _STD atomic_fetch_add;
|
||||
using _STD atomic_fetch_add_explicit;
|
||||
using _STD atomic_fetch_sub;
|
||||
using _STD atomic_fetch_sub_explicit;
|
||||
using _STD atomic_fetch_or;
|
||||
using _STD atomic_fetch_or_explicit;
|
||||
using _STD atomic_fetch_and;
|
||||
using _STD atomic_fetch_and_explicit;
|
||||
using _STD atomic_flag_test_and_set;
|
||||
using _STD atomic_flag_test_and_set_explicit;
|
||||
using _STD atomic_flag_clear;
|
||||
using _STD atomic_flag_clear_explicit;
|
||||
|
||||
using _STD atomic_thread_fence;
|
||||
using _STD atomic_signal_fence;
|
||||
// clang-format on
|
||||
|
||||
#pragma pop_macro("new")
|
||||
_STL_RESTORE_CLANG_WARNINGS
|
||||
#pragma warning(pop)
|
||||
#pragma pack(pop)
|
||||
#endif // ^^^ _HAS_CXX23 ^^^
|
||||
|
||||
#endif // _STL_COMPILER_PREPROCESSOR
|
||||
#endif // _STDATOMIC_H_
|
|
@ -263,6 +263,7 @@
|
|||
|
||||
// _HAS_CXX23 directly controls:
|
||||
// P0401R6 Providing Size Feedback In The Allocator Interface
|
||||
// P0943R6 Supporting C Atomics In C++
|
||||
// P1048R1 is_scoped_enum
|
||||
// P1132R7 out_ptr(), inout_ptr()
|
||||
// P1425R4 Iterator Pair Constructors For stack And queue
|
||||
|
@ -1365,6 +1366,7 @@
|
|||
#define __cpp_lib_out_ptr 202106L
|
||||
#endif // __cpp_lib_concepts
|
||||
|
||||
#define __cpp_lib_stdatomic_h 202011L
|
||||
#define __cpp_lib_string_contains 202011L
|
||||
#define __cpp_lib_to_underlying 202102L
|
||||
#endif // _HAS_CXX23
|
||||
|
|
|
@ -405,6 +405,7 @@ tests\P0898R3_concepts
|
|||
tests\P0898R3_identity
|
||||
tests\P0912R5_coroutine
|
||||
tests\P0919R3_heterogeneous_unordered_lookup
|
||||
tests\P0943R6_stdatomic_h
|
||||
tests\P0966R1_string_reserve_should_not_shrink
|
||||
tests\P0980R1_constexpr_strings
|
||||
tests\P1004R2_constexpr_vector
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\usual_latest_matrix.lst
|
|
@ -0,0 +1,117 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
static_assert(ATOMIC_BOOL_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_CHAR_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_CHAR16_T_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_CHAR32_T_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_WCHAR_T_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_SHORT_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_INT_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_LONG_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_LLONG_LOCK_FREE == 2);
|
||||
static_assert(ATOMIC_POINTER_LOCK_FREE == 2);
|
||||
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
using std::is_same_v;
|
||||
|
||||
static_assert(is_same_v<_Atomic(int), std::atomic<int>>);
|
||||
static_assert(is_same_v<_Atomic(unsigned int), std::atomic<unsigned int>>);
|
||||
static_assert(is_same_v<_Atomic(float), std::atomic<float>>);
|
||||
static_assert(is_same_v<_Atomic(char), std::atomic<char>>);
|
||||
|
||||
static_assert(is_same_v<std::memory_order, memory_order>);
|
||||
static_assert(std::memory_order_relaxed == memory_order_relaxed);
|
||||
static_assert(std::memory_order_consume == memory_order_consume);
|
||||
static_assert(std::memory_order_acquire == memory_order_acquire);
|
||||
static_assert(std::memory_order_release == memory_order_release);
|
||||
static_assert(std::memory_order_acq_rel == memory_order_acq_rel);
|
||||
static_assert(std::memory_order_seq_cst == memory_order_seq_cst);
|
||||
|
||||
static_assert(is_same_v<std::atomic_flag, atomic_flag>);
|
||||
|
||||
static_assert(is_same_v<std::atomic_bool, atomic_bool>);
|
||||
static_assert(is_same_v<std::atomic_char, atomic_char>);
|
||||
static_assert(is_same_v<std::atomic_schar, atomic_schar>);
|
||||
static_assert(is_same_v<std::atomic_uchar, atomic_uchar>);
|
||||
static_assert(is_same_v<std::atomic_short, atomic_short>);
|
||||
static_assert(is_same_v<std::atomic_ushort, atomic_ushort>);
|
||||
static_assert(is_same_v<std::atomic_int, atomic_int>);
|
||||
static_assert(is_same_v<std::atomic_uint, atomic_uint>);
|
||||
static_assert(is_same_v<std::atomic_long, atomic_long>);
|
||||
static_assert(is_same_v<std::atomic_ulong, atomic_ulong>);
|
||||
static_assert(is_same_v<std::atomic_llong, atomic_llong>);
|
||||
static_assert(is_same_v<std::atomic_ullong, atomic_ullong>);
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
static_assert(is_same_v<std::atomic_char8_t, atomic_char8_t>);
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
static_assert(is_same_v<std::atomic_char16_t, atomic_char16_t>);
|
||||
static_assert(is_same_v<std::atomic_char32_t, atomic_char32_t>);
|
||||
static_assert(is_same_v<std::atomic_wchar_t, atomic_wchar_t>);
|
||||
static_assert(is_same_v<std::atomic_int8_t, atomic_int8_t>);
|
||||
static_assert(is_same_v<std::atomic_uint8_t, atomic_uint8_t>);
|
||||
static_assert(is_same_v<std::atomic_int16_t, atomic_int16_t>);
|
||||
static_assert(is_same_v<std::atomic_uint16_t, atomic_uint16_t>);
|
||||
static_assert(is_same_v<std::atomic_int32_t, atomic_int32_t>);
|
||||
static_assert(is_same_v<std::atomic_uint32_t, atomic_uint32_t>);
|
||||
static_assert(is_same_v<std::atomic_int64_t, atomic_int64_t>);
|
||||
static_assert(is_same_v<std::atomic_uint64_t, atomic_uint64_t>);
|
||||
static_assert(is_same_v<std::atomic_int_least8_t, atomic_int_least8_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_least8_t, atomic_uint_least8_t>);
|
||||
static_assert(is_same_v<std::atomic_int_least16_t, atomic_int_least16_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_least16_t, atomic_uint_least16_t>);
|
||||
static_assert(is_same_v<std::atomic_int_least32_t, atomic_int_least32_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_least32_t, atomic_uint_least32_t>);
|
||||
static_assert(is_same_v<std::atomic_int_least64_t, atomic_int_least64_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_least64_t, atomic_uint_least64_t>);
|
||||
static_assert(is_same_v<std::atomic_int_fast8_t, atomic_int_fast8_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_fast8_t, atomic_uint_fast8_t>);
|
||||
static_assert(is_same_v<std::atomic_int_fast16_t, atomic_int_fast16_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_fast16_t, atomic_uint_fast16_t>);
|
||||
static_assert(is_same_v<std::atomic_int_fast32_t, atomic_int_fast32_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_fast32_t, atomic_uint_fast32_t>);
|
||||
static_assert(is_same_v<std::atomic_int_fast64_t, atomic_int_fast64_t>);
|
||||
static_assert(is_same_v<std::atomic_uint_fast64_t, atomic_uint_fast64_t>);
|
||||
static_assert(is_same_v<std::atomic_intptr_t, atomic_intptr_t>);
|
||||
static_assert(is_same_v<std::atomic_uintptr_t, atomic_uintptr_t>);
|
||||
static_assert(is_same_v<std::atomic_size_t, atomic_size_t>);
|
||||
static_assert(is_same_v<std::atomic_ptrdiff_t, atomic_ptrdiff_t>);
|
||||
static_assert(is_same_v<std::atomic_intmax_t, atomic_intmax_t>);
|
||||
static_assert(is_same_v<std::atomic_uintmax_t, atomic_uintmax_t>);
|
||||
|
||||
namespace test {
|
||||
using ::atomic_compare_exchange_strong;
|
||||
using ::atomic_compare_exchange_strong_explicit;
|
||||
using ::atomic_compare_exchange_weak;
|
||||
using ::atomic_compare_exchange_weak_explicit;
|
||||
using ::atomic_exchange;
|
||||
using ::atomic_exchange_explicit;
|
||||
using ::atomic_fetch_add;
|
||||
using ::atomic_fetch_add_explicit;
|
||||
using ::atomic_fetch_and;
|
||||
using ::atomic_fetch_and_explicit;
|
||||
using ::atomic_fetch_or;
|
||||
using ::atomic_fetch_or_explicit;
|
||||
using ::atomic_fetch_sub;
|
||||
using ::atomic_fetch_sub_explicit;
|
||||
using ::atomic_flag_clear;
|
||||
using ::atomic_flag_clear_explicit;
|
||||
using ::atomic_flag_test_and_set;
|
||||
using ::atomic_flag_test_and_set_explicit;
|
||||
using ::atomic_is_lock_free;
|
||||
using ::atomic_load;
|
||||
using ::atomic_load_explicit;
|
||||
using ::atomic_store;
|
||||
using ::atomic_store_explicit;
|
||||
} // namespace test
|
||||
|
||||
static_assert(std::atomic_thread_fence == atomic_thread_fence);
|
||||
static_assert(std::atomic_signal_fence == atomic_signal_fence);
|
||||
|
||||
int main() {} // COMPILE-ONLY
|
|
@ -1498,6 +1498,20 @@ STATIC_ASSERT(__cpp_lib_starts_ends_with == 201711L);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX23
|
||||
#ifndef __cpp_lib_stdatomic_h
|
||||
#error __cpp_lib_stdatomic_h is not defined
|
||||
#elif __cpp_lib_stdatomic_h != 202011L
|
||||
#error __cpp_lib_stdatomic_h is not 202011L
|
||||
#else
|
||||
STATIC_ASSERT(__cpp_lib_stdatomic_h == 202011L);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cpp_lib_stdatomic_h
|
||||
#error __cpp_lib_stdatomic_h is defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX23
|
||||
#ifndef __cpp_lib_string_contains
|
||||
#error __cpp_lib_string_contains is not defined
|
||||
|
|
|
@ -64,6 +64,7 @@ PM_CL="/DMEOW_HEADER=source_location"
|
|||
PM_CL="/DMEOW_HEADER=span"
|
||||
PM_CL="/DMEOW_HEADER=sstream"
|
||||
PM_CL="/DMEOW_HEADER=stack"
|
||||
PM_CL="/DMEOW_HEADER=stdatomic.h"
|
||||
PM_CL="/DMEOW_HEADER=stdexcept"
|
||||
PM_CL="/DMEOW_HEADER=stop_token"
|
||||
PM_CL="/DMEOW_HEADER=streambuf"
|
||||
|
|
Загрузка…
Ссылка в новой задаче