# Ranged integers [nightly only]
**Note: the library relies on the incomplete Rust features:**
- It causes ICEson some Rust toolchains,
- The usage may increase the time compilation time heavily.
- The current version (0.11.0) was tested on nightly-2026-01-31.
[Documentation at docs.rs](https://docs.rs/ranged_integers)
[Sudoku example](https://github.com/disiamylborane/ranged_integers/blob/master/examples/sudoku.rs)
[Changelog](https://github.com/disiamylborane/ranged_integers/blob/master/CHANGELOG.md)
Provides a generic type `Ranged<MIN, MAX>` representing an integer
within a specified range with the following features:
- **Auto data size**. The data size is chosen guided by the range specified, so
`sizeof<Ranged<-50, 50>>` is 1, while `sizeof<Ranged<-20_000, 100_000>>` is 4.
- **Auto bounds recalculation**. During arithmetic operations, the bounds of
the results are calculated at compile time, so the errors such as possible
overflow and zero division are caught.
- **Array slicing**. The fixed size arrays may be indexed with a ranged integer
having the fitting bounds, so the bounds check is performed at compile time.
The result of the slicing yields arrays rather than unsized slices.
- **Const compatibility**. The Ranged operations work in const context.
## Example
```rust
#![allow(incomplete_features)]
#![feature(adt_const_params, generic_const_exprs)]
extern crate ranged_integers;
use ranged_integers::*;
// Consider a simple race game. The player rolls a
// die and then moves forward, backward or forward
// with the double speed according to some rules.
enum MoveType {MoveForward, DoubleSpeed, MoveBackward}
// Get a die roll using a standard random number generator
fn roll_die(rng: &mut dyn rand::RngCore) -> Ranged<1, 6> {
let random: u8 = rng.gen();
// The consistency is proved at compile time:
// r!(6) means Ranged<6,6> with the value 6
// r!(1) means Ranged<1,1> with the value 1
// u8 % Ranged<6, 6> = Ranged<0, 5>
// Ranged<0, 5> + Ranged<1, 1> = Ranged<1, 6>
random % r!(6) + r!(1)
}
// Calculate where the player must move
// The result fits the range -6..=12
fn move_player(
move_type: MoveType,
dice_points: Ranged<1, 6>
) -> Ranged<-6, 12>
{
match move_type {
MoveType::MoveForward => {
// Expand 1..=6 to -6..=12
dice_points.expand()
}
MoveType::DoubleSpeed => {
let mv = dice_points*r!(2); // Ranged<2, 12>
mv.expand() // Expand to -6..=12
}
MoveType::MoveBackward => {
let mv = -dice_points; // Ranged<-6, -1>
mv.expand() // Expand to -6..=12
}
}
}
```