using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
{
// Validate the length
Debug.Assert(boundedLength >= 2, $"Must be >= 2, got {boundedLength}");
- Debug.Assert((boundedLength & (boundedLength - 1)) == 0, $"Must be a power of 2, got {boundedLength}");
+ Debug.Assert(BitOperations.IsPow2(boundedLength), $"Must be a power of 2, got {boundedLength}");
// Initialize the slots and the mask. The mask is used as a way of quickly doing "% _slots.Length",
// instead letting us do "& _slotsMask".
public void AddKeyword(string name, ulong value)
{
- if ((value & (value - 1)) != 0) // Is it a power of 2?
+ if ((value & (value - 1)) != 0) // Must be zero or a power of 2
{
- ManifestError(SR.Format(SR.EventSource_KeywordNeedPowerOfTwo, "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
+ ManifestError(SR.Format(SR.EventSource_KeywordNeedPowerOfTwo, $"0x{value:x}", name), true);
}
if ((flags & EventManifestOptions.Strict) != 0)
{
if (value >= 0x0000100000000000UL && !name.StartsWith("Session", StringComparison.Ordinal))
{
- ManifestError(SR.Format(SR.EventSource_IllegalKeywordsValue, name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ ManifestError(SR.Format(SR.EventSource_IllegalKeywordsValue, name, $"0x{value:x}"));
}
if (keywordTab != null && keywordTab.TryGetValue(value, out string? prevName) && !name.Equals(prevName, StringComparison.Ordinal))
{
- ManifestError(SR.Format(SR.EventSource_KeywordCollision, name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ ManifestError(SR.Format(SR.EventSource_KeywordCollision, name, prevName, $"0x{value:x}"));
}
}
// ETW requires all bitmap values to be powers of 2. Skip the ones that are not.
// TODO: Warn people about the dropping of values.
- if (isbitmap && ((hexValue & (hexValue - 1)) != 0 || hexValue == 0))
+ if (isbitmap && !BitOperations.IsPow2(hexValue))
continue;
hexValue.TryFormat(ulongHexScratch, out int charsWritten, "x");
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.Runtime.CompilerServices;
+using System.Numerics;
using System.Threading;
namespace System.Runtime.CompilerServices
c.CreateEntryNoResize(key, value);
}
- private static bool IsPowerOfTwo(int value) => (value > 0) && ((value & (value - 1)) == 0);
-
//--------------------------------------------------------------------------------------------
// Entry can be in one of four states:
//
internal Container(ConditionalWeakTable<TKey, TValue> parent)
{
Debug.Assert(parent != null);
- Debug.Assert(IsPowerOfTwo(InitialCapacity));
+ Debug.Assert(BitOperations.IsPow2(InitialCapacity));
const int Size = InitialCapacity;
_buckets = new int[Size];
Debug.Assert(buckets != null);
Debug.Assert(entries != null);
Debug.Assert(buckets.Length == entries.Length);
- Debug.Assert(IsPowerOfTwo(buckets.Length));
+ Debug.Assert(BitOperations.IsPow2(buckets.Length));
_parent = parent;
_buckets = buckets;
internal Container Resize(int newSize)
{
Debug.Assert(newSize >= _buckets.Length);
- Debug.Assert(IsPowerOfTwo(newSize));
+ Debug.Assert(BitOperations.IsPow2(newSize));
// Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
// This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
using System.Threading;
using Debug = System.Diagnostics.Debug;
using Interlocked = System.Threading.Interlocked;
/// </summary>
public XHashtableState(ExtractKeyDelegate extractKey, int capacity)
{
- Debug.Assert((capacity & (capacity - 1)) == 0, "capacity must be a power of 2");
+ Debug.Assert(BitOperations.IsPow2(capacity), "capacity must be a power of 2");
Debug.Assert(extractKey != null, "extractKey may not be null");
// Initialize hash table data structures, with specified maximum capacity
<Compile Include="System\Xml\BinHexDecoder.cs" />
<Compile Include="System\Xml\BinHexEncoder.cs" />
<Compile Include="System\Xml\BinHexEncoderAsync.cs" />
- <Compile Include="System\Xml\Bits.cs" />
<Compile Include="System\Xml\BitStack.cs" />
<Compile Include="System\Xml\ByteStack.cs" />
<Compile Include="System\Xml\Core\HtmlEncodedRawTextWriter.cs">
+++ /dev/null
-// 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.Xml
-{
- /// <summary>
- /// Contains static utility methods used to manipulate bits in a word.
- /// </summary>
- internal static class Bits
- {
- private const uint MASK_0101010101010101 = 0x55555555;
- private const uint MASK_0011001100110011 = 0x33333333;
- private const uint MASK_0000111100001111 = 0x0f0f0f0f;
- private const uint MASK_0000000011111111 = 0x00ff00ff;
- private const uint MASK_1111111111111111 = 0x0000ffff;
-
- /// <summary>
- /// Returns the number of 1 bits in an unsigned integer. Counts bits by divide-and-conquer method,
- /// first computing 16 2-bit counts, then 8 4-bit counts, then 4 8-bit counts, then 2 16-bit counts,
- /// and finally 1 32-bit count.
- /// </summary>
- public static int Count(uint num)
- {
- num = (num & MASK_0101010101010101) + ((num >> 1) & MASK_0101010101010101);
- num = (num & MASK_0011001100110011) + ((num >> 2) & MASK_0011001100110011);
- num = (num & MASK_0000111100001111) + ((num >> 4) & MASK_0000111100001111);
- num = (num & MASK_0000000011111111) + ((num >> 8) & MASK_0000000011111111);
- num = (num & MASK_1111111111111111) + (num >> 16);
-
- return (int)num;
- }
-
- /// <summary>
- /// Returns true if the unsigned integer has exactly one bit set.
- /// </summary>
- public static bool ExactlyOne(uint num)
- {
- return num != 0 && (num & (num - 1)) == 0;
- }
-
- /// <summary>
- /// Clear the least significant bit that is set and return the result.
- /// </summary>
- public static uint ClearLeast(uint num)
- {
- return num & (num - 1);
- }
-
- /// <summary>
- /// Compute the 1-based position of the least significant bit that is set, and return it (return 0 if no bits are set).
- /// (e.g. 0x1001100 will return 3, since the 3rd bit is set).
- /// </summary>
- public static int LeastPosition(uint num)
- {
- if (num == 0) return 0;
- return Count(num ^ (num - 1));
- }
- }
-}
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Xml;
using System.Diagnostics;
+using System.Numerics;
using System.Text;
+using System.Xml;
namespace System.Xml.Schema
{
/// </summary>
public XsdDateTime(DateTime dateTime, XsdDateTimeFlags kinds)
{
- Debug.Assert(Bits.ExactlyOne((uint)kinds), "Only one DateTime type code can be set.");
+ Debug.Assert(BitOperations.IsPow2((uint)kinds), "One and only one DateTime type code can be set.");
_dt = dateTime;
- DateTimeTypeCode code = (DateTimeTypeCode)(Bits.LeastPosition((uint)kinds) - 1);
+ DateTimeTypeCode code = (DateTimeTypeCode)BitOperations.TrailingZeroCount((uint)kinds);
int zoneHour = 0;
int zoneMinute = 0;
XsdDateTimeKind kind;
public XsdDateTime(DateTimeOffset dateTimeOffset, XsdDateTimeFlags kinds)
{
- Debug.Assert(Bits.ExactlyOne((uint)kinds), "Only one DateTime type code can be set.");
+ Debug.Assert(BitOperations.IsPow2((uint)kinds), "Only one DateTime type code can be set.");
_dt = dateTimeOffset.DateTime;
TimeSpan zoneOffset = dateTimeOffset.Offset;
- DateTimeTypeCode code = (DateTimeTypeCode)(Bits.LeastPosition((uint)kinds) - 1);
+ DateTimeTypeCode code = (DateTimeTypeCode)BitOperations.TrailingZeroCount((uint)kinds);
XsdDateTimeKind kind;
if (zoneOffset.TotalMinutes < 0)
{
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Xml;
-using System.Xml.XPath;
-using System.Xml.Schema;
-using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;
-using System.Diagnostics.CodeAnalysis;
using TypeFactory = System.Xml.Xsl.XmlQueryTypeFactory;
namespace System.Xml.Xsl.IlGen
kinds = typDerived.NodeKinds & kinds;
// Attempt to allow or disallow exactly one kind
- if (!Bits.ExactlyOne((uint)kinds))
+ if (!BitOperations.IsPow2((uint)kinds))
{
// Not possible to allow one kind, so try to disallow one kind
kinds = ~kinds & XmlNodeKindFlags.Any;
using System.Diagnostics;
using System.Globalization;
using System.IO;
+using System.Numerics;
using System.Xml.Schema;
using System.Xml.XPath;
using TF = System.Xml.Xsl.XmlQueryTypeFactory;
public static XmlQueryType Create(XmlNodeKindFlags nodeKinds)
{
List<XmlQueryType> members;
+ uint kinds = (uint)nodeKinds;
// If exactly one kind is set, then create singleton ItemType
- if (Bits.ExactlyOne((uint)nodeKinds))
- return ItemType.Create(s_nodeKindToTypeCode[Bits.LeastPosition((uint)nodeKinds)], false);
+ if (BitOperations.IsPow2(kinds))
+ {
+ return ItemType.Create(s_nodeKindToTypeCode[BitOperations.TrailingZeroCount(kinds) + 1], false);
+ }
members = new List<XmlQueryType>();
- while (nodeKinds != XmlNodeKindFlags.None)
+ while (kinds != 0)
{
- members.Add(ItemType.Create(s_nodeKindToTypeCode[Bits.LeastPosition((uint)nodeKinds)], false));
+ members.Add(ItemType.Create(s_nodeKindToTypeCode[BitOperations.TrailingZeroCount(kinds) + 1], false));
- nodeKinds = (XmlNodeKindFlags)Bits.ClearLeast((uint)nodeKinds);
+ kinds &= kinds - 1;
}
return Create(members);
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
using QilName = System.Xml.Xsl.Qil.QilName;
namespace System.Xml.Xsl.Xslt
private void AddRecord(ScopeFlags flag, string? ncName, string? uri, [AllowNull] V value)
{
- Debug.Assert(flag == (flag & ScopeFlags.ExclusiveFlags) && (flag & (flag - 1)) == 0 && flag != 0, "One exclusive flag");
+ Debug.Assert(flag == (flag & ScopeFlags.ExclusiveFlags) && BitOperations.IsPow2((uint)flag), "One exclusive flag");
Debug.Assert(uri != null || ncName == null, "null, null means exclude '#all'");
ScopeFlags flags = _records[_lastRecord].flags;
private void SetFlag(ScopeFlags flag, bool value)
{
- Debug.Assert(flag == (flag & ScopeFlags.InheritedFlags) && (flag & (flag - 1)) == 0 && flag != 0, "one inherited flag");
+ Debug.Assert(flag == (flag & ScopeFlags.InheritedFlags) && BitOperations.IsPow2((uint)flag), "one inherited flag");
ScopeFlags flags = _records[_lastRecord].flags;
if (((flags & flag) != 0) != value)
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.XPath;
using T = System.Xml.Xsl.XmlQueryTypeFactory;
}
XmlNodeKindFlags nodeKinds = isType.Right.XmlType!.NodeKinds;
- if (!Bits.ExactlyOne((uint)nodeKinds))
+ if (!BitOperations.IsPow2((uint)nodeKinds))
{
return;
}
internal delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);
}
+namespace System.Numerics
+{
+ internal static class BitOperations
+ {
+ public static bool IsPow2(int value) => (value & (value - 1)) == 0 && value > 0;
+ }
+}
+
namespace System.Threading
{
internal static class InterlockedExtensions
using System.Collections.Generic;
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Threading;
public static bool DifferByOneBit(char a, char b, out int mask)
{
mask = a ^ b;
- return mask != 0 && (mask & (mask - 1)) == 0;
+ return BitOperations.IsPow2(mask);
}
/// <summary>Determines a character's membership in a character class (via the string representation of the class).</summary>