Skip to content

Hierarchy for atomic types / precise casting? #24

Closed

Description

@vigna

Thank you for a much needed crate!

We have been very successful in replacing the type hierarchy in common_traits with num-primitive and num-crates in dsi-bitstream.

We were wondering if there's in the works something like num-primitive for atomic types (or we could try to write one).

Another thing that would be nice to have is a trait for conversion without loss of precision, like in az::StrictCast or common_traits::UpcastableInto. One can convert, say, between signed and unsigned types of the same size with a bit of juggling and AsPrimitive, but I haven't found any way to write a bound implying "this can be cast into a u32 without loss of precision".

Activity

  1. vigna commented on Mar 7, 2026

    @vigna
    Author

    Actually, I'll answer myself: Into<T> + AsPrimitive<T> is equivalent to common_traits::UpcastableInto<T>, albeit it does not support usize.

    The question remains open for atomic types.

  2. vigna commented on Mar 7, 2026

    @vigna
    Author

    And I created an atomic-primitive create to fill the void, replicating exactly the structure of num-primitive.

  3. cuviper commented on Mar 7, 2026

    @cuviper
    Member

    Thanks for the update, and sorry I didn't reply before. I think a separate atomic crate is a reasonable outcome though!

    Actually, I'll answer myself: Into<T> + AsPrimitive<T> is equivalent to common_traits::UpcastableInto<T>, albeit it does not support usize.

    I wonder why you need the as part at all for this, rather than Into<T> alone?

    It also looks like the UpcastableFrom/Into implementations never cross between signed/unsigned/float groups, but the primitive From/Into implementations do. Maybe that's fine for you, and anyway I don't think I'd try to add that kind of distinction to this crate either.

  4. vigna commented on Mar 7, 2026

    @vigna
    Author

    Thanks for the update, and sorry I didn't reply before. I think a separate atomic crate is a reasonable outcome though!

    I hope you don't mind if I borrowed some wording from num-primitive. Actually, I should add a link to remark the parallelism.

    I wonder why you need the as part at all for this, rather than Into<T> alone?

    It also looks like the UpcastableFrom/Into implementations never cross between signed/unsigned/float groups, but the primitive From/Into implementations do. Maybe that's fine for you, and anyway I don't think I'd try to add that kind of distinction to this crate either.

    The problem is with usize. The standard library has zero support. I can understand the rationale: implemented traits would vary with the pointer size.

    In the end, when I really had to test I used const expression blocks with an assert on the relevant sizeof, and I have an AsU128 trait for the more structured situations.

    BTW, would it be possible to have ONE and ZERO as constants? I understand they are in num-traits, but I find myself often using that crate just g
    for the constants, so I reimplement them. This crate really seems their right place...

  5. cuviper commented on Mar 10, 2026

    @cuviper
    Member

    BTW, would it be possible to have ONE and ZERO as constants? I understand they are in num-traits, but I find myself often using that crate just g
    for the constants, so I reimplement them. This crate really seems their right place...

    I'm torn, because I'm trying to keep to the principle that this crate doesn't really implement anything new, only wraps existing standard library functionality into a generic form. AsPrimitive strays a little from that, but at least that's still a language feature.

    At the same time, in my own personal projects using this crate, I also found that I really did need ZERO and ONE to get much of anything done. Maybe we can justify this (and avoid a slippery slope) by relating it to Sum and Product which are included already, since these values are also the sum/product results with empty iterators.

  6. cuviper commented on Mar 10, 2026

    @cuviper
    Member

    A wrinkle with the ZERO and Sum relationship is that the standard library somewhat recently switched to -0.0 for the sum of empty floating point iterators. See also rust-num/num-traits#352

  7. cuviper commented on Mar 17, 2026

    @cuviper
    Member

    I played a bit with ZERO and ONE here, but I fear it's a breaking change for any code that already has ConstZero or ConstOne in scope. This is "minor" being just a path ambiguity, but pretty annoying IMO.

    I just posted #26 as an alternative, providing CONST: [Self: 128] for all numbers that primitives have in common. Please let me know what you think over there!

  8. vigna commented on Mar 17, 2026

    @vigna
    Author

    Seems great—we have ZERO and ONE anyway in a local trait, and now we can define them without macros, which is great.

    One little request: any chance this can be backported to a 0.2.2 version? For a while we're stuck with Rust 1.85. I can put together a PR in case.

  9. cuviper commented on Mar 17, 2026

    @cuviper
    Member

    I can backport it, but it would have to follow the latest at each semver level -- i.e. 0.2.4 at 1.87 and 0.1.2 at 1.85. So the new versions would be 0.2.5 and 0.1.3, same MSRVs.

  10. vigna commented on Mar 17, 2026

    @vigna
    Author

    Ok... Indeed we had to fix =0.2.1 as the MSRV was changing been minor releases, which was causing compilation to fail. We need as_to, so probably we'll be able to use CONST later.

  11. cuviper commented on Mar 17, 2026

    @cuviper
    Member

    If you're on 2024 edition or you explicitly opt into the fallback resolver, then Cargo can figure that out for you, rather than pinning an exact version even for your dependents that could use newer. Either way, there's no room for me to insert a new CONST release in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions