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