main
 1namespace domain
 2{
 3  using System;
 4  using utility;
 5
 6  public static class Ranges
 7  {
 8    public static IRange<T> UpTo<T>(this T start, T end) where T: IComparable<T>, IIncrementable<T>
 9    {
10      return new Range<T>(start, end);
11    }
12  }
13
14  public interface IRange<T> : IVisitable<T> where T : IComparable<T>
15  {
16    void Accept(Action<T> action);
17    bool Contains(T item);
18  }
19
20  public class Range<T> : IRange<T> where T : IComparable<T>, IIncrementable<T>
21  {
22    T start;
23    T end;
24
25    public Range(T start, T end)
26    {
27      this.start = start;
28      this.end = end;
29    }
30
31    public void Accept(IVisitor<T> visitor) 
32    {
33      Accept(visitor.Visit);
34    }
35
36    public void Accept(Action<T> visitor)
37    {
38      var next = this.start;
39      var last = this.end.Next();
40      while(!next.Equals(last))
41      {
42        visitor(next);
43        next = next.Next();
44      }
45    }
46
47    public bool Contains(T item)
48    {
49      return start.CompareTo(item) <= 0 && end.CompareTo(item) > 0;
50    }
51  }
52
53  public interface IIncrementable<T>
54  {
55    T Next();
56  }
57}