// (c) Copyright Microsoft Corporation. // This source is subject to the Microsoft Public License (Ms-PL). // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. using System; using System.Collections.Generic; using System.Globalization; namespace System.Windows.Controls.DataVisualization { /// /// A range of values. /// /// The type of the values. /// Preview public struct Range where T : IComparable { /// /// A flag that determines whether the range is empty or not. /// private bool _hasData; /// /// Gets a value indicating whether the range is empty or not. /// public bool HasData { get { return _hasData; } } /// /// The maximum value in the range. /// private T _maximum; /// /// Gets the maximum value in the range. /// public T Maximum { get { if (!HasData) { throw new InvalidOperationException(Properties.Resources.Range_get_Maximum_CannotReadTheMaximumOfAnEmptyRange); } return _maximum; } } /// /// The minimum value in the range. /// private T _minimum; /// /// Gets the minimum value in the range. /// public T Minimum { get { if (!HasData) { throw new InvalidOperationException(Properties.Resources.Range_get_Minimum_CannotReadTheMinimumOfAnEmptyRange); } return _minimum; } } /// /// Initializes a new instance of the Range class. /// /// The minimum value. /// The maximum value. public Range(T minimum, T maximum) { if (minimum == null) { throw new ArgumentNullException("minimum"); } if (maximum == null) { throw new ArgumentNullException("maximum"); } _hasData = true; _minimum = minimum; _maximum = maximum; int compareValue = ValueHelper.Compare(minimum, maximum); if (compareValue == 1) { throw new InvalidOperationException(Properties.Resources.Range_ctor_MaximumValueMustBeLargerThanOrEqualToMinimumValue); } } /// /// Compare two ranges and return a value indicating whether they are /// equal. /// /// Left-hand side range. /// Right-hand side range. /// A value indicating whether the ranges are equal. public static bool operator ==(Range leftRange, Range rightRange) { if (!leftRange.HasData) { return !rightRange.HasData; } if (!rightRange.HasData) { return !leftRange.HasData; } return leftRange.Minimum.Equals(rightRange.Minimum) && leftRange.Maximum.Equals(rightRange.Maximum); } /// /// Compare two ranges and return a value indicating whether they are /// not equal. /// /// Left-hand side range. /// Right-hand side range. /// A value indicating whether the ranges are not equal. /// public static bool operator !=(Range leftRange, Range rightRange) { return !(leftRange == rightRange); } /// /// Adds a range to the current range. /// /// A range to add to the current range. /// A new range that encompasses the instance range and the /// range parameter. public Range Add(Range range) { if (!this.HasData) { return range; } else if (!range.HasData) { return this; } T minimum = ValueHelper.Compare(this.Minimum, range.Minimum) == -1 ? this.Minimum : range.Minimum; T maximum = ValueHelper.Compare(this.Maximum, range.Maximum) == 1 ? this.Maximum : range.Maximum; return new Range(minimum, maximum); } /// /// Compares the range to another range. /// /// A different range. /// A value indicating whether the ranges are equal. public bool Equals(Range range) { return this == range; } /// /// Compares the range to an object. /// /// Another object. /// A value indicating whether the other object is a range, /// and if so, whether that range is equal to the instance range. /// public override bool Equals(object obj) { Range range = (Range)obj; if (range == null) { return false; } return this == range; } /// /// Returns a value indicating whether a value is within a range. /// /// The value. /// Whether the value is within the range. public bool Contains(T value) { return ValueHelper.Compare(Minimum, value) <= 0 && ValueHelper.Compare(value, Maximum) <= 0; } /////// /////// Returns a new range that contains the value. /////// /////// The value to extend the range to. /////// The range which contains the value. ////public Range ExtendTo(T value) ////{ //// if (!HasData) //// { //// return new Range(value, value); //// } //// if (ValueHelper.Compare(Minimum, value) > 0) //// { //// return new Range(value, Maximum); //// } //// else if (ValueHelper.Compare(Maximum, value) < 0) //// { //// return new Range(Minimum, value); //// } //// return this; ////} /// /// Returns a value indicating whether two ranges intersect. /// /// The range to compare against this range. /// A value indicating whether the ranges intersect. public bool IntersectsWith(Range range) { if (!this.HasData || !range.HasData) { return false; } Func, Range, bool> rightCollidesWithLeft = (leftRange, rightRange) => (ValueHelper.Compare(rightRange.Minimum, leftRange.Maximum) <= 0 && ValueHelper.Compare(rightRange.Minimum, leftRange.Minimum) >= 0) || (ValueHelper.Compare(leftRange.Minimum, rightRange.Maximum) <= 0 && ValueHelper.Compare(leftRange.Minimum, rightRange.Minimum) >= 0); return rightCollidesWithLeft(this, range) || rightCollidesWithLeft(range, this); } /// /// Computes a hash code value. /// /// A hash code value. public override int GetHashCode() { if (!HasData) { return 0; } int num = 0x5374e861; num = (-1521134295 * num) + EqualityComparer.Default.GetHashCode(Minimum); return ((-1521134295 * num) + EqualityComparer.Default.GetHashCode(Maximum)); } /// /// Returns the string representation of the range. /// /// The string representation of the range. public override string ToString() { if (!this.HasData) { return Properties.Resources.Range_ToString_NoData; } else { return string.Format(CultureInfo.CurrentCulture, Properties.Resources.Range_ToString_Data, this.Minimum, this.Maximum); } } } }