machine_int/
lib.rs

1// Copyright 2018 Ed McCardell
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#![cfg_attr(feature = "cargo-clippy", feature(tool_lints))]
10#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
11
12use std::cmp::Ordering;
13use std::fmt;
14use std::ops::{
15    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor,
16    BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign,
17    Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
18};
19
20#[derive(Clone, Copy, Default)]
21#[repr(C)]
22pub struct MachineInt<T>(pub T);
23
24pub trait AsFrom<T>: Sized {
25    fn as_from(_: T) -> Self;
26}
27
28// Trait<T> for MachineInt<T>
29// Trait<MachineInt<T>> for <T>
30macro_rules! lit_impl {
31    ($trait:ident, $meth:ident, $fn:ident) => {};
32    ($trait:ident, $meth:ident, $fn:ident, $t:ty) => {
33        impl $trait<$t> for MachineInt<$t> {
34            type Output = Self;
35            #[inline]
36            fn $meth(self, rhs: $t) -> Self {
37                MachineInt((self.0).$fn(rhs))
38            }
39        }
40
41        impl $trait<MachineInt<$t>> for $t {
42            type Output = MachineInt<$t>;
43            #[inline]
44            fn $meth(self, rhs: Self::Output) -> Self::Output {
45                MachineInt(self.$fn(rhs.0))
46            }
47        }
48
49        impl $trait<MachineInt<$t>> for MachineInt<$t> {
50            type Output = MachineInt<$t>;
51            #[inline]
52            fn $meth(self, rhs: Self) -> Self {
53                MachineInt((self.0).$fn(rhs.0))
54            }
55        }
56    };
57    ($trait:ident, $meth:ident, $fn:ident, $t:ty, $($tail:tt)*) => {
58        lit_impl!($trait, $meth, $fn, $t);
59        lit_impl!($trait, $meth, $fn, $($tail)*);
60    };
61}
62
63lit_impl!(Add, add, wrapping_add, i8, u8, i16, u16, i32, u32, i64, u64);
64lit_impl!(Sub, sub, wrapping_sub, i8, u8, i16, u16, i32, u32, i64, u64);
65lit_impl!(Mul, mul, wrapping_mul, i8, u8, i16, u16, i32, u32, i64, u64);
66lit_impl!(Div, div, div, i8, u8, i16, u16, i32, u32, i64, u64);
67lit_impl!(Rem, rem, rem, i8, u8, i16, u16, i32, u32, i64, u64);
68lit_impl!(BitAnd, bitand, bitand, u8, u16, u32, u64);
69lit_impl!(BitOr, bitor, bitor, u8, u16, u32, u64);
70lit_impl!(BitXor, bitxor, bitxor, u8, u16, u32, u64);
71
72macro_rules! lit_assign_impl {
73    ($trait:ident, $meth:ident, $fn:ident) => {};
74    ($trait:ident, $meth:ident, $fn:ident, $t:ty) => {
75        impl $trait<$t> for MachineInt<$t> {
76            #[inline]
77            fn $meth(&mut self, rhs: $t) {
78                self.0 = (self.0).$fn(rhs);
79            }
80        }
81
82        impl $trait<MachineInt<$t>> for MachineInt<$t> {
83            #[inline]
84            fn $meth(&mut self, rhs: Self) {
85                self.0 = (self.0).$fn(rhs.0);
86            }
87        }
88    };
89    ($trait:ident, $meth:ident, $fn:ident, $t:ty, $($tail:tt)*) => {
90        lit_assign_impl!($trait, $meth, $fn, $t);
91        lit_assign_impl!($trait, $meth, $fn, $($tail)*);
92    };
93}
94
95#[cfg_attr(rustfmt, rustfmt_skip)]
96lit_assign_impl!(AddAssign, add_assign, wrapping_add,
97                 i8, u8, i16, u16, i32, u32, i64, u64);
98#[cfg_attr(rustfmt, rustfmt_skip)]
99lit_assign_impl!(SubAssign, sub_assign, wrapping_sub,
100                 i8, u8, i16, u16, i32, u32, i64, u64);
101#[cfg_attr(rustfmt, rustfmt_skip)]
102lit_assign_impl!(MulAssign, mul_assign, wrapping_mul,
103                 i8, u8, i16, u16, i32, u32, i64, u64);
104#[cfg_attr(rustfmt, rustfmt_skip)]
105lit_assign_impl!(DivAssign, div_assign, div,
106                 i8, u8, i16, u16, i32, u32, i64, u64);
107#[cfg_attr(rustfmt, rustfmt_skip)]
108lit_assign_impl!(RemAssign, rem_assign, rem,
109                 i8, u8, i16, u16, i32, u32, i64, u64);
110lit_assign_impl!(BitAndAssign, bitand_assign, bitand, u8, u16, u32, u64);
111lit_assign_impl!(BitOrAssign, bitor_assign, bitor, u8, u16, u32, u64);
112lit_assign_impl!(BitXorAssign, bitxor_assign, bitxor, u8, u16, u32, u64);
113
114// Trait<T> for MachineInt<U>
115// Trait<MachineInt<U> for T
116// Trait<MachineInt<T>> for MachineInt<T>
117// where T is the unsigned counterpart of U.
118macro_rules! ibit_lit_impl {
119    ($trait:ident, $meth:ident, $fn:ident, $lhs:ty, $rhs:ty) => {
120        impl $trait<$rhs> for MachineInt<$lhs> {
121            type Output = MachineInt<$lhs>;
122            #[inline]
123            fn $meth(self, rhs: $rhs) -> Self::Output {
124                MachineInt((self.0).$fn(rhs as $lhs))
125            }
126        }
127
128        impl $trait<MachineInt<$lhs>> for $rhs {
129            type Output = MachineInt<$lhs>;
130            #[inline]
131            fn $meth(self, rhs: MachineInt<$lhs>) -> Self::Output {
132                MachineInt((self as $lhs).$fn(rhs.0))
133            }
134        }
135
136        impl $trait<MachineInt<$lhs>> for MachineInt<$lhs> {
137            type Output = MachineInt<$lhs>;
138            #[inline]
139            fn $meth(self, rhs: MachineInt<$lhs>) -> Self::Output {
140                MachineInt((self.0).$fn(rhs.0))
141            }
142        }
143    };
144    ($trait:ident, $meth:ident, $fn:ident, $lhs:ty, $rhs:ty, $($tail:tt)*) => {
145        ibit_lit_impl!($trait, $meth, $fn, $lhs, $rhs);
146        ibit_lit_impl!($trait, $meth, $fn, $($tail)*);
147    };
148}
149
150ibit_lit_impl!(BitAnd, bitand, bitand, i64, u64, i32, u32, i16, u16, i8, u8);
151ibit_lit_impl!(BitOr, bitor, bitor, i64, u64, i32, u32, i16, u16, i8, u8);
152ibit_lit_impl!(BitXor, bitxor, bitxor, i64, u64, i32, u32, i16, u16, i8, u8);
153
154macro_rules! ibit_lit_assign_impl {
155    ($trait:ident, $meth:ident, $fn:ident, $lhs:ty, $rhs:ty) => {
156        impl $trait<$rhs> for MachineInt<$lhs> {
157            #[inline]
158            fn $meth(&mut self, rhs: $rhs) {
159                self.0 = (self.0).$fn(rhs as $lhs);
160            }
161        }
162
163        impl $trait<MachineInt<$rhs>> for MachineInt<$lhs> {
164            #[inline]
165            fn $meth(&mut self, rhs: MachineInt<$rhs>) {
166                self.0 = (self.0).$fn(rhs.0 as $lhs)
167            }
168        }
169
170        impl $trait<MachineInt<$lhs>> for MachineInt<$lhs> {
171            #[inline]
172            fn $meth(&mut self, rhs: MachineInt<$lhs>) {
173                self.0 = (self.0).$fn(rhs.0)
174            }
175        }
176    };
177    ($trait:ident, $meth:ident, $fn:ident, $lhs:ty, $rhs:ty, $($tail:tt)*) => {
178        ibit_lit_assign_impl!($trait, $meth, $fn, $lhs, $rhs);
179        ibit_lit_assign_impl!($trait, $meth, $fn, $($tail)*);
180    };
181}
182
183#[cfg_attr(rustfmt, rustfmt_skip)]
184ibit_lit_assign_impl!(BitAndAssign, bitand_assign, bitand,
185                      i64, u64, i32, u32, i16, u16, i8, u8);
186#[cfg_attr(rustfmt, rustfmt_skip)]
187ibit_lit_assign_impl!(BitOrAssign, bitor_assign, bitor,
188                      i64, u64, i32, u32, i16, u16, i8, u8);
189#[cfg_attr(rustfmt, rustfmt_skip)]
190ibit_lit_assign_impl!(BitXorAssign, bitxor_assign, bitxor,
191                      i64, u64, i32, u32, i16, u16, i8, u8);
192
193// Neg, Not, Eq, Ord for MachineInt<T>
194// PartialEq<T> for MachineInt<T>, PartialEq<MachineInt<T>> for T
195// PartialOrd<T> for MachineInt<T>, PartialOrd<MachineInt<T>> for T
196macro_rules! misc_impl {
197    ($($t:ty)*) => ($(
198        impl Neg for MachineInt<$t> {
199            type Output = Self;
200            #[inline]
201            fn neg(self) -> Self {
202                MachineInt(self.0.wrapping_neg())
203            }
204        }
205
206        impl Not for MachineInt<$t> {
207            type Output = Self;
208            #[inline]
209            fn not(self) -> Self {
210                MachineInt(!self.0)
211            }
212        }
213
214        impl Eq for MachineInt<$t> {}
215
216        impl Ord for MachineInt<$t> {
217            #[inline]
218            fn cmp(&self, rhs: &Self) -> Ordering {
219                self.0.cmp(&rhs.0)
220            }
221        }
222
223        impl PartialEq<$t> for MachineInt<$t> {
224            #[inline]
225            fn eq(&self, rhs: &$t) -> bool {
226                self.0 == *rhs
227            }
228        }
229
230        impl PartialEq<MachineInt<$t>> for $t {
231            #[inline]
232            fn eq(&self, rhs: &MachineInt<$t>) -> bool {
233                *self == rhs.0
234            }
235        }
236
237        impl PartialOrd<$t> for MachineInt<$t> {
238            #[inline]
239            fn partial_cmp(&self, rhs: &$t) -> Option<Ordering> {
240                Some(self.0.cmp(&*rhs))
241            }
242        }
243
244        impl PartialOrd<MachineInt<$t>> for $t {
245            #[inline]
246            fn partial_cmp(&self, rhs: &MachineInt<$t>) -> Option<Ordering> {
247                Some(self.cmp(&rhs.0))
248            }
249        }
250
251        impl AsFrom<$t> for MachineInt<$t> {
252            #[inline]
253            fn as_from(val: $t) -> Self {
254                MachineInt(val)
255            }
256        }
257
258        impl AsFrom<MachineInt<$t>> for MachineInt<$t> {
259            #[inline]
260            fn as_from(val: MachineInt<$t>) -> Self {
261                val
262            }
263        }
264
265        impl From<$t> for MachineInt<$t> {
266            #[inline]
267            fn from(val: $t) -> Self {
268                MachineInt(val)
269            }
270        }
271
272        impl From<MachineInt<$t>> for $t {
273            #[inline]
274            fn from(val: MachineInt<$t>) -> Self {
275                val.0
276            }
277        }
278
279        impl Shl<u32> for MachineInt<$t> {
280            type Output = Self;
281            #[inline]
282            fn shl(self, rhs: u32) -> Self {
283                MachineInt(self.0.wrapping_shl(rhs))
284            }
285        }
286
287        impl Shr<u32> for MachineInt<$t> {
288            type Output = Self;
289            #[inline]
290            fn shr(self, rhs: u32) -> Self {
291                MachineInt(self.0.wrapping_shr(rhs))
292            }
293        }
294
295        impl ShlAssign<u32> for MachineInt<$t> {
296            #[inline]
297            fn shl_assign(&mut self, rhs: u32) {
298                self.0 = self.0.wrapping_shl(rhs)
299            }
300        }
301
302        impl ShrAssign<u32> for MachineInt<$t> {
303            #[inline]
304            fn shr_assign(&mut self, rhs: u32) {
305                self.0 = self.0.wrapping_shr(rhs)
306            }
307        }
308    )*)
309}
310
311misc_impl!(i8 u8 i16 u16 i32 u32 i64 u64);
312
313// Trait<MachineInt<T>> for MachineInt<U>
314// where T has the same signedness as U
315// for PartialEq, PartialOrd
316macro_rules! cmp_impl {
317    ($lhs:ty; $rhs:ty) => {
318        impl PartialEq<MachineInt<$rhs>> for MachineInt<$lhs> {
319            #[inline]
320            fn eq(&self, rhs: &MachineInt<$rhs>) -> bool {
321                self.0 == rhs.0 as $lhs
322            }
323        }
324
325        impl PartialOrd<MachineInt<$rhs>> for MachineInt<$lhs> {
326            #[inline]
327            fn partial_cmp(&self, rhs: &MachineInt<$rhs>) -> Option<Ordering> {
328                Some(self.0.cmp(&(rhs.0 as $lhs)))
329            }
330        }
331    };
332    ($lhs:ty; $rhs:ty, $($tail:tt)*) => {
333        cmp_impl!($lhs; $rhs);
334        cmp_impl!($lhs; $($tail)*);
335    };
336}
337
338cmp_impl!(u64; u64, u32, u16, u8);
339cmp_impl!(i64; i64, i32, i16, i8);
340cmp_impl!(u32; u64, u32, u16, u8);
341cmp_impl!(i32; i64, i32, i16, i8);
342cmp_impl!(u16; u64, u32, u16, u8);
343cmp_impl!(i16; i64, i32, i16, i8);
344cmp_impl!(u8; u64, u32, u16, u8);
345cmp_impl!(i8; i64, i32, i16, i8);
346
347// PartialEq<MachineInt<T>> for MachineInt<U>
348// PartialOrd<MachineInt<T>> for MachineInt<U>
349// where P: From<T> and P: From<U>
350macro_rules! icmp_impl {
351    () => {};
352    ($lhs:ty, $rhs:ty, $p:ty) => {
353        impl PartialEq<MachineInt<$rhs>> for MachineInt<$lhs> {
354            #[inline]
355            fn eq(&self, rhs: &MachineInt<$rhs>) -> bool {
356                (self.0 as $p) == (rhs.0 as $p)
357            }
358        }
359
360        impl PartialOrd<MachineInt<$rhs>> for MachineInt<$lhs> {
361            #[inline]
362            fn partial_cmp(&self, rhs: &MachineInt<$rhs>) -> Option<Ordering> {
363                Some((self.0 as $p).cmp(&(rhs.0 as $p)))
364            }
365        }
366    };
367    ($lhs:ty, $rhs:ty, $p:ty; $($tail:tt)*) => {
368        icmp_impl!($lhs, $rhs, $p);
369        icmp_impl!($($tail)*);
370    };
371}
372
373// TODO: u64/ixx
374#[cfg_attr(rustfmt, rustfmt_skip)]
375icmp_impl!(u32, i32, i64; i32, u32, i64;
376           u32, i16, i64; i16, u32, i64;
377           u32, i8, i64; i8, u32, i64);
378#[cfg_attr(rustfmt, rustfmt_skip)]
379icmp_impl!(i32, u16, i32; u16, i32, i32;
380           i32, u8, i32; u8, i32, i32;
381           u16, i16, i32; i16, u16, i32;
382           u16, i8, i32; i8, u16, i32);
383#[cfg_attr(rustfmt, rustfmt_skip)]
384icmp_impl!(i16, u8, i16; u8, i16, i16;
385           u8, i8, i16; i8, u8, i16);
386
387macro_rules! add_impl {
388    () => {};
389    ($b:ty, $s:ty) => {
390        impl Add<MachineInt<$s>> for MachineInt<$b> {
391            type Output = MachineInt<$b>;
392            #[inline]
393            fn add(self, rhs: MachineInt<$s>) -> Self::Output {
394                MachineInt((self.0).wrapping_add(rhs.0 as $b))
395            }
396        }
397
398        impl Add<MachineInt<$b>> for MachineInt<$s> {
399            type Output = MachineInt<$b>;
400            #[inline]
401            fn add(self, rhs: MachineInt<$b>) -> Self::Output {
402                MachineInt((self.0 as $b).wrapping_add(rhs.0))
403            }
404        }
405
406        impl AddAssign<MachineInt<$s>> for MachineInt<$b> {
407            #[inline]
408            fn add_assign(&mut self, rhs: MachineInt<$s>) {
409                self.0 = self.0.wrapping_add(rhs.0 as $b);
410            }
411        }
412
413        impl Sub<MachineInt<$s>> for MachineInt<$b> {
414            type Output = MachineInt<$b>;
415            #[inline]
416            fn sub(self, rhs: MachineInt<$s>) -> Self::Output {
417                MachineInt((self.0).wrapping_sub(rhs.0 as $b))
418            }
419        }
420
421        impl Sub<MachineInt<$b>> for MachineInt<$s> {
422            type Output = MachineInt<$b>;
423            #[inline]
424            fn sub(self, rhs: MachineInt<$b>) -> Self::Output {
425                MachineInt((self.0 as $b).wrapping_sub(rhs.0))
426            }
427        }
428
429        impl SubAssign<MachineInt<$s>> for MachineInt<$b> {
430            #[inline]
431            fn sub_assign(&mut self, rhs: MachineInt<$s>) {
432                self.0 = self.0.wrapping_sub(rhs.0 as $b);
433            }
434        }
435    };
436    ($b:ty, $s:ty; $($tail:tt)*) => {
437        add_impl!($b, $s);
438        add_impl!($($tail)*);
439    };
440}
441
442#[cfg_attr(rustfmt, rustfmt_skip)]
443add_impl!(u64, u32; u64, u16; u64, u8; u64, i32; u64, i16; u64, i8;
444          i64, u32; i64, u16; i64, u8; i64, i32; i64, i16; i64, i8;
445          u32, u16; u32, u8; u32, i16; u32, i8;
446          i32, u16; i32, u8; i32, i16; i32, i8;
447          u16, u8; u16, i8;
448          i16, u8; i16, i8);
449
450macro_rules! bit_impl {
451    () => {};
452    ($b:ty, $s:ty, $p:ty) => {
453        impl BitAnd<MachineInt<$s>> for MachineInt<$b> {
454            type Output = MachineInt<$b>;
455            #[inline]
456            fn bitand(self, rhs: MachineInt<$s>) -> Self::Output {
457                MachineInt(self.0 & (rhs.0 as $p as $b))
458            }
459        }
460
461        impl BitAnd<MachineInt<$b>> for MachineInt<$s> {
462            type Output = MachineInt<$b>;
463            #[inline]
464            fn bitand(self, rhs: MachineInt<$b>) -> Self::Output {
465                MachineInt((self.0 as $p as $b) & rhs.0)
466            }
467        }
468
469        impl BitAndAssign<MachineInt<$s>> for MachineInt<$b> {
470            #[inline]
471            fn bitand_assign(&mut self, rhs: MachineInt<$s>) {
472                self.0 = self.0 & (rhs.0 as $p as $b);
473            }
474        }
475
476        impl BitOr<MachineInt<$s>> for MachineInt<$b> {
477            type Output = MachineInt<$b>;
478            #[inline]
479            fn bitor(self, rhs: MachineInt<$s>) -> Self::Output {
480                MachineInt(self.0 | (rhs.0 as $p as $b))
481            }
482        }
483
484        impl BitOr<MachineInt<$b>> for MachineInt<$s> {
485            type Output = MachineInt<$b>;
486            #[inline]
487            fn bitor(self, rhs: MachineInt<$b>) -> Self::Output {
488                MachineInt((self.0 as $p as $b) | rhs.0)
489            }
490        }
491
492        impl BitOrAssign<MachineInt<$s>> for MachineInt<$b> {
493            #[inline]
494            fn bitor_assign(&mut self, rhs: MachineInt<$s>) {
495                self.0 = self.0 | (rhs.0 as $p as $b);
496            }
497        }
498
499        impl BitXor<MachineInt<$s>> for MachineInt<$b> {
500            type Output = MachineInt<$b>;
501            #[inline]
502            fn bitxor(self, rhs: MachineInt<$s>) -> Self::Output {
503                MachineInt(self.0 ^ (rhs.0 as $p as $b))
504            }
505        }
506
507        impl BitXor<MachineInt<$b>> for MachineInt<$s> {
508            type Output = MachineInt<$b>;
509            #[inline]
510            fn bitxor(self, rhs: MachineInt<$b>) -> Self::Output {
511                MachineInt((self.0 as $p as $b) ^ rhs.0)
512            }
513        }
514
515        impl BitXorAssign<MachineInt<$s>> for MachineInt<$b> {
516            #[inline]
517            fn bitxor_assign(&mut self, rhs: MachineInt<$s>) {
518                self.0 = self.0 ^ (rhs.0 as $p as $b);
519            }
520        }
521    };
522    ($b:ty, $s:ty, $p:ty; $($tail:tt)*) => {
523        bit_impl!($b, $s, $p);
524        bit_impl!($($tail)*);
525    };
526}
527
528#[cfg_attr(rustfmt, rustfmt_skip)]
529bit_impl!(u64, u32, u32; u64, u16, u16; u64, u8, u8;
530          u64, i32, u32; u64, i16, u16; u64, i8, u8;
531          i64, u32, u32; i64, u16, u16; i64, u8, u8;
532          i64, i32, u32; i64, i16, u16; i64, i8, u8;
533          u32, u16, u16; u32, u8, u8;
534          u32, i16, u16; u32, i8, u8;
535          i32, u16, u16; i32, u8, u8;
536          i32, i16, u16; i32, i8, u8;
537          u16, u8, u8; u16, i8, u8;
538          i16, u8, u8; i16, i8, u8);
539
540macro_rules! from_impl {
541    ($lhs:ty, $rhs:ty) => {
542        impl From<MachineInt<$rhs>> for MachineInt<$lhs> {
543            #[inline]
544            fn from(val: MachineInt<$rhs>) -> Self {
545                MachineInt(val.0 as $lhs)
546            }
547        }
548
549        impl From<$rhs> for MachineInt<$lhs> {
550            #[inline]
551            fn from(val: $rhs) -> Self {
552                MachineInt(val as $lhs)
553            }
554        }
555
556        impl From<MachineInt<$rhs>> for $lhs {
557            #[inline]
558            fn from(val: MachineInt<$rhs>) -> Self {
559                val.0 as $lhs
560            }
561        }
562    };
563    ($lhs:ty, $rhs:ty; $($tail:tt)*) => {
564        from_impl!($lhs, $rhs);
565        from_impl!($($tail)*);
566    };
567}
568
569from_impl!(u64, u32; u64, u16; u64, u8);
570from_impl!(i64, u32; i64, u16; i64, u8; i64, i32; i64, i16; i64, i8);
571from_impl!(u32, u16; u32, u8);
572from_impl!(i32, u16; i32, u8; i32, i16; i32, i8);
573from_impl!(u16, u8);
574from_impl!(i16, u8; i16, i8);
575
576#[cfg(target_pointer_width = "64")]
577from_impl!(usize, u64; usize, u32; usize, u16; usize, u8);
578#[cfg(target_pointer_width = "64")]
579from_impl!(isize, i64; isize, i32; isize, i16; isize, i8);
580#[cfg(target_pointer_width = "32")]
581from_impl!(usize, u32; usize, u16; usize, u8);
582#[cfg(target_pointer_width = "32")]
583from_impl!(isize, i32; isize, i16; isize, i8);
584#[cfg(target_pointer_width = "16")]
585from_impl!(usize, u16; usize, u8);
586#[cfg(target_pointer_width = "16")]
587from_impl!(isize, i16; isize, i8);
588
589macro_rules! as_from_impl {
590    ($lhs:ty; $rhs:ty) => {
591        impl AsFrom<MachineInt<$rhs>> for MachineInt<$lhs> {
592            #[inline]
593            fn as_from(val: MachineInt<$rhs>) -> Self {
594                MachineInt(val.0 as $lhs)
595            }
596        }
597
598        impl AsFrom<$rhs> for MachineInt<$lhs> {
599            #[inline]
600            fn as_from(val: $rhs) -> Self {
601                MachineInt(val as $lhs)
602            }
603        }
604    };
605    ($lhs:ty; $rhs:ty, $($tail:tt)*) => {
606        as_from_impl!($lhs; $rhs);
607        as_from_impl!($lhs; $($tail)*);
608    };
609}
610
611#[cfg_attr(rustfmt, rustfmt_skip)]
612as_from_impl!(u64; i64, u32, i32, u16, i16, u8, i8);
613as_from_impl!(i64; u64, u32, i32, u16, i16, u8, i8);
614as_from_impl!(u32; u64, i64, i32, u16, i16, u8, i8);
615as_from_impl!(i32; u64, i64, u32, u16, i16, u8, i8);
616as_from_impl!(u16; u64, i64, u32, i32, i16, u8, i8);
617as_from_impl!(i16; u64, i64, u32, i32, u16, u8, i8);
618as_from_impl!(u8; u64, i64, u32, i32, u16, i16, i8);
619as_from_impl!(i8; u64, i64, u32, i32, u16, i16, u8);
620
621impl<T: fmt::Display> fmt::Display for MachineInt<T> {
622    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
623        fmt::Display::fmt(&self.0, f)
624    }
625}
626
627impl<T: fmt::Debug> fmt::Debug for MachineInt<T> {
628    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629        fmt::Debug::fmt(&self.0, f)
630    }
631}
632
633impl<T: fmt::LowerHex> fmt::LowerHex for MachineInt<T> {
634    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
635        fmt::LowerHex::fmt(&self.0, f)
636    }
637}
638
639impl<T: fmt::UpperHex> fmt::UpperHex for MachineInt<T> {
640    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
641        fmt::UpperHex::fmt(&self.0, f)
642    }
643}
644
645impl<T: fmt::Binary> fmt::Binary for MachineInt<T> {
646    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
647        fmt::Binary::fmt(&self.0, f)
648    }
649}
650
651impl<T: fmt::Octal> fmt::Octal for MachineInt<T> {
652    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
653        fmt::Octal::fmt(&self.0, f)
654    }
655}
656
657macro_rules! rotate_impl {
658    ($($t:ty)*) => ($(
659        impl MachineInt<$t> {
660            #[inline]
661            pub fn rotate_left(self, n: u32) -> Self {
662                MachineInt(self.0.rotate_left(n))
663            }
664
665            #[inline]
666            pub fn rotate_right(self, n: u32) -> Self {
667                MachineInt(self.0.rotate_right(n))
668            }
669        }
670    )*)
671}
672
673rotate_impl!(u8 u16 u32 u64);