Before, to achieve a capacity of 16 elements RingBuffer used an array of 17
elements under the hood. Now the same can be accomplished with an array of 16
elements.
This simplifies the bounds of RingBuffer but it's technically a breaking change.
This change adds an overhead of 1 cycle to the enqueue and dequeue operations.
This commit also documents that using capacities that are powers of two results
in better performance (modulo operations become shifts). This was not documented
before and due to the mismatch of capacity and array size a RB with capacity of
15 performed better than one with a capacity of 16.
43: Put all const functions behind a const-fn feature r=japaric a=XOSplicer
## Purpose
This PR introduces the `const-fn` feature gate, which when enabled makes most `new` methods `const`
and therefore usable for initializing `static` variables.
The idea was introduced in #40 with the purpose to come closer to targeting stable rust.
`const` functions are currently only available on rust nightly (tracking issue: [const fn tracking issue (RFC 911)](https://github.com/rust-lang/rust/issues/24111)).
In order to target stable rust this feature is made opt-in.
This feature is a **breaking change** as users of the library now need to explicitly enable it by changing their `Cargo.toml`:
```
...
[dependencies]
heapless = { version = "0.4.0", features = ["const-fn"] }
...
```
## Approach
The implementation of the feature mainly consist of the `const_fn!` macro, which takes a function with `const` modifier
and removes the modifier if the feature gate is not activated.
For the `const` functions a test is intoduced that checks if `static` variables can be initialized.
These tests are only active if the feature is active.
I have not found a way to make doc-test depend on a feature. Therefore some doc-tests are adapted, so that no static initialization is necessary.
The `ci/script.sh` is adapted to also tests with the `--all-feature` flag
## Future
When in the future the `const_fn` rust feature becomes stable, this feature gate **might become active by default**.
Closes#41 .
Co-authored-by: Felix <stegmaier.felix@gmail.com>
Co-authored-by: Felix Stegmaier <stegmaier.felix@gmail.com>
Co-authored-by: Felix Stegmaier <felix.stegmaier@hpe.com>
45: Fix incorrect length calculation for RingBuffer when head > tail r=japaric a=ReeceStevens
When the head index becomes greater than the tail, the `len()` function returns the incorrect length. This causes iterations over ring buffers to stop early as well, since they use the same calculation.
This PR adds two (very minimal) tests that demonstrate the error.
Co-authored-by: Reece Stevens <reecestevens24@gmail.com>
44: Added Consumer::ready and Producer::ready indicating if it is ready t… r=japaric a=Frans-Willem
…o enqueue/dequeue.
I needed this to use it with a serial library. e.g. without it:
```
if let Some(x) = serial.read() {
if let Err(x) = producer.enqueue(x) {
// Now what ?
}
}
```
With the ready flag:
```
if producer.ready() {
if let Some(x) = serial.read() {
producer.enqueue(x).unwrap();
}
}
```
Co-authored-by: Frans-Willem Hardijzer <fw@hardijzer.nl>
39: Implement FromIterator for Vec r=japaric a=XOSplicer
As discussed in #36
Panics when the vector can not hold all values supplied by the iterator.
Calling `unwrap` on the result might not be the best choice here.
It might be better to match the result and have a custom panic message.
Is this the best possible behavior?
Co-authored-by: Felix <stegmaier.felix@gmail.com>
Co-authored-by: Felix Stegmaier <stegmaier.felix@gmail.com>
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
38: Implement IntoIter for Vec r=japaric a=XOSplicer
~~This implementation uses vec::reverse and vec::pop to move the content of the vector out of it.~~
It might give more performance to avoid the `reverse` and read each element individually. In the end the unmoved items need to be dropped.
Co-authored-by: Felix <stegmaier.felix@gmail.com>
Co-authored-by: Felix Stegmaier <stegmaier.felix@gmail.com>