1#ifndef NEFORCE_CORE_ASYNC_ATOMIC_HPP__
2#define NEFORCE_CORE_ASYNC_ATOMIC_HPP__
12NEFORCE_BEGIN_NAMESPACE__
41 static constexpr int min_align = (
sizeof(T) & (
sizeof(T) - 1)) ||
sizeof(T) > 16 ? 0 :
sizeof(T);
42 static constexpr int align_inner = min_align >
alignof(T) ? min_align : alignof(T);
44 alignas(align_inner) T value_;
47 static_assert(
sizeof(T) > 0,
"Incomplete or zero-sized types are not supported");
55 ~atomic() noexcept = default;
56 atomic(const atomic&) = delete;
57 atomic& operator=(const atomic&) = delete;
58 atomic& operator=(const atomic&) volatile = delete;
59 atomic(atomic&&) noexcept = default;
60 atomic& operator=(atomic&&) noexcept = default;
66 constexpr atomic(T value) noexcept :
73 operator T() const noexcept {
return load(); }
78 operator T() const volatile noexcept {
return load(); }
248struct atomic<T*> : atomic_base<T*> {
250 ~atomic()
noexcept =
default;
251 atomic(
const atomic&) =
delete;
252 atomic& operator=(
const atomic&) =
delete;
253 atomic& operator=(
const atomic&)
volatile =
delete;
254 atomic(atomic&&)
noexcept =
default;
255 atomic& operator=(atomic&&)
noexcept =
default;
257 explicit atomic(T* value) noexcept :
258 atomic_base<T*>(value) {}
260 using atomic_base<T*>::operator=;
270 ~atomic()
noexcept =
default;
271 atomic(
const atomic&) =
delete;
272 atomic& operator=(
const atomic&) =
delete;
273 atomic& operator=(
const atomic&)
volatile =
delete;
274 atomic(atomic&&)
noexcept =
default;
275 atomic& operator=(atomic&&)
noexcept =
default;
277 explicit atomic(T& value) noexcept :
297 ~atomic() noexcept = default;
298 atomic(const atomic&) = delete;
299 atomic& operator=(const atomic&) = delete;
300 atomic& operator=(const atomic&) volatile = delete;
301 atomic(atomic&&) noexcept = default;
302 atomic& operator=(atomic&&) noexcept = default;
308 constexpr atomic(const
bool value) noexcept :
316 bool operator=(
const bool value)
noexcept {
return base_.operator=(value); }
321 bool operator=(
const bool value)
volatile noexcept {
return base_.operator=(value); }
327 operator bool() const noexcept {
return base_.load(); }
332 operator bool() const volatile noexcept {
return base_.load(); }
343 bool is_lock_free() const volatile noexcept {
return base_.is_lock_free(); }
356 base_.store(value, mo);
378 return base_.exchange(value, mo);
385 return base_.exchange(value, mo);
398 return base_.compare_exchange_weak(value1, value2,
success, failure);
406 return base_.compare_exchange_weak(value1, value2,
success, failure);
417 return base_.compare_exchange_weak(value1, value2, mo);
425 return base_.compare_exchange_weak(value1, value2, mo);
438 return base_.compare_exchange_strong(value1, value2,
success, failure);
446 return base_.compare_exchange_strong(value1, value2,
success, failure);
458 return base_.compare_exchange_strong(value1, value2, mo);
466 return base_.compare_exchange_strong(value1, value2, mo);
489struct atomic<char> : atomic_base<char> {
490 using integral_type = char;
491 using base_type = atomic_base<char>;
494 ~atomic()
noexcept =
default;
495 atomic(
const atomic&) =
delete;
496 atomic& operator=(
const atomic&) =
delete;
497 atomic& operator=(
const atomic&)
volatile =
delete;
498 atomic(atomic&&)
noexcept =
default;
499 atomic& operator=(atomic&&)
noexcept =
default;
501 constexpr atomic(
const integral_type value) noexcept :
504 using base_type::operator integral_type;
505 using base_type::operator=;
507 static constexpr bool is_always_lock_free =
true;
512struct atomic<signed char> : atomic_base<signed char> {
513 using integral_type =
signed char;
514 using base_type = atomic_base<signed char>;
517 ~atomic()
noexcept =
default;
518 atomic(
const atomic&) =
delete;
519 atomic& operator=(
const atomic&) =
delete;
520 atomic& operator=(
const atomic&)
volatile =
delete;
521 atomic(atomic&&)
noexcept =
default;
522 atomic& operator=(atomic&&)
noexcept =
default;
524 constexpr atomic(
const integral_type value) noexcept :
527 using base_type::operator integral_type;
528 using base_type::operator=;
530 static constexpr bool is_always_lock_free =
true;
535struct atomic<unsigned char> : atomic_base<unsigned char> {
536 using integral_type =
unsigned char;
537 using base_type = atomic_base<unsigned char>;
540 ~atomic()
noexcept =
default;
541 atomic(
const atomic&) =
delete;
542 atomic& operator=(
const atomic&) =
delete;
543 atomic& operator=(
const atomic&)
volatile =
delete;
544 atomic(atomic&&)
noexcept =
default;
545 atomic& operator=(atomic&&)
noexcept =
default;
547 constexpr atomic(
const integral_type value) noexcept :
550 using base_type::operator integral_type;
551 using base_type::operator=;
553 static constexpr bool is_always_lock_free =
true;
558struct atomic<short> : atomic_base<short> {
559 using integral_type = short;
560 using base_type = atomic_base<short>;
563 ~atomic()
noexcept =
default;
564 atomic(
const atomic&) =
delete;
565 atomic& operator=(
const atomic&) =
delete;
566 atomic& operator=(
const atomic&)
volatile =
delete;
567 atomic(atomic&&)
noexcept =
default;
568 atomic& operator=(atomic&&)
noexcept =
default;
570 constexpr atomic(
const integral_type value) noexcept :
573 using base_type::operator integral_type;
574 using base_type::operator=;
576 static constexpr bool is_always_lock_free =
true;
581struct atomic<unsigned short> : atomic_base<unsigned short> {
582 using integral_type =
unsigned short;
583 using base_type = atomic_base<unsigned short>;
586 ~atomic()
noexcept =
default;
587 atomic(
const atomic&) =
delete;
588 atomic& operator=(
const atomic&) =
delete;
589 atomic& operator=(
const atomic&)
volatile =
delete;
590 atomic(atomic&&)
noexcept =
default;
591 atomic& operator=(atomic&&)
noexcept =
default;
593 constexpr atomic(
const integral_type value) noexcept :
596 using base_type::operator integral_type;
597 using base_type::operator=;
599 static constexpr bool is_always_lock_free =
true;
604struct atomic<int> : atomic_base<int> {
605 using integral_type = int;
606 using base_type = atomic_base<int>;
609 ~atomic()
noexcept =
default;
610 atomic(
const atomic&) =
delete;
611 atomic& operator=(
const atomic&) =
delete;
612 atomic& operator=(
const atomic&)
volatile =
delete;
613 atomic(atomic&&)
noexcept =
default;
614 atomic& operator=(atomic&&)
noexcept =
default;
616 constexpr atomic(
const integral_type value) noexcept :
619 using base_type::operator integral_type;
620 using base_type::operator=;
622 static constexpr bool is_always_lock_free =
true;
627struct atomic<unsigned int> : atomic_base<unsigned int> {
628 using integral_type =
unsigned int;
629 using base_type = atomic_base<unsigned int>;
632 ~atomic()
noexcept =
default;
633 atomic(
const atomic&) =
delete;
634 atomic& operator=(
const atomic&) =
delete;
635 atomic& operator=(
const atomic&)
volatile =
delete;
636 atomic(atomic&&)
noexcept =
default;
637 atomic& operator=(atomic&&)
noexcept =
default;
639 constexpr atomic(
const integral_type value) noexcept :
642 using base_type::operator integral_type;
643 using base_type::operator=;
645 static constexpr bool is_always_lock_free =
true;
650struct atomic<long> : atomic_base<long> {
651 using integral_type = long;
652 using base_type = atomic_base<long>;
655 ~atomic()
noexcept =
default;
656 atomic(
const atomic&) =
delete;
657 atomic& operator=(
const atomic&) =
delete;
658 atomic& operator=(
const atomic&)
volatile =
delete;
659 atomic(atomic&&)
noexcept =
default;
660 atomic& operator=(atomic&&)
noexcept =
default;
662 constexpr atomic(
const integral_type value) noexcept :
665 using base_type::operator integral_type;
666 using base_type::operator=;
668 static constexpr bool is_always_lock_free =
true;
673struct atomic<unsigned long> : atomic_base<unsigned long> {
674 using integral_type =
unsigned long;
675 using base_type = atomic_base<unsigned long>;
678 ~atomic()
noexcept =
default;
679 atomic(
const atomic&) =
delete;
680 atomic& operator=(
const atomic&) =
delete;
681 atomic& operator=(
const atomic&)
volatile =
delete;
682 atomic(atomic&&)
noexcept =
default;
683 atomic& operator=(atomic&&)
noexcept =
default;
685 constexpr atomic(
const integral_type value) noexcept :
688 using base_type::operator integral_type;
689 using base_type::operator=;
691 static constexpr bool is_always_lock_free =
true;
696struct atomic<long long> : atomic_base<long long> {
697 using integral_type =
long long;
698 using base_type = atomic_base<long long>;
701 ~atomic()
noexcept =
default;
702 atomic(
const atomic&) =
delete;
703 atomic& operator=(
const atomic&) =
delete;
704 atomic& operator=(
const atomic&)
volatile =
delete;
705 atomic(atomic&&)
noexcept =
default;
706 atomic& operator=(atomic&&)
noexcept =
default;
708 constexpr atomic(
const integral_type value) noexcept :
711 using base_type::operator integral_type;
712 using base_type::operator=;
714 static constexpr bool is_always_lock_free =
true;
719struct atomic<unsigned long long> : atomic_base<unsigned long long> {
720 using integral_type =
unsigned long long;
721 using base_type = atomic_base<unsigned long long>;
724 ~atomic()
noexcept =
default;
725 atomic(
const atomic&) =
delete;
726 atomic& operator=(
const atomic&) =
delete;
727 atomic& operator=(
const atomic&)
volatile =
delete;
728 atomic(atomic&&)
noexcept =
default;
729 atomic& operator=(atomic&&)
noexcept =
default;
731 constexpr atomic(
const integral_type value) noexcept :
734 using base_type::operator integral_type;
735 using base_type::operator=;
737 static constexpr bool is_always_lock_free =
true;
742struct atomic<wchar_t> : atomic_base<wchar_t> {
743 using integral_type = wchar_t;
744 using base_type = atomic_base<wchar_t>;
747 ~atomic()
noexcept =
default;
748 atomic(
const atomic&) =
delete;
749 atomic& operator=(
const atomic&) =
delete;
750 atomic& operator=(
const atomic&)
volatile =
delete;
751 atomic(atomic&&)
noexcept =
default;
752 atomic& operator=(atomic&&)
noexcept =
default;
754 constexpr atomic(
const integral_type value) noexcept :
757 using base_type::operator integral_type;
758 using base_type::operator=;
760 static constexpr bool is_always_lock_free =
true;
763#ifdef NEFORCE_STANDARD_20
766struct atomic<char8_t> : atomic_base<char8_t> {
767 using integral_type = char8_t;
768 using base_type = atomic_base<char8_t>;
771 ~atomic()
noexcept =
default;
772 atomic(
const atomic&) =
delete;
773 atomic& operator=(
const atomic&) =
delete;
774 atomic& operator=(
const atomic&)
volatile =
delete;
775 atomic(atomic&&)
noexcept =
default;
776 atomic& operator=(atomic&&)
noexcept =
default;
778 constexpr atomic(
const integral_type value) noexcept :
781 using base_type::operator integral_type;
782 using base_type::operator=;
784 static constexpr bool is_always_lock_free =
true;
790struct atomic<char16_t> : atomic_base<char16_t> {
791 using integral_type = char16_t;
792 using base_type = atomic_base<char16_t>;
795 ~atomic()
noexcept =
default;
796 atomic(
const atomic&) =
delete;
797 atomic& operator=(
const atomic&) =
delete;
798 atomic& operator=(
const atomic&)
volatile =
delete;
799 atomic(atomic&&)
noexcept =
default;
800 atomic& operator=(atomic&&)
noexcept =
default;
802 constexpr atomic(
const integral_type value) noexcept :
805 using base_type::operator integral_type;
806 using base_type::operator=;
808 static constexpr bool is_always_lock_free =
true;
813struct atomic<char32_t> : atomic_base<char32_t> {
814 using integral_type = char32_t;
815 using base_type = atomic_base<char32_t>;
818 ~atomic()
noexcept =
default;
819 atomic(
const atomic&) =
delete;
820 atomic& operator=(
const atomic&) =
delete;
821 atomic& operator=(
const atomic&)
volatile =
delete;
822 atomic(atomic&&)
noexcept =
default;
823 atomic& operator=(atomic&&)
noexcept =
default;
825 constexpr atomic(
const integral_type value) noexcept :
828 using base_type::operator integral_type;
829 using base_type::operator=;
831 static constexpr bool is_always_lock_free =
true;
836struct atomic<float> : atomic_float_base<float> {
838 ~atomic()
noexcept =
default;
839 atomic(
const atomic&) =
delete;
840 atomic& operator=(
const atomic&) =
delete;
841 atomic& operator=(
const atomic&)
volatile =
delete;
842 atomic(atomic&&)
noexcept =
default;
843 atomic& operator=(atomic&&)
noexcept =
default;
845 constexpr atomic(
const float value) noexcept :
846 atomic_float_base<float>(value) {}
848 using atomic_float_base<
float>::operator=;
853struct atomic<double> : atomic_float_base<double> {
855 ~atomic()
noexcept =
default;
856 atomic(
const atomic&) =
delete;
857 atomic& operator=(
const atomic&) =
delete;
858 atomic& operator=(
const atomic&)
volatile =
delete;
859 atomic(atomic&&)
noexcept =
default;
860 atomic& operator=(atomic&&)
noexcept =
default;
862 constexpr atomic(
const double value) noexcept :
863 atomic_float_base<double>(value) {}
865 using atomic_float_base<
double>::operator=;
870struct atomic<long double> : atomic_float_base<long double> {
872 ~atomic()
noexcept =
default;
873 atomic(
const atomic&) =
delete;
874 atomic& operator=(
const atomic&) =
delete;
875 atomic& operator=(
const atomic&)
volatile =
delete;
876 atomic(atomic&&)
noexcept =
default;
877 atomic& operator=(atomic&&)
noexcept =
default;
879 constexpr atomic(
const long double value) noexcept :
880 atomic_float_base<long double>(value) {}
882 using atomic_float_base<
long double>::operator=;
889NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_ALWAYS_INLINE_INLINE void atomic_store_any(T *ptr, remove_volatile_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
通用原子加载操作
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_exchange_any(T *ptr, remove_volatile_t< T > desired, 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
通用强比较交换操作
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
NEFORCE_INLINE17 constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
NEFORCE_INLINE17 constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_move_assignable_v
is_move_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_move_constructible_v
is_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_copy_assignable_v
is_copy_assignable的便捷变量模板
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
bool operator=(const bool value) noexcept
赋值运算符
void store(const bool value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
bool operator=(const bool value) volatile noexcept
volatile版本的赋值运算符
void store(const bool value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool exchange(const bool value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void notify_one() noexcept
通知一个等待线程
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
bool exchange(const bool value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
void notify_all() noexcept
通知所有等待线程
bool load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
bool compare_exchange_strong(T &expected, T value, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_strong(T &expected, T desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
T operator=(T value) noexcept
赋值运算符
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
T exchange(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
T operator=(T value) volatile noexcept
volatile版本的赋值运算符
bool compare_exchange_weak(T &expected, T desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
bool compare_exchange_weak(T &expected, T desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_weak(T &expected, T desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
T exchange(T value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
bool compare_exchange_strong(T &expected, T desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
T load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool compare_exchange_weak(T &expected, T desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool compare_exchange_strong(T &expected, T value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作