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, but their attached
18//! functions have not been implemented.
19//!
20//! For example, the `Add` trait is implemented for both unsigned and signed integers, but the
21//! `add` function is not. As there are never any objects of the types defined here, it wouldn't
22//! make sense to implement it. What is important is its associated type `Output`, which is where
23//! the addition happens.
24//!
25//! ```rust
26//! use std::ops::Add;
27//! use typenum::{Integer, P3, P4};
28//!
29//! type X = <P3 as Add<P4>>::Output;
30//! assert_eq!(<X as Integer>::to_i32(), 7);
31//! ```
32//!
33//! In addition, helper aliases are defined for type operators. For example, the above snippet
34//! could be replaced with
35//!
36//! ```rust
37//! use typenum::{Integer, Sum, P3, P4};
38//!
39//! type X = Sum<P3, P4>;
40//! assert_eq!(<X as Integer>::to_i32(), 7);
41//! ```
42//!
43//! Documented in each module is the full list of type operators implemented.
44
45#![no_std]
46#![forbid(unsafe_code)]
47#![warn(missing_docs)]
48#![cfg_attr(feature = "strict", deny(missing_docs))]
49#![cfg_attr(feature = "strict", deny(warnings))]
50#![doc(html_root_url = "https://docs.rs/typenum/1.18.0")]
51#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
52
53// For debugging macros:
54// #![feature(trace_macros)]
55// trace_macros!(true);
56
57use core::cmp::Ordering;
58
59pub mod bit;
60mod gen;
61pub mod int;
62pub mod marker_traits;
63pub mod operator_aliases;
64pub mod private;
65pub mod type_operators;
66pub mod uint;
67
68pub mod array;
69
70pub use crate::{
71    array::{ATerm, TArr},
72    gen::consts,
73    int::{NInt, PInt},
74    marker_traits::*,
75    operator_aliases::*,
76    type_operators::*,
77    uint::{UInt, UTerm},
78};
79
80#[doc(no_inline)]
81#[rustfmt::skip]
82pub use consts::*;
83
84#[cfg(feature = "const-generics")]
85pub use crate::gen::generic_const_mappings;
86
87#[cfg(feature = "const-generics")]
88#[doc(no_inline)]
89pub use generic_const_mappings::{Const, ToUInt, U};
90
91/// A potential output from `Cmp`, this is the type equivalent to the enum variant
92/// `core::cmp::Ordering::Greater`.
93#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
94#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
95pub struct Greater;
96
97/// A potential output from `Cmp`, this is the type equivalent to the enum variant
98/// `core::cmp::Ordering::Less`.
99#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
100#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
101pub struct Less;
102
103/// A potential output from `Cmp`, this is the type equivalent to the enum variant
104/// `core::cmp::Ordering::Equal`.
105#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
106#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
107pub struct Equal;
108
109/// Returns `core::cmp::Ordering::Greater`
110impl Ord for Greater {
111    #[inline]
112    fn to_ordering() -> Ordering {
113        Ordering::Greater
114    }
115}
116
117/// Returns `core::cmp::Ordering::Less`
118impl Ord for Less {
119    #[inline]
120    fn to_ordering() -> Ordering {
121        Ordering::Less
122    }
123}
124
125/// Returns `core::cmp::Ordering::Equal`
126impl Ord for Equal {
127    #[inline]
128    fn to_ordering() -> Ordering {
129        Ordering::Equal
130    }
131}
132
133/// Asserts that two types are the same.
134#[macro_export]
135macro_rules! assert_type_eq {
136    ($a:ty, $b:ty) => {
137        const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
138            core::marker::PhantomData;
139    };
140}
141
142/// Asserts that a type is `True`, aka `B1`.
143#[macro_export]
144macro_rules! assert_type {
145    ($a:ty) => {
146        const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
147            core::marker::PhantomData;
148    };
149}
150
151mod sealed {
152    use crate::{
153        ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
154        Z0,
155    };
156
157    pub trait Sealed {}
158
159    impl Sealed for B0 {}
160    impl Sealed for B1 {}
161
162    impl Sealed for UTerm {}
163    impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
164
165    impl Sealed for Z0 {}
166    impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
167    impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
168
169    impl Sealed for Less {}
170    impl Sealed for Equal {}
171    impl Sealed for Greater {}
172
173    impl Sealed for ATerm {}
174    impl<V, A> Sealed for TArr<V, A> {}
175}