667 lines · 29.9 KB · C#
RawDownload
//******************************************************************************************************//  Range.cs - Gbtc////  Copyright © 2015, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  06/30/2015 - Stephen C. Wills//       Generated original version of source code.////****************************************************************************************************** using System;using System.Collections.Generic;using System.Linq; namespace GSF{    /// <summary>    /// Represents a range of values defined by start and end value.    /// </summary>    public class Range<T>    {        #region [ Constructors ]         /// <summary>        /// Creates a new instance of the <see cref="Range{T}"/> class using the default comparer.        /// </summary>        /// <param name="start">The start value of the range.</param>        /// <param name="end">The end value of the range.</param>        public Range(T start, T end)        {            Start = start;            End = end;        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets the start value of the range.        /// </summary>        public T Start { get; }         /// <summary>        /// Gets the end value of the range.        /// </summary>        public T End { get; }         #endregion         #region [ Methods ]         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(T value)        {            return Contains(value, Comparer<T>.Default);        }         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(T value, IComparer<T> comparer)        {            return Contains(value, comparer.Compare);        }         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(T value, Comparison<T> comparison)        {            return comparison(Start, value) <= 0 && comparison(value, End) <= 0;        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<T> range)        {            return Contains(range, Comparer<T>.Default);        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<T> range, IComparer<T> comparer)        {            return Contains(range, comparer.Compare);        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<T> range, Comparison<T> comparison)        {            return comparison(Start, range.Start) <= 0 && comparison(range.End, End) <= 0;        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<T> range)        {            return Overlaps(range, Comparer<T>.Default);        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<T> range, IComparer<T> comparer)        {            return Overlaps(range, comparer.Compare);        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<T> range, Comparison<T> comparison)        {            return comparison(Start, range.End) <= 0 && comparison(range.Start, End) <= 0;        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>        /// <returns>The range that fully encompasses the merged ranges.</returns>        public Range<T> Merge(Range<T> range)        {            return Merge(range, Comparer<T>.Default);        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The range that fully encompasses the merged ranges.</returns>        public Range<T> Merge(Range<T> range, IComparer<T> comparer)        {            return Merge(range, comparer.Compare);        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The range that fully encompasses the merged ranges.</returns>        public Range<T> Merge(Range<T> range, Comparison<T> comparison)        {            T start = comparison(Start, range.Start) <= 0 ? Start : range.Start;            T end = comparison(End, range.End) >= 0 ? End : range.End;            return new Range<T>(start, end);        }         #endregion         #region [ Static ]         // Static Methods         /// <summary>        /// Merges all ranges in a collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges to be merged.</param>        /// <returns>A range that is the result of merging all ranges in the collection.</returns>        public static Range<T> Merge(IEnumerable<Range<T>> ranges)        {            return Merge(ranges, Comparer<T>.Default);        }         /// <summary>        /// Merges all ranges in a collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges to be merged.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>A range that is the result of merging all ranges in the collection.</returns>        public static Range<T> Merge(IEnumerable<Range<T>> ranges, Comparer<T> comparer)        {            return Merge(ranges, comparer.Compare);        }         /// <summary>        /// Merges all ranges in a collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges to be merged.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>A range that is the result of merging all ranges in the collection.</returns>        public static Range<T> Merge(IEnumerable<Range<T>> ranges, Comparison<T> comparison)        {            return ranges.Aggregate((range1, range2) => range1.Merge(range2, comparison));        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <returns>The collection of merged ranges.</returns>        public static IEnumerable<Range<T>> MergeConsecutiveOverlapping(IEnumerable<Range<T>> ranges)        {            return MergeConsecutiveOverlapping(ranges, Comparer<T>.Default);        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The collection of merged ranges.</returns>        public static IEnumerable<Range<T>> MergeConsecutiveOverlapping(IEnumerable<Range<T>> ranges, IComparer<T> comparer)        {            return MergeConsecutiveOverlapping(ranges, comparer.Compare);        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The collection of merged ranges.</returns>        public static IEnumerable<Range<T>> MergeConsecutiveOverlapping(IEnumerable<Range<T>> ranges, Comparison<T> comparison)        {            Range<T> currentRange = null;             foreach (Range<T> range in ranges)            {                if ((object)currentRange == null)                {                    currentRange = range;                }                else if (currentRange.Overlaps(range, comparison))                {                    currentRange = currentRange.Merge(range, comparison);                }                else                {                    yield return currentRange;                    currentRange = range;                }            }             if ((object)currentRange != null)                yield return currentRange;        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <returns>The collection of merged ranges.</returns>        /// <remarks>This method does not preserve the order of the source collection.</remarks>        public static IEnumerable<Range<T>> MergeAllOverlapping(IEnumerable<Range<T>> ranges)        {            return MergeAllOverlapping(ranges, Comparer<T>.Default);        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The collection of merged ranges.</returns>        /// <remarks>This method does not preserve the order of the source collection.</remarks>        public static IEnumerable<Range<T>> MergeAllOverlapping(IEnumerable<Range<T>> ranges, Comparison<T> comparison)        {            return MergeAllOverlapping(ranges, Comparer<T>.Create(comparison));        }         /// <summary>        /// Merges all consecutive groups of overlapping ranges in a        /// collection and returns the resulting collection of ranges.        /// </summary>        /// <param name="ranges">The collection of ranges.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="T"/>.</param>        /// <returns>The collection of merged ranges.</returns>        /// <remarks>This method does not preserve the order of the source collection.</remarks>        public static IEnumerable<Range<T>> MergeAllOverlapping(IEnumerable<Range<T>> ranges, IComparer<T> comparer)        {            return MergeConsecutiveOverlapping(ranges.OrderBy(range => range.Start, comparer));        }         #endregion    }     /// <summary>    /// Represents a range of values defined by a start and end value with encapsulated state.    /// </summary>    /// <remarks>    /// This class provides flexibility in allowing the user to define their own state and how it is merged.    /// Because of potentially undesirable behavior which could result from merging objects inherited from    /// this class, the class has been sealed to prevent inheritance.    /// </remarks>    public sealed class Range<TRange, TState>    {        #region [ Constructors ]         /// <summary>        /// Creates a new instance of the <see cref="Range{TRange, TState}"/> class using the default comparer.        /// </summary>        /// <param name="start">The start value of the range.</param>        /// <param name="end">The end value of the range.</param>        /// <param name="state">The state object encapsulated by the range.</param>        public Range(TRange start, TRange end, TState state)        {            Start = start;            End = end;            State = state;        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets the start value of the range.        /// </summary>        public TRange Start { get; }         /// <summary>        /// Gets the end value of the range.        /// </summary>        public TRange End { get; }         /// <summary>        /// Gets the state encapsulated by the range.        /// </summary>        public TState State { get; }         #endregion         #region [ Methods ]         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(TRange value)        {            return Contains(value, Comparer<TRange>.Default);        }         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(TRange value, IComparer<TRange> comparer)        {            return Contains(value, comparer.Compare);        }         /// <summary>        /// Determines whether the range contains the given value.        /// </summary>        /// <param name="value">The value to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the value exists within the range; false otherwise.</returns>        public bool Contains(TRange value, Comparison<TRange> comparison)        {            return comparison(Start, value) <= 0 && comparison(value, End) <= 0;        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<TRange, TState> range)        {            return Contains(range, Comparer<TRange>.Default);        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<TRange, TState> range, IComparer<TRange> comparer)        {            return Contains(range, comparer.Compare);        }         /// <summary>        /// Determines whether the range contains the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the given range exists within this range; false otherwise.</returns>        public bool Contains(Range<TRange, TState> range, Comparison<TRange> comparison)        {            return comparison(Start, range.Start) <= 0 && comparison(range.End, End) <= 0;        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<TRange, TState> range)        {            return Overlaps(range, Comparer<TRange>.Default);        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<TRange, TState> range, IComparer<TRange> comparer)        {            return Overlaps(range, comparer.Compare);        }         /// <summary>        /// Determines whether the range overlaps with the given range.        /// </summary>        /// <param name="range">The range to be compared with.</param>        /// <param name="comparison">The comparison used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>True if the ranges overlap; false otherwise.</returns>        public bool Overlaps(Range<TRange, TState> range, Comparison<TRange> comparison)        {            return comparison(Start, range.End) <= 0 && comparison(range.Start, End) <= 0;        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>        /// <returns>The range that fully encompasses the merged ranges.</returns>        /// <exception cref="InvalidOperationException"><typeparamref name="TState"/> is not <see cref="IMergeable{TState}"/>.</exception>        public Range<TRange, TState> Merge(Range<TRange, TState> range)        {            return Merge(range, Comparer<TRange>.Default);        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>        /// <param name="comparer">The comparer used to compare objects of type <typeparamref name="TRange"/>.</param>        /// <returns>The range that fully encompasses the merged ranges.</returns>        /// <exception cref="InvalidOperationException"><typeparamref name="TState"/> is not <see cref="IMergeable{TState}"/>.</exception>        public Range<TRange, TState> Merge(Range<TRange, TState> range, IComparer<TRange> comparer)        {            return Merge(range, comparer.Compare);        }         /// <summary>        /// Merges two ranges into one range that fully encompasses both ranges.        /// </summary>        /// <param name="range">The range to be merged with this one.</param>

Lines 1–500 of 667.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t