substrate_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#![cfg_attr(
51    feature = "cargo-clippy",
52    allow(
53        clippy::len_without_is_empty,
54        clippy::many_single_char_names,
55        clippy::new_without_default,
56        clippy::suspicious_arithmetic_impl,
57        clippy::type_complexity,
58        clippy::wrong_self_convention,
59    )
60)]
61#![cfg_attr(feature = "cargo-clippy", deny(clippy::missing_inline_in_public_items))]
62#![doc(html_root_url = "https://docs.rs/typenum/1.14.0")]
63
64// For debugging macros:
65// #![feature(trace_macros)]
66// trace_macros!(true);
67
68use core::cmp::Ordering;
69#[cfg(feature = "derive_scale")]
70use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
71
72#[cfg(feature = "force_unix_path_separator")]
73mod generated {
74    include!(concat!(env!("OUT_DIR"), "/op.rs"));
75    include!(concat!(env!("OUT_DIR"), "/consts.rs"));
76}
77
78#[cfg(not(feature = "force_unix_path_separator"))]
79mod generated {
80    include!(env!("TYPENUM_BUILD_OP"));
81    include!(env!("TYPENUM_BUILD_CONSTS"));
82}
83
84pub mod bit;
85pub mod int;
86pub mod marker_traits;
87pub mod operator_aliases;
88pub mod private;
89pub mod type_operators;
90pub mod uint;
91
92pub mod array;
93
94pub use crate::{
95    array::{ATerm, TArr},
96    consts::*,
97    generated::consts,
98    int::{NInt, PInt},
99    marker_traits::*,
100    operator_aliases::*,
101    type_operators::*,
102    uint::{UInt, UTerm},
103};
104
105/// A potential output from `Cmp`, this is the type equivalent to the enum variant
106/// `core::cmp::Ordering::Greater`.
107#[cfg_attr(
108    feature = "derive_scale",
109    derive(scale_info::TypeInfo, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen)
110)]
111#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
112pub struct Greater;
113
114/// A potential output from `Cmp`, this is the type equivalent to the enum variant
115/// `core::cmp::Ordering::Less`.
116#[cfg_attr(
117    feature = "derive_scale",
118    derive(scale_info::TypeInfo, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen)
119)]
120#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
121pub struct Less;
122
123/// A potential output from `Cmp`, this is the type equivalent to the enum variant
124/// `core::cmp::Ordering::Equal`.
125#[cfg_attr(
126    feature = "derive_scale",
127    derive(scale_info::TypeInfo, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen)
128)]
129#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
130pub struct Equal;
131
132/// Returns `core::cmp::Ordering::Greater`
133impl Ord for Greater {
134    #[inline]
135    fn to_ordering() -> Ordering {
136        Ordering::Greater
137    }
138}
139
140/// Returns `core::cmp::Ordering::Less`
141impl Ord for Less {
142    #[inline]
143    fn to_ordering() -> Ordering {
144        Ordering::Less
145    }
146}
147
148/// Returns `core::cmp::Ordering::Equal`
149impl Ord for Equal {
150    #[inline]
151    fn to_ordering() -> Ordering {
152        Ordering::Equal
153    }
154}
155
156/// Asserts that two types are the same.
157#[macro_export]
158macro_rules! assert_type_eq {
159    ($a:ty, $b:ty) => {
160        const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
161            core::marker::PhantomData;
162    };
163}
164
165/// Asserts that a type is `True`, aka `B1`.
166#[macro_export]
167macro_rules! assert_type {
168    ($a:ty) => {
169        const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
170            core::marker::PhantomData;
171    };
172}
173
174mod sealed {
175    use crate::{
176        ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
177        Z0,
178    };
179
180    pub trait Sealed {}
181
182    impl Sealed for B0 {}
183    impl Sealed for B1 {}
184
185    impl Sealed for UTerm {}
186    impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
187
188    impl Sealed for Z0 {}
189    impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
190    impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
191
192    impl Sealed for Less {}
193    impl Sealed for Equal {}
194    impl Sealed for Greater {}
195
196    impl Sealed for ATerm {}
197    impl<V, A> Sealed for TArr<V, A> {}
198}
199
200#[cfg(test)]
201#[cfg(feature = "derive_scale")]
202mod tests {
203    use crate::U64;
204    use scale_info::TypeInfo;
205
206    #[test]
207    fn scale_info_works() {
208        // it suffices if that code compiles
209        U64::type_info();
210    }
211}