Auto merge of #82703 - iago-lito:nonzero_add_mul_pow, r=m-ou-se
Implement nonzero arithmetics for NonZero types. Hello'all, this is my first PR to this repo. Non-zero natural numbers are stable by addition/multiplication/exponentiation, so it makes sense to make this arithmetic possible with `NonZeroU*`. The major pitfall is that overflowing underlying `u*` types possibly lead to underlying `0` values, which break the major invariant of `NonZeroU*`. To accommodate it, only `checked_` and `saturating_` operations are implemented. Other variants allowing wrapped results like `wrapping_` or `overflowing_` are ruled out *de facto*. `impl Add<u*> for NonZeroU* { .. }` was considered, as it panics on overflow which enforces the invariant, but it does not so in release mode. I considered forcing `NonZeroU*::add` to panic in release mode by deferring the check to `u*::checked_add`, but this is less explicit for the user than directly using `NonZeroU*::checked_add`. Following `@Lokathor's` advice on zulip, I have dropped the idea. `@poliorcetics` on Discord also suggested implementing `_sub` operations, but I'd postpone this to another PR if there is a need for it. My opinion is that it could be useful in some cases, but that it makes less sense because non-null natural numbers are not stable by subtraction even in theory, while the overflowing problem is just about technical implementation. One thing I don't like is that the type of the `other` arg differs in every implementation: `_add` methods accept any raw positive integer, `_mul` methods only accept non-zero values otherwise the invariant is also broken, and `_pow` only seems to accept `u32` for a reason I ignore but that seems consistent throughout `std`. Maybe there is a better way to harmonize this? This is it, Iope I haven't forgotten anything and I'll be happy to read your feedback.
Showing
想要评论请 注册 或 登录