Introduce Between clusivity

This commit is contained in:
Oliver Booth 2022-02-14 16:24:14 +00:00
parent 6c27227c3e
commit 64bcb34a11
3 changed files with 55 additions and 6 deletions

View File

@ -9,14 +9,26 @@ namespace X10D.Tests.Core
public class ComparableTests
{
/// <summary>
/// Tests for <see cref="ComparableExtensions.Between{T}" />.
/// Tests <see cref="ComparableExtensions.Between{T1, T2, T3}" />
/// </summary>
[TestMethod]
public void Between()
{
Assert.IsTrue(5.Between(2, 7));
Assert.IsTrue(10.Between(9, 11));
Assert.IsFalse(100.Between(80, 99));
const int lower = 5;
const int upper = 15;
const int value = 10;
Assert.IsTrue(value.Between(lower, upper), "value.Between(lower, upper)");
Assert.IsFalse(lower.Between(value, upper), "lower.Between(value, upper)");
Assert.IsFalse(upper.Between(lower, value), "upper.Between(lower, value)");
Assert.IsTrue(upper.Between(lower, upper, Clusivity.UpperInclusive), "upper.Between(lower, upper, Clusivity.UpperInclusive)");
Assert.IsTrue(upper.Between(lower, upper, Clusivity.Inclusive), "upper.Between(lower, upper, Clusivity.Inclusive)");
Assert.IsFalse(upper.Between(lower, upper, Clusivity.LowerInclusive), "upper.Between(lower, upper, Clusivity.LowerInclusive)");
Assert.IsTrue(lower.Between(lower, upper, Clusivity.LowerInclusive), "lower.Between(lower, upper, Clusivity.LowerInclusive)");
Assert.IsTrue(lower.Between(lower, upper, Clusivity.Inclusive), "lower.Between(lower, upper, Clusivity.Inclusive)");
Assert.IsFalse(lower.Between(lower, upper, Clusivity.UpperInclusive), "lower.Between(lower, upper, Clusivity.UpperInclusive)");
}
}
}

View File

@ -0,0 +1,28 @@
namespace X10D;
/// <summary>
/// Provides options for <see cref="ComparableExtensions.Between{T1, T2, T3}" /> clusivity.
/// </summary>
[Flags]
public enum Clusivity : byte
{
/// <summary>
/// Indicates that the comparison will be exclusive.
/// </summary>
Exclusive,
/// <summary>
/// Indicates that the comparison will treat the upper bound as exclusive.
/// </summary>
UpperInclusive,
/// <summary>
/// Indicates that the comparison will treat the lower bound as exclusive.
/// </summary>
LowerInclusive,
/// <summary>
/// Indicates that the comparison will treat both the upper and lower bound as exclusive.
/// </summary>
Inclusive
}

View File

@ -16,6 +16,7 @@ namespace X10D
/// <param name="value">The value to compare.</param>
/// <param name="lower">The exclusive lower bound.</param>
/// <param name="upper">The exclusive upper bound.</param>
/// <param name="clusivity">The comparison clusivity.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is between the <paramref name="lower" /> and
/// <paramref name="upper" />
@ -43,7 +44,7 @@ namespace X10D
/// // True
/// </code>
/// </example>
public static bool Between<T1, T2, T3>(this T1 value, T2 lower, T3 upper)
public static bool Between<T1, T2, T3>(this T1 value, T2 lower, T3 upper, Clusivity clusivity = Clusivity.Exclusive)
where T1 : IComparable<T2>, IComparable<T3>
where T2 : IComparable<T3>
where T3 : IComparable<T2>
@ -60,7 +61,15 @@ namespace X10D
nameof(lower));
}
return value.CompareTo(lower) > 0 && value.CompareTo(upper) < 0;
bool lowerComparison = (clusivity & Clusivity.LowerInclusive) != 0
? value.CompareTo(lower) >= 0
: value.CompareTo(lower) > 0;
bool upperComparison = (clusivity & Clusivity.UpperInclusive) != 0
? value.CompareTo(upper) <= 0
: value.CompareTo(upper) < 0;
return lowerComparison && upperComparison;
}
/// <summary>