1#ifndef NEFORCE_CORE_ASYNC_ATOMIC_BASE_HPP__
2#define NEFORCE_CORE_ASYNC_ATOMIC_BASE_HPP__
14#ifdef NEFORCE_COMPILER_MSVC
17NEFORCE_BEGIN_NAMESPACE__
38#ifdef NEFORCE_COMPILER_MSVC
42# if defined(NEFORCE_ARCH_X86)
43 ::_ReadWriteBarrier();
46 ::_InterlockedIncrement(&guard);
47 ::_ReadWriteBarrier();
49# elif defined(NEFORCE_ARCH_ARM)
51 ::_Memory_load_acquire_barrier();
53 ::_ReadWriteBarrier();
59 __atomic_thread_fence(
static_cast<int32_t>(mo));
70#ifdef NEFORCE_COMPILER_MSVC
72 ::_ReadWriteBarrier();
75 __atomic_signal_fence(
static_cast<int32_t>(mo));
83#ifdef NEFORCE_COMPILER_MSVC
86struct interlocked_exchange_impl;
89struct interlocked_exchange_impl<1> {
91 static T call(
volatile T* target, T value) {
92 return static_cast<T
>(
93 ::_InterlockedExchange8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
97struct interlocked_exchange_impl<2> {
99 static T call(
volatile T* target, T value) {
100 return static_cast<T
>(
101 ::_InterlockedExchange16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
105struct interlocked_exchange_impl<4> {
106 template <
typename T>
107 static T call(
volatile T* target, T value) {
108 return static_cast<T
>(
109 ::_InterlockedExchange(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
113struct interlocked_exchange_impl<8> {
114 template <
typename T>
115 static T call(
volatile T* target, T value) {
116 return static_cast<T
>(
117 ::_InterlockedExchange64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
121template <
size_t Size>
122struct interlocked_compare_exchange_impl;
125struct interlocked_compare_exchange_impl<1> {
126 template <
typename T>
127 static bool call(
volatile T* target, T* expected, T desired) {
129 ::_InterlockedCompareExchange8(
reinterpret_cast<volatile char*
>(target),
130 *
reinterpret_cast<char*
>(&desired), *
reinterpret_cast<char*
>(expected));
131 if (old == *
reinterpret_cast<char*
>(expected)) {
134 *
reinterpret_cast<char*
>(expected) = old;
139struct interlocked_compare_exchange_impl<2> {
140 template <
typename T>
141 static bool call(
volatile T* target, T* expected, T desired) {
142 const short old = ::_InterlockedCompareExchange16(
reinterpret_cast<volatile short*
>(target),
143 *
reinterpret_cast<short*
>(&desired),
144 *
reinterpret_cast<short*
>(expected));
145 if (old == *
reinterpret_cast<short*
>(expected)) {
148 *
reinterpret_cast<short*
>(expected) = old;
153struct interlocked_compare_exchange_impl<4> {
154 template <
typename T>
155 static bool call(
volatile T* target, T* expected, T desired) {
157 ::_InterlockedCompareExchange(
reinterpret_cast<volatile long*
>(target),
158 *
reinterpret_cast<long*
>(&desired), *
reinterpret_cast<long*
>(expected));
159 if (old == *
reinterpret_cast<long*
>(expected)) {
162 *
reinterpret_cast<long*
>(expected) = old;
167struct interlocked_compare_exchange_impl<8> {
168 template <
typename T>
169 static bool call(
volatile T* target, T* expected, T desired) {
170 const long long old = ::_InterlockedCompareExchange64(
reinterpret_cast<volatile long long*
>(target),
171 *
reinterpret_cast<long long*
>(&desired),
172 *
reinterpret_cast<long long*
>(expected));
173 if (old == *
reinterpret_cast<long long*
>(expected)) {
176 *
reinterpret_cast<long long*
>(expected) = old;
181struct interlocked_compare_exchange_impl<16> {
182 template <
typename T>
183 static bool call(
volatile T* target, T* expected, T desired) {
184 alignas(16)
long long exp_arr[2];
185 alignas(16)
long long des_arr[2];
189 const bool result = ::_InterlockedCompareExchange128(
reinterpret_cast<volatile long long*
>(target), des_arr[1],
190 des_arr[0], exp_arr) != 0;
199template <
size_t Size>
200struct interlocked_fetch_add_impl;
203struct interlocked_fetch_add_impl<1> {
204 template <
typename T>
205 static T call(
volatile T* target, T value) {
206 return static_cast<T
>(
207 ::_InterlockedExchangeAdd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
211struct interlocked_fetch_add_impl<2> {
212 template <
typename T>
213 static T call(
volatile T* target, T value) {
214 return static_cast<T
>(
215 ::_InterlockedExchangeAdd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
219struct interlocked_fetch_add_impl<4> {
220 template <
typename T>
221 static T call(
volatile T* target, T value) {
222 return static_cast<T
>(
223 ::_InterlockedExchangeAdd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
227struct interlocked_fetch_add_impl<8> {
228 template <
typename T>
229 static T call(
volatile T* target, T value) {
230 return static_cast<T
>(::_InterlockedExchangeAdd64(
reinterpret_cast<volatile long long*
>(target),
231 static_cast<long long>(value)));
235template <
size_t Size>
236struct interlocked_fetch_and_impl;
239struct interlocked_fetch_and_impl<1> {
240 template <
typename T>
241 static T call(
volatile T* target, T value) {
242 return static_cast<T
>(::_InterlockedAnd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
246struct interlocked_fetch_and_impl<2> {
247 template <
typename T>
248 static T call(
volatile T* target, T value) {
249 return static_cast<T
>(
250 ::_InterlockedAnd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
254struct interlocked_fetch_and_impl<4> {
255 template <
typename T>
256 static T call(
volatile T* target, T value) {
257 return static_cast<T
>(::_InterlockedAnd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
261struct interlocked_fetch_and_impl<8> {
262 template <
typename T>
263 static T call(
volatile T* target, T value) {
264 return static_cast<T
>(
265 ::_InterlockedAnd64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
269template <
size_t Size>
270struct interlocked_fetch_or_impl;
273struct interlocked_fetch_or_impl<1> {
274 template <
typename T>
275 static T call(
volatile T* target, T value) {
276 return static_cast<T
>(::_InterlockedOr8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
280struct interlocked_fetch_or_impl<2> {
281 template <
typename T>
282 static T call(
volatile T* target, T value) {
283 return static_cast<T
>(::_InterlockedOr16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
287struct interlocked_fetch_or_impl<4> {
288 template <
typename T>
289 static T call(
volatile T* target, T value) {
290 return static_cast<T
>(::_InterlockedOr(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
294struct interlocked_fetch_or_impl<8> {
295 template <
typename T>
296 static T call(
volatile T* target, T value) {
297 return static_cast<T
>(
298 ::_InterlockedOr64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
302template <
size_t Size>
303struct interlocked_fetch_xor_impl;
306struct interlocked_fetch_xor_impl<1> {
307 template <
typename T>
308 static T call(
volatile T* target, T value) {
309 return static_cast<T
>(::_InterlockedXor8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
313struct interlocked_fetch_xor_impl<2> {
314 template <
typename T>
315 static T call(
volatile T* target, T value) {
316 return static_cast<T
>(
317 ::_InterlockedXor16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
321struct interlocked_fetch_xor_impl<4> {
322 template <
typename T>
323 static T call(
volatile T* target, T value) {
324 return static_cast<T
>(::_InterlockedXor(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
328struct interlocked_fetch_xor_impl<8> {
329 template <
typename T>
330 static T call(
volatile T* target, T value) {
331 return static_cast<T
>(
332 ::_InterlockedXor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
338#ifdef NEFORCE_COMPILER_MSVC
339template <
size_t Size>
340struct atomic_is_always_lock_free_impl {
341 static constexpr bool value =
false;
344struct atomic_is_always_lock_free_impl<1> {
345 static constexpr bool value =
true;
348struct atomic_is_always_lock_free_impl<2> {
349 static constexpr bool value =
true;
352struct atomic_is_always_lock_free_impl<4> {
353 static constexpr bool value =
true;
356struct atomic_is_always_lock_free_impl<8> {
357 static constexpr bool value =
true;
360struct atomic_is_always_lock_free_impl<16> {
361# ifdef NEFORCE_ARCH_X86_64
362 static constexpr bool value =
true;
364 static constexpr bool value =
false;
393#ifdef NEFORCE_COMPILER_GNUC
394 __atomic_store_n(ptr, value,
static_cast<int32_t>(mo));
396 inner::interlocked_exchange_impl<
sizeof(T)>::call(ptr, value);
398 ::_ReadWriteBarrier();
414#ifdef NEFORCE_COMPILER_GNUC
415 return __atomic_load_n(ptr,
static_cast<int32_t>(mo));
419 ::_ReadWriteBarrier();
438#ifdef NEFORCE_COMPILER_GNUC
439 return __atomic_exchange_n(ptr, value,
static_cast<int32_t>(mo));
443 ::_ReadWriteBarrier();
467#ifdef NEFORCE_COMPILER_GNUC
468 return __atomic_compare_exchange_n(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
469 static_cast<int32_t>(failure));
471# if defined(NEFORCE_ARCH_X86)
472 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, desired);
474 ::_ReadWriteBarrier();
481# if defined(NEFORCE_ARCH_ARM)
482 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
483 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
484 "cmp %[loaded], %[old_val]\n\t"
486 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
488 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
489 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
492 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
493 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
494 "cmp %[loaded], %[old_val]\n\t"
496 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
498 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
499 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
502 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
503 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
504 "cmp %[loaded], %[old_val]\n\t"
506 "strex %w[success], %w[desired], [%[ptr]]\n\t"
508 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
509 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
512 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
520 "ldrexd %[lo], %[hi], [%[ptr]]\n\t"
521 "cmp %[lo], %[old_lo]\n\t"
522 "cmpeq %[hi], %[old_hi]\n\t"
524 "strexd %[success], %[des_lo], %[des_hi], [%[ptr]]\n\t"
526 : [lo]
"=&r"(loaded_lo), [hi]
"=&r"(loaded_hi), [
success]
"=&r"(tmp_success)
527 : [ptr]
"r"(ptr), [old_lo]
"r"(old_lo), [old_hi]
"r"(old_hi), [des_lo]
"r"(des_lo), [des_hi]
"r"(des_hi)
529 loaded =
static_cast<T
>(
static_cast<uint64_t>(loaded_lo) | (
static_cast<uint64_t>(loaded_hi) << 32));
530 success_flag = (tmp_success == 0);
531 if (loaded != old_val) {
537# elif defined(NEFORCE_ARCH_RISCV)
538 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
539 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
540 "bne %[loaded], %[old_val], 1f\n\t"
541 "sc.w %[success], %[desired], (%[ptr])\n\t"
543 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
544 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
547 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
548 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
549 "bne %[loaded], %[old_val], 1f\n\t"
550 "sc.d %[success], %[desired], (%[ptr])\n\t"
552 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
553 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
556# elif defined(NEFORCE_ARCH_LOONGARCH)
557 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
560 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
561 "bne %[loaded], %[old_val], 1f\n\t"
562 "sc.w %[des_copy], %[ptr]\n\t"
564 "move %[success], %[des_copy]\n\t"
565 : [loaded]
"=&r"(loaded), [des_copy]
"+r"(des_copy), [
success]
"=r"(sc_result)
566 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val)
568 success_flag = (sc_result == 0);
570 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
571 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
572 "bne %[loaded], %[old_val], 1f\n\t"
573 "sc.d %[desired], %[ptr]\n\t"
574 "move %[success], %[desired]\n\t"
576 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
577 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
581 if (loaded != old_val) {
585 return success_flag == 0;
608#ifdef NEFORCE_COMPILER_GNUC
609 return __atomic_compare_exchange_n(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
610 static_cast<int32_t>(failure));
612# if defined(NEFORCE_ARCH_X86)
620 if (*expected != old_val) {
641#ifdef NEFORCE_COMPILER_GNUC
642 return __atomic_fetch_add(ptr, value,
static_cast<int32_t>(mo));
646 ::_ReadWriteBarrier();
665#ifdef NEFORCE_COMPILER_GNUC
666 return __atomic_fetch_sub(ptr, value,
static_cast<int32_t>(mo));
685#ifdef NEFORCE_COMPILER_GNUC
686 return __atomic_fetch_and(ptr, value,
static_cast<int32_t>(mo));
690 ::_ReadWriteBarrier();
709#ifdef NEFORCE_COMPILER_GNUC
710 return __atomic_fetch_or(ptr, value,
static_cast<int32_t>(mo));
714 ::_ReadWriteBarrier();
733#ifdef NEFORCE_COMPILER_GNUC
734 return __atomic_fetch_xor(ptr, value,
static_cast<int32_t>(mo));
738 ::_ReadWriteBarrier();
757#ifdef NEFORCE_COMPILER_GNUC
758 return __atomic_add_fetch(ptr, value,
static_cast<int32_t>(mo));
777#ifdef NEFORCE_COMPILER_GNUC
778 return __atomic_sub_fetch(ptr, value,
static_cast<int32_t>(mo));
797#ifdef NEFORCE_COMPILER_GNUC
798 return __atomic_and_fetch(ptr, value,
static_cast<int32_t>(mo));
817#ifdef NEFORCE_COMPILER_GNUC
818 return __atomic_or_fetch(ptr, value,
static_cast<int32_t>(mo));
837#ifdef NEFORCE_COMPILER_GNUC
838 return __atomic_xor_fetch(ptr, value,
static_cast<int32_t>(mo));
861#ifdef NEFORCE_COMPILER_GNUC
862 return __atomic_compare_exchange(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
863 static_cast<int32_t>(failure));
865# if defined(NEFORCE_ARCH_X86)
866 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
868 ::_ReadWriteBarrier();
875# if defined(NEFORCE_ARCH_ARM)
876 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
877 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
878 "cmp %[loaded], %[old_val]\n\t"
880 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
882 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
883 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
886 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
887 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
888 "cmp %[loaded], %[old_val]\n\t"
890 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
892 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
893 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
896 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
897 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
898 "cmp %[loaded], %[old_val]\n\t"
900 "strex %w[success], %w[desired], [%[ptr]]\n\t"
902 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
903 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
906 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
907 asm volatile(
"ldrexd %[loaded], [%[ptr]]\n\t"
908 "cmp %[loaded], %[old_val]\n\t"
910 "strexd %w[success], %[desired], [%[ptr]]\n\t"
912 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
913 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
916# elif defined(NEFORCE_ARCH_RISCV)
917 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
918 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
919 "bne %[loaded], %[old_val], 1f\n\t"
920 "sc.w %[success], %[desired], (%[ptr])\n\t"
922 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
923 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
926 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
927 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
928 "bne %[loaded], %[old_val], 1f\n\t"
929 "sc.d %[success], %[desired], (%[ptr])\n\t"
931 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
932 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
935# elif defined(NEFORCE_ARCH_LOONGARCH)
936 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
937 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
938 "bne %[loaded], %[old_val], 1f\n\t"
939 "sc.w %[desired], %[ptr]\n\t"
940 "move %[success], %[desired]\n\t"
942 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
943 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
946 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
947 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
948 "bne %[loaded], %[old_val], 1f\n\t"
949 "sc.d %[desired], %[ptr]\n\t"
950 "move %[success], %[desired]\n\t"
952 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
953 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
957 if (loaded != old_val) {
961 return success_flag == 0;
982#ifdef NEFORCE_COMPILER_GNUC
983 return __atomic_compare_exchange(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
984 static_cast<int32_t>(failure));
986# if defined(NEFORCE_ARCH_X86)
987 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
989 ::_ReadWriteBarrier();
1014template <
typename T>
1016#ifdef NEFORCE_COMPILER_GNUC
1034template <
typename T>
1036#ifdef NEFORCE_COMPILER_GNUC
1037 alignas(T)
byte_t buffer[
sizeof(T)];
1039 __atomic_load(ptr, dest,
static_cast<int32_t>(mo));
1045 ::_ReadWriteBarrier();
1060template <
typename T>
1063#ifdef NEFORCE_COMPILER_GNUC
1064 alignas(T)
byte_t buffer[
sizeof(T)];
1066 __atomic_exchange(ptr, _NEFORCE
addressof(desired), dest,
static_cast<int32_t>(mo));
1085template <
typename T>
1090 new_value = old_value + value;
1103template <
typename T>
1108 new_value = old_value - value;
1121template <
typename T>
1126 new_value = old_value + value;
1139template <
typename T>
1144 new_value = old_value - value;
1156template <
size_t Size,
size_t Align>
1158#ifdef NEFORCE_COMPILER_GNUC
1159 return __atomic_is_lock_free(Size,
reinterpret_cast<void*
>(-Align));
1161 return inner::atomic_is_always_lock_free_impl<Size>::value;
1177#ifdef NEFORCE_COMPILER_MSVC
1206#ifdef NEFORCE_COMPILER_GNUC
1207 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1209 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1211 ::_ReadWriteBarrier();
1213 return old_val != 0;
1221#ifdef NEFORCE_COMPILER_GNUC
1222 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1224 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1226 ::_ReadWriteBarrier();
1228 return old_val != 0;
1238#ifdef NEFORCE_COMPILER_GNUC
1240 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1243 const long as_bytes =
flag_;
1245 ::_ReadWriteBarrier();
1247 return as_bytes != 0;
1255#ifdef NEFORCE_COMPILER_GNUC
1257 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1260 const long as_bytes =
flag_;
1262 ::_ReadWriteBarrier();
1264 return as_bytes != 0;
1276 [
this, mo] {
return this->
test(mo); });
1286 [
this, mo] {
return this->
test(mo); });
1309#ifdef NEFORCE_COMPILER_GNUC
1325#ifdef NEFORCE_COMPILER_GNUC
1340template <
typename T>
1348 static constexpr size_t align_inner =
sizeof(T) >
alignof(T) ?
sizeof(T) : alignof(T);
1353 atomic_base() noexcept = default;
1354 ~atomic_base() noexcept = default;
1355 atomic_base(const atomic_base&) = delete;
1356 atomic_base& operator=(const atomic_base&) = delete;
1357 atomic_base& operator=(const atomic_base&) volatile = delete;
1358 atomic_base(atomic_base&&) noexcept = default;
1359 atomic_base& operator=(atomic_base&&) noexcept = default;
1801template <
typename T>
1802struct atomic_base<T*> {
1810 return dest *
sizeof(T);
1952#ifdef NEFORCE_COMPILER_GNUC
1953 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
1955 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr);
1957 ::_ReadWriteBarrier();
1972#ifdef NEFORCE_COMPILER_GNUC
1973 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
1975 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr);
1977 ::_ReadWriteBarrier();
1991#ifdef NEFORCE_COMPILER_GNUC
1992 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
1996 ::_ReadWriteBarrier();
2009#ifdef NEFORCE_COMPILER_GNUC
2010 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2014 ::_ReadWriteBarrier();
2028#ifdef NEFORCE_COMPILER_GNUC
2029 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2032 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2034 ::_ReadWriteBarrier();
2045#ifdef NEFORCE_COMPILER_GNUC
2046 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2049 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2051 ::_ReadWriteBarrier();
2180 return reinterpret_cast<value_type>(old_val);
2191 return reinterpret_cast<value_type>(old_val);
2205 return reinterpret_cast<value_type>(old_val);
2216 return reinterpret_cast<value_type>(old_val);
2228template <
typename Float>
2229struct atomic_float_base {
2236 alignas(
alignof(Float)) Float float_ =
static_cast<Float
>(0);
2239 atomic_float_base() =
default;
2240 atomic_float_base(
const atomic_float_base&) =
delete;
2241 atomic_float_base& operator=(
const atomic_float_base&) =
delete;
2242 atomic_float_base& operator=(
const atomic_float_base&)
volatile =
delete;
2243 atomic_float_base(atomic_float_base&&) noexcept = default;
2244 atomic_float_base& operator=(atomic_float_base&&) noexcept = default;
2312 operator Float() const noexcept {
return this->
load(); }
2317 operator Float() const volatile noexcept {
return this->
load(); }
2491template <
typename T,
bool IsIntegral = is_
integral_v<T>,
bool IsFloatingPo
int = is_
floating_po
int_v<T>>
2499template <
typename T>
2504 static constexpr int align_inner = (
sizeof(T) & (
sizeof(T) - 1)) ||
sizeof(T) > 16 ? 0 :
sizeof(T);
2540 operator T() const noexcept {
return this->
load(); }
2645template <
typename T>
2646struct atomic_ref_base<T, true, false> {
2659 atomic_ref_base() =
delete;
2660 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
2661 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
2686 NEFORCE_NODISCARD
operator T() const noexcept {
return this->
load(); }
2902template <
typename Float>
2903struct atomic_ref_base<Float, false, true> {
2916 atomic_ref_base() =
delete;
2917 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
2918 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
2943 operator Float() const noexcept {
return this->
load(); }
3086#ifdef NEFORCE_COMPILER_CLANG
3087# pragma clang diagnostic push
3088# pragma clang diagnostic ignored "-Watomic-alignment"
3091template <
typename T>
3094 using value_type = T*;
3100 static constexpr difference_type real_type_sizes(
const difference_type dest)
noexcept {
3102 return dest *
sizeof(T);
3107 static constexpr size_t required_alignment =
sizeof(T*) == 8 ? 8 : alignof(T*);
3127 T* operator=(T* value)
noexcept {
3136 operator T*()
const noexcept {
return this->load(); }
3243 NEFORCE_ALWAYS_INLINE value_type fetch_add(
const difference_type dest,
3245 const uintptr_t byte_offset =
static_cast<uintptr_t>(dest *
static_cast<difference_type
>(
sizeof(T)));
3247 return reinterpret_cast<value_type
>(old_val);
3256 NEFORCE_ALWAYS_INLINE value_type fetch_sub(
const difference_type dest,
3258 const uintptr_t byte_offset =
static_cast<uintptr_t>(dest *
static_cast<difference_type
>(
sizeof(T)));
3260 return reinterpret_cast<value_type
>(old_val);
3267 value_type operator++(
int)
noexcept {
return fetch_add(1); }
3273 value_type operator--(
int)
noexcept {
return fetch_sub(1); }
3279 value_type operator++() noexcept {
return fetch_add(1) + 1; }
3285 value_type operator--() noexcept {
return fetch_sub(1) - 1; }
3292 value_type operator+=(
const difference_type dest)
noexcept {
return fetch_add(dest) + dest; }
3299 value_type operator-=(
const difference_type dest)
noexcept {
return fetch_sub(dest) - dest; }
3302#ifdef NEFORCE_COMPILER_CLANG
3303# pragma clang diagnostic pop
3310NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_sub(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并减去操作
T atomic_fetch_add_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并添加操作
NEFORCE_ALWAYS_INLINE_INLINE void atomic_store_any(T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
通用原子存储操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_add(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并添加操作
NEFORCE_CONSTEXPR17 bool is_always_lock_free() noexcept
检查是否支持无锁操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_load_any(const T *ptr, memory_order mo) noexcept
通用原子加载操作
T atomic_fetch_sub_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并减去操作
T atomic_add_fetch_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子添加并获取操作
NEFORCE_ALWAYS_INLINE_INLINE bool atomic_cmpexch_strong(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void atomic_wait_address_v(const T *addr, T old, Func f) noexcept
基于值的原子等待
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_exchange(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子交换操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_add_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子添加并获取操作
void atomic_notify_address(const T *addr, const bool all) noexcept
原子通知
T atomic_sub_fetch_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子减去并获取操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_xor(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并异或操作
NEFORCE_ALWAYS_INLINE_INLINE void atomic_signal_fence(const memory_order mo) noexcept
信号内存屏障
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_xor_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子异或并获取操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_sub_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子减去并获取操作
NEFORCE_ALWAYS_INLINE_INLINE bool atomic_cmpexch_weak_any(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > *desired, const memory_order success, const memory_order failure) noexcept
通用弱比较交换操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_or(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并或操作
NEFORCE_ALWAYS_INLINE_INLINE void atomic_store(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子存储操作
NEFORCE_ALWAYS_INLINE_INLINE bool atomic_cmpexch_weak(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
conditional_t< is_pointer_v< T >, ptrdiff_t, remove_volatile_t< T > > atomic_diff_t
原子操作的差值类型
NEFORCE_ALWAYS_INLINE_INLINE void atomic_thread_fence(const memory_order mo) noexcept
线程内存屏障
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_and(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并与操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_or_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子或并获取操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_load(const volatile T *ptr, const memory_order mo) noexcept
原子加载操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_exchange_any(T *ptr, remove_volatile_t< T > desired, memory_order mo) noexcept
通用原子交换操作
NEFORCE_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_and_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子与并获取操作
NEFORCE_ALWAYS_INLINE_INLINE bool atomic_cmpexch_strong_any(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > *desired, const memory_order success, const memory_order failure) noexcept
通用强比较交换操作
NEFORCE_INLINE17 constexpr bool is_floating_point_v
is_floating_point的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_integral_v
is_integral的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_integral_like_v
is_integral_like的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
NEFORCE_CONSTEXPR14 void * memory_copy(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14 int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
NEFORCE_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_consume
数据依赖内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
@ memory_order_mask
内存顺序掩码
typename remove_volatile< T >::type remove_volatile_t
remove_volatile的便捷别名
NEFORCE_CONSTEXPR14 T exchange(T &val, U &&new_val) noexcept(is_nothrow_move_constructible_v< T > &&is_nothrow_assignable_v< T &, U >)
将新值赋给对象并返回旧值
NEFORCE_INLINE17 constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
NEFORCE_ALWAYS_INLINE_INLINE value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加指针偏移
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
value_type operator--(int) noexcept
后置递减运算符
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换指针操作
value_type operator--(int) volatile noexcept
volatile版本的后置递减运算符
NEFORCE_ALWAYS_INLINE void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子存储指针操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换指针操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换指针操作
value_type operator+=(const ptrdiff_t dest) noexcept
指针加法赋值运算符
value_type operator--() noexcept
前置递减运算符
NEFORCE_ALWAYS_INLINE value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子交换指针操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
NEFORCE_ALWAYS_INLINE_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载指针操作
NEFORCE_ALWAYS_INLINE value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加指针偏移
value_type operator=(const value_type ptr) noexcept
赋值运算符
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
NEFORCE_ALWAYS_INLINE_INLINE void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储指针操作
value_type operator-=(const ptrdiff_t dest) volatile noexcept
volatile版本的指针减法赋值运算符
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换指针操作
NEFORCE_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载指针操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换指针操作
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
value_type operator++() noexcept
前置递增运算符
NEFORCE_ALWAYS_INLINE_INLINE value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换指针操作
value_type operator=(const value_type ptr) volatile noexcept
volatile版本的赋值运算符
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
NEFORCE_ALWAYS_INLINE_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换指针操作
NEFORCE_ALWAYS_INLINE_INLINE value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去指针偏移
value_type operator+=(const ptrdiff_t dest) volatile noexcept
volatile版本的指针加法赋值运算符
NEFORCE_ALWAYS_INLINE_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换指针操作
ptrdiff_t difference_type
差值类型
value_type operator-=(const ptrdiff_t dest) noexcept
指针减法赋值运算符
NEFORCE_ALWAYS_INLINE value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去指针偏移
value_type operator++(int) noexcept
后置递增运算符
NEFORCE_ALWAYS_INLINE void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待指针改变
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换指针操作
value_type operator--(int) noexcept
后置递减运算符
NEFORCE_ALWAYS_INLINE value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
NEFORCE_ALWAYS_INLINE value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
NEFORCE_ALWAYS_INLINE value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type operator|=(value_type value) volatile noexcept
volatile版本的位或赋值运算符
NEFORCE_ALWAYS_INLINE value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
NEFORCE_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
value_type operator--() noexcept
前置递减运算符
NEFORCE_ALWAYS_INLINE void store(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type operator=(value_type value) volatile noexcept
volatile版本的赋值运算符
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
value_type operator^=(value_type value) noexcept
位异或赋值运算符
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
value_type operator++(int) noexcept
后置递增运算符
NEFORCE_ALWAYS_INLINE void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
NEFORCE_ALWAYS_INLINE value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
NEFORCE_ALWAYS_INLINE void store(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
value_type operator--(int) volatile noexcept
volatile版本的后置递减运算符
value_type operator=(value_type value) noexcept
赋值运算符
NEFORCE_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
NEFORCE_ALWAYS_INLINE value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并与操作
value_type operator++() noexcept
前置递增运算符
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
NEFORCE_ALWAYS_INLINE value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
NEFORCE_ALWAYS_INLINE value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator^=(value_type value) volatile noexcept
volatile版本的位异或赋值运算符
value_type operator|=(value_type value) noexcept
位或赋值运算符
NEFORCE_ALWAYS_INLINE value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
NEFORCE_ALWAYS_INLINE value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并异或操作
value_type operator&=(value_type value) noexcept
位与赋值运算符
value_type operator&=(value_type value) volatile noexcept
volatile版本的位与赋值运算符
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
NEFORCE_ALWAYS_INLINE value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
NEFORCE_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
NEFORCE_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
NEFORCE_ALWAYS_INLINE value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并或操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
NEFORCE_ALWAYS_INLINE_INLINE bool test(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的测试标志值
NEFORCE_ALWAYS_INLINE_INLINE void wait(const bool old, const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的等待标志值改变
NEFORCE_ALWAYS_INLINE void clear(const memory_order mo=memory_order_seq_cst) noexcept
清除标志
NEFORCE_ALWAYS_INLINE bool test(const memory_order mo=memory_order_seq_cst) const noexcept
测试标志值
NEFORCE_ALWAYS_INLINE_INLINE bool test_and_set(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的测试并设置标志
NEFORCE_ALWAYS_INLINE bool test_and_set(const memory_order mo=memory_order_seq_cst) noexcept
测试并设置标志
NEFORCE_ALWAYS_INLINE_INLINE void clear(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的清除标志
NEFORCE_ALWAYS_INLINE void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待标志值改变
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
Float operator=(Float value) noexcept
赋值运算符
value_type difference_type
差值类型
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
void store(Float value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
NEFORCE_ALWAYS_INLINE void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
Float operator=(Float value) volatile noexcept
volatile版本的赋值运算符
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
void store(Float value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
Float load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
void store(Float value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
static constexpr size_t required_alignment
对齐需求
value_type difference_type
差值类型
NEFORCE_ALWAYS_INLINE void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
atomic_ref_base(Float &value)
构造函数
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
Float operator=(Float value) noexcept
赋值运算符
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
NEFORCE_ALWAYS_INLINE void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
atomic_ref_base(T &value)
构造函数
T operator=(T value) noexcept
赋值运算符
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
static constexpr size_t required_alignment
对齐需求
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
NEFORCE_ALWAYS_INLINE value_type operator++(int) noexcept
后置递增运算符
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
NEFORCE_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
static constexpr size_t required_alignment
对齐需求
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type operator++() noexcept
前置递增运算符
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
T operator=(T value) noexcept
赋值运算符
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
NEFORCE_NODISCARD bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator^=(value_type value) noexcept
位异或赋值运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
NEFORCE_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
value_type difference_type
差值类型
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
atomic_ref_base(T &value)
构造函数
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
value_type operator&=(value_type value) noexcept
位与赋值运算符
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
NEFORCE_ALWAYS_INLINE void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
value_type operator|=(value_type value) noexcept
位或赋值运算符
value_type operator--() noexcept
前置递减运算符
NEFORCE_ALWAYS_INLINE value_type operator--(int) noexcept
后置递减运算符
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作