Remove use of Option<T> inside of RingBuf

Fix for task in Metabug #18009

This changes much of about how RingBuf functions. `lo`, `nelts` are replaced by a more traditional `head` and`tail`. The `Vec<Option<T>>` is replaced by a bare pointer that is managed by the `RingBuf` itself. This also expects the ring buffer to always be size that is a power of 2.

This change also includes a number of new tests to cover the some areas that could be of concern with manual memory management.

The benchmarks have been reworked since the old ones were benchmarking of the Ring buffers growth rather then the actual test.

## Benchmark
**Before:**
```
test ringbuf::tests::bench_grow_1025                       ... bench:      9200 ns/iter (+/- 100)
test ringbuf::tests::bench_iter_1000                       ... bench:      1341 ns/iter (+/- 34)
test ringbuf::tests::bench_mut_iter_1000                   ... bench:      2250 ns/iter (+/- 44)
test ringbuf::tests::bench_new                             ... bench:        22 ns/iter (+/- 0)
test ringbuf::tests::bench_pop_100                         ... bench:       351 ns/iter (+/- 3)
test ringbuf::tests::bench_pop_front_100                   ... bench:      1169 ns/iter (+/- 61)
test ringbuf::tests::bench_push_back_100                   ... bench:       244 ns/iter (+/- 3)
test ringbuf::tests::bench_push_front_100                  ... bench:       246 ns/iter (+/- 5)
```
**After:**
```
test ringbuf::tests::bench_grow_1025                       ... bench:      4005 ns/iter (+/- 96)
test ringbuf::tests::bench_iter_1000                       ... bench:       657 ns/iter (+/- 7)
test ringbuf::tests::bench_mut_iter_1000                   ... bench:       633 ns/iter (+/- 7)
test ringbuf::tests::bench_new                             ... bench:        15 ns/iter (+/- 0)
test ringbuf::tests::bench_pop_100                         ... bench:       210 ns/iter (+/- 0)
test ringbuf::tests::bench_pop_front_100                   ... bench:       179 ns/iter (+/- 1)
test ringbuf::tests::bench_push_back_100                   ... bench:       187 ns/iter (+/- 1)
test ringbuf::tests::bench_push_front_100                  ... bench:       174 ns/iter (+/- 2)
```
There are a few ways we can choose the size. 
```rust
// Current (or will be when I fix the issue pointed out by Gankro)
// avoids a branching, but wastes one space. can cause strange
// behavior if size is chooses as a power of 2 (which is common)
capacity = next_power_of_two(size + 1);

// Avoids branching by using a flag to indicate if the ringbuf is full
// adds branches to check size and move the head/tail.
capacity = next_power_of_two(size);

// Capacity can be any size. Needs more care when dealing with the wrap
// and calculating the length of filled positions.
capacity = size;

// Capacity can be any size. Uses a modulus operations to to calculate the
// head/tail and length. Should be branch less but uses a slow integer division.
// wastes a space to make the math work correctly.
capacity = size + 1;
```

I'm not heavily opinionated on which is best. The current solutions is going to be the fastest as far as index calculation. But might be slower since it uses the most space which can cause performance issues with cache. This second point is not going to be reflected in the benchmarks since they are too small to show this type of cache behavior.

One thing to keep in mind is that we want to select a solution that will be fast on slower platforms. Like in-order arm cores. These may not have the best branch prediction performance, so benchmarking on the latest greatest intel processor might be misleading.