Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3d88a64
Minimal changes to support constexpr allocation in MSVC (#1313)
CaseyCarter Sep 22, 2020
5f4bc22
Implement ranges::uninitialized_meow (#1164)
miscco Sep 22, 2020
9e264ab
P0660R10 <stop_token> And jthread (#1196)
BillyONeal Sep 22, 2020
d49e401
Use constexpr is_sorted, add charconv tests, update comments (#1278)
StephanTLavavej Sep 23, 2020
7a9998c
Account for C++17 deferred temporary materialization in invocable_r (…
CaseyCarter Sep 23, 2020
8be9877
Fix two VS 2019 16.8 Preview 3 blocked issues (#1291)
SuperWig Sep 23, 2020
648f2b1
Fix atomic_ref<int8_t>::operator--(int) compiler error (#1303)
AlexGuteniev Sep 23, 2020
6e6321c
P1007R3 assume_aligned() (#1306)
fsb4000 Sep 23, 2020
5847f82
<complex>: prevent invalid conversions (#1294)
Arzaghi Sep 23, 2020
7210dd7
Mark memory_resource dtor as default to enable constant destruction i…
cdacamar Sep 23, 2020
400aec0
Make _Execute_once XFG-compatible. (#1318)
jrabet Sep 25, 2020
554b5d3
Remove XP (and Server 2003) support from STL (#1194)
AlexGuteniev Sep 25, 2020
d0c089e
<filesystem>: create_directories() should throw for empty paths (#1285)
Arzaghi Sep 25, 2020
c47cedc
P0339R6 polymorphic_allocator<> (#1311)
onihusube Sep 25, 2020
c70b7a8
Accept 80-bit long double in <complex> (#1316)
simmse Sep 25, 2020
530bdc5
Cleanup header inclusion in stl/src (#1270)
SunnyWar Sep 26, 2020
c385d02
<random>: Fix incorrect rounding in rejection method. (#1159)
MattStephanson Oct 3, 2020
974582f
<charconv>: Simplify _Assemble_floating_point_value and optimize _Rig…
statementreply Oct 3, 2020
a8b62af
<random>: Prevent distributions from returning NaN/Inf (#1228)
Arzaghi Oct 3, 2020
4386d74
Workaround VSO-1222776 in <ranges> (#1287)
CaseyCarter Oct 3, 2020
bb05875
<functional>: bind_front() should use decayed types to determine its …
CaseyCarter Oct 3, 2020
d05f8ec
<complex>: Fix the pow(complex, arithmetic) overload set (#1299)
MattStephanson Oct 3, 2020
7c3742e
Remove macros and a compiler workaround (#1307)
StephanTLavavej Oct 3, 2020
d247352
Remove unused ConcRT wrappers (#1325)
StephanTLavavej Oct 3, 2020
0614c8c
Support upstream EDG in the std test suite (#1328)
Oct 3, 2020
02130c4
<vector>: vector's move ctor should initialize members once (#1330)
Arzaghi Oct 3, 2020
03ab954
Updated _MSVC_STL_UPDATE to October 2020 (#1340)
praveenojha33 Oct 3, 2020
b1ed29c
Port MSVC-internal changes (#1344)
StephanTLavavej Oct 5, 2020
7402883
<iomanip>: std::get_time should not fail when format is longer than t…
Arzaghi Oct 5, 2020
b6437a9
Fix _Execute_once XFG trampoline (#1356)
jrabet Oct 8, 2020
4af65e3
P0896R4 stream iterator changes (#1281)
CaseyCarter Oct 9, 2020
20a19e4
_Node_handle: destroy with value_type allocator (#1310)
CaseyCarter Oct 9, 2020
5be862d
Remove workarounds for several compiler bugs (#1327)
CaseyCarter Oct 9, 2020
8050cbe
Azure Pipelines: Skip tests if build fails, run both tools even if ot…
sylveon Oct 9, 2020
f3094e8
Update cgmanifest for 16.8 (#1354)
CaseyCarter Oct 9, 2020
a6c1042
_M_ARM64EC cleanups. Fifth time's the charm. (#1355)
StephanTLavavej Oct 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions azure-devops/run-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
jobs:
- job: ${{ parameters.targetPlatform }}
timeoutInMinutes: 360
pool:
name: $(agentPool)

variables:
buildOutputLocation: 'D:\build\${{ parameters.targetPlatform }}'
Expand Down Expand Up @@ -74,7 +72,7 @@ jobs:
- task: CmdLine@2
displayName: 'Run Tests'
timeoutInMinutes: 120
condition: in('${{ parameters.targetPlatform }}', 'x64', 'x86')
condition: and(succeeded(), in('${{ parameters.targetPlatform }}', 'x64', 'x86'))
inputs:
workingDirectory: $(buildOutputLocation)
script: |
Expand All @@ -85,7 +83,7 @@ jobs:
- task: PublishTestResults@2
displayName: 'Publish Tests'
timeoutInMinutes: 10
condition: in('${{ parameters.targetPlatform }}', 'x64', 'x86')
condition: and(succeededOrFailed(), in('${{ parameters.targetPlatform }}', 'x64', 'x86'))
inputs:
searchFolder: $(buildOutputLocation)
testResultsFormat: JUnit
Expand Down
8 changes: 4 additions & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@
# Build STL targeting x86, x64, arm, arm64

variables:
agentPool: 'StlBuild-2020-09-14'
tmpDir: 'D:\Temp'

pool: 'StlBuild-2020-09-14'

stages:
- stage: Code_Format
displayName: 'Code Format'
jobs:
- job: Code_Format_Validation
timeoutInMinutes: 90
displayName: 'Validation'
pool:
name: $(agentPool)

variables:
buildOutputLocation: 'D:\tools'
steps:
Expand All @@ -43,6 +41,7 @@ stages:
- task: BatchScript@1
displayName: 'Enforce clang-format'
timeoutInMinutes: 60
condition: succeededOrFailed()
inputs:
filename: 'azure-devops/enforce-clang-format.cmd'
failOnStandardError: true
Expand All @@ -51,6 +50,7 @@ stages:
- task: BatchScript@1
displayName: 'Validate Files'
timeoutInMinutes: 2
condition: succeededOrFailed()
inputs:
filename: 'azure-devops/validate-files.cmd'
failOnStandardError: true
Expand Down
2 changes: 1 addition & 1 deletion docs/cgmanifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"type": "git",
"git": {
"repositoryUrl": "https://github.com/microsoft/STL.git",
"commitHash": "81d88bd8e40b2b229776a9602c8bf5f49c128a9b"
"commitHash": "c70b7a830eda523a69934ba949ac700da2c0dfd2"
}
}
},
Expand Down
5 changes: 3 additions & 2 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/sstream
${CMAKE_CURRENT_LIST_DIR}/inc/stack
${CMAKE_CURRENT_LIST_DIR}/inc/stdexcept
${CMAKE_CURRENT_LIST_DIR}/inc/stop_token
${CMAKE_CURRENT_LIST_DIR}/inc/streambuf
${CMAKE_CURRENT_LIST_DIR}/inc/string
${CMAKE_CURRENT_LIST_DIR}/inc/string_view
Expand Down Expand Up @@ -437,11 +438,11 @@ function(add_stl_dlls D_SUFFIX THIS_CONFIG_DEFINITIONS THIS_CONFIG_COMPILE_OPTIO
target_compile_options(msvcp${D_SUFFIX}_eha_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHa")

add_library(msvcp${D_SUFFIX} SHARED)
target_link_libraries(msvcp${D_SUFFIX} PRIVATE msvcp${D_SUFFIX}_eha_objects msvcp${D_SUFFIX}_objects "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib" "${TOOLSET_LIB}/concrt${D_SUFFIX}.lib" "delayimp.lib")
target_link_libraries(msvcp${D_SUFFIX} PRIVATE msvcp${D_SUFFIX}_eha_objects msvcp${D_SUFFIX}_objects "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib")
set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_base${D_SUFFIX}${VCLIBS_SUFFIX}")
set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
set_target_properties(msvcp${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}${VCLIBS_SUFFIX}")
target_link_options(msvcp${D_SUFFIX} PRIVATE "${THIS_CONFIG_LINK_OPTIONS};/delayload:concrt140${D_SUFFIX}.dll")
target_link_options(msvcp${D_SUFFIX} PRIVATE "${THIS_CONFIG_LINK_OPTIONS}")

# import library 'statics'
add_library(msvcp${D_SUFFIX}_implib_objects OBJECT ${IMPLIB_SOURCES})
Expand Down
Binary file modified stl/aliases/amd64/std_init_once_begin_initialize.obj
Binary file not shown.
Binary file modified stl/aliases/amd64/std_init_once_complete.obj
Binary file not shown.
Binary file modified stl/aliases/arm/std_init_once_begin_initialize.obj
Binary file not shown.
Binary file modified stl/aliases/arm/std_init_once_complete.obj
Binary file not shown.
Binary file modified stl/aliases/arm64/std_init_once_begin_initialize.obj
Binary file not shown.
Binary file modified stl/aliases/arm64/std_init_once_complete.obj
Binary file not shown.
Binary file not shown.
Binary file added stl/aliases/arm64ec/std_init_once_complete.obj
Binary file not shown.
Binary file modified stl/aliases/chpe/std_init_once_begin_initialize.obj
Binary file not shown.
Binary file modified stl/aliases/chpe/std_init_once_complete.obj
Binary file not shown.
24 changes: 22 additions & 2 deletions stl/aliases/generate.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ rmdir /s /q amd64
rmdir /s /q arm
rmdir /s /q arm64
rmdir /s /q chpe
rmdir /s /q arm64ec

mkdir i386
mkdir amd64
mkdir arm
mkdir arm64
mkdir chpe
mkdir arm64ec

:: __std_init_once_begin_initialize
..\..\..\..\..\tools\x86\aliasobj.exe ^
Expand All @@ -31,11 +33,20 @@ mkdir chpe
__imp___std_init_once_begin_initialize ^
__imp_InitOnceBeginInitialize ^
arm\std_init_once_begin_initialize.obj
copy amd64\std_init_once_begin_initialize.obj arm64\std_init_once_begin_initialize.obj
..\..\..\..\..\tools\amd64\aliasobj.exe ^
/machine:arm64 ^
__imp___std_init_once_begin_initialize ^
__imp_InitOnceBeginInitialize ^
arm64\std_init_once_begin_initialize.obj
..\..\..\..\..\tools\x86\aliasobj.exe ^
__imp_#__std_init_once_begin_initialize@16 ^
__imp_#InitOnceBeginInitialize@16 ^
chpe\std_init_once_begin_initialize.obj
..\..\..\..\..\tools\amd64\aliasobj.exe ^
/machine:arm64ec ^
__imp___std_init_once_begin_initialize ^
__imp_InitOnceBeginInitialize ^
arm64ec\std_init_once_begin_initialize.obj

:: __std_init_once_complete
..\..\..\..\..\tools\x86\aliasobj.exe ^
Expand All @@ -50,8 +61,17 @@ copy amd64\std_init_once_begin_initialize.obj arm64\std_init_once_begin_initiali
__imp___std_init_once_complete ^
__imp_InitOnceComplete ^
arm\std_init_once_complete.obj
copy amd64\std_init_once_complete.obj arm64\std_init_once_complete.obj
..\..\..\..\..\tools\amd64\aliasobj.exe ^
/machine:arm64 ^
__imp___std_init_once_complete ^
__imp_InitOnceComplete ^
arm64\std_init_once_complete.obj
..\..\..\..\..\tools\x86\aliasobj.exe ^
__imp_#__std_init_once_complete@12 ^
__imp_#InitOnceComplete@12 ^
chpe\std_init_once_complete.obj
..\..\..\..\..\tools\amd64\aliasobj.exe ^
/machine:arm64ec ^
__imp___std_init_once_complete ^
__imp_InitOnceComplete ^
arm64ec\std_init_once_complete.obj
Binary file modified stl/aliases/i386/std_init_once_begin_initialize.obj
Binary file not shown.
Binary file modified stl/aliases/i386/std_init_once_complete.obj
Binary file not shown.
1 change: 1 addition & 0 deletions stl/inc/__msvc_all_public_headers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
#include <barrier>
#include <latch>
#include <semaphore>
#include <stop_token>
#endif // _M_CEE_PURE

#ifndef _M_CEE
Expand Down
105 changes: 92 additions & 13 deletions stl/inc/atomic
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ _STL_DISABLE_CLANG_WARNINGS

#define _Compiler_barrier() _STL_DISABLE_DEPRECATED_WARNING _ReadWriteBarrier() _STL_RESTORE_DEPRECATED_WARNING

#if defined(_M_ARM) || defined(_M_ARM64)
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
#define _Memory_barrier() __dmb(0xB) // inner shared data memory barrier
#define _Compiler_or_memory_barrier() _Memory_barrier()
#elif defined(_M_IX86) || defined(_M_X64)
Expand Down Expand Up @@ -69,18 +69,18 @@ extern "C" _NODISCARD char __stdcall __std_atomic_has_cmpxchg16b() noexcept;

// MACRO _ATOMIC_HAS_DCAS
// Controls whether atomic::is_always_lock_free triggers for sizeof(void *) or 2 * sizeof(void *)
#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64)
#if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64) || defined(_M_ARM64EC)
#define _ATOMIC_HAS_DCAS 1
#else // ^^^ We always have DCAS / We only sometimes have DCAS vvv
#define _ATOMIC_HAS_DCAS 0
#endif // _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64)
#endif // _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B == 1 || !defined(_M_X64) || defined(_M_ARM64EC)

// MACRO _ATOMIC_CHOOSE_INTRINSIC
#if defined(_M_IX86) || defined(_M_X64)
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
_Check_memory_order(_Order); \
_Result = _Intrinsic(__VA_ARGS__)
#elif defined(_M_ARM) || defined(_M_ARM64)
#elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
switch (_Order) { \
case memory_order_relaxed: \
Expand Down Expand Up @@ -335,7 +335,7 @@ struct _Atomic_storage_traits { // properties for how _Ty is stored in an atomic
: sizeof(_Ty) == 2 ? 2
: sizeof(_Ty) <= 4 ? 4
: sizeof(_Ty) <= 8 ? 8
#if defined(_M_X64) || defined(_M_ARM64)
#if defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM64EC)
: sizeof(_Ty) <= 16 ? 16
#endif // 64 bits
: sizeof(_Ty);
Expand Down Expand Up @@ -639,7 +639,7 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics
void store(const _TVal _Value) noexcept { // store with sequential consistency
const auto _Mem = _Atomic_address_as<char>(_Storage);
const char _As_bytes = _Atomic_reinterpret_as<char>(_Value);
#if defined(_M_ARM) || defined(_M_ARM64)
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
_Memory_barrier();
__iso_volatile_store8(_Mem, _As_bytes);
_Memory_barrier();
Expand Down Expand Up @@ -760,7 +760,7 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics
void store(const _TVal _Value) noexcept { // store with sequential consistency
const auto _Mem = _Atomic_address_as<short>(_Storage);
const short _As_bytes = _Atomic_reinterpret_as<short>(_Value);
#if defined(_M_ARM) || defined(_M_ARM64)
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
_Memory_barrier();
__iso_volatile_store16(_Mem, _As_bytes);
_Memory_barrier();
Expand Down Expand Up @@ -878,7 +878,7 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics
}

void store(const _TVal _Value) noexcept { // store with sequential consistency
#if defined(_M_ARM) || defined(_M_ARM64)
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
_Memory_barrier();
__iso_volatile_store32(_Atomic_address_as<int>(_Storage), _Atomic_reinterpret_as<int>(_Value));
_Memory_barrier();
Expand Down Expand Up @@ -1158,7 +1158,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics
}

_NODISCARD _TVal load(const memory_order _Order) const noexcept { // load with given memory order
#ifdef _M_ARM64
#if defined(_M_ARM64) || defined(_M_ARM64EC)
long long* const _Storage_ptr = const_cast<long long*>(_Atomic_address_as<const long long>(_Storage));
_Int128 _Result{}; // atomic CAS 0 with 0
switch (_Order) {
Expand Down Expand Up @@ -1218,7 +1218,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics
_Int128 _Mask_val{};
_CSTD memcpy(&_Mask_val, _Mask._Ptr(), sizeof(_TVal));
for (;;) {
#ifdef _M_ARM64
#if defined(_M_ARM64) || defined(_M_ARM64EC)
_ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _InterlockedCompareExchange128,
_Atomic_address_as<long long>(_Storage), _Desired_bytes._High, _Desired_bytes._Low,
&_Expected_temp._Low);
Expand All @@ -1244,7 +1244,7 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics
}
}
#endif // _CMPXCHG_MASK_OUT_PADDING_BITS
#ifdef _M_ARM64
#if defined(_M_ARM64) || defined(_M_ARM64EC)
_ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _InterlockedCompareExchange128,
_Atomic_address_as<long long>(_Storage), _Desired_bytes._High, _Desired_bytes._Low, &_Expected_temp._Low);
#else // ^^^ _M_ARM64 / _M_X64 vvv
Expand Down Expand Up @@ -1365,7 +1365,7 @@ struct _Atomic_integral<_Ty, 1> : _Atomic_storage<_Ty> { // atomic integral oper
}

_TVal operator--(int) noexcept {
return static_cast<_Ty>(_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), -1));
return static_cast<_TVal>(_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), -1));
}

_TVal operator--() noexcept {
Expand Down Expand Up @@ -1810,6 +1810,22 @@ struct _Atomic_integral_facade<_Ty&> : _Atomic_integral<_Ty&> {
return fetch_add(_Negate(_Operand), _Order);
}

_Ty operator++(int) const noexcept {
return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++(0);
}

_Ty operator++() const noexcept {
return const_cast<_Atomic_integral_facade*>(this)->_Base::operator++();
}

_Ty operator--(int) const noexcept {
return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--(0);
}

_Ty operator--() const noexcept {
return const_cast<_Atomic_integral_facade*>(this)->_Base::operator--();
}

_Ty operator+=(const _Ty _Operand) const noexcept {
return static_cast<_Ty>(fetch_add(_Operand) + _Operand);
}
Expand Down Expand Up @@ -2970,6 +2986,69 @@ inline void atomic_flag_notify_all(volatile atomic_flag* const _Flag) noexcept {
inline void atomic_flag_notify_all(atomic_flag* const _Flag) noexcept {
return _Flag->notify_all();
}

template <class _Ty>
class _Locked_pointer {
public:
static_assert(alignof(_Ty) >= (1 << 2), "2 low order bits are needed by _Locked_pointer");
static constexpr uintptr_t _Lock_mask = 3;
static constexpr uintptr_t _Not_locked = 0;
static constexpr uintptr_t _Locked_notify_not_needed = 1;
static constexpr uintptr_t _Locked_notify_needed = 2;
static constexpr uintptr_t _Ptr_value_mask = ~_Lock_mask;

constexpr _Locked_pointer() noexcept : _Storage{} {}
explicit _Locked_pointer(_Ty* const _Ptr) noexcept : _Storage{reinterpret_cast<uintptr_t>(_Ptr)} {}

_Locked_pointer(const _Locked_pointer&) = delete;
_Locked_pointer& operator=(const _Locked_pointer&) = delete;

_NODISCARD _Ty* _Lock_and_load() noexcept {
uintptr_t _Rep = _Storage.load(memory_order_relaxed);
for (;;) {
switch (_Rep & _Lock_mask) {
case _Not_locked: // Can try to lock now
if (_Storage.compare_exchange_weak(_Rep, _Rep | _Locked_notify_not_needed)) {
return reinterpret_cast<_Ty*>(_Rep);
}
_YIELD_PROCESSOR();
break;

case _Locked_notify_not_needed: // Try to set "notify needed" and wait
if (!_Storage.compare_exchange_weak(_Rep, (_Rep & _Ptr_value_mask) | _Locked_notify_needed)) {
// Failed to set notify needed flag, try again
_YIELD_PROCESSOR();
break;
}
_Rep = (_Rep & _Ptr_value_mask) | _Locked_notify_needed;
[[fallthrough]];

case _Locked_notify_needed: // "Notify needed" is already set, just wait
_Storage.wait(_Rep, memory_order_relaxed);
_Rep = _Storage.load(memory_order_relaxed);
break;

default: // Unrecognized bit pattern
_CSTD abort();
}
}
}

void _Store_and_unlock(_Ty* const _Value) noexcept {
const auto _Rep = _Storage.exchange(reinterpret_cast<uintptr_t>(_Value));
if ((_Rep & _Lock_mask) == _Locked_notify_needed) {
// As we don't count waiters, every waiter is notified, and then some may re-request notification
_Storage.notify_all();
}
}

_NODISCARD _Ty* _Unsafe_load_relaxed() const noexcept {
return reinterpret_cast<_Ty*>(_Storage.load(memory_order_relaxed));
}

private:
atomic<uintptr_t> _Storage;
};
#endif // _HAS_CXX20

_STD_END
Expand Down
Loading