/*
* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Utils
* File: BitField.cs
*
* BitField.cs is part of VNLib.Utils which is part of the larger
* VNLib collection of libraries and utilities.
*
* VNLib.Utils is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 2 of the License,
* or (at your option) any later version.
*
* VNLib.Utils is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/.
*/
using System.Runtime.CompilerServices;
namespace VNLib.Utils
{
///
/// Represents a field of 64 bits that can be set or cleared using unsigned or signed masks
///
public class BitField
{
private ulong Field;
///
/// The readonly value of the
///
public ulong Value => Field;
///
/// Creates a new initialized to the specified value
///
/// Initial value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitField(ulong initial) => Field = initial;
///
/// Creates a new initialized to the specified value
///
/// Initial value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BitField(long initial) => Field = unchecked((ulong)initial);
///
/// Determines if the specified flag is set
///
/// The mask to compare against the field value
/// True if the flag(s) is currently set, false if flag is not set
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsSet(ulong mask) => (Field & mask) != 0;
///
/// Determines if the specified flag is set
///
/// The mask to compare against the field value
/// True if the flag(s) is currently set, false if flag is not set
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsSet(long mask) => (Field & unchecked((ulong)mask)) != 0;
///
/// Determines if the specified flag is set
///
/// The mask to compare against the field value
/// True if the flag(s) is currently set, false if flag is not set
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(ulong mask) => Field |= mask;
///
/// Determines if the specified flag is set
///
/// The mask to compare against the field value
/// True if the flag(s) is currently set, false if flag is not set
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(long mask) => Field |= unchecked((ulong)mask);
///
/// Sets or clears a flag(s) indentified by a mask based on the value
///
/// Mask used to identify flags
/// True to set a flag, false to clear a flag
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Set(ulong mask, bool value)
{
if (value)
{
Set(mask);
}
else
{
Clear(mask);
}
}
///
/// Clears the flag identified by the specified mask
///
/// The mask used to clear the given flag
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear(ulong mask) => Field &= ~mask;
///
/// Clears the flag identified by the specified mask
///
/// The mask used to clear the given flag
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear(long mask) => Field &= ~unchecked((ulong)mask);
///
/// Clears all flags by setting the property value to 0
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ClearAll() => Field = 0;
}
}