# Where is std::num::Saturating? (Going to pre-RFC!)

**URL:** <https://internals.rust-lang.org/t/where-is-std-saturating-going-to-pre-rfc/13053>\
**Category:** libs\
**Created:** [September 13, 2020, 7:50pm UTC](https://internals.rust-lang.org/t/where-is-std-saturating-going-to-pre-rfc/13053 "2020-09-13T19:50:58Z")\
**Posts on this page:** 1\
**Showing post:** 27

<div class="post-metadata">

**Author:** ![pdolezal](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pdolezal/32/7137_2.png) [@pdolezal](https://internals.rust-lang.org/u/pdolezal)\
**Post date:** [November 1, 2020, 9:56pm UTC](https://internals.rust-lang.org/t/where-is-std-saturating-going-to-pre-rfc/13053/27 "2020-11-01T21:56:45Z")

</div>

Because it seems that more people would like to close the gap, I prepared a pre-RFC. Thanks for your comments in advance.

* * *

- Feature Name: `missing_integer_wrappers`
- Start Date: 2020-10-10
- RFC PR:
- Rust Issue:

# Summary

This RFC proposes the addition of `Saturating`, `Overflowing` and `Checked` types in the `std::num` module.

# Motivation

For convenience, the `std::num` module provides a `Wrapping` type. This type improves ergonomy of wrapping arithmetics. However, the remaining operation modes (saturating, overflowing and checked) lack similar support. This RFC suggests to close this gap and make this part of the `std::num` module complete.

According to [this discussion on Rust Internals](https://internals.rust-lang.org/t/where-is-std-saturating/13053), closing the gap would be appreciated. For instance, checked operations are considered essential for secure implementations of many types of cryptography.

# Guide-level explanation

The default semantics of integer arithmetic operations consider an overflow to be an error and panics in debug mode. Built-in integer types provide methods for altenative semantics, which provide better control of the outcome. For instance `wrapping_add` performs wrapping (modular) addition, or `checked_add` returns an `Option` with the `None` variant when the result overflows.

However, using these methods can be cumbersome and worse readable than arithmetic operators. The `Wrapping`, `Saturating`, `Overflowing` and `Checked` types allow natural use of arithmetic operators with alternative semantics (as indicated by their names):

```rust
let value = (Checked(u32::MAX) + Checked(2)) / Checked(8);
// The computation encountered an overflow, so the overall result is None
assert_eq!(None, value.0);

```

# Reference-level explanation

The `Saturating<T>` can be almost identical to the existing `Wrapping<T>` type, it just has to delegate to `T::saturating_*` methods instead of `T::wrapping_*`.

The `Checked<T>` type wraps an `Option<T>` type:

```rust
pub struct Checked<T>(pub Option<T>);

```

It delegates to `T::checked_*` methods if none operand of the operation is `None`. If an operand is `None` or the delegated method invocation returns `None`, the result wraps `None` as well.

The `Overflowing<T>` type wraps `(T, bool)`:

```rust
pub Overflowing<T>(pub T, pub bool);

```

It delegates to `T::overflowing_*` methods and just wraps their result, hence the `bool` component tracks whether an overflow occurred.

# Drawbacks

It increases the size of the standard library.

# Rationale and alternatives

All the types should provide similar user experience and features. Therefore the described design follows closely the existing implementation and avoids proposals that would affect it.

For the `Overflowing` type an alternative representation could be:

```rust
pub Overflowing<T>(pub Result<T, T>);

```

The `Err` variant carries the result that overflew. This approach allows leveraging the feature-rich `Result` type. The disadvantage is the difference from the return type of `overflowing_*` methods.

It is worth mentioning some features of the `Checked` type implemented in the [`checked`](https://crates.io/crates/checked) crate:

- It implements the `From` trait as a convenient alternative to `Checked(Some(number))`.
- It implements the `Deref` and `DerefMut` traits to return a reference to the wrapped `Option`.
- It implements binary operators that take a built-in integer as well.

Implementing the `From` trait seems to be harmless and it should be probably implemented for the `Wrapping` type anyway. It would provide the same means for wrapping an integer value, regardless of the actual structure of the wrapping type.

Implementing `Deref`, `DerefMut` and the binary operators is more questionable as the boundaries between arithmetic modes become less visible. And while it yet works for the `Checked` type, because the wrapped `Option` type can't be confused with a numeric type, it is not viable for the `Wrapping` and `Saturating` types.

# Prior art

- `std::num::Wrapping`
- [`checked`](https://crates.io/crates/checked) crate

# Future possibilities

It might be worth implementing macros for a scoped change of the arithmetic mode:

```rust
let value = checked! { a + b * foo(x) }.ok().map(|n| overflowing! { n + 1 })?;

```

The operands in the expressions are wrapped in the appropriate wrapper type. Here the advantage of using the `Result` type for the `Overflowing` wrapper are clearly visible.

---

_[View the full topic](https://internals.rust-lang.org/t/where-is-std-saturating-going-to-pre-rfc/13053)._
