danlehmann / arbitrary-int

A modern and lightweight implementation of arbitrary integers for Rust
MIT License
31 stars 12 forks source link

Feature request: `NonZeroU*` structs #46

Open al8n opened 1 month ago

al8n commented 1 month ago

Hi, thanks for the amazing crate. May I ask to support NonZeroU* structs?

vortexofdoom commented 1 week ago

Is your use case for these something that would be covered by a crate-wide niche optimization implementation? (ie. just having a NonZeroU* be the same size as a U*) A decent NonZeroU* wrapper would probably require that regardless (you wouldn't want a 2-byte NonZeroU4), and if it was there, I almost wonder whether it would even be worth including directly in the crate, since no further optimization would be needed to make a naive implementation take advantage of the niche optimization (since for all of the non-native types, there's already a niche even without excluding 0, and for native types you have std::num::NonZero to enable those optimizations.)

I'm hoping to get back to this soon, was just wondering if the niche optimization alone would be sufficient, as thus far this crate has leaned pretty heavily toward not adding a ton of stuff. It wouldn't be a terribly complex feature, though, and could reasonably be behind a cargo feature if it's decided that it merits doing.

al8n commented 1 week ago

Hi, in my use case, I just want NonZeroU* has the same size as U*.

vortexofdoom commented 1 week ago

Looking further into it, any kind of niche optimizations (including NonZero) will be kind of tricky to make work with the const generic structure of this crate. I don't exactly think it's impossible, but the long and short of it is that it will require the user facing structs to not directly contain a u32 or whatever, but instead a custom #[repr(C)] struct built from enums that enforce the compile-time limits.

You can get away with only specifying #[repr(u8)] enums for 7 bits and below (including 0), then building the rest out of those and u8, and const generics could possibly be leveraged in the building of these inner structs, but I'm not sure it could be kept as lightweight as the current implementation.