/// <summary> /// Returns a new bit set composed of bits from this bit set /// from the specified <b>from</b> index (inclusive) to the /// <b>to</b> index (exclusive). /// </summary> /// <param name="from"> /// The index of the first bit to include. /// </param> /// <param name="to"> /// The index after the last bit to include. /// </param> /// <returns> /// A new <see cref="CyrusBuilt.MonoPi.BitSet"/> instance /// composed of the specified range of bits from this instance. /// </returns> /// <exception cref="IndexOutOfRangeException"> /// <paramref name="from"/> is less than zero - or - /// <paramref name="to"/> is less than zero - or - /// <paramref name="from"/> is greater than <paramref name="to"/>. /// </exception> public BitSet Get(Int32 from, Int32 to) { CheckRange(from, to); this.CheckInvariants(); // If no set bits in range, the return empty BitSet. Int32 len = this.Length; if ((len <= from) || (from == to)) { return new BitSet(0); } // Optimize. if (to > len) { to = len; } BitSet bs = new BitSet(to - from); Int32 targetWords = WordIndex(to - from - 1) + 1; Int32 sourceIndex = WordIndex(from); Boolean aligned = ((from & BIT_INDEX_MASK) == 0); // Process all words but the last one. for (Int32 i = 0; i < targetWords - 1; i++, sourceIndex++) { bs._bits[i] = aligned ? this._bits[sourceIndex] : (this._bits[sourceIndex] >> from) | (this._bits[sourceIndex + 1] << -from); } // Process the last word. long lastWordMask = LONG_MASK >> -to; bs._bits[targetWords - 1] = ((to - 1) & BIT_INDEX_MASK) < (from & BIT_INDEX_MASK) ? ((this._bits[sourceIndex] >> from) | (this._bits[sourceIndex + 1] & lastWordMask) << -from) : ((this._bits[sourceIndex] & lastWordMask) >> from); bs._wordsInUse = targetWords; bs.RecalculateWordsInUse(); bs.CheckInvariants(); return bs; }
/// <summary> /// Returns true if the specified bit set has any bits set /// to true that are also set to true in this bit set. /// </summary> /// <param name="bs"> /// The bit set to intersect with. /// </param> /// <returns> /// true if this instance intersects with the specified /// <see cref="CyrusBuilt.MonoPi.BitSet"/>. /// </returns> public Boolean Intersects(BitSet bs) { Boolean goodBits = false; Int32 i = Math.Min(this._bits.Length, bs._bits.Length); while (--i >= 0) { if ((this._bits[i] & bs._bits[i]) != 0) { goodBits = true; break; } } return goodBits; }
/// <summary> /// Performs a logical <b>XOR</b> of this bit set with the specified /// bit set. This bit set is modified so that a bit in it has the /// value <code>true</code> if and only if one of the following /// statements holds true:<br/> /// - The bit initially has the value <code>true</code>, and the /// corresponding bit in the specified bit set has the value /// <code>false</code>.<br/><br/> /// - Thi bit initially has the value <code>false</code>, and the /// corresponding bit in the specified bit set has the value /// <code>true</code>. /// </summary> /// <param name="bs"> /// A bit set. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="bs"/> cannot be null. /// </exception> public void XOr(BitSet bs) { if (bs == null) { throw new ArgumentNullException("bs"); } // Calculate how many words with have in common with the other bit set. Int32 wordsInCommon = Math.Min(this._wordsInUse, bs._wordsInUse); if (this._wordsInUse < bs._wordsInUse) { this.EnsureCapacity(bs._wordsInUse); this._wordsInUse = bs._wordsInUse; } // Perform logical XOR on words in common. for (Int32 i = 0; i < wordsInCommon; i++) { this._bits[i] ^= bs._bits[i]; } // Copy any remaining words. if (wordsInCommon < bs._wordsInUse) { Array.Copy(bs._bits, wordsInCommon, this._bits, wordsInCommon, bs._wordsInUse - wordsInCommon); } this.RecalculateWordsInUse(); this.CheckInvariants(); }
/// <summary> /// Performs a logical <b>OR</b> of this bit set with the specified /// bit set. This bit set is modified so that a bit in it has the /// value <code>true</code> if and only if either it already had /// the value <code>true</code> or the corresponding bit in the /// specified bit set has the value <code>true</code>. /// </summary> /// <param name="bs"> /// A bit set. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="bs"/> cannot be null. /// </exception> public void Or(BitSet bs) { if (bs == null) { throw new ArgumentNullException("bs"); } if (this == bs) { return; } Int32 wordsInCommon = Math.Min(this._wordsInUse, bs._wordsInUse); if (this._wordsInUse < bs._wordsInUse) { this.EnsureCapacity(bs._wordsInUse); this._wordsInUse = bs._wordsInUse; } for (Int32 i = 0; i < wordsInCommon; i++) { this._bits[i] |= bs._bits[i]; } if (wordsInCommon < bs._wordsInUse) { Array.Copy(bs._bits, wordsInCommon, this._bits, wordsInCommon, this._wordsInUse - wordsInCommon); } this.CheckInvariants(); }
/// <summary> /// Clears all of the bits in this bit set whose corresponding /// bit is set in the specified bit set. /// </summary> /// <param name="bs"> /// The bit set with which to mask this instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="bs"/> cannot be null. /// </exception> public void AndNot(BitSet bs) { if (bs == null) { throw new ArgumentNullException("bs"); } Int32 i = Math.Min(this._bits.Length, bs._bits.Length); while (--i >= 0) { this._bits[i] &= ~bs._bits[i]; } this.RecalculateWordsInUse(); this.CheckInvariants(); }
/// <summary> /// Performs a logical <b>AND</b> of this target bit set with the /// argument bit set. This bit set is modified so that each bit in /// it has the value <code>true</code> if and only if it both /// initially had the value <code>true</code> and the corresponding /// bit in the specified bit set also had the value <code>true</code>. /// </summary> /// <param name="bs"> /// A bit set. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="bs"/> cannot be null. /// </exception> public void And(BitSet bs) { if (bs == null) { throw new ArgumentNullException("bs"); } if (this == bs) { return; } while (this._wordsInUse > bs._wordsInUse) { this._bits[--this._wordsInUse] = 0; } for (Int32 i = 0; i < this._wordsInUse; i++) { this._bits[i] &= bs._bits[i]; } this.RecalculateWordsInUse(); this.CheckInvariants(); }
/// <summary> /// This method is used by EnumSet for efficiency. It checks /// to see if this instance contains all the same bits /// as the specified bit set. /// </summary> /// <param name="other"> /// The bit set to check. /// </param> /// <returns> /// true if the specified bit set contains all the same bits; /// Otherwise, false. /// </returns> public Boolean ContainsAll(BitSet other) { if (other == null) { return false; } Boolean result = true; for (Int32 i = 0; i < other._bits.Length; i++) { if ((this._bits[i] & other._bits[i]) != other._bits[i]) { result = false; break; } } return result; }