#integer #const-generics #bounded #integer-arithmetic #nightly #refinement #arithmetic-operations

nightly no-std ranged_integers

由 const generics 驱动的编译时定义边界的整数限制

11 个不稳定版本

0.8.0 2024年2月7日
0.7.1 2023年2月1日
0.7.0 2022年9月30日
0.6.0 2021年9月24日
0.3.1 2021年7月26日

#1018 in Rust 模式

每月下载量:36

MIT 许可证

95KB
1.5K SLoC

范围整数 [仅 nightly 版本]

注意:该库在某些 Rust 工具链上会导致 ICE。 当前版本(0.8.0)已测试于 nightly-2024-02-04。

文档在 docs.rs

数独示例

变更日志

提供表示指定范围内的整数的泛型类型 Ranged<MIN, MAX>。它自动根据指定的范围选择数据大小(因此 Ranged<-50, 50> 是 1 字节,而 Ranged<-20_000, 100_000> 是 4 字节)并支持带自动边界重新计算的算术运算和范围迭代/固定大小数组索引。

转换和算术函数会在编译时捕获错误,例如可能的溢出和零除。

示例

#![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(
    mtype: 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
        }
    }
}

无运行时依赖