1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std::cmp::Ordering;
12 use syntax::attr::IntType;
13 use syntax::ast::{IntTy, UintTy};
19 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
34 pub use self::ConstInt::*;
38 ($ct: ty, $($t:ident $min:ident $max:ident)*) => {
40 pub const $min: $ct = $t::min_value() as $ct;
41 pub const $max: $ct = $t::max_value() as $ct;
44 ($ct: ty: $min_val: expr, $($t:ident $min:ident $max:ident)*) => {
46 pub const $min: $ct = $min_val;
47 pub const $max: $ct = $t::max_value() as $ct;
55 i8 I8MIN I8MAX i16 I16MIN I16MAX i32 I32MIN I32MAX i64 I64MIN I64MAX i128 I128MIN I128MAX
56 u8 U8MIN U8MAX u16 U16MIN U16MAX u32 U32MIN U32MAX u64 U64MIN U64MAX u128 U128MIN U128MAX
57 // do not add constants for isize/usize, because these are guaranteed to be wrong for
58 // arbitrary host/target combinations
64 bounds!(i128, u64 U64MIN U64MAX);
66 pub const U128MIN: i128 = 0;
67 pub const U128MAX: i128 = i128::max_value();
70 i8 I8MIN I8MAX i16 I16MIN I16MAX i32 I32MIN I32MAX i64 I64MIN I64MAX i128 I128MIN I128MAX
71 u8 U8MIN U8MAX u16 U16MIN U16MAX u32 U32MIN U32MAX
72 // do not add constants for isize/usize, because these are guaranteed to be wrong for
73 // arbitrary host/target combinations
78 /// Creates a new unsigned ConstInt with matching type while also checking that overflow does
80 pub fn new_unsigned(val: u128, ty: UintTy, usize_ty: UintTy) -> Option<ConstInt> {
82 UintTy::U8 if val <= ubounds::U8MAX => Some(U8(val as u8)),
83 UintTy::U16 if val <= ubounds::U16MAX => Some(U16(val as u16)),
84 UintTy::U32 if val <= ubounds::U32MAX => Some(U32(val as u32)),
85 UintTy::U64 if val <= ubounds::U64MAX => Some(U64(val as u64)),
86 UintTy::Us if val <= ubounds::U64MAX => ConstUsize::new(val as u64, usize_ty).ok()
88 UintTy::U128 => Some(U128(val)),
93 /// Creates a new signed ConstInt with matching type while also checking that overflow does
95 pub fn new_signed(val: i128, ty: IntTy, isize_ty: IntTy) -> Option<ConstInt> {
97 IntTy::I8 if val <= ibounds::I8MAX => Some(I8(val as i8)),
98 IntTy::I16 if val <= ibounds::I16MAX => Some(I16(val as i16)),
99 IntTy::I32 if val <= ibounds::I32MAX => Some(I32(val as i32)),
100 IntTy::I64 if val <= ibounds::I64MAX => Some(I64(val as i64)),
101 IntTy::Is if val <= ibounds::I64MAX => ConstIsize::new(val as i64, isize_ty).ok()
103 IntTy::I128 => Some(I128(val)),
108 /// Creates a new unsigned ConstInt with matching type.
109 pub fn new_unsigned_truncating(val: u128, ty: UintTy, usize_ty: UintTy) -> ConstInt {
111 UintTy::U8 => U8(val as u8),
112 UintTy::U16 => U16(val as u16),
113 UintTy::U32 => U32(val as u32),
114 UintTy::U64 => U64(val as u64),
115 UintTy::Us => Usize(ConstUsize::new_truncating(val, usize_ty)),
116 UintTy::U128 => U128(val)
120 /// Creates a new signed ConstInt with matching type.
121 pub fn new_signed_truncating(val: i128, ty: IntTy, isize_ty: IntTy) -> ConstInt {
123 IntTy::I8 => I8(val as i8),
124 IntTy::I16 => I16(val as i16),
125 IntTy::I32 => I32(val as i32),
126 IntTy::I64 => I64(val as i64),
127 IntTy::Is => Isize(ConstIsize::new_truncating(val, isize_ty)),
128 IntTy::I128 => I128(val)
132 /// Description of the type, not the value
133 pub fn description(&self) -> &'static str {
150 /// Erases the type and returns a u128.
151 /// This is not the same as `-5i8 as u128` but as `-5i8 as i128 as u128`
152 pub fn to_u128_unchecked(self) -> u128 {
154 I8(i) => i as i128 as u128,
155 I16(i) => i as i128 as u128,
156 I32(i) => i as i128 as u128,
157 I64(i) => i as i128 as u128,
158 I128(i) => i as i128 as u128,
159 Isize(Is16(i)) => i as i128 as u128,
160 Isize(Is32(i)) => i as i128 as u128,
161 Isize(Is64(i)) => i as i128 as u128,
166 U128(i) => i as u128,
167 Usize(Us16(i)) => i as u128,
168 Usize(Us32(i)) => i as u128,
169 Usize(Us64(i)) => i as u128,
173 /// Converts the value to a `u32` if it's in the range 0...std::u32::MAX
174 pub fn to_u32(&self) -> Option<u32> {
175 self.to_u128().and_then(|v| if v <= u32::max_value() as u128 {
182 /// Converts the value to a `u64` if it's in the range 0...std::u64::MAX
183 pub fn to_u64(&self) -> Option<u64> {
184 self.to_u128().and_then(|v| if v <= u64::max_value() as u128 {
191 /// Converts the value to a `u128` if it's in the range 0...std::u128::MAX
192 pub fn to_u128(&self) -> Option<u128> {
194 I8(v) if v >= 0 => Some(v as u128),
195 I16(v) if v >= 0 => Some(v as u128),
196 I32(v) if v >= 0 => Some(v as u128),
197 I64(v) if v >= 0 => Some(v as u128),
198 I128(v) if v >= 0 => Some(v as u128),
199 Isize(Is16(v)) if v >= 0 => Some(v as u128),
200 Isize(Is32(v)) if v >= 0 => Some(v as u128),
201 Isize(Is64(v)) if v >= 0 => Some(v as u128),
202 U8(v) => Some(v as u128),
203 U16(v) => Some(v as u128),
204 U32(v) => Some(v as u128),
205 U64(v) => Some(v as u128),
206 U128(v) => Some(v as u128),
207 Usize(Us16(v)) => Some(v as u128),
208 Usize(Us32(v)) => Some(v as u128),
209 Usize(Us64(v)) => Some(v as u128),
214 pub fn to_f32(self) -> f32 {
221 Isize(Is16(i)) => i as f32,
222 Isize(Is32(i)) => i as f32,
223 Isize(Is64(i)) => i as f32,
229 Usize(Us16(i)) => i as f32,
230 Usize(Us32(i)) => i as f32,
231 Usize(Us64(i)) => i as f32,
235 pub fn to_f64(self) -> f64 {
242 Isize(Is16(i)) => i as f64,
243 Isize(Is32(i)) => i as f64,
244 Isize(Is64(i)) => i as f64,
250 Usize(Us16(i)) => i as f64,
251 Usize(Us32(i)) => i as f64,
252 Usize(Us64(i)) => i as f64,
256 pub fn is_negative(&self) -> bool {
263 Isize(Is16(v)) => v < 0,
264 Isize(Is32(v)) => v < 0,
265 Isize(Is64(v)) => v < 0,
270 /// Compares the values if they are of the same type
271 pub fn try_cmp(self, rhs: Self) -> Result<::std::cmp::Ordering, ConstMathErr> {
273 (I8(a), I8(b)) => Ok(a.cmp(&b)),
274 (I16(a), I16(b)) => Ok(a.cmp(&b)),
275 (I32(a), I32(b)) => Ok(a.cmp(&b)),
276 (I64(a), I64(b)) => Ok(a.cmp(&b)),
277 (I128(a), I128(b)) => Ok(a.cmp(&b)),
278 (Isize(Is16(a)), Isize(Is16(b))) => Ok(a.cmp(&b)),
279 (Isize(Is32(a)), Isize(Is32(b))) => Ok(a.cmp(&b)),
280 (Isize(Is64(a)), Isize(Is64(b))) => Ok(a.cmp(&b)),
281 (U8(a), U8(b)) => Ok(a.cmp(&b)),
282 (U16(a), U16(b)) => Ok(a.cmp(&b)),
283 (U32(a), U32(b)) => Ok(a.cmp(&b)),
284 (U64(a), U64(b)) => Ok(a.cmp(&b)),
285 (U128(a), U128(b)) => Ok(a.cmp(&b)),
286 (Usize(Us16(a)), Usize(Us16(b))) => Ok(a.cmp(&b)),
287 (Usize(Us32(a)), Usize(Us32(b))) => Ok(a.cmp(&b)),
288 (Usize(Us64(a)), Usize(Us64(b))) => Ok(a.cmp(&b)),
289 _ => Err(CmpBetweenUnequalTypes),
293 /// Adds 1 to the value and wraps around if the maximum for the type is reached
294 pub fn wrap_incr(self) -> Self {
296 ($e:expr) => { ($e).wrapping_add(1) }
299 ConstInt::I8(i) => ConstInt::I8(add1!(i)),
300 ConstInt::I16(i) => ConstInt::I16(add1!(i)),
301 ConstInt::I32(i) => ConstInt::I32(add1!(i)),
302 ConstInt::I64(i) => ConstInt::I64(add1!(i)),
303 ConstInt::I128(i) => ConstInt::I128(add1!(i)),
304 ConstInt::Isize(ConstIsize::Is16(i)) => ConstInt::Isize(ConstIsize::Is16(add1!(i))),
305 ConstInt::Isize(ConstIsize::Is32(i)) => ConstInt::Isize(ConstIsize::Is32(add1!(i))),
306 ConstInt::Isize(ConstIsize::Is64(i)) => ConstInt::Isize(ConstIsize::Is64(add1!(i))),
307 ConstInt::U8(i) => ConstInt::U8(add1!(i)),
308 ConstInt::U16(i) => ConstInt::U16(add1!(i)),
309 ConstInt::U32(i) => ConstInt::U32(add1!(i)),
310 ConstInt::U64(i) => ConstInt::U64(add1!(i)),
311 ConstInt::U128(i) => ConstInt::U128(add1!(i)),
312 ConstInt::Usize(ConstUsize::Us16(i)) => ConstInt::Usize(ConstUsize::Us16(add1!(i))),
313 ConstInt::Usize(ConstUsize::Us32(i)) => ConstInt::Usize(ConstUsize::Us32(add1!(i))),
314 ConstInt::Usize(ConstUsize::Us64(i)) => ConstInt::Usize(ConstUsize::Us64(add1!(i))),
318 pub fn int_type(self) -> IntType {
320 ConstInt::I8(_) => IntType::SignedInt(IntTy::I8),
321 ConstInt::I16(_) => IntType::SignedInt(IntTy::I16),
322 ConstInt::I32(_) => IntType::SignedInt(IntTy::I32),
323 ConstInt::I64(_) => IntType::SignedInt(IntTy::I64),
324 ConstInt::I128(_) => IntType::SignedInt(IntTy::I128),
325 ConstInt::Isize(_) => IntType::SignedInt(IntTy::Is),
326 ConstInt::U8(_) => IntType::UnsignedInt(UintTy::U8),
327 ConstInt::U16(_) => IntType::UnsignedInt(UintTy::U16),
328 ConstInt::U32(_) => IntType::UnsignedInt(UintTy::U32),
329 ConstInt::U64(_) => IntType::UnsignedInt(UintTy::U64),
330 ConstInt::U128(_) => IntType::UnsignedInt(UintTy::U128),
331 ConstInt::Usize(_) => IntType::UnsignedInt(UintTy::Us),
336 impl ::std::cmp::PartialOrd for ConstInt {
337 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
338 self.try_cmp(*other).ok()
342 impl ::std::cmp::Ord for ConstInt {
343 fn cmp(&self, other: &Self) -> Ordering {
344 self.try_cmp(*other).unwrap()
348 impl ::std::fmt::Display for ConstInt {
349 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
351 I8(i) => write!(fmt, "{}i8", i),
352 I16(i) => write!(fmt, "{}i16", i),
353 I32(i) => write!(fmt, "{}i32", i),
354 I64(i) => write!(fmt, "{}i64", i),
355 I128(i) => write!(fmt, "{}i128", i),
356 Isize(ConstIsize::Is64(i)) => write!(fmt, "{}isize", i),
357 Isize(ConstIsize::Is32(i)) => write!(fmt, "{}isize", i),
358 Isize(ConstIsize::Is16(i)) => write!(fmt, "{}isize", i),
359 U8(i) => write!(fmt, "{}u8", i),
360 U16(i) => write!(fmt, "{}u16", i),
361 U32(i) => write!(fmt, "{}u32", i),
362 U64(i) => write!(fmt, "{}u64", i),
363 U128(i) => write!(fmt, "{}u128", i),
364 Usize(ConstUsize::Us64(i)) => write!(fmt, "{}usize", i),
365 Usize(ConstUsize::Us32(i)) => write!(fmt, "{}usize", i),
366 Usize(ConstUsize::Us16(i)) => write!(fmt, "{}usize", i),
371 macro_rules! overflowing {
372 ($e:expr, $err:expr) => {{
374 return Err(Overflow($err));
381 macro_rules! impl_binop {
382 ($op:ident, $func:ident, $checked_func:ident) => {
383 impl ::std::ops::$op for ConstInt {
384 type Output = Result<Self, ConstMathErr>;
385 fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
387 (I8(a), I8(b)) => a.$checked_func(b).map(I8),
388 (I16(a), I16(b)) => a.$checked_func(b).map(I16),
389 (I32(a), I32(b)) => a.$checked_func(b).map(I32),
390 (I64(a), I64(b)) => a.$checked_func(b).map(I64),
391 (I128(a), I128(b)) => a.$checked_func(b).map(I128),
392 (Isize(Is16(a)), Isize(Is16(b))) => a.$checked_func(b).map(Is16).map(Isize),
393 (Isize(Is32(a)), Isize(Is32(b))) => a.$checked_func(b).map(Is32).map(Isize),
394 (Isize(Is64(a)), Isize(Is64(b))) => a.$checked_func(b).map(Is64).map(Isize),
395 (U8(a), U8(b)) => a.$checked_func(b).map(U8),
396 (U16(a), U16(b)) => a.$checked_func(b).map(U16),
397 (U32(a), U32(b)) => a.$checked_func(b).map(U32),
398 (U64(a), U64(b)) => a.$checked_func(b).map(U64),
399 (U128(a), U128(b)) => a.$checked_func(b).map(U128),
400 (Usize(Us16(a)), Usize(Us16(b))) => a.$checked_func(b).map(Us16).map(Usize),
401 (Usize(Us32(a)), Usize(Us32(b))) => a.$checked_func(b).map(Us32).map(Usize),
402 (Usize(Us64(a)), Usize(Us64(b))) => a.$checked_func(b).map(Us64).map(Usize),
403 _ => return Err(UnequalTypes(Op::$op)),
404 }.ok_or(Overflow(Op::$op))
410 macro_rules! derive_binop {
411 ($op:ident, $func:ident) => {
412 impl ::std::ops::$op for ConstInt {
413 type Output = Result<Self, ConstMathErr>;
414 fn $func(self, rhs: Self) -> Result<Self, ConstMathErr> {
416 (I8(a), I8(b)) => Ok(I8(a.$func(b))),
417 (I16(a), I16(b)) => Ok(I16(a.$func(b))),
418 (I32(a), I32(b)) => Ok(I32(a.$func(b))),
419 (I64(a), I64(b)) => Ok(I64(a.$func(b))),
420 (I128(a), I128(b)) => Ok(I128(a.$func(b))),
421 (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a.$func(b)))),
422 (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a.$func(b)))),
423 (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a.$func(b)))),
424 (U8(a), U8(b)) => Ok(U8(a.$func(b))),
425 (U16(a), U16(b)) => Ok(U16(a.$func(b))),
426 (U32(a), U32(b)) => Ok(U32(a.$func(b))),
427 (U64(a), U64(b)) => Ok(U64(a.$func(b))),
428 (U128(a), U128(b)) => Ok(U128(a.$func(b))),
429 (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a.$func(b)))),
430 (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a.$func(b)))),
431 (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a.$func(b)))),
432 _ => Err(UnequalTypes(Op::$op)),
439 impl_binop!(Add, add, checked_add);
440 impl_binop!(Sub, sub, checked_sub);
441 impl_binop!(Mul, mul, checked_mul);
442 derive_binop!(BitAnd, bitand);
443 derive_binop!(BitOr, bitor);
444 derive_binop!(BitXor, bitxor);
446 const I128_MIN: i128 = ::std::i128::MIN;
453 ) -> Result<(), ConstMathErr> {
455 (I8(_), I8(0)) => Err(zerr),
456 (I16(_), I16(0)) => Err(zerr),
457 (I32(_), I32(0)) => Err(zerr),
458 (I64(_), I64(0)) => Err(zerr),
459 (I128(_), I128(0)) => Err(zerr),
460 (Isize(_), Isize(Is16(0))) => Err(zerr),
461 (Isize(_), Isize(Is32(0))) => Err(zerr),
462 (Isize(_), Isize(Is64(0))) => Err(zerr),
464 (U8(_), U8(0)) => Err(zerr),
465 (U16(_), U16(0)) => Err(zerr),
466 (U32(_), U32(0)) => Err(zerr),
467 (U64(_), U64(0)) => Err(zerr),
468 (U128(_), U128(0)) => Err(zerr),
469 (Usize(_), Usize(Us16(0))) => Err(zerr),
470 (Usize(_), Usize(Us32(0))) => Err(zerr),
471 (Usize(_), Usize(Us64(0))) => Err(zerr),
473 (I8(::std::i8::MIN), I8(-1)) => Err(Overflow(op)),
474 (I16(::std::i16::MIN), I16(-1)) => Err(Overflow(op)),
475 (I32(::std::i32::MIN), I32(-1)) => Err(Overflow(op)),
476 (I64(::std::i64::MIN), I64(-1)) => Err(Overflow(op)),
477 (I128(I128_MIN), I128(-1)) => Err(Overflow(op)),
478 (Isize(Is16(::std::i16::MIN)), Isize(Is16(-1))) => Err(Overflow(op)),
479 (Isize(Is32(::std::i32::MIN)), Isize(Is32(-1))) => Err(Overflow(op)),
480 (Isize(Is64(::std::i64::MIN)), Isize(Is64(-1))) => Err(Overflow(op)),
486 impl ::std::ops::Div for ConstInt {
487 type Output = Result<Self, ConstMathErr>;
488 fn div(self, rhs: Self) -> Result<Self, ConstMathErr> {
489 let (lhs, rhs) = (self, rhs);
490 check_division(lhs, rhs, Op::Div, DivisionByZero)?;
492 (I8(a), I8(b)) => Ok(I8(a/b)),
493 (I16(a), I16(b)) => Ok(I16(a/b)),
494 (I32(a), I32(b)) => Ok(I32(a/b)),
495 (I64(a), I64(b)) => Ok(I64(a/b)),
496 (I128(a), I128(b)) => Ok(I128(a/b)),
497 (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a/b))),
498 (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a/b))),
499 (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a/b))),
501 (U8(a), U8(b)) => Ok(U8(a/b)),
502 (U16(a), U16(b)) => Ok(U16(a/b)),
503 (U32(a), U32(b)) => Ok(U32(a/b)),
504 (U64(a), U64(b)) => Ok(U64(a/b)),
505 (U128(a), U128(b)) => Ok(U128(a/b)),
506 (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a/b))),
507 (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a/b))),
508 (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a/b))),
510 _ => Err(UnequalTypes(Op::Div)),
515 impl ::std::ops::Rem for ConstInt {
516 type Output = Result<Self, ConstMathErr>;
517 fn rem(self, rhs: Self) -> Result<Self, ConstMathErr> {
518 let (lhs, rhs) = (self, rhs);
519 // should INT_MIN%-1 be zero or an error?
520 check_division(lhs, rhs, Op::Rem, RemainderByZero)?;
522 (I8(a), I8(b)) => Ok(I8(a%b)),
523 (I16(a), I16(b)) => Ok(I16(a%b)),
524 (I32(a), I32(b)) => Ok(I32(a%b)),
525 (I64(a), I64(b)) => Ok(I64(a%b)),
526 (I128(a), I128(b)) => Ok(I128(a%b)),
527 (Isize(Is16(a)), Isize(Is16(b))) => Ok(Isize(Is16(a%b))),
528 (Isize(Is32(a)), Isize(Is32(b))) => Ok(Isize(Is32(a%b))),
529 (Isize(Is64(a)), Isize(Is64(b))) => Ok(Isize(Is64(a%b))),
531 (U8(a), U8(b)) => Ok(U8(a%b)),
532 (U16(a), U16(b)) => Ok(U16(a%b)),
533 (U32(a), U32(b)) => Ok(U32(a%b)),
534 (U64(a), U64(b)) => Ok(U64(a%b)),
535 (U128(a), U128(b)) => Ok(U128(a%b)),
536 (Usize(Us16(a)), Usize(Us16(b))) => Ok(Usize(Us16(a%b))),
537 (Usize(Us32(a)), Usize(Us32(b))) => Ok(Usize(Us32(a%b))),
538 (Usize(Us64(a)), Usize(Us64(b))) => Ok(Usize(Us64(a%b))),
540 _ => Err(UnequalTypes(Op::Rem)),
545 impl ::std::ops::Shl<ConstInt> for ConstInt {
546 type Output = Result<Self, ConstMathErr>;
547 fn shl(self, rhs: Self) -> Result<Self, ConstMathErr> {
548 let b = rhs.to_u32().ok_or(ShiftNegative)?;
550 I8(a) => Ok(I8(overflowing!(a.overflowing_shl(b), Op::Shl))),
551 I16(a) => Ok(I16(overflowing!(a.overflowing_shl(b), Op::Shl))),
552 I32(a) => Ok(I32(overflowing!(a.overflowing_shl(b), Op::Shl))),
553 I64(a) => Ok(I64(overflowing!(a.overflowing_shl(b), Op::Shl))),
554 I128(a) => Ok(I128(overflowing!(a.overflowing_shl(b), Op::Shl))),
555 Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
556 Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
557 Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
558 U8(a) => Ok(U8(overflowing!(a.overflowing_shl(b), Op::Shl))),
559 U16(a) => Ok(U16(overflowing!(a.overflowing_shl(b), Op::Shl))),
560 U32(a) => Ok(U32(overflowing!(a.overflowing_shl(b), Op::Shl))),
561 U64(a) => Ok(U64(overflowing!(a.overflowing_shl(b), Op::Shl))),
562 U128(a) => Ok(U128(overflowing!(a.overflowing_shl(b), Op::Shl))),
563 Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shl(b), Op::Shl)))),
564 Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shl(b), Op::Shl)))),
565 Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shl(b), Op::Shl)))),
570 impl ::std::ops::Shr<ConstInt> for ConstInt {
571 type Output = Result<Self, ConstMathErr>;
572 fn shr(self, rhs: Self) -> Result<Self, ConstMathErr> {
573 let b = rhs.to_u32().ok_or(ShiftNegative)?;
575 I8(a) => Ok(I8(overflowing!(a.overflowing_shr(b), Op::Shr))),
576 I16(a) => Ok(I16(overflowing!(a.overflowing_shr(b), Op::Shr))),
577 I32(a) => Ok(I32(overflowing!(a.overflowing_shr(b), Op::Shr))),
578 I64(a) => Ok(I64(overflowing!(a.overflowing_shr(b), Op::Shr))),
579 I128(a) => Ok(I128(overflowing!(a.overflowing_shr(b), Op::Shr))),
580 Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
581 Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
582 Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
583 U8(a) => Ok(U8(overflowing!(a.overflowing_shr(b), Op::Shr))),
584 U16(a) => Ok(U16(overflowing!(a.overflowing_shr(b), Op::Shr))),
585 U32(a) => Ok(U32(overflowing!(a.overflowing_shr(b), Op::Shr))),
586 U64(a) => Ok(U64(overflowing!(a.overflowing_shr(b), Op::Shr))),
587 U128(a) => Ok(U128(overflowing!(a.overflowing_shr(b), Op::Shr))),
588 Usize(Us16(a)) => Ok(Usize(Us16(overflowing!(a.overflowing_shr(b), Op::Shr)))),
589 Usize(Us32(a)) => Ok(Usize(Us32(overflowing!(a.overflowing_shr(b), Op::Shr)))),
590 Usize(Us64(a)) => Ok(Usize(Us64(overflowing!(a.overflowing_shr(b), Op::Shr)))),
595 impl ::std::ops::Neg for ConstInt {
596 type Output = Result<Self, ConstMathErr>;
597 fn neg(self) -> Result<Self, ConstMathErr> {
599 I8(a) => Ok(I8(overflowing!(a.overflowing_neg(), Op::Neg))),
600 I16(a) => Ok(I16(overflowing!(a.overflowing_neg(), Op::Neg))),
601 I32(a) => Ok(I32(overflowing!(a.overflowing_neg(), Op::Neg))),
602 I64(a) => Ok(I64(overflowing!(a.overflowing_neg(), Op::Neg))),
603 I128(a) => Ok(I128(overflowing!(a.overflowing_neg(), Op::Neg))),
604 Isize(Is16(a)) => Ok(Isize(Is16(overflowing!(a.overflowing_neg(), Op::Neg)))),
605 Isize(Is32(a)) => Ok(Isize(Is32(overflowing!(a.overflowing_neg(), Op::Neg)))),
606 Isize(Is64(a)) => Ok(Isize(Is64(overflowing!(a.overflowing_neg(), Op::Neg)))),
607 a@U8(0) | a@U16(0) | a@U32(0) | a@U64(0) | a@U128(0) |
608 a@Usize(Us16(0)) | a@Usize(Us32(0)) | a@Usize(Us64(0)) => Ok(a),
609 U8(_) | U16(_) | U32(_) | U64(_) | U128(_) | Usize(_) => Err(UnsignedNegation),
614 impl ::std::ops::Not for ConstInt {
615 type Output = Result<Self, ConstMathErr>;
616 fn not(self) -> Result<Self, ConstMathErr> {
619 I16(a) => Ok(I16(!a)),
620 I32(a) => Ok(I32(!a)),
621 I64(a) => Ok(I64(!a)),
622 I128(a) => Ok(I128(!a)),
623 Isize(Is16(a)) => Ok(Isize(Is16(!a))),
624 Isize(Is32(a)) => Ok(Isize(Is32(!a))),
625 Isize(Is64(a)) => Ok(Isize(Is64(!a))),
627 U16(a) => Ok(U16(!a)),
628 U32(a) => Ok(U32(!a)),
629 U64(a) => Ok(U64(!a)),
630 U128(a) => Ok(U128(!a)),
631 Usize(Us16(a)) => Ok(Usize(Us16(!a))),
632 Usize(Us32(a)) => Ok(Usize(Us32(!a))),
633 Usize(Us64(a)) => Ok(Usize(Us64(!a))),