`[begin, past-the-end)`

That is, we start at
`begin`

, include numbers `begin+1, begin+2, ...`

, upto, `past-the-end`

.
So, for example, `[0, 3) = [0, 1, 2]`

, while `[0, 1) = [0]`

, and `[0, 0) = []`

.
I am not allowed to use `[begin, end]`

, or `(before-begin, past-the-end)`

or
any such variation I represent and think of intervals.
`for/while/do while`

loops. `i != n`

or `i == m`

.
I am not allowed to write `i < n`

, `i <= n`

, `i > n`

, `i >= n`

for my `for`

loops.
`i`

in `for(int i = a; i != b; ++i)`

is to be thought of as
getting to/living right before" the values `[a, a+1, a+2, ... b-1]`

. In
ASCII-art:
```
|| a-1 || a || a+1 || ... || b-1 || b || b+1 ||
^^ ^^ ^^ ^^
(i=a) (i=a+1) (i=a+2) ... (i=b)
```

```
for(int i = begin; i != past-the-end; ++i) {
// NO: i from begin to past-the-end.
// YES: [i _getting to_ the beginning] till [i _getting_ past-the-end]
}
```

`i < n`

and `i != n`

. The former
makes on aware of when the loop runs; the latter of when the loop quits.
I wish to be cognizant of the precisely when a loop quits.
On writing `i != past-the-end`

, I know that we quit as soon as we
`i < n`

.
`[begin, past-the-end)`

is the same as `[begin, begin+length)`

. I've found this
to be of great help to flit between length-based-thoughts and
indexing-based-thoughts.
`0`

length `[begin, begin+length)`

holds when
`length`

is ```
for(int i = begin; i != begin + 0; ++ i) { ... }
```

does the right thing and iterates over no elements.
`-ve`

length `[begin, begin+length)`

holds even when `length`

is `(n-1)`

, and we want a segment
of length `-2`

from there, so our loop is:
```
for(int i = n-1; i != (n-1) + -2; i--) {
// loops over the correct segment.
}
```

`len`

,
- The first sub-array is
`[0, len)`

since it starts at location`0`

and has length`len`

. - Since we have taken
`len`

elements, the second sub-array must have length`n-len`

. It must start at index`len`

since`len`

is past-the-end for the first sub-array. So, the second sub-array has indeces`[len, n-len)`

.

`1, 2, 4, 8, ...`

which is common if one
is building data structures such as segment trees and fenwick trees,
in a half-open representation, this literally becomes `[a, a+1)`

,
`[a, a+2)`

, `[a, a+4)`

and so on. On the other hand, if one wants
to use closed interval based indexing, one needs to generate the
series $2^n - 1$, which is `[a, a+0]`

, `[a, a+3]`

, `[a, a+7]`

which is
slightly more finicky.
```
for(int i = 0; i < 5; i += 2) { ... }
```

the naive `i != 5`

translation will not work since `i`

only takes
on even numbers `[0, 2, 4, 6, ...]`

. For this, we can perform a
simple transformation and always make sure our loop variables increment
by `1`

. In a compiler, this is often called as "canonicalizing the loop
induction variable". In LLVM the canonicalization is
performed by the `-indvars`

pass .
The above example canonicalized becomes:
```
// btc = backedge taken count. How many times we have
// gone past the "back edge" of the loop to go back to the
// beginning of the loop.
for(int btc = 0; btc != 5 / 2; btc += 1) { const int i = btc * 2; }
```