typst / ecow

Compact, clone-on-write vector and string.
Apache License 2.0
205 stars 16 forks source link

Feature request: make `EcoVec::new()` const #27

Closed Kmeakin closed 1 year ago

Kmeakin commented 1 year ago

It would be nice if EcoVec::new() were callable in const contexts, to match Vec::new()

laurmaedje commented 1 year ago

Unfortunately, it is not possible in the current design because EcoVec::new depends on a static and const fns can't reference statics.

Vec initializes its pointer with NonNull::dangling and uses its capacity to track whether it is allocated. EcoVec in comparison initializes its pointer with the address of a static SENTINEL value and uses that to track whether it is allocated. Using NonNull::dangling isn't possible because we have no other means to track whether we are allocated and NonNull::dangling could be a valid pointer to an allocation.

Null cannot be used in either case because a slice's pointer can't be null and we want deref to slice to be a no-op (that's a design goal).

Kmeakin commented 1 year ago

Could the sign bit in len be used as the allocated flag? Allocations of more than isize::MAX are not allowed in Rust, so self.len > (isize::MAX as usize) could be used to signal an unallocated EcoVec

laurmaedje commented 1 year ago

Then EcoVec<T>'s deref to [T] isn't a no-op once again. Moreover, EcoString (which uses EcoVec internally) uses that bit to distinguish between inline and heap (EcoVec<u8>) representation.

Kmeakin commented 1 year ago

Possible implementation: https://github.com/typst/ecow/pull/28

laurmaedje commented 1 year ago

Implemented in https://github.com/typst/ecow/pull/28.

I'll publish a new release soon.

flyingmutant commented 1 year ago

Sorry for the ping, any news about the release?

laurmaedje commented 1 year ago

@flyingmutant I'll make one later today.

laurmaedje commented 1 year ago

@flyingmutant I've just released ecow 0.1.2.