Description
- integers <-> native
- floats<-> native
- Option <-> std::optional
- Result <-> std::expected (c++23...so far away)
- Tuple <-> std::tuple
- input_range <-> Iterator
- Vec <-> std::vector
- Array <-> std::array
- Slice/SliceMut <-> std::span
- Box <-> std::unique_ptr
- Can we convert errors to
unique_ptr<DynError>
? And strings?
- Can we convert errors to
References?
The tricky thing is when we have a reference type in the sus type.
Option<T&>
can convert tooptional<T*>
, butoptional<T*>
will convert toOption<T*>
.- Or should
Option<T&>
convert tooptional<T>
? - Same question for
Result<T&, E>
.
Vec
For Vec
, we can't construct a std::vector
with a pointer of our choosing, or rip the pointer out of it. So proposing that instead of Vec<T, Allocator>
we have Vec<T, Driver>
.
The Driver
will provide the Allocator
but it will also provide an abstract API that can choose how to store the Vec
's data. Then we provide two Drivers:
VecDriver
which uses theSlice
pointers in theVec
in-place to manage the memory (this is how the code is written today). The VecDriver is an empty class so it does not contribute to Vec's size at all.StdDriver
which stores astd::vector
inside it, and then mirrors thestd::vector
's pointers into theVec
'sSlice
pointers.
What this means is we can construct a Vec<T, StdDriver<T>>
from a std::vector
with just a (cheap) move of the std::vector
, and we can unwrap the Vec<T, StdDriver<T>>
back into a std::vector<T>
as well. The Vec
with a StdDriver
is necessarily larger, unless we commit ABI crimes and just read/write from the std::vector
as a char
array. That is another possible Driver option though.
Converting between Vec<T, StdDriver<T>>
and std::vector<T>
would be ~the same as a move of std::vector<T>
. Whereas converting between Vec<T>
and std::vector<T>
will require an allocation and a move of each item between buffers.
Because allocators are also a thing, the Driver would have an optional Allocator type parameter, so technically its Vec<T, Driver<Allocator>>
.