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