public void Interesection() { var mo = new InversionListCodePointSet('m','o'); var ao = new InversionListCodePointSet('a','o'); var mx = new InversionListCodePointSet('m','z'); Assert.AreEqual(mo, ao.Intersect(mx)); }
public void Union() { var eg = new InversionListCodePointSet('e','g'); var xz = new InversionListCodePointSet('x','z'); var fhxz = new InversionListCodePointSet('f','h').Union(xz); var ehxz = new InversionListCodePointSet('e','h').Union(xz); Assert.AreEqual(ehxz, eg.Union(fhxz)); }
public void Identities() { var a = new InversionListCodePointSet('a'); var b = new InversionListCodePointSet('b'); var x = new InversionListCodePointSet('x'); Assert.AreEqual(a.Union(b).Complement(), a.Complement().Intersect(b.Complement()), "!(a|b) == !a & !b"); Assert.AreEqual(a.Union(x).Complement(), a.Complement().Intersect(x.Complement()), "!(a|x) == !a & !x"); }
public bool Equals(InversionListCodePointSet other) { if (ranges.Length != other.ranges.Length) { return(false); } for (var i = 0; i < ranges.Length; i++) { if (ranges[i] != other.ranges[i]) { return(false); } } return(true); }
public InversionListCodePointSet Intersect(InversionListCodePointSet value) { var a = ranges; var b = value.ranges; var tempResult = new CodePoint[a.Length + b.Length]; var posA = 0; var posB = 0; var posResult = 0; var count = 0; // go through the two sets as though you're merging them while (posA < a.Length && posB < b.Length) { CodePoint c; int pos; // if the lower entry is in the first array, or if the // entries are equal and this one's the end of a range, // consider the entry from the first array next if (a[posA] < b[posB] || (a[posA] == b[posB] && (posA & 1) == 1)) { pos = posA; c = a[posA++]; } // otherwise, consider the entry from the second array next else { pos = posB; c = b[posB++]; } // if the entry is the start of a range (i.e., an even-numbered // entry), increment the running count. If the count goes to two // after incrementing then write the entry to the result set, // because both sets contain this. if ((pos & 1) == 0) { ++count; if (count == 2) { tempResult[posResult++] = c; } } // if the entry is the end of a range (i.e., an odd-numbered // entry), decrement the running count. If the count is two // before decrementing, also write the entry to the result set, // because only one set contains this range now else { if (count == 2) { tempResult[posResult++] = c; } --count; } } // figure out how big the result should really be var length = posResult; // if we stopped in the middle of a range, increment the count // before figuring out whether there are extra entries to write if ((posA != a.Length && (posA & 1) == 0) || (posB != b.Length && (posB & 1) == 0)) { ++count; } // if, after the adjustment, the count is 0, then all // entries from the set we haven't exhausted also go into // the result if (count == 2) { length += (a.Length - posA) + (b.Length - posB); } // copy the results into the actual result array (they may // include the excess from the array we hadn't finished // examining) var result = new CodePoint[length]; Array.Copy(tempResult, 0, result, 0, posResult); if (count == 2) { // only one of these two calls will do anything Array.Copy(a, posA, result, posResult, a.Length - posA); Array.Copy(b, posB, result, posResult, b.Length - posB); } return(new InversionListCodePointSet(result)); }
public bool Equals(InversionListCodePointSet other) { if(ranges.Length != other.ranges.Length) return false; for(var i = 0; i < ranges.Length; i++) if(ranges[i] != other.ranges[i]) return false; return true; }
public InversionListCodePointSet Union(InversionListCodePointSet value) { var a = ranges; var b = value.ranges; var tempResult = new CodePoint[a.Length + b.Length]; var posA = 0; var posB = 0; var posResult = 0; var count = 0; // go through the two sets as though you're merging them while(posA < a.Length && posB < b.Length) { CodePoint c; int pos; // if the lower entry is in the first array, or if the // entries are equal and this one's the start of a range, // consider the entry from the first array next if(a[posA] < b[posB] || (a[posA] == b[posB] && (posA & 1) == 0)) { pos = posA; c = a[posA++]; } // otherwise, consider the entry from the second array next else { pos = posB; c = b[posB++]; } // if the entry is the start of a range (i.e., an even-numbered // entry), increment the running count. If the count was zero // before incrementing, also write the entry to the result // set becuase we are starting an included range. if((pos & 1) == 0) { if(count == 0) tempResult[posResult++] = c; ++count; } // if the entry is the end of a range (i.e., an odd-numbered // entry), decrement the running count. If this makes the // count zero, also write the entry to the result set becuase we // are ending the range else { --count; if(count == 0) tempResult[posResult++] = c; } } // figure out how big the result should really be var length = posResult; // if we stopped in the middle of a range, decrement the count // before figuring out whether there are extra entries to write if((posA != a.Length && (posA & 1) == 1) || (posB != b.Length && (posB & 1) == 1)) --count; // if, after the adjustment, the count is 0, then all // entries from the set we haven't exhausted also go into // the result if(count == 0) length += (a.Length - posA) + (b.Length - posB); // copy the results into the actual result array (they may // include the excess from the array we hadn't finished // examining) var result = new CodePoint[length]; Array.Copy(tempResult, 0, result, 0, posResult); if(count == 0) { // only one of these two calls will do anything Array.Copy(a, posA, result, posResult, a.Length - posA); Array.Copy(b, posB, result, posResult, b.Length - posB); } return new InversionListCodePointSet(result); }