AtomicEnum<TEnum>
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();
}
}
}