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 
68 use core::cmp::Ordering;
69 
70 #[cfg(feature = "force_unix_path_separator")]
71 mod generated {
72     include!(concat!(env!("OUT_DIR"), "/op.rs"));
73     include!(concat!(env!("OUT_DIR"), "/consts.rs"));
74 }
75 
76 #[cfg(not(feature = "force_unix_path_separator"))]
77 mod generated {
78     include!(env!("TYPENUM_BUILD_OP"));
79     include!(env!("TYPENUM_BUILD_CONSTS"));
80 }
81 
82 pub mod bit;
83 pub mod int;
84 pub mod marker_traits;
85 pub mod operator_aliases;
86 pub mod private;
87 pub mod type_operators;
88 pub mod uint;
89 
90 pub mod array;
91 
92 pub use crate::{
93     array::{ATerm, TArr},
94     consts::*,
95     generated::consts,
96     int::{NInt, PInt},
97     marker_traits::*,
98     operator_aliases::*,
99     type_operators::*,
100     uint::{UInt, UTerm},
101 };
102 
103 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
104 /// `core::cmp::Ordering::Greater`.
105 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
106 pub struct Greater;
107 
108 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
109 /// `core::cmp::Ordering::Less`.
110 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
111 pub struct Less;
112 
113 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
114 /// `core::cmp::Ordering::Equal`.
115 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
116 pub struct Equal;
117 
118 /// Returns `core::cmp::Ordering::Greater`
119 impl Ord for Greater {
120     #[inline]
to_ordering() -> Ordering121     fn to_ordering() -> Ordering {
122         Ordering::Greater
123     }
124 }
125 
126 /// Returns `core::cmp::Ordering::Less`
127 impl Ord for Less {
128     #[inline]
to_ordering() -> Ordering129     fn to_ordering() -> Ordering {
130         Ordering::Less
131     }
132 }
133 
134 /// Returns `core::cmp::Ordering::Equal`
135 impl Ord for Equal {
136     #[inline]
to_ordering() -> Ordering137     fn to_ordering() -> Ordering {
138         Ordering::Equal
139     }
140 }
141 
142 /// Asserts that two types are the same.
143 #[macro_export]
144 macro_rules! assert_type_eq {
145     ($a:ty, $b:ty) => {
146         const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
147             core::marker::PhantomData;
148     };
149 }
150 
151 /// Asserts that a type is `True`, aka `B1`.
152 #[macro_export]
153 macro_rules! assert_type {
154     ($a:ty) => {
155         const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
156             core::marker::PhantomData;
157     };
158 }
159 
160 mod sealed {
161     use crate::{
162         ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
163         Z0,
164     };
165 
166     pub trait Sealed {}
167 
168     impl Sealed for B0 {}
169     impl Sealed for B1 {}
170 
171     impl Sealed for UTerm {}
172     impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
173 
174     impl Sealed for Z0 {}
175     impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
176     impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
177 
178     impl Sealed for Less {}
179     impl Sealed for Equal {}
180     impl Sealed for Greater {}
181 
182     impl Sealed for ATerm {}
183     impl<V, A> Sealed for TArr<V, A> {}
184 }
185