typenum/
lib.rs

1//! This crate provides type-level numbers evaluated at compile time. It depends only on libcore.
2//!
3//! The traits defined or used in this crate are used in a typical manner. They can be divided into
4//! two categories: **marker traits** and **type operators**.
5//!
6//! Many of the marker traits have functions defined, but they all do essentially the same thing:
7//! convert a type into its runtime counterpart, and are really just there for debugging. For
8//! example,
9//!
10//! ```rust
11//! use typenum::{Integer, N4};
12//!
13//! assert_eq!(N4::to_i32(), -4);
14//! ```
15//!
16//! **Type operators** are traits that behave as functions at the type level. These are the meat of
17//! this library. Where possible, traits defined in libcore have been used.
18//!
19//! For example, the `Add` trait is implemented for both unsigned and signed integers, where its
20//! associated type `Output` represents the sum of the two integers.
21//!
22//! ```rust
23//! use std::ops::Add;
24//! use typenum::{Integer, P3, P4};
25//!
26//! type X = <P3 as Add<P4>>::Output;
27//! assert_eq!(<X as Integer>::to_i32(), 7);
28//! ```
29//!
30//! In addition, helper aliases are defined for type operators. For example, the above snippet
31//! could be replaced with
32//!
33//! ```rust
34//! use typenum::{Integer, Sum, P3, P4};
35//!
36//! type X = Sum<P3, P4>;
37//! assert_eq!(<X as Integer>::to_i32(), 7);
38//! ```
39//!
40//! Documented in each module is the full list of type operators implemented.
41
42#![no_std]
43#![forbid(unsafe_code)]
44#![warn(missing_docs)]
45#![cfg_attr(feature = "strict", deny(missing_docs))]
46#![cfg_attr(feature = "strict", deny(warnings))]
47#![doc(html_root_url = "https://docs.rs/typenum/1.19.0")]
48#![cfg_attr(docsrs, feature(doc_cfg))]
49
50// For debugging macros:
51// #![feature(trace_macros)]
52// trace_macros!(true);
53
54use core::cmp::Ordering;
55
56pub mod bit;
57mod gen;
58pub mod int;
59pub mod marker_traits;
60pub mod operator_aliases;
61pub mod private;
62pub mod type_operators;
63pub mod uint;
64
65pub mod array;
66
67pub use crate::{
68    array::{ATerm, TArr},
69    gen::consts,
70    int::{NInt, PInt},
71    marker_traits::*,
72    operator_aliases::*,
73    type_operators::*,
74    uint::{UInt, UTerm},
75};
76
77#[doc(no_inline)]
78#[rustfmt::skip]
79pub use consts::*;
80
81#[cfg(feature = "const-generics")]
82pub use crate::gen::generic_const_mappings;
83
84#[cfg(feature = "const-generics")]
85#[doc(no_inline)]
86pub use generic_const_mappings::{Const, ToUInt, U};
87
88/// A potential output from `Cmp`, this is the type equivalent to the enum variant
89/// `core::cmp::Ordering::Greater`.
90#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
91#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
92pub struct Greater;
93
94/// A potential output from `Cmp`, this is the type equivalent to the enum variant
95/// `core::cmp::Ordering::Less`.
96#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
97#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
98pub struct Less;
99
100/// A potential output from `Cmp`, this is the type equivalent to the enum variant
101/// `core::cmp::Ordering::Equal`.
102#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
103#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
104pub struct Equal;
105
106/// Returns `core::cmp::Ordering::Greater`
107impl Ord for Greater {
108    #[inline]
109    fn to_ordering() -> Ordering {
110        Ordering::Greater
111    }
112}
113
114/// Returns `core::cmp::Ordering::Less`
115impl Ord for Less {
116    #[inline]
117    fn to_ordering() -> Ordering {
118        Ordering::Less
119    }
120}
121
122/// Returns `core::cmp::Ordering::Equal`
123impl Ord for Equal {
124    #[inline]
125    fn to_ordering() -> Ordering {
126        Ordering::Equal
127    }
128}
129
130/// Asserts that two types are the same.
131#[macro_export]
132macro_rules! assert_type_eq {
133    ($a:ty, $b:ty) => {
134        const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
135            core::marker::PhantomData;
136    };
137}
138
139/// Asserts that a type is `True`, aka `B1`.
140#[macro_export]
141macro_rules! assert_type {
142    ($a:ty) => {
143        const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
144            core::marker::PhantomData;
145    };
146}
147
148mod sealed {
149    use crate::{
150        ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
151        Z0,
152    };
153
154    pub trait Sealed {}
155
156    impl Sealed for B0 {}
157    impl Sealed for B1 {}
158
159    impl Sealed for UTerm {}
160    impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
161
162    impl Sealed for Z0 {}
163    impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
164    impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
165
166    impl Sealed for Less {}
167    impl Sealed for Equal {}
168    impl Sealed for Greater {}
169
170    impl Sealed for ATerm {}
171    impl<V, A> Sealed for TArr<V, A> {}
172}