pub struct Construe<T, const N: usize> { /* private fields */ }
Expand description
Alternative to Vec
for const
Used to write const
functions as though they have a dynamically sized buffer (i.e. a Vec
).
It requires calling the function twice: on the first run, which uses N = 0
, the Construe
just pretends to store the items it is given, and it only tracks how many there are.
Then wherever this function is invoked can use Construe::needs_len
to determine the size of the buffer (i.e. the correct N
) that is needed and invoke the same function again, but with a “real” buffer instead.
Implementations§
source§impl<T> Construe<T, 0>
impl<T> Construe<T, 0>
sourcepub const fn start() -> Self
pub const fn start() -> Self
Create a Construe
instance without the buffer
This instance will behave (almost) exactly the same as the instance that has the buffer.
Crucially, it is used exactly the same, allowing you to write const
functions that collect items into it as though it were a variably-sized buffer.
Then, you simply call those functions twice: the first run (N = 0
, using this constructor) determines the amount of space you need for the second run (where you use Construe::new
with N =
Construe::needs_len
from before), which actually stores the collected items.
Obviously, this requires that the functions are deterministic (though it will just panic if not).
sourcepub const fn needs_len(&self) -> usize
pub const fn needs_len(&self) -> usize
Amount of items supposed to be stored in the buffer
This is the same as Construe::len
, but it exists as a separate method that’s only implemented for N = 0
so that the const N: usize
generic parameter on functions returning this can be inferred as 0
for the first run.
source§impl<T, const N: usize> Construe<T, N>
impl<T, const N: usize> Construe<T, N>
sourcepub const fn new() -> Self
pub const fn new() -> Self
Create a Construe
instance (with or without the buffer)
Like Construe::start
but for any N
, allowing you to write functions that create their own Construe
.
They’ll need a const N
generic, which the call site will use to indicate whether this is the first or second run.
sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Amount of items stored (or supposed to be stored) in the buffer
sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Whether there are no items (supposed to be) stored in the buffer
sourcepub const fn push(self, item: T) -> (Self, Option<T>)
pub const fn push(self, item: T) -> (Self, Option<T>)
Add item to the buffer
Note that this takes self
by-value: since &mut
references aren’t yet stable in const
contexts, we have to keep reassigning the output of the function to the variable.
On the first run, when the buffer isn’t available yet, this returns the item inside the Option
.
This is necessary because there’s no way to restrict T
to not have a destructor (which can’t be used by const
functions).
By giving back the T
in case we can’t store it, we avoid taking on the responsibility to drop it.
use construe::Construe;
// `mut` because we pass it by-value
let mut construe = Construe::start();
// `.0` to ignore (i.e. drop) the `Option<&str>`
construe = construe.push("something").0;
sourcepub const unsafe fn steal_from_slice(self, slice: &[T]) -> Self
pub const unsafe fn steal_from_slice(self, slice: &[T]) -> Self
Perform a bitwise copy of the slice contents into the buffer
This function is untested.
If at all possible, loop over the slice and use Construe::push
instead.
For Copy
types, use copy_from
instead.
Safety
Essentially, this function takes ownership of the contents of the slice.
For several reasons, it is not currently possible to accept (and use) a [T; M]
array by value.
Because of this, the caller must pass in a slice of an array it owns, and then drop/forget the array immediately after this function returns.
This function may not be called outside of const
contexts or with a T
that needs to be dropped.