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::{N4, Integer};
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::{Sum, Integer, 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 
46 #![no_std]
47 #![warn(missing_docs)]
48 #![cfg_attr(feature = "i128", feature(i128_type))]
49 #![cfg_attr(feature = "strict", deny(missing_docs))]
50 #![cfg_attr(feature = "strict", deny(warnings))]
51 #![cfg_attr(feature = "cargo-clippy", deny(clippy))]
52 #![cfg_attr(feature = "cargo-clippy",
53             allow(type_complexity, len_without_is_empty, new_without_default_derive))]
54 
55 // For debugging macros:
56 // #![feature(trace_macros)]
57 // trace_macros!(true);
58 
59 use core::cmp::Ordering;
60 
61 include!(concat!(env!("OUT_DIR"), "/consts.rs"));
62 include!(concat!(env!("OUT_DIR"), "/op.rs"));
63 pub mod bit;
64 pub mod uint;
65 pub mod int;
66 pub mod private;
67 pub mod marker_traits;
68 pub mod type_operators;
69 pub mod operator_aliases;
70 
71 pub mod array;
72 
73 pub use consts::*;
74 pub use marker_traits::*;
75 pub use type_operators::*;
76 pub use operator_aliases::*;
77 
78 pub use uint::{UInt, UTerm};
79 pub use int::{NInt, PInt};
80 pub use array::{ATerm, TArr};
81 
82 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
83 /// `core::cmp::Ordering::Greater`.
84 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
85 pub struct Greater;
86 
87 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
88 /// `core::cmp::Ordering::Less`.
89 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
90 pub struct Less;
91 
92 /// A potential output from `Cmp`, this is the type equivalent to the enum variant
93 /// `core::cmp::Ordering::Equal`.
94 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
95 pub struct Equal;
96 
97 /// Returns `core::cmp::Ordering::Greater`
98 impl Ord for Greater {
99     #[inline]
to_ordering() -> Ordering100     fn to_ordering() -> Ordering {
101         Ordering::Greater
102     }
103 }
104 
105 /// Returns `core::cmp::Ordering::Less`
106 impl Ord for Less {
107     #[inline]
to_ordering() -> Ordering108     fn to_ordering() -> Ordering {
109         Ordering::Less
110     }
111 }
112 
113 /// Returns `core::cmp::Ordering::Equal`
114 impl Ord for Equal {
115     #[inline]
to_ordering() -> Ordering116     fn to_ordering() -> Ordering {
117         Ordering::Equal
118     }
119 }
120 
121 /// Asserts that two types are the same.
122 #[macro_export]
123 macro_rules! assert_type_eq {
124     ($a:ty, $b:ty) => (
125         let _: <$a as $crate::Same<$b>>::Output;
126     );
127 }
128 
129 /// Asserts that a type is `True`, aka `B1`.
130 #[macro_export]
131 macro_rules! assert_type {
132     ($a:ty) => (
133         let _: <$a as $crate::Same<True>>::Output;
134     );
135 }
136