Exemplo n.º 1
0
        public static Range <int> EqualRange <TElement, TValue>(
            [NotNull, ItemNotNull, InstantHandle] this IList <TElement> list,
            TValue value,
            int startIndex,
            int endIndex)
            where TElement : IComparable <TValue>
        {
            Code.NotNull(list, nameof(list));
            ValidateIndicesRange(startIndex, endIndex, list.Count);
            var upperBoundStartIndex = startIndex;
            var upperBoundEndIndex   = endIndex;

            // the loop locates the lower bound at the same time restricting the range for upper bound search
            while (startIndex < endIndex)
            {
                var median        = startIndex + (endIndex - startIndex) / 2;
                var compareResult = list[median].CompareTo(value);
                if (compareResult < 0)
                {
                    startIndex           = median + 1;
                    upperBoundStartIndex = startIndex;
                }
                else if (compareResult == 0)
                {
                    endIndex             = median;
                    upperBoundStartIndex = endIndex + 1;
                }
                else
                {
                    endIndex           = median;
                    upperBoundEndIndex = endIndex;
                }
            }
            return(Range.Create(startIndex, UpperBoundCore(list, value, upperBoundStartIndex, upperBoundEndIndex)));
        }
        public static Range <int> EqualRange(
            [NotNull, InstantHandle] this IList <float> list,
            float value,
            int startIndex,
            int endIndex)
        {
            Code.NotNull(list, nameof(list));
            ValidateIndicesRange(startIndex, endIndex, list.Count);
            var upperBoundStartIndex = startIndex;
            var upperBoundEndIndex   = endIndex;

            // the loop locates the lower bound at the same time restricting the range for upper bound search
            while (startIndex < endIndex)
            {
                var median = startIndex + (endIndex - startIndex) / 2;
                if (list[median] < value)
                {
                    startIndex           = median + 1;
                    upperBoundStartIndex = startIndex;
                }
                else if (list[median] == value)
                {
                    endIndex             = median;
                    upperBoundStartIndex = endIndex + 1;
                }
                else
                {
                    endIndex           = median;
                    upperBoundEndIndex = endIndex;
                }
            }
            return(Range.Create(startIndex, UpperBoundCore(list, value, upperBoundStartIndex, upperBoundEndIndex)));
        }
Exemplo n.º 3
0
        public static void TestRangeToString()
        {
            int?value1 = 1;
            int?empty  = null;
            var key    = "Hello!";

            AreEqual(Range <int> .Empty.ToString(), "∅");
            AreEqual(Range <int> .Infinite.ToString(), "(-∞..+∞)");
            AreEqual(Range.Create(1, 1).ToString(), "[1..1]");
            AreEqual(Range.Create(1, 2).ToString(), "[1..2]");
            AreEqual(Range.CreateExclusive(1, 2).ToString(), "(1..2)");
            AreEqual(Range.CreateExclusiveFrom(1, 2).ToString(), "(1..2]");
            AreEqual(Range.CreateExclusiveTo(1, 2).ToString(), "[1..2)");
            AreEqual(Range.CreateExclusive(value1, empty).ToString("000"), "(001..+∞)");

            AreEqual(Range.Create(RangeBoundaryFrom <int> .Empty, RangeBoundaryTo <int> .Empty, key).ToString(), "'Hello!':∅");
            AreEqual(Range.Create(empty, empty, key).ToString(), "'Hello!':(-∞..+∞)");
            AreEqual(Range.Create(empty, empty, (string)null).ToString(), "'':(-∞..+∞)");
            AreEqual(Range.Create(1, 1, key).ToString(), "'Hello!':[1..1]");
            AreEqual(Range.Create(1, 2, key).ToString(), "'Hello!':[1..2]");
            AreEqual(Range.CreateExclusive(1, 2, key).ToString(), "'Hello!':(1..2)");
            AreEqual(Range.CreateExclusiveFrom(1, 2, key).ToString(), "'Hello!':(1..2]");
            AreEqual(Range.CreateExclusiveTo(1, 2, key).ToString(), "'Hello!':[1..2)");
            AreEqual(Range.CreateExclusive(value1, empty, 3).ToString("000"), "'3':(001..+∞)");

            var cultureRu = CultureInfo.GetCultureInfo("ru-RU");
            var cultureEn = CultureInfo.GetCultureInfo("en-US");

            AreEqual(Range.Create(1.5, 2.5, 1.1).ToString("000.000", cultureRu), "'1,1':[001,500..002,500]");
            AreEqual(Range.Create(1.5, 2.5, 1.1).ToString("000.000", cultureEn), "'1.1':[001.500..002.500]");
            AreEqual(Range.Create(1.5, 2.5, (string)null).ToString(null, cultureRu), "'':[1,5..2,5]");
            AreEqual(Range.Create(1.5, 2.5, (string)null).ToString(null, cultureEn), "'':[1.5..2.5]");
        }
        public static void TestRangeAdjust()
        {
            var emptyFrom = RangeBoundaryFrom <double> .Empty;
            var emptyTo   = RangeBoundaryTo <double> .Empty;

            var range = Range.Create(1.0, 2.0);

            AreEqual(range.Adjust(double.NegativeInfinity), 1);
            AreEqual(range.Adjust(0), 1);
            AreEqual(range.Adjust(1), 1);
            AreEqual(range.Adjust(1.5), 1.5);
            AreEqual(range.Adjust(2), 2);
            AreEqual(range.Adjust(3), 2);
            AreEqual(range.Adjust(double.PositiveInfinity), 2);

            range = Range.Create(double.NegativeInfinity, double.PositiveInfinity);
            AreEqual(range.Adjust(double.NegativeInfinity), double.NegativeInfinity);
            AreEqual(range.Adjust(0), 0);
            AreEqual(range.Adjust(double.PositiveInfinity), double.PositiveInfinity);

            range = Range.Create(emptyFrom, emptyTo);
            Throws <ArgumentException>(() => range.Adjust(double.NegativeInfinity));
            Throws <ArgumentException>(() => range.Adjust(1));
            Throws <ArgumentException>(() => range.Adjust(double.PositiveInfinity));

            range = Range.CreateExclusive(1.0, 2.0);
            Throws <ArgumentException>(() => range.Adjust(double.NegativeInfinity));
            Throws <ArgumentException>(() => range.Adjust(1.5));
            Throws <ArgumentException>(() => range.Adjust(double.PositiveInfinity));
        }
        public static void TestRangeMakeInclusiveExclusive()
        {
            var range = Range.Create(1, 2);

            AreEqual(range, range.MakeInclusive(i => i - 1, i => i + 1));
            range = Range.CreateExclusive(1, 2);
            AreEqual(Range.Create(0, 3), range.MakeInclusive(i => i - 1, i => i + 1));
            range = Range.CreateExclusiveTo(1, 2);
            AreEqual(Range.Create(1, 3), range.MakeInclusive(i => i - 1, i => i + 1));

            range = Range.CreateExclusive(1, 2);
            AreEqual(range, range.MakeExclusive(i => i - 1, i => i + 1));
            range = Range.Create(1, 2);
            AreEqual(Range.CreateExclusive(0, 3), range.MakeExclusive(i => i - 1, i => i + 1));
            range = Range.CreateExclusiveFrom(1, 2);
            AreEqual(Range.CreateExclusive(1, 3), range.MakeExclusive(i => i - 1, i => i + 1));

            range = Range.CreateExclusive(2, 3);
            IsTrue(range.MakeInclusive(i => i + 1, i => i - 1).IsEmpty);
            range = Range.Create(2, 3);
            IsTrue(range.MakeExclusive(i => i + 1, i => i - 1).IsEmpty);

            range = Range.CreateExclusive(2, 3);
            IsTrue(range.MakeInclusive(i => i + 1, i => i - 1).IsEmpty);
            range = Range.Create(2, 3);
            IsTrue(range.MakeExclusive(i => i + 1, i => i - 1).IsEmpty);

            var range2 = Range.CreateExclusive(1, double.PositiveInfinity);

            IsTrue(range2.MakeInclusive(i => double.NegativeInfinity, i => i + 1).IsInfinite);
            range2 = Range.Create(double.NegativeInfinity, 2);
            IsTrue(range2.MakeExclusive(i => i + 1, i => double.PositiveInfinity).IsInfinite);
            range2 = Range.Create(double.NegativeInfinity, double.PositiveInfinity);
            AreEqual(range2, range2.MakeInclusive(i => i - 1, i => i + 1));
        }
Exemplo n.º 6
0
        public static void TestRangeProperties()
        {
            int?value1 = 1;
            int?value2 = 2;
            int?empty  = null;
            var key    = "Hello!";

            var a = new Range <int?>();

            Throws <InvalidOperationException>(() => a.FromValue.ToString());
            Throws <InvalidOperationException>(() => a.ToValue.ToString());
            AreEqual(a.From.Kind, RangeBoundaryFromKind.Empty);
            AreEqual(a.To.Kind, RangeBoundaryToKind.Empty);
            IsTrue(a.IsEmpty);
            IsFalse(a.IsNotEmpty);
            IsFalse(a.IsInfinite);
            IsFalse(a.IsSinglePoint);

            a = Range <int?> .Infinite;
            Throws <InvalidOperationException>(() => a.FromValue.ToString());
            Throws <InvalidOperationException>(() => a.ToValue.ToString());
            AreEqual(a.From.Kind, RangeBoundaryFromKind.Infinite);
            AreEqual(a.To.Kind, RangeBoundaryToKind.Infinite);
            IsFalse(a.IsEmpty);
            IsTrue(a.IsNotEmpty);
            IsTrue(a.IsInfinite);
            IsFalse(a.IsSinglePoint);

            a = Range.CreateExclusiveTo(empty, value2);
            Throws <InvalidOperationException>(() => a.FromValue.ToString());
            AreEqual(a.ToValue, value2);
            AreEqual(a.From.Kind, RangeBoundaryFromKind.Infinite);
            AreEqual(a.To.Kind, RangeBoundaryToKind.Exclusive);
            IsFalse(a.IsEmpty);
            IsTrue(a.IsNotEmpty);
            IsFalse(a.IsInfinite);
            IsFalse(a.IsSinglePoint);

            a = Range.Create(value1, value2);
            AreEqual(a.FromValue, value1);
            AreEqual(a.ToValue, value2);
            AreEqual(a.From.Kind, RangeBoundaryFromKind.Inclusive);
            AreEqual(a.To.Kind, RangeBoundaryToKind.Inclusive);
            IsFalse(a.IsEmpty);
            IsTrue(a.IsNotEmpty);
            IsFalse(a.IsInfinite);
            IsFalse(a.IsSinglePoint);

            var b = Range.Create(value1, value1, key);

            AreEqual(b.FromValue, value1);
            AreEqual(b.ToValue, value1);
            AreEqual(b.Key, key);
            AreEqual(b.From.Kind, RangeBoundaryFromKind.Inclusive);
            AreEqual(b.To.Kind, RangeBoundaryToKind.Inclusive);
            IsFalse(b.IsEmpty);
            IsTrue(b.IsNotEmpty);
            IsFalse(b.IsInfinite);
            IsTrue(b.IsSinglePoint);
        }
Exemplo n.º 7
0
        public static void TestRangeEquality()
        {
            int?value1 = 1;
            int?value2 = 2;
            int?empty  = null;
            var key    = "Hello!";
            var key2   = "Hello2!";

            var eFrom = new RangeBoundaryFrom <int?>();
            var eTo   = new RangeBoundaryTo <int?>();

            AreEqual(Range <int?> .Empty, Range.Create(eFrom, eTo));
            AreEqual(Range <int?> .Infinite, Range.Create(empty, empty));
            AreNotEqual(Range <double?> .Infinite, Range.Create(empty, empty));

            AreEqual(
                Range.CreateExclusiveFrom(value1, value2).From,
                Range.BoundaryFromExclusive(value1));

            AreEqual(
                Range.CreateExclusiveFrom(value1, value2).To,
                Range.BoundaryTo(value2));

            AreNotEqual(
                Range.CreateExclusiveFrom(value1, value2),
                Range.Create(value1, value2));

            IsTrue(Range.Create(value1, value2) == Range.Create <int?>(1, 2));
            IsTrue(Range.Create(value1, value2) != Range.Create(value1, 1));
            IsTrue(Range.Create(value1, value2, key) == Range.Create <int?, string>(1, 2, key));
            IsTrue(Range.Create(value1, value2, key) != Range.Create <int?, string>(1, 2, key2));
            IsTrue(Range.Create(value1, value2, key) != Range.Create <int?, string>(1, 1, key));
        }
 public static CompositeRange <T, TKey> ToCompositeRange <T, TKey>(
     this IEnumerable <TKey> source,
     [InstantHandle] Func <TKey, T> fromValueSelector,
     [InstantHandle] Func <TKey, T> toValueSelector)
     where TKey : notnull =>
 source
 .Select(s => Range.Create(fromValueSelector(s), toValueSelector(s), s))
 .ToCompositeRange();
Exemplo n.º 9
0
 /// <summary>Converts sequence of elements to the composite range.</summary>
 /// <typeparam name="TSource">The type of the values in original collection.</typeparam>
 /// <typeparam name="T">The type of the range values.</typeparam>
 /// <typeparam name="TKey">The type of the range key</typeparam>
 /// <param name="source">Original collection.</param>
 /// <param name="fromValueSelector">Callback to obtain a value for the From boundary.</param>
 /// <param name="toValueSelector">Callback to obtain a value for the To boundary.</param>
 /// <param name="keySelector">Callback to obtain a value for the range key.</param>
 /// <returns>A new composite range with keys filled from the original collection.</returns>
 public static CompositeRange <T, TKey> ToCompositeRange <TSource, T, TKey>(
     [NotNull] this IEnumerable <TSource> source,
     [NotNull, InstantHandle] Func <TSource, T> fromValueSelector,
     [NotNull, InstantHandle] Func <TSource, T> toValueSelector,
     [NotNull, InstantHandle] Func <TSource, TKey> keySelector) =>
 source
 .Select(s => Range.Create(fromValueSelector(s), toValueSelector(s), keySelector(s)))
 .ToCompositeRange();
Exemplo n.º 10
0
        public static void TestRangeContainsRange2()
        {
            double?empty     = null;
            double?value1    = 1;
            double?value2    = 2;
            var    emptyFrom = RangeBoundaryFrom <double?> .Empty;
            var    emptyTo   = RangeBoundaryTo <double?> .Empty;

            var range = Range.Create(value1, value2);

            IsTrue(range.Contains(1, 2));
            IsFalse(range.Contains(1, null));
            IsFalse(range.Contains(null, null));
            IsFalse(range.Contains(double.NegativeInfinity, double.PositiveInfinity));
            Throws <ArgumentException>(() => range.Contains(2, 1));
            Throws <ArgumentException>(() => range.Contains(double.PositiveInfinity, double.NegativeInfinity));
            IsTrue(range.Contains(1.5, 1.5));
            IsTrue(range.Contains(1.5, 2));
            IsFalse(range.Contains(0, 3));
            IsFalse(range.Contains(0, 1.5));
            IsFalse(range.Contains(1.5, 3));
            IsFalse(range.Contains(3, 4));

            range = Range.Create(emptyFrom, emptyTo);
            IsTrue(range.Contains(range));
            IsFalse(range.Contains(1, 2));
            IsTrue(range.Contains(Range.Create(emptyFrom, emptyTo, _rangeKey2)));
            IsFalse(range.Contains(1, null));
            IsTrue(range.Contains(Range <double?> .Empty));
            IsFalse(range.Contains(Range <double?> .Infinite));
            IsFalse(range.Contains(null, null));
            IsFalse(range.Contains(double.NegativeInfinity, double.PositiveInfinity));
            Throws <ArgumentException>(
                () => range.Contains(2, 1));
            Throws <ArgumentException>(
                () => range.Contains(double.PositiveInfinity, double.NegativeInfinity));

            range = Range.CreateExclusive(empty, empty);
            IsTrue(range.Contains(range));
            IsTrue(range.Contains(Range.CreateExclusive(empty, empty, _rangeKey2)));
            IsTrue(range.Contains(1, 2));
            IsTrue(range.Contains(1, null));
            IsFalse(range.Contains(Range <double?> .Empty));
            IsTrue(range.Contains(Range <double?> .Infinite));
            IsTrue(range.Contains(null, null));
            IsTrue(range.Contains(double.NegativeInfinity, double.PositiveInfinity));
            Throws <ArgumentException>(
                () => range.Contains(2, 1));
            Throws <ArgumentException>(
                () => range.Contains(double.PositiveInfinity, double.NegativeInfinity));

            range = Range.CreateExclusive(value1, value2);
            IsTrue(range.Contains(Range.CreateExclusive(value1, value2, _rangeKey2)));
            IsFalse(range.Contains(1, 2));
            IsTrue(range.Contains(1.5, 1.5));
            IsFalse(range.Contains(1.5, 2));
            IsFalse(range.Contains(3, 4));
        }
Exemplo n.º 11
0
        public static void TestRangeContains()
        {
            double?empty     = null;
            double?value1    = 1;
            double?value2    = 2;
            var    emptyFrom = RangeBoundaryFrom <double?> .Empty;
            var    emptyTo   = RangeBoundaryTo <double?> .Empty;

            var range = Range.Create(value1, value2);

            IsFalse(range.Contains(null));
            IsFalse(range.Contains(double.NegativeInfinity));
            IsFalse(range.Contains(double.PositiveInfinity));
            IsFalse(range.Contains(RangeBoundaryFrom <double?> .Empty));
            IsFalse(range.Contains(RangeBoundaryTo <double?> .Empty));
            IsFalse(range.Contains(0));
            IsTrue(range.Contains(1));
            IsTrue(range.Contains(1.5));
            IsTrue(range.Contains(2));
            IsFalse(range.Contains(3));

            range = Range.Create(emptyFrom, emptyTo);
            IsFalse(range.Contains(null));
            IsFalse(range.Contains(double.NegativeInfinity));
            IsFalse(range.Contains(double.PositiveInfinity));
            IsTrue(range.Contains(RangeBoundaryFrom <double?> .Empty));
            IsTrue(range.Contains(RangeBoundaryTo <double?> .Empty));
            IsFalse(range.Contains(0));

            range = Range.CreateExclusive(empty, empty);
            IsTrue(range.Contains(null));
            IsTrue(range.Contains(double.NegativeInfinity));
            IsTrue(range.Contains(double.PositiveInfinity));
            IsFalse(range.Contains(RangeBoundaryFrom <double?> .Empty));
            IsFalse(range.Contains(RangeBoundaryTo <double?> .Empty));
            IsTrue(range.Contains(0));

            range = Range.CreateExclusive(value1, value2);
            IsFalse(range.Contains(1));
            IsTrue(range.Contains(1.5));
            IsFalse(range.Contains(2));

            range = Range.CreateExclusive(value1, value2);
            IsFalse(range.Contains(Range.BoundaryFrom <double?>(1)));
            IsFalse(range.Contains(Range.BoundaryTo <double?>(2)));
            IsTrue(range.Contains(Range.BoundaryFromExclusive <double?>(1)));
            IsTrue(range.Contains(Range.BoundaryFromExclusive <double?>(1.5)));
            IsFalse(range.Contains(Range.BoundaryFromExclusive <double?>(2)));
            IsFalse(range.Contains(Range.BoundaryToExclusive <double?>(1)));
            IsTrue(range.Contains(Range.BoundaryToExclusive <double?>(1.5)));
            IsTrue(range.Contains(Range.BoundaryToExclusive <double?>(2)));

            Throws <ArgumentException>(
                () => range.Contains(Range.BoundaryFrom <double?>(double.PositiveInfinity)));
            Throws <ArgumentException>(
                () => range.Contains(Range.BoundaryTo <double?>(double.NegativeInfinity)));
        }
Exemplo n.º 12
0
        public static void TestRangeWithKey()
        {
            var range = Range.Create(1, 2);

            AreEqual(range.WithKey(_rangeKey2), Range.Create(1, 2, _rangeKey2));
            AreEqual(range.WithKey(_rangeKey2).WithoutKey(), new Range <int>(1, 2));

            var toInf  = (double?)double.PositiveInfinity;
            var range2 = Range.CreateExclusive(1, toInf);

            AreEqual(range2.WithKey(_rangeKey2).Key, _rangeKey2);
        }
Exemplo n.º 13
0
        public void CompareTo()
        {
            Assert.AreEqual(-1, Range.StartsWith(1).CompareTo(Range.StartsWith(1, false)));
            Assert.AreEqual(0, Range.StartsWith(1).CompareTo(Range.StartsWith(1)));
            Assert.AreEqual(0, Range.StartsWith(1, false).CompareTo(Range.StartsWith(1, false)));
            Assert.AreEqual(1, Range.StartsWith(1, false).CompareTo(Range.StartsWith(1, true)));

            Assert.AreEqual(0, Range.Create(1, 3, true).CompareTo(Range.Create(1, 3, true)));
            Assert.AreEqual(0, Range.Create(1, 3, false).CompareTo(Range.Create(1, 3, false)));

            Assert.AreEqual(1, Range.Create(1, 3, true, true).CompareTo(Range.Create(1, 3, true, false)));
            Assert.AreEqual(-1, Range.Create(1, 3, true, false).CompareTo(Range.Create(1, 3, true, true)));
        }
Exemplo n.º 14
0
        public static Range <T> ParseRange <T>(string value, Func <string, T> parseValueCallback)
        {
            if (value == RangeInternal.EmptyString)
            {
                return(Range <T> .Empty);
            }

            var boundaries = value.Split(new[] { RangeInternal.SeparatorString }, 2, StringSplitOptions.None);

            return(Range.Create(
                       ParseBoundaryFromCore(boundaries[0], parseValueCallback),
                       ParseBoundaryToCore(boundaries[1], parseValueCallback)));
        }
Exemplo n.º 15
0
        public static void TestKeyedRangeUnion()
        {
            double value1        = 1;
            double value2        = 2;
            var    emptyFrom     = RangeBoundaryFrom <double> .Empty;
            var    emptyTo       = RangeBoundaryTo <double> .Empty;
            var    emptyRange    = Range.Create(emptyFrom, emptyTo, RangeKey);
            var    infiniteRange = Range.Create(double.NegativeInfinity, double.PositiveInfinity, RangeKey);

            var range = Range.Create(value1, value2, RangeKey);

            AreEqual(range.Union(range), range);
            AreEqual(range.Union(1, 2), range);
            AreEqual(range.Union(1.5, 1.5), range);
            AreEqual(range.Union(0, 3), Range.Create(0.0, 3.0, RangeKey));
            AreEqual(range.Union(1.5, 3), Range.Create(1.0, 3.0, RangeKey));
            AreEqual(range.Union(0, 1.5), Range.Create(0.0, 2.0, RangeKey));
            AreEqual(range.Union(3, 4), Range.Create(1.0, 4.0, RangeKey));
            AreEqual(range.Union(-2, -1), Range.Create(-2.0, 2.0, RangeKey));
            AreEqual(range.Union(emptyRange), range);
            AreEqual(emptyRange.Union(range), range);
            AreEqual(range.Union(infiniteRange), infiniteRange);
            AreEqual(infiniteRange.Union(range), infiniteRange);
            AreEqual(emptyRange.Union(infiniteRange), infiniteRange);
            AreEqual(infiniteRange.Union(emptyRange), infiniteRange);

            range = Range.CreateExclusive(value1, value2, RangeKey);
            AreEqual(range.Union(range), range);
            AreEqual(range.Union(1, 2), Range.Create(1.0, 2.0, RangeKey));
            AreEqual(range.Union(1.5, 1.5), range);
            AreEqual(range.Union(0, 3), Range.Create(0.0, 3.0, RangeKey));
            AreEqual(range.Union(1.5, 3), Range.CreateExclusiveFrom(1.0, 3.0, RangeKey));
            AreEqual(range.Union(0, 1.5), Range.CreateExclusiveTo(0.0, 2.0, RangeKey));
            AreEqual(range.Union(3, 4), Range.CreateExclusiveFrom(1.0, 4.0, RangeKey));
            AreEqual(range.Union(-2, -1), Range.CreateExclusiveTo(-2.0, 2.0, RangeKey));
            AreEqual(range.Union(emptyRange), range);
            AreEqual(emptyRange.Union(range), range);
            AreEqual(range.Union(infiniteRange), infiniteRange);
            AreEqual(infiniteRange.Union(range), infiniteRange);
            AreEqual(emptyRange.Union(infiniteRange), infiniteRange);
            AreEqual(infiniteRange.Union(emptyRange), infiniteRange);

            Throws <ArgumentException>(
                () => range.Union(2, 1));
            Throws <ArgumentException>(
                () => range.Union(double.PositiveInfinity, double.NegativeInfinity));
            Throws <ArgumentException>(
                () => range.Union(2, double.NegativeInfinity));
            Throws <ArgumentException>(
                () => range.Union(double.PositiveInfinity, 1));
        }
Exemplo n.º 16
0
        public static void TestRangeIntersection()
        {
            double value1        = 1;
            double value2        = 2;
            var    emptyFrom     = RangeBoundaryFrom <double> .Empty;
            var    emptyTo       = RangeBoundaryTo <double> .Empty;
            var    emptyRange    = Range.Create(emptyFrom, emptyTo);
            var    infiniteRange = Range.Create(double.NegativeInfinity, double.PositiveInfinity);

            var range = Range.Create(value1, value2);

            AreEqual(range.Intersect(range), range);
            AreEqual(range.Intersect(1, 2), range);
            AreEqual(range.Intersect(1.5, 1.5), Range.Create(1.5, 1.5));
            AreEqual(range.Intersect(0, 3), range);
            AreEqual(range.Intersect(1.5, 3), Range.Create(1.5, 2.0));
            AreEqual(range.Intersect(0, 1.5), Range.Create(1.0, 1.5));
            AreEqual(range.Intersect(3, 4), emptyRange);
            AreEqual(range.Intersect(-2, -1), emptyRange);
            AreEqual(range.Intersect(emptyRange), emptyRange);
            AreEqual(emptyRange.Intersect(range), emptyRange);
            AreEqual(range.Intersect(infiniteRange), range);
            AreEqual(infiniteRange.Intersect(range), range);
            AreEqual(emptyRange.Intersect(infiniteRange), emptyRange);
            AreEqual(infiniteRange.Intersect(emptyRange), emptyRange);

            range = Range.CreateExclusive(value1, value2);
            AreEqual(range.Intersect(range), range);
            AreEqual(range.Intersect(1, 2), range);
            AreEqual(range.Intersect(1.5, 1.5), Range.Create(1.5, 1.5));
            AreEqual(range.Intersect(0, 3), range);
            AreEqual(range.Intersect(1.5, 3), Range.CreateExclusiveTo(1.5, 2.0));
            AreEqual(range.Intersect(0, 1.5), Range.CreateExclusiveFrom(1.0, 1.5));
            AreEqual(range.Intersect(3, 4), emptyRange);
            AreEqual(range.Intersect(-2, -1), emptyRange);
            AreEqual(range.Intersect(emptyRange), emptyRange);
            AreEqual(emptyRange.Intersect(range), emptyRange);
            AreEqual(range.Intersect(infiniteRange), range);
            AreEqual(infiniteRange.Intersect(range), range);
            AreEqual(emptyRange.Intersect(infiniteRange), emptyRange);
            AreEqual(infiniteRange.Intersect(emptyRange), emptyRange);

            Throws <ArgumentException>(
                () => range.Intersect(2, 1));
            Throws <ArgumentException>(
                () => range.Intersect(double.PositiveInfinity, double.NegativeInfinity));
            Throws <ArgumentException>(
                () => range.Intersect(2, double.NegativeInfinity));
            Throws <ArgumentException>(
                () => range.Intersect(double.PositiveInfinity, 1));
        }
Exemplo n.º 17
0
        public void Exclude()
        {
            CheckExclude(Range.EndsWith(5, true), Range.Create(2, 3, true, true), "..(2)", "(3)..5");
            CheckExclude(Range.EndsWith(5, true), Range.Create(2, 5, true, false), "..(2)", "5");
            CheckExclude(Range.EndsWith(5, true), Range.Create(2, 5, true, true), "..(2)");
            CheckExclude(Range.EndsWith(5, false), Range.Create(2, 5, true, true), "..(2)");
            CheckExclude(Range.EndsWith(5, false), Range.Create(2, 5, true, false), "..(2)");

            CheckExclude(Range.Create(0, 5, true, true), Range.Create(2, 5, true, true), "0..(2)");
            CheckExclude(Range.Create(0, 5, true, true), Range.Create(2, 10, true, true), "0..(2)");
            CheckExclude(Range.Create(0, 5, true, true), Range.StartsWith(2, true), "0..(2)");
            CheckExclude(Range.Create(0, 5, true, true), Range.StartsWith(5, false), "0..5");
            CheckExclude(Range.Create(0, 5, true, true), Range.StartsWith(5, true), "0..(5)");
        }
        /// <summary>Creates instance of <seealso cref="CompositeRange{T}"/>.</summary>
        /// <param name="ranges">Contained ranges.</param>
        /// <param name="skipsArgHandling">Stub argument to mark unsafe (no validation) constructor overload.</param>
        internal CompositeRange([NotNull] IEnumerable <Range <T, TKey> > ranges, UnsafeOverload skipsArgHandling)
        {
            Code.NotNull(ranges, nameof(ranges));

#pragma warning disable 618 // ok by design.
            bool rangesReady = skipsArgHandling == UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged;
            var  tempRanges  = rangesReady || skipsArgHandling == UnsafeOverload.NoEmptyRanges
                                ? ranges.ToArray()
                                : ranges.Where(r => r.IsNotEmpty).ToArray();
#pragma warning restore 618

            if (tempRanges.Length == 0)
            {
                _ranges           = _emptyRanges;
                _hasRangesToMerge = false;
                _containingRange  = _emptyRangeNoKey;
                return;
            }

            if (tempRanges.Length == 1 || rangesReady)
            {
                _ranges           = tempRanges.AsReadOnly();
                _hasRangesToMerge = false;
                _containingRange  = Range.Create(tempRanges[0].From, tempRanges[tempRanges.Length - 1].To);
                return;
            }

#pragma warning disable 618 // ok by design.
            if (skipsArgHandling != UnsafeOverload.RangesAlreadySorted)
#pragma warning restore 618
            {
                Array.Sort(tempRanges, _rangeComparer);
            }

            bool hasRangesToMerge = false;
            var  maxToBoundary    = tempRanges[0].To;
            for (int i = 1; i < tempRanges.Length; i++)
            {
                var range = tempRanges[i];

                // TODO: check for keyed range.
                hasRangesToMerge = hasRangesToMerge || IsContinuationFor(maxToBoundary, range);

                maxToBoundary = Range.Max(maxToBoundary, range.To);
            }

            _ranges           = tempRanges.AsReadOnly();
            _hasRangesToMerge = hasRangesToMerge;
            _containingRange  = Range.Create(tempRanges[0].From, maxToBoundary);
        }
Exemplo n.º 19
0
        public static void TestKeyedRangeKeyFlow()
        {
            int?value1 = 1;
            int?empty  = null;
            var key    = "Hello!";

            var range = Range.Create(value1, empty).WithKey("A");

            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'A':[1..+∞)");
            AreNotEqual(range.Key, key);

            var prevRange = range.WithKey(key);

            range = prevRange;
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':[1..+∞)");
            AreEqual(range.Key, key);
            AreEqual(range, prevRange);

            range = range.Intersect(1, 2);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':[1..2]");
            AreEqual(range.Key, key);
            AreNotEqual(range, prevRange);

            range = range.Union(4, 8);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':[1..8]");
            AreEqual(range.Key, key);
            AreNotEqual(range, prevRange);

            range = range.Intersect(10, 20);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':∅");
            AreEqual(range.Key, key);
            AreNotEqual(range, prevRange);

            range = range.Union(null, null);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':(-∞..+∞)");
            AreEqual(range.Key, key);
            AreNotEqual(range, prevRange);

            range = range.TrimFrom(1);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'Hello!':[1..+∞)");
            AreEqual(range.Key, key);
            AreEqual(range, prevRange);

            range = Range.Create(value1, value1)
                    .WithKey("B")
                    .Intersect(range);
            AreEqual(range.ToString(CultureInfo.InvariantCulture), "'B':[1..1]");
            AreNotEqual(range.Key, key);
            AreNotEqual(range, prevRange);
        }
Exemplo n.º 20
0
        public void Invert()
        {
            var list = Range.Create(20, 30).ToRangeList().Add(Range.Create(11, 12, false, true));

            CheckList(list, "[(11)..12, 20..30]");

            var invertedList = list.Invert();

            CheckList(invertedList, "[..11, (12)..(20), (30)..]");

            var invertedAgain = invertedList.Invert();

            CheckList(invertedAgain, "[(11)..12, 20..30]");

            Assert.AreEqual(list, invertedAgain);
        }
Exemplo n.º 21
0
        public void Contains()
        {
            var range = Range.Create(0, 2);

            Assert.IsTrue(range.Contains(0));
            Assert.IsTrue(range.Contains(1));
            Assert.IsTrue(range.Contains(2));

            range = Range.Create(0, 2, false);

            Assert.IsFalse(range.Contains(0));
            Assert.IsTrue(range.Contains(1));
            Assert.IsFalse(range.Contains(2));

            Assert.IsFalse(Range.Empty <int>().Contains(10));
        }
Exemplo n.º 22
0
        public static void TestRangesCore(CompositeRange <int, string> ranges)
        {
            var tree = new IntervalTree <int, string>(ranges);

            for (var i = ranges.ContainingRange.FromValue; i <= ranges.ContainingRange.ToValue; i++)
            {
                var overlapRange = Range.Create(i, i);
                AssertSameOverlap(ranges, tree, overlapRange);
                overlapRange = Range.Create(i - 1, i + 1);
                AssertSameOverlap(ranges, tree, overlapRange);
                overlapRange = Range.Create(i - 2, i + 2);
                AssertSameOverlap(ranges, tree, overlapRange);
                overlapRange = Range.Create(i - 10, i);
                AssertSameOverlap(ranges, tree, overlapRange);
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Converts sequence of elements to the composite range using only From boundary.
        /// The To boundary value is taken from the next item in sequence (+∞ for the last item in sequence)
        /// </summary>
        /// <typeparam name="TSource">The type of the values in original collection.</typeparam>
        /// <typeparam name="T">The type of the range values.</typeparam>
        /// <typeparam name="TKey">The type of the range key</typeparam>
        /// <param name="source">Original collection.</param>
        /// <param name="fromValueSelector">Callback to obtain a value for the From boundary.</param>
        /// <param name="keySelector">Callback to obtain a value for the range key.</param>
        /// <returns>A new composite range with keys filled from the original collection.</returns>
        public static CompositeRange <T, TKey> ToCompositeRangeFrom <TSource, T, TKey>(
            [NotNull] this IEnumerable <TSource> source,
            [NotNull, InstantHandle] Func <TSource, T> fromValueSelector,
            [NotNull, InstantHandle] Func <TSource, TKey> keySelector)
        {
            var keyAndFromBoundary = source
                                     .Select(s => (From: Range.BoundaryFrom(fromValueSelector(s)), Key: keySelector(s)))
                                     .OrderBy(s => s.From)
                                     .ToArray();

            if (keyAndFromBoundary.Length == 0)
            {
                return(CompositeRange <T, TKey> .Empty);
            }

            // logic is following:
            // foreach item in sequence
            //   if same boundary as before - add to pending
            //   else add all (pending to current) ranges. Store current as pending.

            var prevBoundary = RangeBoundaryFrom <T> .Empty;
            var prevKeys     = new List <TKey>();
            var ranges       = new List <Range <T, TKey> >();

            foreach (var fromWithKey in keyAndFromBoundary)
            {
                if (prevBoundary != fromWithKey.From)
                {
                    foreach (var prevKey in prevKeys)
                    {
                        ranges.Add(Range.Create(prevBoundary, fromWithKey.From.GetComplementation(), prevKey));
                    }
                    prevKeys.Clear();
                    prevBoundary = fromWithKey.From;
                }

                prevKeys.Add(fromWithKey.Key);
            }

            foreach (var prevKey in prevKeys)
            {
                ranges.Add(Range.Create(prevBoundary, RangeBoundaryTo <T> .PositiveInfinity, prevKey));
            }

            return(ranges.ToCompositeRange());
        }
Exemplo n.º 24
0
        public static void TestRangeTrimTo()
        {
            double?empty      = null;
            double?value1     = 1;
            double?value2     = 2;
            var    emptyFrom  = RangeBoundaryFrom <double?> .Empty;
            var    emptyTo    = RangeBoundaryTo <double?> .Empty;
            var    emptyRange = Range.Create(emptyFrom, emptyTo);

            var range = Range.Create(value1, value2);

            AreEqual(range.TrimTo(null), range);
            AreEqual(range.TrimTo(double.PositiveInfinity), range);
            Throws <ArgumentException>(() => range.TrimTo(double.NegativeInfinity));
            AreEqual(range.TrimTo(RangeBoundaryTo <double?> .Empty), emptyRange);
            AreEqual(range.TrimTo(0), emptyRange);
            AreEqual(range.TrimTo(1), Range.Create(value1, 1));
            AreEqual(range.TrimTo(1.5), Range.Create(value1, 1.5));
            AreEqual(range.TrimTo(2), range);
            AreEqual(range.TrimTo(3), range);

            range = Range.Create(emptyFrom, emptyTo);
            AreEqual(range.TrimTo(null), range);
            AreEqual(range.TrimTo(double.PositiveInfinity), range);
            Throws <ArgumentException>(() => range.TrimTo(double.NegativeInfinity));
            AreEqual(range.TrimTo(RangeBoundaryTo <double?> .Empty), range);
            AreEqual(range.TrimTo(0), range);

            range = Range.CreateExclusive(empty, empty);
            AreEqual(range.TrimTo(null), range);
            AreEqual(range.TrimTo(double.PositiveInfinity), range);
            Throws <ArgumentException>(() => range.TrimTo(double.NegativeInfinity));
            AreEqual(range.TrimTo(RangeBoundaryTo <double?> .Empty), emptyRange);
            AreEqual(range.TrimTo(0), Range.Create(empty, 0));

            range = Range.CreateExclusive(value1, value2);
            AreEqual(range.TrimTo(2), range);
            AreEqual(range.TrimTo(1.5), Range.CreateExclusiveFrom(value1, 1.5));
            AreEqual(range.TrimTo(1), emptyRange);

            range = Range.CreateExclusive(value1, value2);
            AreEqual(range.TrimTo(Range.BoundaryTo <double?>(2)), range);
            AreEqual(range.TrimTo(Range.BoundaryTo <double?>(1.5)), Range.CreateExclusiveFrom(value1, 1.5));
            AreEqual(range.TrimTo(Range.BoundaryTo <double?>(1)), emptyRange);
        }
        public static void TestKeyedRangeTrimFrom()
        {
            double?empty      = null;
            double?value1     = 1;
            double?value2     = 2;
            var    emptyFrom  = RangeBoundaryFrom <double?> .Empty;
            var    emptyTo    = RangeBoundaryTo <double?> .Empty;
            var    emptyRange = Range.Create(emptyFrom, emptyTo, _rangeKey);

            var range = Range.Create(value1, value2, _rangeKey);

            AreEqual(range.TrimFrom(null), range);
            AreEqual(range.TrimFrom(double.NegativeInfinity), range);
            Throws <ArgumentException>(() => range.TrimFrom(double.PositiveInfinity));
            AreEqual(range.TrimFrom(RangeBoundaryFrom <double?> .Empty), emptyRange);
            AreEqual(range.TrimFrom(0), range);
            AreEqual(range.TrimFrom(1), range);
            AreEqual(range.TrimFrom(1.5), Range.Create(1.5, value2, _rangeKey));
            AreEqual(range.TrimFrom(2), Range.Create(2, value2, _rangeKey));
            AreEqual(range.TrimFrom(3), emptyRange);

            range = Range.Create(emptyFrom, emptyTo, _rangeKey);
            AreEqual(range.TrimFrom(null), range);
            AreEqual(range.TrimFrom(double.NegativeInfinity), range);
            Throws <ArgumentException>(() => range.TrimFrom(double.PositiveInfinity));
            AreEqual(range.TrimFrom(RangeBoundaryFrom <double?> .Empty), range);
            AreEqual(range.TrimFrom(0), range);

            range = Range.CreateExclusive(empty, empty, _rangeKey);
            AreEqual(range.TrimFrom(null), range);
            AreEqual(range.TrimFrom(double.NegativeInfinity), range);
            Throws <ArgumentException>(() => range.TrimFrom(double.PositiveInfinity));
            AreEqual(range.TrimFrom(RangeBoundaryFrom <double?> .Empty), emptyRange);
            AreEqual(range.TrimFrom(0), Range.Create(0, empty, _rangeKey));

            range = Range.CreateExclusive(value1, value2, _rangeKey);
            AreEqual(range.TrimFrom(1), range);
            AreEqual(range.TrimFrom(1.5), Range.CreateExclusiveTo(1.5, value2, _rangeKey));
            AreEqual(range.TrimFrom(2), emptyRange);

            range = Range.CreateExclusive(value1, value2, _rangeKey);
            AreEqual(range.TrimFrom(Range.BoundaryFrom <double?>(1)), range);
            AreEqual(range.TrimFrom(Range.BoundaryFrom <double?>(1.5)), Range.CreateExclusiveTo(1.5, value2, _rangeKey));
            AreEqual(range.TrimFrom(Range.BoundaryFrom <double?>(2)), emptyRange);
        }
Exemplo n.º 26
0
        public static void TestKeyedRangeExtendTo()
        {
            double?empty     = null;
            double?value1    = 1;
            double?value2    = 2;
            var    emptyFrom = RangeBoundaryFrom <double?> .Empty;
            var    emptyTo   = RangeBoundaryTo <double?> .Empty;

            var range = Range.Create(value1, value2, RangeKey);

            AreEqual(range.ExtendTo(null), Range.Create(value1, empty, RangeKey));
            AreEqual(range.ExtendTo(double.PositiveInfinity), Range.Create(value1, empty, RangeKey));
            Throws <ArgumentException>(() => range.ExtendTo(double.NegativeInfinity));
            AreEqual(range.ExtendTo(RangeBoundaryTo <double?> .Empty), range);
            AreEqual(range.ExtendTo(0), range);
            AreEqual(range.ExtendTo(1), range);
            AreEqual(range.ExtendTo(1.5), range);
            AreEqual(range.ExtendTo(2), range);
            AreEqual(range.ExtendTo(3), Range.Create(value1, 3, RangeKey));

            range = Range.Create(emptyFrom, emptyTo, RangeKey);
            AreEqual(range.ExtendTo(null), range);
            AreEqual(range.ExtendTo(double.PositiveInfinity), range);
            Throws <ArgumentException>(() => range.ExtendTo(double.NegativeInfinity));
            AreEqual(range.ExtendTo(RangeBoundaryTo <double?> .Empty), range);
            AreEqual(range.ExtendTo(0), range);

            range = Range.CreateExclusive(empty, empty, RangeKey);
            AreEqual(range.ExtendTo(null), range);
            AreEqual(range.ExtendTo(double.PositiveInfinity), range);
            Throws <ArgumentException>(() => range.ExtendTo(double.NegativeInfinity));
            AreEqual(range.ExtendTo(RangeBoundaryTo <double?> .Empty), range);
            AreEqual(range.ExtendTo(0), range);

            range = Range.CreateExclusive(value1, value2, RangeKey);
            AreEqual(range.ExtendTo(1), range);
            AreEqual(range.ExtendTo(1.5), range);
            AreEqual(range.ExtendTo(2), Range.CreateExclusiveFrom(value1, 2, RangeKey));

            range = Range.CreateExclusive(value1, value2, RangeKey);
            AreEqual(range.ExtendTo(Range.BoundaryTo <double?>(2)), Range.CreateExclusiveFrom(value1, 2, RangeKey));
            AreEqual(range.ExtendTo(Range.BoundaryToExclusive <double?>(2)), range);
            AreEqual(range.ExtendTo(Range.BoundaryToExclusive <double?>(3)), Range.CreateExclusive(value1, 3, RangeKey));
        }
Exemplo n.º 27
0
        public static CompositeRange <T, TKey> ToCompositeRangeTo <TSource, T, TKey>(
            this IEnumerable <TSource> source,
            [InstantHandle] Func <TSource, T> toValueSelector,
            [InstantHandle] Func <TSource, TKey> keySelector)
            where TKey : notnull
        {
            var keyAndToBoundary = source
                                   .Select(s => (Key: keySelector(s), To: Range.BoundaryTo(toValueSelector(s))))
                                   .OrderBy(s => s.To)
                                   .ToArray();

            if (keyAndToBoundary.Length == 0)
            {
                return(CompositeRange <T, TKey> .Empty);
            }

            // logic is following:
            // foreach item in sequence
            //   if To is same as before - add same range with new key
            //   else add range (old.To..To, key) and.

            var prevRange = Range <T, TKey> .Empty;
            var ranges    = new List <Range <T, TKey> >();

            foreach (var(key, to) in keyAndToBoundary)
            {
                if (prevRange.IsEmpty)
                {
                    prevRange = Range.Create(RangeBoundaryFrom <T> .NegativeInfinity, to, key);
                }
                else if (prevRange.To == to)
                {
                    prevRange = prevRange.WithKey(key);
                }
                else
                {
                    prevRange = Range.Create(prevRange.To.GetComplementation(), to, key);
                }
                ranges.Add(prevRange);
            }

            return(ranges.ToCompositeRange());
        }
Exemplo n.º 28
0
        private static CompositeRange <T> GetComplementationCore <T, TCompositeRange>(
            TCompositeRange compositeRange)
            where TCompositeRange : ICompositeRange <T>
        {
            if (compositeRange.IsEmpty)
            {
                return(CompositeRange <T> .Infinite);
            }

            var result = new List <Range <T> >();

            if (compositeRange.ContainingRange.From.HasValue)
            {
                result.Add(
                    Range.Create(
                        RangeBoundaryFrom <T> .NegativeInfinity,
                        compositeRange.ContainingRange.From.GetComplementation()));
            }

            var previousRange = Range <T> .Empty;

            foreach (var range in compositeRange.GetMergedRanges())
            {
                if (previousRange.IsNotEmpty)
                {
                    result.Add(
                        Range.Create(
                            previousRange.To.GetComplementation(),
                            range.From.GetComplementation()));
                }
                previousRange = range;
            }

            if (compositeRange.ContainingRange.To.HasValue)
            {
                result.Add(
                    Range.Create(
                        compositeRange.ContainingRange.To.GetComplementation(),
                        RangeBoundaryTo <T> .PositiveInfinity));
            }

            return(new CompositeRange <T>(result, UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged));
        }
Exemplo n.º 29
0
        public static void TestRangeWithValue()
        {
            var range = Range.Create(1, 2);

            AreEqual(Range.Create(0, 3), range.WithValues(i => i - 1, i => i + 1));

            range = Range.CreateExclusiveFrom(1, 2);
            AreEqual(Range.CreateExclusiveFrom(0, 3), range.WithValues(i => i - 1, i => i + 1));

            range = Range.CreateExclusive(1, 2);
            AreEqual(Range.CreateExclusive(2, 3), range.WithValues(i => i + 1));

            var toInf  = (double?)double.PositiveInfinity;
            var range2 = Range.CreateExclusive(1, toInf);

            IsTrue(range2.WithValues(i => (double?)null).IsInfinite);
            range2 = Range.Create(double.NegativeInfinity, toInf);
            AreEqual(range2, range2.WithValues(i => i - 1, i => i + 1));
        }
        public CompositeRange <T> GetComplementation()
        {
            if (IsEmpty)
            {
                // ReSharper disable once ArrangeStaticMemberQualifier
                // Used for codegen
                return(CompositeRange <T> .Infinite);
            }

            var result = new List <Range <T> >();

            if (ContainingRange.From.HasValue)
            {
                result.Add(
                    Range.Create(
                        RangeBoundaryFrom <T> .NegativeInfinity,
                        ContainingRange.From.GetComplementation()));
            }

            var previousRange = Range <T> .Empty;

            foreach (var range in GetMergedRanges())
            {
                if (previousRange.IsNotEmpty)
                {
                    result.Add(
                        Range.Create(
                            previousRange.To.GetComplementation(),
                            range.From.GetComplementation()));
                }
                previousRange = range;
            }

            if (ContainingRange.To.HasValue)
            {
                result.Add(
                    Range.Create(
                        ContainingRange.To.GetComplementation(),
                        RangeBoundaryTo <T> .PositiveInfinity));
            }

            return(new CompositeRange <T>(result, UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged));
        }