1use super::*;
9use core::num::*;
10
11pub trait PrimitiveCollapse: private::Sealed
14{
15 fn collapse(&self) -> u8;
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Copy, Default, Ord, PartialOrd)]
39#[repr(transparent)]
40pub struct Primitive<T>(T);
41
42impl<T: PrimitiveCollapse+ Eq> Collapse for Primitive<T>
43{
44 #[inline(always)] fn collapse(&self) -> u8 {
45 self.0.collapse()
46 }
47}
48
49impl<T: PrimitiveCollapse+ Eq> Primitive<T>
50{
51 #[cfg(nightly)] #[inline] pub const fn new(value: T) -> Self
53 {
54 Self(value)
55 }
56 #[cfg(not(nightly))] #[inline] pub fn new(value: T) -> Self
58 {
59 Self(value)
60 }
61 #[inline] pub fn into_inner(self) -> T
63 {
64 self.0
65 }
66 #[inline] pub fn inner(&self) -> &T
72 {
73 &self.0
74 }
75 #[inline] pub fn inner_mut(&mut self) -> &mut T
77 {
78 &mut self.0
79 }
80
81 #[cfg(nightly)] #[inline] pub const fn into_inner_copy(self) -> T
87 where T: Copy
88 {
89 self.0
90 }
91 #[cfg(not(nightly))] #[inline(always)] #[deprecated = "This function should only be used on Rust nightly. Please use `into_inner` instead"] pub fn into_inner_copy(self) -> T
92 where T: Copy
93 {
94 self.0
95 }
96}
97
98impl<T> From<T> for Primitive<T>
99 where T: PrimitiveCollapse + Eq
100{
101 #[inline] fn from(from: T) -> Self
102 {
103 Self::new(from)
104 }
105}
106
107macro_rules! prim {
108 ($name:ty) => {
109 impl private::Sealed for $name{}
110 impl PrimitiveCollapse for $name
111 {
112 #[inline(always)] fn collapse(&self) -> u8 {
113 (*self) as u8
114 }
115 }
116 };
117 ($name:ty: +) => {
118 impl private::Sealed for $name{}
119 impl PrimitiveCollapse for $name
120 {
121 #[inline(always)] fn collapse(&self) -> u8 {
122 self.get() as u8
123 }
124 }
125 };
126 ($name:ty: ^) => {
127 impl private::Sealed for $name{}
128 impl PrimitiveCollapse for $name
129 {
130 #[inline(always)] fn collapse(&self) -> u8 {
131 super::collapse(<$name>::to_ne_bytes(*self))
132 }
133 }
134 };
135 ($name:ty: ^+) => {
136 impl private::Sealed for $name{}
137 impl PrimitiveCollapse for $name
138 {
139 #[inline(always)] fn collapse(&self) -> u8 {
140 super::collapse(self.get().to_ne_bytes())
141 }
142 }
143 };
144 ($name:ty: fn {$($block:tt)*}) => {
145 impl private::Sealed for $name{}
146 impl PrimitiveCollapse for $name
147 {
148 #[inline(always)] fn collapse(&self) -> u8 {
149 $($block)+
150 }
151 }
152 };
153 ($name:ty: {$($block:tt)*}) => {
154 impl private::Sealed for $name{}
155 impl PrimitiveCollapse for $name
156 {
157 $($block)+
158 }
159 };
160
161}
162
163prim!(u8);
164prim!(i8);
165prim!(u16: ^);
166prim!(i16: ^);
167prim!(u32: ^);
168prim!(i32: ^);
169prim!(u64: ^);
170prim!(i64: ^);
171prim!(u128: ^);
172prim!(i128: ^);
173prim!(isize: ^);
174prim!(usize: ^);
175
176prim!(NonZeroU8: +);
177prim!(NonZeroI8: +);
178prim!(NonZeroU16: ^+);
179prim!(NonZeroI16: ^+);
180prim!(NonZeroU32: ^+);
181prim!(NonZeroI32: ^+);
182prim!(NonZeroU64: ^+);
183prim!(NonZeroI64: ^+);
184prim!(NonZeroU128: ^+);
185prim!(NonZeroI128: ^+);
186prim!(NonZeroIsize: ^+);
187prim!(NonZeroUsize: ^+);
188
189prim!((): fn {
190 0
191});
192
193#[cfg(nightly)]
194prim!(!: {
195 fn collapse(&self) -> u8
196 {
197 *self
198 }
199});