NumericExtensions.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. // ReSharper disable once CheckNamespace
  2. namespace Terminal.Gui.Analyzers.Internal.Compatibility;
  3. /// <summary>
  4. /// Extension methods for <see langword="int"/> and <see langword="uint"/> types.
  5. /// </summary>
  6. /// <remarks>
  7. /// This is mostly just for backward compatibility with netstandard2.0.
  8. /// </remarks>
  9. public static class NumericExtensions
  10. {
  11. /// <summary>
  12. /// Gets the population count (number of bits set to 1) of this 32-bit value.
  13. /// </summary>
  14. /// <param name="value">The value to get the population count of.</param>
  15. /// <remarks>
  16. /// The algorithm is the well-known SWAR (SIMD Within A Register) method for population count.<br/>
  17. /// Included for hardware- and runtime- agnostic support for the equivalent of the x86 popcnt instruction, since
  18. /// System.Numerics.Intrinsics isn't available in netstandard2.0.<br/>
  19. /// It performs the operation simultaneously on 4 bytes at a time, rather than the naive method of testing all 32 bits
  20. /// individually.<br/>
  21. /// Most compilers can recognize this and turn it into a single platform-specific instruction, when available.
  22. /// </remarks>
  23. /// <returns>
  24. /// An unsigned 32-bit integer value containing the population count of <paramref name="value"/>.
  25. /// </returns>
  26. [MethodImpl (MethodImplOptions.AggressiveInlining)]
  27. public static uint GetPopCount (this uint value)
  28. {
  29. unchecked
  30. {
  31. value -= (value >> 1) & 0x55555555;
  32. value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
  33. value = (value + (value >> 4)) & 0x0F0F0F0F;
  34. return (value * 0x01010101) >> 24;
  35. }
  36. }
  37. /// <inheritdoc cref="GetPopCount(uint)"/>
  38. [MethodImpl (MethodImplOptions.AggressiveInlining)]
  39. public static uint GetPopCount (this int value) { return GetPopCount (Unsafe.As<int, uint> (ref value)); }
  40. }