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