public override Container INot(int firstOfRange, int lastOfRange)
{
// TODO: may need to convert to a RunContainer
// determine the span of array indices to be affected
int startIndex = Utility.UnsignedBinarySearch(Content, 0, Cardinality, (ushort)firstOfRange);
if (startIndex < 0)
{
startIndex = -startIndex - 1;
}
int lastIndex = Utility.UnsignedBinarySearch(Content, 0, Cardinality, (ushort)(lastOfRange - 1));
if (lastIndex < 0)
{
lastIndex = -lastIndex - 1 - 1;
}
int currentValuesInRange = lastIndex - startIndex + 1;
int spanToBeFlipped = lastOfRange - firstOfRange;
int newValuesInRange = spanToBeFlipped - currentValuesInRange;
ushort[] buffer = new ushort[newValuesInRange];
int cardinalityChange = newValuesInRange - currentValuesInRange;
int newCardinality = Cardinality + cardinalityChange;
if (cardinalityChange > 0)
{ // expansion, right shifting needed
if (newCardinality > Content.Length)
{
// so big we need a bitmap?
if (newCardinality > DEFAULT_MAX_SIZE)
{
return ToBitsetContainer().INot(firstOfRange, lastOfRange);
}
// Change the size of the array based on the new cardinality
Array.Resize(ref Content, newCardinality);
}
// slide right the contents after the range
Array.Copy(Content,
lastIndex + 1, Content,
lastIndex + 1 + cardinalityChange,
Cardinality - 1 - lastIndex);
NegateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange);
}
else
{ // no expansion needed
NegateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange);
if (cardinalityChange < 0)
{
// contraction, left sliding.
// Leave array oversize
Array.Copy(Content, startIndex + newValuesInRange - cardinalityChange,
Content, startIndex + newValuesInRange,
newCardinality - (startIndex + newValuesInRange));
}
}
Cardinality = newCardinality;
return this;
}