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)) != 0U ||
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(is_complete_v<T>,
"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(); }
252struct atomic<T*> : atomic_base<T*> {
254 ~atomic()
noexcept =
default;
255 atomic(
const atomic&) =
delete;
256 atomic& operator=(
const atomic&) =
delete;
257 atomic& operator=(
const atomic&)
volatile =
delete;
258 atomic(atomic&&)
noexcept =
default;
259 atomic& operator=(atomic&&)
noexcept =
default;
261 explicit atomic(T* value) noexcept :
262 atomic_base<T*>(value) {}
264 using atomic_base<T*>::operator=;
274 ~atomic()
noexcept =
default;
275 atomic(
const atomic&) =
delete;
276 atomic& operator=(
const atomic&) =
delete;
277 atomic& operator=(
const atomic&)
volatile =
delete;
278 atomic(atomic&&)
noexcept =
default;
279 atomic& operator=(atomic&&)
noexcept =
default;
281 explicit atomic(T& value) noexcept :
301 ~atomic() noexcept = default;
302 atomic(const atomic&) = delete;
303 atomic& operator=(const atomic&) = delete;
304 atomic& operator=(const atomic&) volatile = delete;
305 atomic(atomic&&) noexcept = default;
306 atomic& operator=(atomic&&) noexcept = default;
312 constexpr atomic(const
bool value) noexcept :
320 bool operator=(
const bool value)
noexcept {
return base_.operator=(value); }
325 bool operator=(
const bool value)
volatile noexcept {
return base_.operator=(value); }
331 operator bool() const noexcept {
return base_.load(); }
336 operator bool() const volatile noexcept {
return base_.load(); }
342 NEFORCE_NODISCARD
bool is_lock_free() const noexcept {
return base_.is_lock_free(); }
347 NEFORCE_NODISCARD
bool is_lock_free() const volatile noexcept {
return base_.is_lock_free(); }
360 base_.store(value, mo);
374 return base_.load(mo);
384 return base_.exchange(value, mo);
391 return base_.exchange(value, mo);
404 return base_.compare_exchange_weak(value1, value2,
success, failure);
412 return base_.compare_exchange_weak(value1, value2,
success, failure);
423 return base_.compare_exchange_weak(value1, value2, mo);
431 return base_.compare_exchange_weak(value1, value2, mo);
444 return base_.compare_exchange_strong(value1, value2,
success, failure);
452 return base_.compare_exchange_strong(value1, value2,
success, failure);
464 return base_.compare_exchange_strong(value1, value2, mo);
472 return base_.compare_exchange_strong(value1, value2, mo);
495struct atomic<char> : atomic_base<char> {
496 using integral_type = char;
497 using base_type = atomic_base<char>;
500 ~atomic()
noexcept =
default;
501 atomic(
const atomic&) =
delete;
502 atomic& operator=(
const atomic&) =
delete;
503 atomic& operator=(
const atomic&)
volatile =
delete;
504 atomic(atomic&&)
noexcept =
default;
505 atomic& operator=(atomic&&)
noexcept =
default;
507 constexpr atomic(
const integral_type value) noexcept :
510 using base_type::operator integral_type;
511 using base_type::operator=;
513 static constexpr bool is_always_lock_free =
true;
518struct atomic<signed char> : atomic_base<signed char> {
519 using integral_type =
signed char;
520 using base_type = atomic_base<signed char>;
523 ~atomic()
noexcept =
default;
524 atomic(
const atomic&) =
delete;
525 atomic& operator=(
const atomic&) =
delete;
526 atomic& operator=(
const atomic&)
volatile =
delete;
527 atomic(atomic&&)
noexcept =
default;
528 atomic& operator=(atomic&&)
noexcept =
default;
530 constexpr atomic(
const integral_type value) noexcept :
533 using base_type::operator integral_type;
534 using base_type::operator=;
536 static constexpr bool is_always_lock_free =
true;
541struct atomic<unsigned char> : atomic_base<unsigned char> {
542 using integral_type =
unsigned char;
543 using base_type = atomic_base<unsigned char>;
546 ~atomic()
noexcept =
default;
547 atomic(
const atomic&) =
delete;
548 atomic& operator=(
const atomic&) =
delete;
549 atomic& operator=(
const atomic&)
volatile =
delete;
550 atomic(atomic&&)
noexcept =
default;
551 atomic& operator=(atomic&&)
noexcept =
default;
553 constexpr atomic(
const integral_type value) noexcept :
556 using base_type::operator integral_type;
557 using base_type::operator=;
559 static constexpr bool is_always_lock_free =
true;
564struct atomic<short> : atomic_base<short> {
565 using integral_type = short;
566 using base_type = atomic_base<short>;
569 ~atomic()
noexcept =
default;
570 atomic(
const atomic&) =
delete;
571 atomic& operator=(
const atomic&) =
delete;
572 atomic& operator=(
const atomic&)
volatile =
delete;
573 atomic(atomic&&)
noexcept =
default;
574 atomic& operator=(atomic&&)
noexcept =
default;
576 constexpr atomic(
const integral_type value) noexcept :
579 using base_type::operator integral_type;
580 using base_type::operator=;
582 static constexpr bool is_always_lock_free =
true;
587struct atomic<unsigned short> : atomic_base<unsigned short> {
588 using integral_type =
unsigned short;
589 using base_type = atomic_base<unsigned short>;
592 ~atomic()
noexcept =
default;
593 atomic(
const atomic&) =
delete;
594 atomic& operator=(
const atomic&) =
delete;
595 atomic& operator=(
const atomic&)
volatile =
delete;
596 atomic(atomic&&)
noexcept =
default;
597 atomic& operator=(atomic&&)
noexcept =
default;
599 constexpr atomic(
const integral_type value) noexcept :
602 using base_type::operator integral_type;
603 using base_type::operator=;
605 static constexpr bool is_always_lock_free =
true;
610struct atomic<int> : atomic_base<int> {
611 using integral_type = int;
612 using base_type = atomic_base<int>;
615 ~atomic()
noexcept =
default;
616 atomic(
const atomic&) =
delete;
617 atomic& operator=(
const atomic&) =
delete;
618 atomic& operator=(
const atomic&)
volatile =
delete;
619 atomic(atomic&&)
noexcept =
default;
620 atomic& operator=(atomic&&)
noexcept =
default;
622 constexpr atomic(
const integral_type value) noexcept :
625 using base_type::operator integral_type;
626 using base_type::operator=;
628 static constexpr bool is_always_lock_free =
true;
633struct atomic<unsigned int> : atomic_base<unsigned int> {
634 using integral_type =
unsigned int;
635 using base_type = atomic_base<unsigned int>;
638 ~atomic()
noexcept =
default;
639 atomic(
const atomic&) =
delete;
640 atomic& operator=(
const atomic&) =
delete;
641 atomic& operator=(
const atomic&)
volatile =
delete;
642 atomic(atomic&&)
noexcept =
default;
643 atomic& operator=(atomic&&)
noexcept =
default;
645 constexpr atomic(
const integral_type value) noexcept :
648 using base_type::operator integral_type;
649 using base_type::operator=;
651 static constexpr bool is_always_lock_free =
true;
656struct atomic<long> : atomic_base<long> {
657 using integral_type = long;
658 using base_type = atomic_base<long>;
661 ~atomic()
noexcept =
default;
662 atomic(
const atomic&) =
delete;
663 atomic& operator=(
const atomic&) =
delete;
664 atomic& operator=(
const atomic&)
volatile =
delete;
665 atomic(atomic&&)
noexcept =
default;
666 atomic& operator=(atomic&&)
noexcept =
default;
668 constexpr atomic(
const integral_type value) noexcept :
671 using base_type::operator integral_type;
672 using base_type::operator=;
674 static constexpr bool is_always_lock_free =
true;
679struct atomic<unsigned long> : atomic_base<unsigned long> {
680 using integral_type =
unsigned long;
681 using base_type = atomic_base<unsigned long>;
684 ~atomic()
noexcept =
default;
685 atomic(
const atomic&) =
delete;
686 atomic& operator=(
const atomic&) =
delete;
687 atomic& operator=(
const atomic&)
volatile =
delete;
688 atomic(atomic&&)
noexcept =
default;
689 atomic& operator=(atomic&&)
noexcept =
default;
691 constexpr atomic(
const integral_type value) noexcept :
694 using base_type::operator integral_type;
695 using base_type::operator=;
697 static constexpr bool is_always_lock_free =
true;
702struct atomic<long long> : atomic_base<long long> {
703 using integral_type =
long long;
704 using base_type = atomic_base<long long>;
707 ~atomic()
noexcept =
default;
708 atomic(
const atomic&) =
delete;
709 atomic& operator=(
const atomic&) =
delete;
710 atomic& operator=(
const atomic&)
volatile =
delete;
711 atomic(atomic&&)
noexcept =
default;
712 atomic& operator=(atomic&&)
noexcept =
default;
714 constexpr atomic(
const integral_type value) noexcept :
717 using base_type::operator integral_type;
718 using base_type::operator=;
720 static constexpr bool is_always_lock_free =
true;
725struct atomic<unsigned long long> : atomic_base<unsigned long long> {
726 using integral_type =
unsigned long long;
727 using base_type = atomic_base<unsigned long long>;
730 ~atomic()
noexcept =
default;
731 atomic(
const atomic&) =
delete;
732 atomic& operator=(
const atomic&) =
delete;
733 atomic& operator=(
const atomic&)
volatile =
delete;
734 atomic(atomic&&)
noexcept =
default;
735 atomic& operator=(atomic&&)
noexcept =
default;
737 constexpr atomic(
const integral_type value) noexcept :
740 using base_type::operator integral_type;
741 using base_type::operator=;
743 static constexpr bool is_always_lock_free =
true;
748struct atomic<wchar_t> : atomic_base<wchar_t> {
749 using integral_type = wchar_t;
750 using base_type = atomic_base<wchar_t>;
753 ~atomic()
noexcept =
default;
754 atomic(
const atomic&) =
delete;
755 atomic& operator=(
const atomic&) =
delete;
756 atomic& operator=(
const atomic&)
volatile =
delete;
757 atomic(atomic&&)
noexcept =
default;
758 atomic& operator=(atomic&&)
noexcept =
default;
760 constexpr atomic(
const integral_type value) noexcept :
763 using base_type::operator integral_type;
764 using base_type::operator=;
766 static constexpr bool is_always_lock_free =
true;
769#ifdef NEFORCE_STANDARD_20
772struct atomic<char8_t> : atomic_base<char8_t> {
773 using integral_type = char8_t;
774 using base_type = atomic_base<char8_t>;
777 ~atomic()
noexcept =
default;
778 atomic(
const atomic&) =
delete;
779 atomic& operator=(
const atomic&) =
delete;
780 atomic& operator=(
const atomic&)
volatile =
delete;
781 atomic(atomic&&)
noexcept =
default;
782 atomic& operator=(atomic&&)
noexcept =
default;
784 constexpr atomic(
const integral_type value) noexcept :
787 using base_type::operator integral_type;
788 using base_type::operator=;
790 static constexpr bool is_always_lock_free =
true;
796struct atomic<char16_t> : atomic_base<char16_t> {
797 using integral_type = char16_t;
798 using base_type = atomic_base<char16_t>;
801 ~atomic()
noexcept =
default;
802 atomic(
const atomic&) =
delete;
803 atomic& operator=(
const atomic&) =
delete;
804 atomic& operator=(
const atomic&)
volatile =
delete;
805 atomic(atomic&&)
noexcept =
default;
806 atomic& operator=(atomic&&)
noexcept =
default;
808 constexpr atomic(
const integral_type value) noexcept :
811 using base_type::operator integral_type;
812 using base_type::operator=;
814 static constexpr bool is_always_lock_free =
true;
819struct atomic<char32_t> : atomic_base<char32_t> {
820 using integral_type = char32_t;
821 using base_type = atomic_base<char32_t>;
824 ~atomic()
noexcept =
default;
825 atomic(
const atomic&) =
delete;
826 atomic& operator=(
const atomic&) =
delete;
827 atomic& operator=(
const atomic&)
volatile =
delete;
828 atomic(atomic&&)
noexcept =
default;
829 atomic& operator=(atomic&&)
noexcept =
default;
831 constexpr atomic(
const integral_type value) noexcept :
834 using base_type::operator integral_type;
835 using base_type::operator=;
837 static constexpr bool is_always_lock_free =
true;
842struct atomic<float> : atomic_float_base<float> {
844 ~atomic()
noexcept =
default;
845 atomic(
const atomic&) =
delete;
846 atomic& operator=(
const atomic&) =
delete;
847 atomic& operator=(
const atomic&)
volatile =
delete;
848 atomic(atomic&&)
noexcept =
default;
849 atomic& operator=(atomic&&)
noexcept =
default;
851 constexpr atomic(
const float value) noexcept :
852 atomic_float_base<float>(value) {}
854 using atomic_float_base<
float>::operator=;
859struct atomic<double> : atomic_float_base<double> {
861 ~atomic()
noexcept =
default;
862 atomic(
const atomic&) =
delete;
863 atomic& operator=(
const atomic&) =
delete;
864 atomic& operator=(
const atomic&)
volatile =
delete;
865 atomic(atomic&&)
noexcept =
default;
866 atomic& operator=(atomic&&)
noexcept =
default;
868 constexpr atomic(
const double value) noexcept :
869 atomic_float_base<double>(value) {}
871 using atomic_float_base<
double>::operator=;
876struct atomic<long double> : atomic_float_base<long double> {
878 ~atomic()
noexcept =
default;
879 atomic(
const atomic&) =
delete;
880 atomic& operator=(
const atomic&) =
delete;
881 atomic& operator=(
const atomic&)
volatile =
delete;
882 atomic(atomic&&)
noexcept =
default;
883 atomic& operator=(atomic&&)
noexcept =
default;
885 constexpr atomic(
const long double value) noexcept :
886 atomic_float_base<long double>(value) {}
888 using atomic_float_base<
long double>::operator=;
895NEFORCE_END_NAMESPACE__
constexpr T * addressof(T &x) 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
通用强比较交换操作
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
检查是否支持无锁操作
remove_volatile_t< T > atomic_load_any(const T *ptr, memory_order mo) 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 bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
constexpr bool is_move_constructible_v
is_move_constructible的便捷变量模板
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
constexpr bool is_move_assignable_v
is_move_assignable的便捷变量模板
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版本的简化版强比较交换操作