| File: System\Text\Json\Serialization\ValueBitArray.cs | Web Access |
| Project: src\runtime\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; namespace System.Text.Json.Serialization { internal readonly ref struct ValueBitArray { public const int ScratchBufferSize = 4; private readonly int _bitCount; private readonly Span<ulong> _buffer; public readonly bool IsEmpty { get { bool isEmpty = true; foreach (ulong word in _buffer) { isEmpty &= word is 0; } return isEmpty; } } public bool this[int index] { readonly get { Debug.Assert((uint)index < (uint)_bitCount); ulong mask = 1UL << (index % (sizeof(ulong) * 8)); return (_buffer[index / (sizeof(ulong) * 8)] & mask) is not 0; } set { Debug.Assert((uint)index < (uint)_bitCount); ulong mask = 1UL << (index % (sizeof(ulong) * 8)); ref ulong word = ref _buffer[index / (sizeof(ulong) * 8)]; word = value ? word | mask : word & ~mask; } } /// <summary>Initializes a bit array using the supplied scratch buffer when possible.</summary> /// <param name="bitCount">The number of addressable bits.</param> /// <param name="stackBuffer"> /// A scratch buffer whose length must equal <see cref="ScratchBufferSize"/>. /// </param> /// <param name="initialWordValue">The initial value assigned to each backing word.</param> public ValueBitArray( int bitCount, Span<ulong> stackBuffer, ulong initialWordValue = 0) { Debug.Assert(bitCount >= 0); Debug.Assert(stackBuffer.Length == ScratchBufferSize); _bitCount = bitCount; int requiredUInt64Count = bitCount is 0 ? 0 : ((bitCount - 1) / (sizeof(ulong) * 8)) + 1; _buffer = requiredUInt64Count <= stackBuffer.Length ? stackBuffer.Slice(0, requiredUInt64Count) : new ulong[requiredUInt64Count]; _buffer.Fill(initialWordValue); } public void Clear() => _buffer.Clear(); public void IntersectWith(scoped ValueBitArray other) { Debug.Assert(_bitCount == other._bitCount); if (_buffer.Length is 1) { _buffer[0] &= other._buffer[0]; return; } for (int i = 0; i < _buffer.Length; i++) { _buffer[i] &= other._buffer[i]; } } } }