/* * Karinto Library Project * * This software is distributed under a zlib-style license. * See license.txt for more information. */ using System; using System.Collections.Generic; namespace Karinto { /// /// 範囲を示す /// public class Range { #region constructors /// /// 終端を含む範囲 /// /// 最初の要素 /// 最後の要素 public Range(IComparable first, IComparable last) : this(first, last, false) { } /// /// 範囲 /// /// 最初の要素 /// 最後の要素 /// 終端を含むか否か(含まないときtrue) public Range(IComparable first, IComparable last, bool excludeEnd) { if (first.GetType() != last.GetType()) { throw new ArgumentException("The boundary elements must be same type."); } First = first; Last = last; ExcludesEnd = excludeEnd; } #endregion #region properties public IComparable First { get; private set; } public IComparable Last { get; private set; } public bool ExcludesEnd { get; private set; } #endregion #region public methods /// /// 対象が範囲内か調べる /// /// 対象 /// 範囲内か否か(範囲内ならtrue) public bool Includes(IComparable other) { if (other.CompareTo(First) < 0) return false; if (other.CompareTo(Last) > 0) return false; if (other.CompareTo(Last) == 0) return !ExcludesEnd; return true; } /// /// 両端に値を加算することで範囲を移動させる /// /// 変化量 public void Shift(double delta) { First = (double)First + delta; Last = (double)Last + delta; } /// /// 両端に値を加算することで範囲を移動させる /// /// 変化量 public void Shift(int delta) { First = (int)First + delta; Last = (int)Last + delta; } public IEnumerator GetEnumerator() { Int32 cursor = Convert.ToInt32(First); Int32 last = Convert.ToInt32(Last); while (cursor < last) { yield return cursor; cursor++; } if (cursor == last) { if (!ExcludesEnd) yield return cursor; } } /// /// イテレータブロック /// /// 刻み /// step刻みの範囲内の要素 public IEnumerable Step(Int32 step) { Int32 cursor = Convert.ToInt32(First); Int32 last = Convert.ToInt32(Last); while (cursor < last) { yield return cursor; cursor += step; } if (cursor == last) { if (!ExcludesEnd) yield return cursor; } } /// /// イテレータブロック /// /// 刻み /// step刻みの範囲内の要素 public IEnumerable Step(double stepWidth) { int i = 0; double first = Convert.ToDouble(First); double last = Convert.ToDouble(Last); double cursor = first; while (cursor < last) { yield return cursor; i++; cursor = first + stepWidth * i;//単純に加算していくと誤差が蓄積する } if (cursor == last) { if (!ExcludesEnd) yield return cursor; } } #endregion } }