当前位置: 首页 > news >正文

【typenum】 12 类型级数组(array.rs)

一、源码

代码实现了typenum库中的类型级数组功能,允许在编译时对类型数组进行操作和计算。

//! A type-level array of type-level numbers.
//!
//! It is not very featureful right now, and should be considered a work in progress.use core::ops::{Add, Div, Mul, Sub};use super::*;/// The terminating type for type arrays.
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
pub struct ATerm;impl TypeArray for ATerm {}/// `TArr` is a type that acts as an array of types. It is defined similarly to `UInt`, only its
/// values can be more than bits, and it is designed to act as an array. So you can only add two if
/// they have the same number of elements, for example.
///
/// This array is only really designed to contain `Integer` types. If you use it with others, you
/// may find it lacking functionality.
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
pub struct TArr<V, A> {first: V,rest: A,
}impl<V, A> TypeArray for TArr<V, A> {}/// Create a new type-level array. Only usable on Rust 1.13.0 or newer.
///
/// There's not a whole lot you can do with it right now.
///
/// # Example
/// ```rust
/// #[macro_use]
/// extern crate typenum;
/// use typenum::consts::*;
///
/// type Array = tarr![P3, N4, Z0, P38];
/// # fn main() { let _: Array; }
#[macro_export]
macro_rules! tarr {() => ( $crate::ATerm );($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );($n:ty | $rest:ty) => ( $crate::TArr<$n, $rest> );($n:ty, $($tail:ty),+ | $rest:ty) => ( $crate::TArr<$n, tarr![$($tail),+ | $rest]> );
}// ---------------------------------------------------------------------------------------
// Length/// Length of `ATerm` by itself is 0
impl Len for ATerm {type Output = U0;#[inline]fn len(&self) -> Self::Output {UTerm}
}/// Size of a `TypeArray`
impl<V, A> Len for TArr<V, A>
whereA: Len,Length<A>: Add<B1>,Sum<Length<A>, B1>: Unsigned,
{type Output = Add1<Length<A>>;#[inline]fn len(&self) -> Self::Output {self.rest.len() + B1}
}// ---------------------------------------------------------------------------------------
// FoldAdd/// Hide our `Null` type
const _: () = {/// A type which contributes nothing when adding (i.e. a zero)pub struct Null;impl<T> Add<T> for Null {type Output = T;fn add(self, rhs: T) -> Self::Output {rhs}}impl FoldAdd for ATerm {type Output = Null;}
};impl<V, A> FoldAdd for TArr<V, A>
whereA: FoldAdd,FoldSum<A>: Add<V>,
{type Output = Sum<FoldSum<A>, V>;
}// ---------------------------------------------------------------------------------------
// FoldMul/// Hide our `Null` type
const _: () = {/// A type which contributes nothing when multiplying (i.e. a one)pub struct Null;impl<T> Mul<T> for Null {type Output = T;fn mul(self, rhs: T) -> Self::Output {rhs}}impl FoldMul for ATerm {type Output = Null;}
};impl<V, A> FoldMul for TArr<V, A>
whereA: FoldMul,FoldProd<A>: Mul<V>,
{type Output = Prod<FoldProd<A>, V>;
}// ---------------------------------------------------------------------------------------
// Add arrays
// Note that two arrays are only addable if they are the same length.impl Add<ATerm> for ATerm {type Output = ATerm;#[inline]fn add(self, _: ATerm) -> Self::Output {ATerm}
}impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
whereAl: Add<Ar>,Vl: Add<Vr>,
{type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;#[inline]fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {TArr {first: self.first + rhs.first,rest: self.rest + rhs.rest,}}
}// ---------------------------------------------------------------------------------------
// Subtract arrays
// Note that two arrays are only subtractable if they are the same length.impl Sub<ATerm> for ATerm {type Output = ATerm;#[inline]fn sub(self, _: ATerm) -> Self::Output {ATerm}
}impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
whereVl: Sub<Vr>,Al: Sub<Ar>,
{type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;#[inline]fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {TArr {first: self.first - rhs.first,rest: self.rest - rhs.rest,}}
}// ---------------------------------------------------------------------------------------
// Multiply an array by a scalarimpl<Rhs> Mul<Rhs> for ATerm {type Output = ATerm;#[inline]fn mul(self, _: Rhs) -> Self::Output {ATerm}
}impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
whereV: Mul<Rhs>,A: Mul<Rhs>,Rhs: Copy,
{type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;#[inline]fn mul(self, rhs: Rhs) -> Self::Output {TArr {first: self.first * rhs,rest: self.rest * rhs,}}
}impl Mul<ATerm> for Z0 {type Output = ATerm;#[inline]fn mul(self, _: ATerm) -> Self::Output {ATerm}
}impl<U> Mul<ATerm> for PInt<U>
whereU: Unsigned + NonZero,
{type Output = ATerm;#[inline]fn mul(self, _: ATerm) -> Self::Output {ATerm}
}impl<U> Mul<ATerm> for NInt<U>
whereU: Unsigned + NonZero,
{type Output = ATerm;#[inline]fn mul(self, _: ATerm) -> Self::Output {ATerm}
}impl<V, A> Mul<TArr<V, A>> for Z0
whereZ0: Mul<A>,
{type Output = TArr<Z0, Prod<Z0, A>>;#[inline]fn mul(self, rhs: TArr<V, A>) -> Self::Output {TArr {first: Z0,rest: self * rhs.rest,}}
}impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
whereU: Unsigned + NonZero,PInt<U>: Mul<A> + Mul<V>,
{type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;#[inline]fn mul(self, rhs: TArr<V, A>) -> Self::Output {TArr {first: self * rhs.first,rest: self * rhs.rest,}}
}impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
whereU: Unsigned + NonZero,NInt<U>: Mul<A> + Mul<V>,
{type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;#[inline]fn mul(self, rhs: TArr<V, A>) -> Self::Output {TArr {first: self * rhs.first,rest: self * rhs.rest,}}
}// ---------------------------------------------------------------------------------------
// Divide an array by a scalarimpl<Rhs> Div<Rhs> for ATerm {type Output = ATerm;#[inline]fn div(self, _: Rhs) -> Self::Output {ATerm}
}impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
whereV: Div<Rhs>,A: Div<Rhs>,Rhs: Copy,
{type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;#[inline]fn div(self, rhs: Rhs) -> Self::Output {TArr {first: self.first / rhs,rest: self.rest / rhs,}}
}// ---------------------------------------------------------------------------------------
// Partial Divide an array by a scalarimpl<Rhs> PartialDiv<Rhs> for ATerm {type Output = ATerm;#[inline]fn partial_div(self, _: Rhs) -> Self::Output {ATerm}
}impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
whereV: PartialDiv<Rhs>,A: PartialDiv<Rhs>,Rhs: Copy,
{type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;#[inline]fn partial_div(self, rhs: Rhs) -> Self::Output {TArr {first: self.first.partial_div(rhs),rest: self.rest.partial_div(rhs),}}
}// ---------------------------------------------------------------------------------------
// Modulo an array by a scalar
use core::ops::Rem;impl<Rhs> Rem<Rhs> for ATerm {type Output = ATerm;#[inline]fn rem(self, _: Rhs) -> Self::Output {ATerm}
}impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
whereV: Rem<Rhs>,A: Rem<Rhs>,Rhs: Copy,
{type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;#[inline]fn rem(self, rhs: Rhs) -> Self::Output {TArr {first: self.first % rhs,rest: self.rest % rhs,}}
}// ---------------------------------------------------------------------------------------
// Negate an array
use core::ops::Neg;impl Neg for ATerm {type Output = ATerm;#[inline]fn neg(self) -> Self::Output {ATerm}
}impl<V, A> Neg for TArr<V, A>
whereV: Neg,A: Neg,
{type Output = TArr<Negate<V>, Negate<A>>;#[inline]fn neg(self) -> Self::Output {TArr {first: -self.first,rest: -self.rest,}}
}

二、核心概念

  1. 类型数组定义
  • ATerm:类型数组的终止类型,类似于空数组或链表中的nil
pub struct ATerm;
  • TArr<V, A>:类型数组节点,包含:

    • first:当前元素(类型V)

    • rest:剩余数组(类型A)

pub struct TArr<V, A> {first: V,rest: A,
}
  1. 创建类型数组的宏
    tarr!宏提供了创建类型数组的便捷语法:
tarr![P3, N4, Z0, P38]  // 创建包含4个元素的类型数组
tarr![P3 | rest]        // 创建以P3开头,后面接rest数组的类型数组

三、主要功能实现

  1. 数组长度计算
  • Len trait为类型数组提供长度计算能力

  • ATerm长度为0

  • TArr长度为1 + 剩余部分的长度

impl Len for ATerm {type Output = U0;
}impl<V, A> Len for TArr<V, A> where ... {type Output = Add1<Length<A>>;
}
  1. 数组运算
加法运算
  • 只能对相同长度的数组相加

  • 对应位置的元素相加

impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al> where ... {type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
}
减法运算
  • 只能对相同长度的数组相减

  • 对应位置的元素相减

impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al> where ... {type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
}
标量乘法
  • 数组每个元素乘以标量
impl<V, A, Rhs> Mul<Rhs> for TArr<V, A> where ... {type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
}
标量除法
  • 数组每个元素除以标量
impl<V, A, Rhs> Div<Rhs> for TArr<V, A> where ... {type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
}
取模运算
  • 数组每个元素对标量取模
impl<V, A, Rhs> Rem<Rhs> for TArr<V, A> where ... {type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
}
数组取反
  • 数组每个元素取反
impl<V, A> Neg for TArr<V, A> where ... {type Output = TArr<Negate<V>, Negate<A>>;
}
  1. 折叠操作
求和(FoldAdd)
  • 使用Null作为加法单位元(类似0)

  • 递归地对数组所有元素求和

impl<V, A> FoldAdd for TArr<V, A> where ... {type Output = Sum<FoldSum<A>, V>;
}
求积(FoldMul)
  • 使用Null作为乘法单位元(类似1)

  • 递归地对数组所有元素求积

impl<V, A> FoldMul for TArr<V, A> where ... {type Output = Prod<FoldProd<A>, V>;
}

四、设计特点

  1. 类型级递归:所有操作都是通过类型系统递归实现的

  2. 编译时计算:所有运算都在编译时完成,不产生运行时开销

  3. 类型安全:操作限制(如相同长度才能相加)通过类型系统保证

  4. 扩展性:可以方便地添加新的操作和功能

五、使用示例

use typenum::consts::*;
type Array1 = tarr![P3, N4, Z0, P38];
type Array2 = tarr![P1, P1, P1, P1];
type SumArray = <Array1 as Add<Array2>>::Output;  // tarr![P4, N3, P1, P39]

这段代码为typenum库提供了强大的类型级数组功能,使得在编译时进行复杂的数组操作成为可能,同时保持了类型安全和零运行时开销的特性。

http://www.xdnf.cn/news/520957.html

相关文章:

  • Node.js 框架
  • 20-HAL库
  • 进程控制总结
  • Spyglass:参数(parameter)及其设置方式
  • 考研数学积分学
  • supervisorctl守护进程
  • PCB设计实践(十九)PCB设计中NPN/PNP选型策略
  • C++(23):容器类<vector>
  • C++控制结构详解:if-else、switch、循环(for/while/do-while)
  • 嵌入式学习笔记 - U(S)ART 模块HAL 库函数总结
  • 开启健康生活的多元养生之道
  • Prism使用消息总线打开窗体的案例(中介者模式)
  • GBS 8.0服装裁剪计划软件在线试用
  • SAPROv5.7
  • Muduo网络库大总结
  • 大语言模型 vs NLTK/SpaCy:NLP工具的代际跃迁与互补之道
  • LORA 微调 - LoRA 介绍与 LoRA 微调指南
  • 最长公共子序列(LCS)
  • 网络编程套接字(二)
  • 17 C 语言数据类型转换与数据溢出回绕详解:隐式转换、显式转换、VS Code 警告配置、溢出回绕机制
  • 并发编程(4)
  • 中山市东区信息学竞赛2025 题目解析
  • CMake调试与详细输出选项解析
  • 基于区块链技术的智能汽车诊断与性能分析
  • 运行vscode编辑器源码
  • 课外活动:再次理解页面实例化PO对象的魔法方法__getattr__
  • 【免杀】C2免杀技术(五)动态API
  • C2S-Scale方法解读
  • [Android] 青木扫描全能文档3.0,支持自动扫描功能
  • 机器学习入门之朴素叶贝斯和决策树分类(四)