public static int GetSetBits(UnsafeBitSet *set, UnsafeArray *array) { Assert.Check(UnsafeArray.GetTypeHandle(array) == typeof(int).TypeHandle.Value); if (UnsafeArray.Length(array) < set->_sizeBits) { throw new InvalidOperationException(SET_ARRAY_LESS_CAPACITY); } var setCount = 0; var bitOffset = 0; var arrayBuffer = (int *)UnsafeArray.GetBuffer(array); for (var i = 0; i < set->_sizeBuckets; ++i) { var word64 = set->_bits[i]; if (word64 == WORD_ZERO) { // since we're skipping whole word, step up offset bitOffset += WORD_SIZE_BITS; continue; } var word32Count = 0; NEXT_WORD32: var word32 = *((uint *)word64 + word32Count); if (word32 != 0) { var word16Count = 0; NEXT_WORD16: var word16 = *((ushort *)word32 + word16Count); if (word16 != 0) { var word8Count = 0; NEXT_WORD8: var word8 = *((byte *)word16 + word8Count); if (word8 != 0) { if ((word8 & (1 << 0)) == 1 << 0) { arrayBuffer[setCount++] = (bitOffset + 0); } if ((word8 & (1 << 1)) == 1 << 1) { arrayBuffer[setCount++] = (bitOffset + 1); } if ((word8 & (1 << 2)) == 1 << 2) { arrayBuffer[setCount++] = (bitOffset + 2); } if ((word8 & (1 << 3)) == 1 << 3) { arrayBuffer[setCount++] = (bitOffset + 3); } if ((word8 & (1 << 4)) == 1 << 4) { arrayBuffer[setCount++] = (bitOffset + 4); } if ((word8 & (1 << 5)) == 1 << 5) { arrayBuffer[setCount++] = (bitOffset + 5); } if ((word8 & (1 << 6)) == 1 << 6) { arrayBuffer[setCount++] = (bitOffset + 6); } if ((word8 & (1 << 7)) == 1 << 7) { arrayBuffer[setCount++] = (bitOffset + 7); } } // always step up bitoffset here bitOffset += (WORD_SIZE_BITS / 8); if (word8Count == 0) { ++word8Count; // go back goto NEXT_WORD8; } } else { bitOffset += (WORD_SIZE_BITS / 4); } if (word16Count == 0) { ++word16Count; // go back goto NEXT_WORD16; } } else { bitOffset += (WORD_SIZE_BITS / 2); } if (word32Count == 0) { ++word32Count; // go back goto NEXT_WORD32; } } return(setCount); }