1#ifndef NEFORCE_CORE_ASYNC_ATOMIC_HPP__
2#define NEFORCE_CORE_ASYNC_ATOMIC_HPP__
12NEFORCE_BEGIN_NAMESPACE__
38 static constexpr int min_align = (
sizeof(T) & (
sizeof(T) - 1)) != 0U ||
sizeof(T) > 16 ? 0 :
sizeof(T);
39 static constexpr int align_inner = min_align >
alignof(T) ? min_align : alignof(T);
41 alignas(align_inner) T value_;
44 static_assert(is_complete_v<T>,
"Incomplete or zero-sized types are not supported");
52 ~atomic() noexcept = default;
53 atomic(const atomic&) = delete;
54 atomic& operator=(const atomic&) = delete;
55 atomic& operator=(const atomic&) volatile = delete;
56 atomic(atomic&&) noexcept = default;
57 atomic& operator=(atomic&&) noexcept = default;
63 constexpr atomic(T value) noexcept :
70 operator T() const noexcept {
return load(); }
75 operator T() const volatile noexcept {
return load(); }
249struct atomic<T*> : atomic_base<T*> {
250 atomic()
noexcept =
default;
251 ~atomic()
noexcept =
default;
252 atomic(
const atomic&) =
delete;
253 atomic& operator=(
const atomic&) =
delete;
254 atomic& operator=(
const atomic&)
volatile =
delete;
255 atomic(atomic&&)
noexcept =
default;
256 atomic& operator=(atomic&&)
noexcept =
default;
258 explicit atomic(T* value) noexcept :
259 atomic_base<T*>(value) {}
261 using atomic_base<T*>::operator=;
271 ~atomic()
noexcept =
default;
272 atomic(
const atomic&) =
delete;
273 atomic& operator=(
const atomic&) =
delete;
274 atomic& operator=(
const atomic&)
volatile =
delete;
275 atomic(atomic&&)
noexcept =
default;
276 atomic& operator=(atomic&&)
noexcept =
default;
278 explicit atomic(T& value) noexcept :
298 ~atomic() noexcept = default;
299 atomic(const atomic&) = delete;
300 atomic& operator=(const atomic&) = delete;
301 atomic& operator=(const atomic&) volatile = delete;
302 atomic(atomic&&) noexcept = default;
303 atomic& operator=(atomic&&) noexcept = default;
309 constexpr atomic(const
bool value) noexcept :
317 bool operator=(
const bool value)
noexcept {
return base_.operator=(value); }
322 bool operator=(
const bool value)
volatile noexcept {
return base_.operator=(value); }
328 operator bool() const noexcept {
return base_.load(); }
333 operator bool() const volatile noexcept {
return base_.load(); }
339 NEFORCE_NODISCARD
bool is_lock_free() const noexcept {
return base_.is_lock_free(); }
344 NEFORCE_NODISCARD
bool is_lock_free() const volatile noexcept {
return base_.is_lock_free(); }
357 base_.store(value, mo);
371 return base_.load(mo);
381 return base_.exchange(value, mo);
388 return base_.exchange(value, mo);
401 return base_.compare_exchange_weak(value1, value2,
success, failure);
409 return base_.compare_exchange_weak(value1, value2,
success, failure);
420 return base_.compare_exchange_weak(value1, value2, mo);
428 return base_.compare_exchange_weak(value1, value2, mo);
441 return base_.compare_exchange_strong(value1, value2,
success, failure);
449 return base_.compare_exchange_strong(value1, value2,
success, failure);
461 return base_.compare_exchange_strong(value1, value2, mo);
469 return base_.compare_exchange_strong(value1, value2, mo);
492struct atomic<char> : atomic_base<char> {
493 using integral_type = char;
494 using base_type = atomic_base<char>;
497 ~atomic()
noexcept =
default;
498 atomic(
const atomic&) =
delete;
499 atomic& operator=(
const atomic&) =
delete;
500 atomic& operator=(
const atomic&)
volatile =
delete;
501 atomic(atomic&&)
noexcept =
default;
502 atomic& operator=(atomic&&)
noexcept =
default;
504 constexpr atomic(
const integral_type value) noexcept :
507 using base_type::operator integral_type;
508 using base_type::operator=;
510 static constexpr bool is_always_lock_free =
true;
515struct atomic<signed char> : atomic_base<signed char> {
516 using integral_type =
signed char;
517 using base_type = atomic_base<signed char>;
520 ~atomic()
noexcept =
default;
521 atomic(
const atomic&) =
delete;
522 atomic& operator=(
const atomic&) =
delete;
523 atomic& operator=(
const atomic&)
volatile =
delete;
524 atomic(atomic&&)
noexcept =
default;
525 atomic& operator=(atomic&&)
noexcept =
default;
527 constexpr atomic(
const integral_type value) noexcept :
530 using base_type::operator integral_type;
531 using base_type::operator=;
533 static constexpr bool is_always_lock_free =
true;
538struct atomic<unsigned char> : atomic_base<unsigned char> {
539 using integral_type =
unsigned char;
540 using base_type = atomic_base<unsigned char>;
543 ~atomic()
noexcept =
default;
544 atomic(
const atomic&) =
delete;
545 atomic& operator=(
const atomic&) =
delete;
546 atomic& operator=(
const atomic&)
volatile =
delete;
547 atomic(atomic&&)
noexcept =
default;
548 atomic& operator=(atomic&&)
noexcept =
default;
550 constexpr atomic(
const integral_type value) noexcept :
553 using base_type::operator integral_type;
554 using base_type::operator=;
556 static constexpr bool is_always_lock_free =
true;
561struct atomic<short> : atomic_base<short> {
562 using integral_type = short;
563 using base_type = atomic_base<short>;
566 ~atomic()
noexcept =
default;
567 atomic(
const atomic&) =
delete;
568 atomic& operator=(
const atomic&) =
delete;
569 atomic& operator=(
const atomic&)
volatile =
delete;
570 atomic(atomic&&)
noexcept =
default;
571 atomic& operator=(atomic&&)
noexcept =
default;
573 constexpr atomic(
const integral_type value) noexcept :
576 using base_type::operator integral_type;
577 using base_type::operator=;
579 static constexpr bool is_always_lock_free =
true;
584struct atomic<unsigned short> : atomic_base<unsigned short> {
585 using integral_type =
unsigned short;
586 using base_type = atomic_base<unsigned short>;
589 ~atomic()
noexcept =
default;
590 atomic(
const atomic&) =
delete;
591 atomic& operator=(
const atomic&) =
delete;
592 atomic& operator=(
const atomic&)
volatile =
delete;
593 atomic(atomic&&)
noexcept =
default;
594 atomic& operator=(atomic&&)
noexcept =
default;
596 constexpr atomic(
const integral_type value) noexcept :
599 using base_type::operator integral_type;
600 using base_type::operator=;
602 static constexpr bool is_always_lock_free =
true;
607struct atomic<int> : atomic_base<int> {
608 using integral_type = int;
609 using base_type = atomic_base<int>;
612 ~atomic()
noexcept =
default;
613 atomic(
const atomic&) =
delete;
614 atomic& operator=(
const atomic&) =
delete;
615 atomic& operator=(
const atomic&)
volatile =
delete;
616 atomic(atomic&&)
noexcept =
default;
617 atomic& operator=(atomic&&)
noexcept =
default;
619 constexpr atomic(
const integral_type value) noexcept :
622 using base_type::operator integral_type;
623 using base_type::operator=;
625 static constexpr bool is_always_lock_free =
true;
630struct atomic<unsigned int> : atomic_base<unsigned int> {
631 using integral_type =
unsigned int;
632 using base_type = atomic_base<unsigned int>;
635 ~atomic()
noexcept =
default;
636 atomic(
const atomic&) =
delete;
637 atomic& operator=(
const atomic&) =
delete;
638 atomic& operator=(
const atomic&)
volatile =
delete;
639 atomic(atomic&&)
noexcept =
default;
640 atomic& operator=(atomic&&)
noexcept =
default;
642 constexpr atomic(
const integral_type value) noexcept :
645 using base_type::operator integral_type;
646 using base_type::operator=;
648 static constexpr bool is_always_lock_free =
true;
653struct atomic<long> : atomic_base<long> {
654 using integral_type = long;
655 using base_type = atomic_base<long>;
658 ~atomic()
noexcept =
default;
659 atomic(
const atomic&) =
delete;
660 atomic& operator=(
const atomic&) =
delete;
661 atomic& operator=(
const atomic&)
volatile =
delete;
662 atomic(atomic&&)
noexcept =
default;
663 atomic& operator=(atomic&&)
noexcept =
default;
665 constexpr atomic(
const integral_type value) noexcept :
668 using base_type::operator integral_type;
669 using base_type::operator=;
671 static constexpr bool is_always_lock_free =
true;
676struct atomic<unsigned long> : atomic_base<unsigned long> {
677 using integral_type =
unsigned long;
678 using base_type = atomic_base<unsigned long>;
681 ~atomic()
noexcept =
default;
682 atomic(
const atomic&) =
delete;
683 atomic& operator=(
const atomic&) =
delete;
684 atomic& operator=(
const atomic&)
volatile =
delete;
685 atomic(atomic&&)
noexcept =
default;
686 atomic& operator=(atomic&&)
noexcept =
default;
688 constexpr atomic(
const integral_type value) noexcept :
691 using base_type::operator integral_type;
692 using base_type::operator=;
694 static constexpr bool is_always_lock_free =
true;
699struct atomic<long long> : atomic_base<long long> {
700 using integral_type =
long long;
701 using base_type = atomic_base<long long>;
704 ~atomic()
noexcept =
default;
705 atomic(
const atomic&) =
delete;
706 atomic& operator=(
const atomic&) =
delete;
707 atomic& operator=(
const atomic&)
volatile =
delete;
708 atomic(atomic&&)
noexcept =
default;
709 atomic& operator=(atomic&&)
noexcept =
default;
711 constexpr atomic(
const integral_type value) noexcept :
714 using base_type::operator integral_type;
715 using base_type::operator=;
717 static constexpr bool is_always_lock_free =
true;
722struct atomic<unsigned long long> : atomic_base<unsigned long long> {
723 using integral_type =
unsigned long long;
724 using base_type = atomic_base<unsigned long long>;
727 ~atomic()
noexcept =
default;
728 atomic(
const atomic&) =
delete;
729 atomic& operator=(
const atomic&) =
delete;
730 atomic& operator=(
const atomic&)
volatile =
delete;
731 atomic(atomic&&)
noexcept =
default;
732 atomic& operator=(atomic&&)
noexcept =
default;
734 constexpr atomic(
const integral_type value) noexcept :
737 using base_type::operator integral_type;
738 using base_type::operator=;
740 static constexpr bool is_always_lock_free =
true;
745struct atomic<wchar_t> : atomic_base<wchar_t> {
746 using integral_type = wchar_t;
747 using base_type = atomic_base<wchar_t>;
750 ~atomic()
noexcept =
default;
751 atomic(
const atomic&) =
delete;
752 atomic& operator=(
const atomic&) =
delete;
753 atomic& operator=(
const atomic&)
volatile =
delete;
754 atomic(atomic&&)
noexcept =
default;
755 atomic& operator=(atomic&&)
noexcept =
default;
757 constexpr atomic(
const integral_type value) noexcept :
760 using base_type::operator integral_type;
761 using base_type::operator=;
763 static constexpr bool is_always_lock_free =
true;
766#ifdef NEFORCE_STANDARD_20
769struct atomic<char8_t> : atomic_base<char8_t> {
770 using integral_type = char8_t;
771 using base_type = atomic_base<char8_t>;
774 ~atomic()
noexcept =
default;
775 atomic(
const atomic&) =
delete;
776 atomic& operator=(
const atomic&) =
delete;
777 atomic& operator=(
const atomic&)
volatile =
delete;
778 atomic(atomic&&)
noexcept =
default;
779 atomic& operator=(atomic&&)
noexcept =
default;
781 constexpr atomic(
const integral_type value) noexcept :
784 using base_type::operator integral_type;
785 using base_type::operator=;
787 static constexpr bool is_always_lock_free =
true;
793struct atomic<char16_t> : atomic_base<char16_t> {
794 using integral_type = char16_t;
795 using base_type = atomic_base<char16_t>;
798 ~atomic()
noexcept =
default;
799 atomic(
const atomic&) =
delete;
800 atomic& operator=(
const atomic&) =
delete;
801 atomic& operator=(
const atomic&)
volatile =
delete;
802 atomic(atomic&&)
noexcept =
default;
803 atomic& operator=(atomic&&)
noexcept =
default;
805 constexpr atomic(
const integral_type value) noexcept :
808 using base_type::operator integral_type;
809 using base_type::operator=;
811 static constexpr bool is_always_lock_free =
true;
816struct atomic<char32_t> : atomic_base<char32_t> {
817 using integral_type = char32_t;
818 using base_type = atomic_base<char32_t>;
821 ~atomic()
noexcept =
default;
822 atomic(
const atomic&) =
delete;
823 atomic& operator=(
const atomic&) =
delete;
824 atomic& operator=(
const atomic&)
volatile =
delete;
825 atomic(atomic&&)
noexcept =
default;
826 atomic& operator=(atomic&&)
noexcept =
default;
828 constexpr atomic(
const integral_type value) noexcept :
831 using base_type::operator integral_type;
832 using base_type::operator=;
834 static constexpr bool is_always_lock_free =
true;
839struct atomic<float> : atomic_float_base<float> {
841 ~atomic()
noexcept =
default;
842 atomic(
const atomic&) =
delete;
843 atomic& operator=(
const atomic&) =
delete;
844 atomic& operator=(
const atomic&)
volatile =
delete;
845 atomic(atomic&&)
noexcept =
default;
846 atomic& operator=(atomic&&)
noexcept =
default;
848 constexpr atomic(
const float value) noexcept :
849 atomic_float_base<float>(value) {}
851 using atomic_float_base<
float>::operator=;
856struct atomic<double> : atomic_float_base<double> {
858 ~atomic()
noexcept =
default;
859 atomic(
const atomic&) =
delete;
860 atomic& operator=(
const atomic&) =
delete;
861 atomic& operator=(
const atomic&)
volatile =
delete;
862 atomic(atomic&&)
noexcept =
default;
863 atomic& operator=(atomic&&)
noexcept =
default;
865 constexpr atomic(
const double value) noexcept :
866 atomic_float_base<double>(value) {}
868 using atomic_float_base<
double>::operator=;
873struct atomic<long double> : atomic_float_base<long double> {
875 ~atomic()
noexcept =
default;
876 atomic(
const atomic&) =
delete;
877 atomic& operator=(
const atomic&) =
delete;
878 atomic& operator=(
const atomic&)
volatile =
delete;
879 atomic(atomic&&)
noexcept =
default;
880 atomic& operator=(atomic&&)
noexcept =
default;
882 constexpr atomic(
const long double value) noexcept :
883 atomic_float_base<long double>(value) {}
885 using atomic_float_base<
long double>::operator=;
892NEFORCE_END_NAMESPACE__
constexpr T * addressof(T &x) noexcept
获取对象的地址
remove_volatile_t< T > atomic_load_any(const T *ptr, memory_order mo) noexcept
通用原子加载操作
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
通用弱比较交换操作
constexpr bool is_always_lock_free() noexcept
检查是否支持无锁操作
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
通用强比较交换操作
void atomic_store_any(T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
通用原子存储操作
remove_volatile_t< T > atomic_exchange_any(T *ptr, remove_volatile_t< T > desired, memory_order mo) noexcept
通用原子交换操作
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
constexpr bool is_move_constructible_v
is_move_constructible的便捷变量模板
constexpr bool is_move_assignable_v
is_move_assignable的便捷变量模板
constexpr bool is_copy_assignable_v
is_copy_assignable的便捷变量模板
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
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 mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
bool operator=(const bool value) noexcept
赋值运算符
bool load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
bool exchange(const bool value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
void store(const bool value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
bool compare_exchange_strong(bool &value1, const bool value2, 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 load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
void notify_one() noexcept
通知一个等待线程
bool exchange(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) volatile noexcept
volatile版本的弱比较交换操作
bool operator=(const bool value) volatile noexcept
volatile版本的赋值运算符
void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order success, const memory_order failure) noexcept
强比较交换操作
bool compare_exchange_weak(bool &value1, const bool value2, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
bool compare_exchange_strong(bool &value1, const bool value2, const memory_order success, const memory_order failure) 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 mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
T operator=(T value) volatile noexcept
volatile版本的赋值运算符
bool compare_exchange_strong(T &expected, T value, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
block * load(const memory_order mo=memory_order_seq_cst) const noexcept
bool compare_exchange_weak(T &expected, T desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
T operator=(T value) noexcept
赋值运算符
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) noexcept
强比较交换操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
T exchange(T value, 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) noexcept
弱比较交换操作
bool compare_exchange_weak(T &expected, T desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_strong(T &expected, T value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_strong(T &expected, T desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作