DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="4.12.3" />

 AtomicEnum<TEnum>

public struct AtomicEnum<TEnum> : IEquatable<TEnum> where TEnum : struct, Enum
Represents atomic enum value.
using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Threading; namespace DotNext.Threading { public struct AtomicEnum<TEnum> : IEquatable<TEnum> where TEnum : struct, Enum { private ulong value; public TEnum Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] [IsReadOnly] get { return EnumConverter.ToEnumUnchecked<TEnum>(ref value.VolatileRead()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { ref this.value.VolatileWrite(EnumConverter.ToUInt64Unchecked<TEnum>(value)); } } public AtomicEnum(TEnum value) { this.value = EnumConverter.ToUInt64Unchecked<TEnum>(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TEnum CompareExchange(TEnum update, TEnum expected) { return EnumConverter.ToEnumUnchecked<TEnum>(Interlocked.CompareExchange(ref value, EnumConverter.ToUInt64Unchecked<TEnum>(update), EnumConverter.ToUInt64Unchecked<TEnum>(expected))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CompareAndSet(TEnum expected, TEnum update) { return EqualityComparer<TEnum>.Default.Equals(CompareExchange(update, expected), expected); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TEnum GetAndSet(TEnum update) { return EnumConverter.ToEnumUnchecked<TEnum>(ref value.GetAndSet(EnumConverter.ToUInt64Unchecked<TEnum>(update))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TEnum SetAndGet(TEnum update) { Value = update; return update; } private (TEnum OldValue, TEnum NewValue) Update<TUpdater>(TUpdater updater) where TUpdater : struct, ISupplier<TEnum, TEnum> { TEnum val = this.Value; TEnum val3; TEnum val2; do { val3 = ((ISupplier<TEnum, TEnum>)updater).Invoke(val2 = val); } while (!EqualityComparer<TEnum>.Default.Equals(val = this.CompareExchange(val3, val2), val2)); return (val2, val3); } private (TEnum OldValue, TEnum NewValue) Accumulate<TAccumulator>(TEnum x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<TEnum, TEnum, TEnum> { TEnum val = this.Value; TEnum val3; TEnum val2; do { val3 = ((ISupplier<TEnum, TEnum, TEnum>)accumulator).Invoke(val2 = val, x); } while (!EqualityComparer<TEnum>.Default.Equals(val = this.CompareExchange(val3, val2), val2)); return (val2, val3); } public TEnum AccumulateAndGet(TEnum x, [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0, 0 })] Func<TEnum, TEnum, TEnum> accumulator) { return Accumulate(x, (DelegatingSupplier<TEnum, TEnum, TEnum>)accumulator).NewValue; } [CLSCompliant(false)] public TEnum AccumulateAndGet(TEnum x, IntPtr accumulator) { return Accumulate(x, (Supplier<TEnum, TEnum, TEnum>)(long)accumulator).NewValue; } public TEnum GetAndAccumulate(TEnum x, [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0, 0 })] Func<TEnum, TEnum, TEnum> accumulator) { return Accumulate(x, (DelegatingSupplier<TEnum, TEnum, TEnum>)accumulator).OldValue; } [CLSCompliant(false)] public TEnum GetAndAccumulate(TEnum x, IntPtr accumulator) { return Accumulate(x, (Supplier<TEnum, TEnum, TEnum>)(long)accumulator).OldValue; } public TEnum UpdateAndGet([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0 })] Func<TEnum, TEnum> updater) { return Update((DelegatingSupplier<TEnum, TEnum>)updater).NewValue; } [CLSCompliant(false)] public TEnum UpdateAndGet(IntPtr updater) { return Update((Supplier<TEnum, TEnum>)(long)updater).NewValue; } public TEnum GetAndUpdate([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0 })] Func<TEnum, TEnum> updater) { return Update((DelegatingSupplier<TEnum, TEnum>)updater).OldValue; } [CLSCompliant(false)] public TEnum GetAndUpdate(IntPtr updater) { return Update((Supplier<TEnum, TEnum>)(long)updater).OldValue; } [IsReadOnly] public bool Equals(TEnum other) { return EqualityComparer<TEnum>.Default.Equals(Value, other); } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(2)] public override bool Equals([NotNullWhen(true)] object other) { if (!(other is TEnum)) { if (!(other is AtomicEnum<TEnum>)) return false; return Equals(((AtomicEnum<TEnum>)other).Value); } TEnum other2 = (TEnum)other; return Equals(other2); } [IsReadOnly] public override int GetHashCode() { return Value.GetHashCode(); } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(1)] public override string ToString() { return Value.ToString(); } } }