7 releases
0.1.0-alpha.13 | Jun 10, 2024 |
---|---|
0.1.0-alpha.12 | May 4, 2024 |
0.1.0-alpha.11 | Jun 30, 2023 |
0.1.0-alpha.10 | Apr 24, 2023 |
0.1.0-alpha.4 |
|
#2471 in Rust patterns
Used in unsized-vec
65KB
1K
SLoC
emplacable
Return values of unsized types, like [i32]
or dyn Any
, from functions,
with a mechanism similar to placement new.
Written to support the unsized-vec
crate, but is independent of it.
Experimental, and requires nightly Rust.
lib.rs
:
Machinery to support functions that return unsized values.
Written to support the unsized-vec
crate, but is independent of it.
Requires nightly Rust.
Unsized values can take many forms:
-
On stable Rust, values of unsized types like [
str
],[u8]
, anddyn Any
are generally encountered behind a pointer, like&str
orBox<dyn Any>
. -
Nightly Rust provides limited support for passing unsized values by value as arguments to functions, using the
unsized_fn_params
feature. There is alsounsized_locals
, for storing these values on the stack using alloca. (However, that feature is "incomplete" and this crate doesn't make use of it). But even with thse two feature gates enabled, functions cannot return unsized values directly. Also, the only way to produce a by-value unsized value in today's Rust is by dereferencing a [Box
]; this crate provides theunsize
macro to work around this limitation. -
For functions that return unsized values, this crate provides the
Emplacable
type. Functions that want to return a value of typeT
, whereT
is unsized, return anEmplacable<T, _>
instead.Emplacable<T>
wraps a closure; that closure contains instructions for writing out aT
to a caller-provided region of memory. Other functions accept theEmplacable
as an argument and call its contained closure to write out theT
to some allocation provided by them. For example, this crate provides thebox_new_with
function, which turns anEmplacable<T>
into aBox<T>
.
Converting between types
I have | I want | I can use |
---|---|---|
[i32; 2] |
[i32] |
unsize |
[i32; 2] |
Emplacable<[i32; 2], _> |
Into::into |
[i32] |
Emplacable<[i32], _> |
with_emplacable_for |
[i32] |
Box<[i32]> |
box_new |
Box<[i32; 2]> |
Box<[i32]> |
CoerceUnsized |
Box<[i32]> |
[i32] |
dereference the box with * |
Box<[i32]> |
Emplacable<[i32], _> |
Into::into |
Vec<i32> |
Emplacable<[i32], _> |
Into::into |
Emplacable<[i32; 2], _> |
[i32; 2] |
Emplacable::get |
Emplacable<[i32; 2], _> |
Emplacable<[i32], _> |
Into::into |
Emplacable<[i32; 2], _> |
Emplacable<dyn Debug, _> |
Emplacable::unsize |
Emplacable<[i32], _> |
Box<[i32]> |
box_new_with |
Emplacable<[i32], _> |
Vec<i32> |
Into::into |
Emplacable<[i32], _> |
Rc<[i32]> |
Into::into |
Emplacable<[i32], _> |
Arc<[i32]> |
Into::into |
&[i32] |
Box<[i32]> |
Into::into |
&[i32] |
Emplacable<[i32], _> |
Into::into |
You can replace [i32; 2]
and [i32]
above by any pair of types (T
, U
)
such that T: Unsize<U>
.
A note on examples
This crate has very few examples, as it provides tools to work with unsized types
but no fun things that use the tools. If you want more usage examples,
check out unsized-vec
's documentation and the examples
folder on GitHub.