/// <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);
}