The Enumerator<T> concept currently prescribes the following usage pattern:
- zero or one
move_first
- if zero
move_first, done
- else if one
move_first and false, done
- else one
move_first and true, proceed to (2)
- zero or more
current
- zero or one
move_next
- if zero
move_next, done
- if one
move_next and false, done
- else one
move_next and true, proceed to (2)
The Enumerator<T> concept should prescribe the following usage pattern:
- zero or one
move_first
- if zero
move_first, done
- else if one
move_first and false, zero or more move_next (all returning false) then done
- else one
move_first and true, proceed to (2)
- zero or more
current
- zero or one
move_next
- if zero
move_next, done
- if one
move_next and false, zero or more move_next (all returning false) then done
- else one
move_next and true, proceed to (2)
This differs from the previous semantics, which forbid calling move_next any more after having gotten a false return from move_first or move_next. That previous restriction imposed by the semantics was both unnecessary and (it turns out) inconvenient. Operations like merge, union, intersect, except, etc. can be implemented with less state if this restriction is relaxed.