BitMap.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. namespace ARMeilleure.Common
  4. {
  5. class BitMap : IEnumerable<int>
  6. {
  7. private const int IntSize = 32;
  8. private const int IntMask = IntSize - 1;
  9. private List<int> _masks;
  10. public BitMap(int initialCapacity)
  11. {
  12. int count = (initialCapacity + IntMask) / IntSize;
  13. _masks = new List<int>(count);
  14. while (count-- > 0)
  15. {
  16. _masks.Add(0);
  17. }
  18. }
  19. public bool Set(int bit)
  20. {
  21. EnsureCapacity(bit + 1);
  22. int wordIndex = bit / IntSize;
  23. int wordBit = bit & IntMask;
  24. int wordMask = 1 << wordBit;
  25. if ((_masks[wordIndex] & wordMask) != 0)
  26. {
  27. return false;
  28. }
  29. _masks[wordIndex] |= wordMask;
  30. return true;
  31. }
  32. public void Clear(int bit)
  33. {
  34. EnsureCapacity(bit + 1);
  35. int wordIndex = bit / IntSize;
  36. int wordBit = bit & IntMask;
  37. int wordMask = 1 << wordBit;
  38. _masks[wordIndex] &= ~wordMask;
  39. }
  40. public bool IsSet(int bit)
  41. {
  42. EnsureCapacity(bit + 1);
  43. int wordIndex = bit / IntSize;
  44. int wordBit = bit & IntMask;
  45. return (_masks[wordIndex] & (1 << wordBit)) != 0;
  46. }
  47. public bool Set(BitMap map)
  48. {
  49. EnsureCapacity(map._masks.Count * IntSize);
  50. bool modified = false;
  51. for (int index = 0; index < _masks.Count; index++)
  52. {
  53. int newValue = _masks[index] | map._masks[index];
  54. if (_masks[index] != newValue)
  55. {
  56. _masks[index] = newValue;
  57. modified = true;
  58. }
  59. }
  60. return modified;
  61. }
  62. public bool Clear(BitMap map)
  63. {
  64. EnsureCapacity(map._masks.Count * IntSize);
  65. bool modified = false;
  66. for (int index = 0; index < _masks.Count; index++)
  67. {
  68. int newValue = _masks[index] & ~map._masks[index];
  69. if (_masks[index] != newValue)
  70. {
  71. _masks[index] = newValue;
  72. modified = true;
  73. }
  74. }
  75. return modified;
  76. }
  77. private void EnsureCapacity(int size)
  78. {
  79. while (_masks.Count * IntSize < size)
  80. {
  81. _masks.Add(0);
  82. }
  83. }
  84. public IEnumerator<int> GetEnumerator()
  85. {
  86. for (int index = 0; index < _masks.Count; index++)
  87. {
  88. int mask = _masks[index];
  89. while (mask != 0)
  90. {
  91. int bit = BitUtils.LowestBitSet(mask);
  92. mask &= ~(1 << bit);
  93. yield return index * IntSize + bit;
  94. }
  95. }
  96. }
  97. IEnumerator IEnumerable.GetEnumerator()
  98. {
  99. return GetEnumerator();
  100. }
  101. }
  102. }