Convert query_range to an iterator & factor the region field out of the variants

The iterator is significantly faster, especially for large/deep trees, since it
avoids allocating so much (a single backing stack that only grows a few times).

    test bench_large_range_query       ... bench:     36122 ns/iter (+/- 9220)
    test bench_large_range_query_iter  ... bench:      6164 ns/iter (+/- 472)
    test bench_medium_range_query      ... bench:       488 ns/iter (+/- 141)
    test bench_medium_range_query_iter ... bench:       154 ns/iter (+/- 85)
    test bench_small_range_query       ... bench:        88 ns/iter (+/- 36)
    test bench_small_range_query_iter  ... bench:        79 ns/iter (+/- 14)

This also reduces the number of `contains` checks to 1 for each point
yielded, down from `O(depth(p))` in the old version.


The `region` refactoring reduces some duplication, stops the internal variants being exposed publicly and seems to make the iterator slightly faster too.