Ejemplo n.º 1
0
        internal static IEnumerable <Range <T> > NormalizeFromSorted <T>(this IEnumerable <Range <T> > that)  // Items MUST be sorted by `From` property
            where T : IComparable <T>
        {
            using (var enumerator = that.GetEnumerator()) {
                if (enumerator.MoveNext())
                {
                    var range = enumerator.Current;
                    var from  = range.From;
                    var to    = range.To;
                    while ((to.CompareTo(Incrementor <T> .MaxValue) < 0) && enumerator.MoveNext())
                    {
                        range = enumerator.Current;
                        if (range.From.CompareTo(Incrementor <T> .Increment(to)) > 0)
                        {
                            yield return(new Range <T>(@from, to));

                            @from = range.From;
                            to    = range.To;
                        }
                        else if (range.To.CompareTo(to) > 0)
                        {
                            to = range.To;
                        }
                    }
                    yield return(new Range <T>(@from, to));
                }
            }
        }
 private static void Check(Incrementor inc, ref long rollingKey, byte nb, long mask)
 {
     if (nb == 255)
     {
         return;
     }
     rollingKey = ((rollingKey & mask) << 2) | nb;
     inc.Increment(rollingKey);
 }
 private static bool IsAdjacent(IReadOnlyList <KeyValuePair <Range <TLetter>, LetterId> > ranges, int left, int right)
 {
     Debug.Assert((Math.Max(left, right) >= 0) && (Math.Min(left, right) < ranges.Count) && ((left + 1) == right));
     if (left < 0)
     {
         return(ranges[right].Key.From.Equals(Incrementor <TLetter> .MinValue));
     }
     if (right >= ranges.Count)
     {
         return(ranges[left].Key.To.Equals(Incrementor <TLetter> .MaxValue));
     }
     return(Incrementor <TLetter> .Increment(ranges[left].Key.To).Equals(ranges[right].Key.From));
 }
Ejemplo n.º 4
0
        public int Count()
        {
            if (typeof(IConvertible).IsAssignableFrom(typeof(T)))
            {
                return((int)(((IConvertible)this.To).ToInt64(CultureInfo.InvariantCulture) - ((IConvertible)this.From).ToInt64(CultureInfo.InvariantCulture)) + 1);
            }
            var result  = 1;
            var current = this.From;

            while (current.CompareTo(this.To) < 0)
            {
                result++;
                current = Incrementor <T> .Increment(current);
            }
            return(result);
        }
        private static UsedRangeList <TLetter> MakeRanges(IDictionary <Id <RxMatch <TLetter> >, KeyValuePair <RangeSet <TLetter>, ICollection <LetterId> > > charsets, RangeSet <TLetter> validRanges)
        {
            var ranges = new UsedRangeList <TLetter>();

            foreach (var validRange in validRanges)
            {
                ranges.Add(new UsedLetterRange <TLetter>(validRange, null));
            }
            foreach (var pair in charsets)
            {
                foreach (var charRange in pair.Value.Key)
                {
                    // split left if necessary
                    var left = RangeOperations <TLetter> .BinarySearch(ranges, charRange.From);

                    var leftRange = ranges[left];
                    if (leftRange.From.CompareTo(charRange.From) < 0)
                    {
                        ranges.Insert(left++, new UsedLetterRange <TLetter>(leftRange.From, Incrementor <TLetter> .Decrement(charRange.From), leftRange.Users));
                        ranges[left] = new UsedLetterRange <TLetter>(charRange.From, leftRange.To, leftRange.Users);
                    }
                    // split right if necessary
                    var right = RangeOperations <TLetter> .BinarySearch(ranges, charRange.To);

                    var rightRange = ranges[right];
                    if (rightRange.To.CompareTo(charRange.To) > 0)
                    {
                        ranges[right] = new UsedLetterRange <TLetter>(rightRange.From, charRange.To, rightRange.Users);
                        ranges.Insert(right + 1, new UsedLetterRange <TLetter>(Incrementor <TLetter> .Increment(charRange.To), rightRange.To, rightRange.Users));
                    }
                    // add user information
                    for (var i = left; i <= right; i++)
                    {
                        ranges[i] = ranges[i].AddUser(pair.Key);
                    }
                }
            }
            return(ranges);
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     Enumerates all ranges of left and right combined, and call the <paramref name="process" /> callback for each range,
        ///     passing the index into the origin left and/or right range set.
        /// </summary>
        /// <typeparam name="TRangeSetLeft">Type of the left range set.</typeparam>
        /// <typeparam name="TRangeSetRight">Type of the right range set.</typeparam>
        /// <typeparam name="TResult">Type of the result.</typeparam>
        /// <param name="left">The left <see cref="RangeSet{T}" />.</param>
        /// <param name="right">The right <see cref="RangeSet{T}" />.</param>
        /// <param name="process">The process.</param>
        /// <returns>An enumerator that allows foreach to be used to process the ranges in this collection.</returns>
        public static IEnumerable <TResult> EnumerateRanges <TRangeSetLeft, TRangeSetRight, TResult>(TRangeSetLeft left, TRangeSetRight right, Func <Range <T>, int?, int?, TResult> process)
            where TRangeSetLeft : IRangeSet <T>
            where TRangeSetRight : IRangeSet <T>
        {
            using (var enumLeft = left == null ? Enumerable.Empty <Range <T> >().GetEnumerator() : left.GetEnumerator()) {
                using (var enumRight = right == null ? Enumerable.Empty <Range <T> >().GetEnumerator() : right.GetEnumerator()) {
                    var ixLeft   = -1;
                    var ixRight  = -1;
                    var rngLeft  = enumLeft.GetNext(ref ixLeft);
                    var rngRight = enumRight.GetNext(ref ixRight);
                    while (rngLeft.HasValue || rngRight.HasValue)
                    {
                        if (rngLeft.HasValue && (!rngRight.HasValue || (rngLeft.Value.To.CompareTo(rngRight.Value.From) < 0)))
                        {
                            // no overlap, only in this
                            yield return(process(rngLeft.Value, ixLeft, null));

                            rngLeft = enumLeft.GetNext(ref ixLeft);
                            continue;
                        }
                        // if we get here then rngOther.HasValue == true
                        if (!rngLeft.HasValue || (rngRight.Value.To.CompareTo(rngLeft.Value.From) < 0))
                        {
                            // no overlap, only in other
                            yield return(process(rngRight.Value, null, ixRight));

                            rngRight = enumRight.GetNext(ref ixRight);
                            continue;
                        }
                        // if we get here then we have an overlap. first return any overhang on the "from" side
                        if (rngLeft.Value.From.CompareTo(rngRight.Value.From) < 0)
                        {
                            Debug.Assert(rngLeft.Value.To.CompareTo(rngRight.Value.From) >= 0);
                            yield return(process(new Range <T>(rngLeft.Value.From, Incrementor <T> .Decrement(rngRight.Value.From)), ixLeft, null));

                            rngLeft = new Range <T>(rngRight.Value.From, rngLeft.Value.To);
                        }
                        else if (rngLeft.Value.From.CompareTo(rngRight.Value.From) > 0)
                        {
                            Debug.Assert(rngRight.Value.To.CompareTo(rngLeft.Value.From) >= 0);
                            yield return(process(new Range <T>(rngRight.Value.From, Incrementor <T> .Decrement(rngLeft.Value.From)), null, ixRight));

                            rngRight = new Range <T>(rngLeft.Value.From, rngRight.Value.To);
                        }
                        // next return overlapping part and fixup ranges for next iteration
                        Debug.Assert(rngLeft.Value.From.CompareTo(rngRight.Value.From) == 0);
                        if (rngLeft.Value.To.CompareTo(rngRight.Value.To) < 0)
                        {
                            // rngOther is longer
                            yield return(process(rngLeft.Value, ixLeft, ixRight));

                            rngRight = new Range <T>(Incrementor <T> .Increment(rngLeft.Value.To), rngRight.Value.To);
                            rngLeft  = enumLeft.GetNext(ref ixLeft);
                        }
                        else if (rngLeft.Value.To.CompareTo(rngRight.Value.To) > 0)
                        {
                            // rngThis is longer
                            yield return(process(rngRight.Value, ixLeft, ixRight));

                            rngLeft  = new Range <T>(Incrementor <T> .Increment(rngRight.Value.To), rngLeft.Value.To);
                            rngRight = enumRight.GetNext(ref ixRight);
                        }
                        else
                        {
                            // both equal
                            yield return(process(rngLeft.Value, ixLeft, ixRight));

                            rngLeft  = enumLeft.GetNext(ref ixLeft);
                            rngRight = enumRight.GetNext(ref ixRight);
                        }
                    }
                }
            }
        }