public sealed class CharEnumerator : IEnumerator, ICloneable
{
private string str;
- private int idx;
- private int len;
+ private int index;
+ private int length;
+ // Representation invariant:
+ // length == str.Length
+ // -1 <= index <= length
// Constructor
internal CharEnumerator (string s)
{
str = s;
- idx = -1;
- len = s.Length;
+ index = -1;
+ length = s.Length;
}
// Property
public char Current
{
- get { if (idx == -1)
- throw new InvalidOperationException ("The position is not valid.");
+ get {
+ if (index == -1 || index == length)
+ throw new InvalidOperationException
+ ("The position is not valid.");
- return str [idx];
+ return str [index];
}
}
object IEnumerator.Current
{
- get { if (idx == -1)
- throw new InvalidOperationException ("The position is not valid");
+ get {
+ if (index == -1 || index == length)
+ throw new InvalidOperationException
+ ("The position is not valid");
- return str [idx];
+ return str [index];
}
}
public object Clone ()
{
CharEnumerator x = new CharEnumerator (str);
- x.idx = idx;
+ x.index = index;
return x;
}
public bool MoveNext ()
{
- if (len < 0)
- return false;
-
- idx++;
+ // Representation invariant holds: -1 <= index <= length
+
+ index ++;
+
+ // Now: 0 <= index <= length+1;
+ // <=>
+ // 0 <= index < length (OK) ||
+ // length <= index <= length+1 (Out of bounds)
- if (idx > len) {
- idx = -2;
- return false;
+ if (index >= length) {
+ index = length;
+ // Invariant restored:
+ // length == index
+ // =>
+ // -1 <= index <= length
+ return false;
}
-
- return true;
+ else
+ return true;
}
public void Reset ()
{
- idx = -1;
-
+ index = -1;
}
}
}