1 // Copyright 2014 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 #![allow(missing_docs)]
13 #![unstable(feature = "wrapping", reason = "may be removed or relocated")]
19 use intrinsics
::{i8_add_with_overflow, u8_add_with_overflow}
;
20 use intrinsics
::{i16_add_with_overflow, u16_add_with_overflow}
;
21 use intrinsics
::{i32_add_with_overflow, u32_add_with_overflow}
;
22 use intrinsics
::{i64_add_with_overflow, u64_add_with_overflow}
;
23 use intrinsics
::{i8_sub_with_overflow, u8_sub_with_overflow}
;
24 use intrinsics
::{i16_sub_with_overflow, u16_sub_with_overflow}
;
25 use intrinsics
::{i32_sub_with_overflow, u32_sub_with_overflow}
;
26 use intrinsics
::{i64_sub_with_overflow, u64_sub_with_overflow}
;
27 use intrinsics
::{i8_mul_with_overflow, u8_mul_with_overflow}
;
28 use intrinsics
::{i16_mul_with_overflow, u16_mul_with_overflow}
;
29 use intrinsics
::{i32_mul_with_overflow, u32_mul_with_overflow}
;
30 use intrinsics
::{i64_mul_with_overflow, u64_mul_with_overflow}
;
32 use ::{i8,i16,i32,i64}
;
34 pub trait OverflowingOps
{
35 fn overflowing_add(self, rhs
: Self) -> (Self, bool
);
36 fn overflowing_sub(self, rhs
: Self) -> (Self, bool
);
37 fn overflowing_mul(self, rhs
: Self) -> (Self, bool
);
39 fn overflowing_div(self, rhs
: Self) -> (Self, bool
);
40 fn overflowing_rem(self, rhs
: Self) -> (Self, bool
);
41 fn overflowing_neg(self) -> (Self, bool
);
43 fn overflowing_shl(self, rhs
: u32) -> (Self, bool
);
44 fn overflowing_shr(self, rhs
: u32) -> (Self, bool
);
47 macro_rules
! sh_impl
{
49 #[stable(feature = "rust1", since = "1.0.0")]
50 impl Shl
<$f
> for Wrapping
<$t
> {
51 type Output
= Wrapping
<$t
>;
54 fn shl(self, other
: $f
) -> Wrapping
<$t
> {
55 Wrapping(self.0 << other
)
59 #[stable(feature = "rust1", since = "1.0.0")]
60 impl Shr
<$f
> for Wrapping
<$t
> {
61 type Output
= Wrapping
<$t
>;
64 fn shr(self, other
: $f
) -> Wrapping
<$t
> {
65 Wrapping(self.0 >> other
)
71 // FIXME (#23545): uncomment the remaining impls
72 macro_rules
! sh_impl_all
{
74 // sh_impl! { $t, u8 }
75 // sh_impl! { $t, u16 }
76 // sh_impl! { $t, u32 }
77 // sh_impl! { $t, u64 }
78 sh_impl
! { $t, usize }
80 // sh_impl! { $t, i8 }
81 // sh_impl! { $t, i16 }
82 // sh_impl! { $t, i32 }
83 // sh_impl! { $t, i64 }
84 // sh_impl! { $t, isize }
88 sh_impl_all
! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
90 macro_rules
! wrapping_impl
{
92 #[stable(feature = "rust1", since = "1.0.0")]
93 impl Add
for Wrapping
<$t
> {
94 type Output
= Wrapping
<$t
>;
97 fn add(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
98 Wrapping(self.0.wrapping_add(other
.0))
102 #[stable(feature = "rust1", since = "1.0.0")]
103 impl Sub
for Wrapping
<$t
> {
104 type Output
= Wrapping
<$t
>;
107 fn sub(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
108 Wrapping(self.0.wrapping_sub(other
.0))
112 #[stable(feature = "rust1", since = "1.0.0")]
113 impl Mul
for Wrapping
<$t
> {
114 type Output
= Wrapping
<$t
>;
117 fn mul(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
118 Wrapping(self.0.wrapping_mul(other
.0))
122 #[stable(feature = "rust1", since = "1.0.0")]
123 impl Not
for Wrapping
<$t
> {
124 type Output
= Wrapping
<$t
>;
127 fn not(self) -> Wrapping
<$t
> {
132 #[stable(feature = "rust1", since = "1.0.0")]
133 impl BitXor
for Wrapping
<$t
> {
134 type Output
= Wrapping
<$t
>;
137 fn bitxor(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
138 Wrapping(self.0 ^ other
.0)
142 #[stable(feature = "rust1", since = "1.0.0")]
143 impl BitOr
for Wrapping
<$t
> {
144 type Output
= Wrapping
<$t
>;
147 fn bitor(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
148 Wrapping(self.0 | other
.0)
152 #[stable(feature = "rust1", since = "1.0.0")]
153 impl BitAnd
for Wrapping
<$t
> {
154 type Output
= Wrapping
<$t
>;
157 fn bitand(self, other
: Wrapping
<$t
>) -> Wrapping
<$t
> {
158 Wrapping(self.0 & other
.0)
164 wrapping_impl
! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
167 #![allow(non_upper_case_globals)]
169 pub const i8: u32 = (1 << 3) - 1;
170 pub const i16: u32 = (1 << 4) - 1;
171 pub const i32: u32 = (1 << 5) - 1;
172 pub const i64: u32 = (1 << 6) - 1;
174 pub const u8: u32 = i8;
175 pub const u16: u32 = i16;
176 pub const u32: u32 = i32;
177 pub const u64: u32 = i64;
180 macro_rules
! signed_overflowing_impl
{
181 ($
($t
:ident
)*) => ($
(
182 impl OverflowingOps
for $t
{
184 fn overflowing_add(self, rhs
: $t
) -> ($t
, bool
) {
186 concat_idents
!($t
, _add_with_overflow
)(self, rhs
)
190 fn overflowing_sub(self, rhs
: $t
) -> ($t
, bool
) {
192 concat_idents
!($t
, _sub_with_overflow
)(self, rhs
)
196 fn overflowing_mul(self, rhs
: $t
) -> ($t
, bool
) {
198 concat_idents
!($t
, _mul_with_overflow
)(self, rhs
)
203 fn overflowing_div(self, rhs
: $t
) -> ($t
, bool
) {
204 if self == $t
::MIN
&& rhs
== -1 {
211 fn overflowing_rem(self, rhs
: $t
) -> ($t
, bool
) {
212 if self == $t
::MIN
&& rhs
== -1 {
220 fn overflowing_shl(self, rhs
: u32) -> ($t
, bool
) {
221 (self << (rhs
& self::shift_max
::$t
),
222 (rhs
> self::shift_max
::$t
))
225 fn overflowing_shr(self, rhs
: u32) -> ($t
, bool
) {
226 (self >> (rhs
& self::shift_max
::$t
),
227 (rhs
> self::shift_max
::$t
))
231 fn overflowing_neg(self) -> ($t
, bool
) {
242 macro_rules
! unsigned_overflowing_impl
{
243 ($
($t
:ident
)*) => ($
(
244 impl OverflowingOps
for $t
{
246 fn overflowing_add(self, rhs
: $t
) -> ($t
, bool
) {
248 concat_idents
!($t
, _add_with_overflow
)(self, rhs
)
252 fn overflowing_sub(self, rhs
: $t
) -> ($t
, bool
) {
254 concat_idents
!($t
, _sub_with_overflow
)(self, rhs
)
258 fn overflowing_mul(self, rhs
: $t
) -> ($t
, bool
) {
260 concat_idents
!($t
, _mul_with_overflow
)(self, rhs
)
265 fn overflowing_div(self, rhs
: $t
) -> ($t
, bool
) {
269 fn overflowing_rem(self, rhs
: $t
) -> ($t
, bool
) {
274 fn overflowing_shl(self, rhs
: u32) -> ($t
, bool
) {
275 (self << (rhs
& self::shift_max
::$t
),
276 (rhs
> self::shift_max
::$t
))
279 fn overflowing_shr(self, rhs
: u32) -> ($t
, bool
) {
280 (self >> (rhs
& self::shift_max
::$t
),
281 (rhs
> self::shift_max
::$t
))
285 fn overflowing_neg(self) -> ($t
, bool
) {
286 ((!self).wrapping_add(1), true)
292 signed_overflowing_impl
! { i8 i16 i32 i64 }
293 unsigned_overflowing_impl
! { u8 u16 u32 u64 }
295 #[cfg(target_pointer_width = "64")]
296 impl OverflowingOps
for usize {
298 fn overflowing_add(self, rhs
: usize) -> (usize, bool
) {
300 let res
= u64_add_with_overflow(self as u64, rhs
as u64);
301 (res
.0 as usize, res
.1)
305 fn overflowing_sub(self, rhs
: usize) -> (usize, bool
) {
307 let res
= u64_sub_with_overflow(self as u64, rhs
as u64);
308 (res
.0 as usize, res
.1)
312 fn overflowing_mul(self, rhs
: usize) -> (usize, bool
) {
314 let res
= u64_mul_with_overflow(self as u64, rhs
as u64);
315 (res
.0 as usize, res
.1)
319 fn overflowing_div(self, rhs
: usize) -> (usize, bool
) {
320 let (r
, f
) = (self as u64).overflowing_div(rhs
as u64);
324 fn overflowing_rem(self, rhs
: usize) -> (usize, bool
) {
325 let (r
, f
) = (self as u64).overflowing_rem(rhs
as u64);
329 fn overflowing_neg(self) -> (usize, bool
) {
330 let (r
, f
) = (self as u64).overflowing_neg();
334 fn overflowing_shl(self, rhs
: u32) -> (usize, bool
) {
335 let (r
, f
) = (self as u64).overflowing_shl(rhs
);
339 fn overflowing_shr(self, rhs
: u32) -> (usize, bool
) {
340 let (r
, f
) = (self as u64).overflowing_shr(rhs
);
345 #[cfg(target_pointer_width = "32")]
346 impl OverflowingOps
for usize {
348 fn overflowing_add(self, rhs
: usize) -> (usize, bool
) {
350 let res
= u32_add_with_overflow(self as u32, rhs
as u32);
351 (res
.0 as usize, res
.1)
355 fn overflowing_sub(self, rhs
: usize) -> (usize, bool
) {
357 let res
= u32_sub_with_overflow(self as u32, rhs
as u32);
358 (res
.0 as usize, res
.1)
362 fn overflowing_mul(self, rhs
: usize) -> (usize, bool
) {
364 let res
= u32_mul_with_overflow(self as u32, rhs
as u32);
365 (res
.0 as usize, res
.1)
369 fn overflowing_div(self, rhs
: usize) -> (usize, bool
) {
370 let (r
, f
) = (self as u32).overflowing_div(rhs
as u32);
374 fn overflowing_rem(self, rhs
: usize) -> (usize, bool
) {
375 let (r
, f
) = (self as u32).overflowing_rem(rhs
as u32);
379 fn overflowing_neg(self) -> (usize, bool
) {
380 let (r
, f
) = (self as u32).overflowing_neg();
384 fn overflowing_shl(self, rhs
: u32) -> (usize, bool
) {
385 let (r
, f
) = (self as u32).overflowing_shl(rhs
);
389 fn overflowing_shr(self, rhs
: u32) -> (usize, bool
) {
390 let (r
, f
) = (self as u32).overflowing_shr(rhs
);
395 #[cfg(target_pointer_width = "64")]
396 impl OverflowingOps
for isize {
398 fn overflowing_add(self, rhs
: isize) -> (isize, bool
) {
400 let res
= i64_add_with_overflow(self as i64, rhs
as i64);
401 (res
.0 as isize, res
.1)
405 fn overflowing_sub(self, rhs
: isize) -> (isize, bool
) {
407 let res
= i64_sub_with_overflow(self as i64, rhs
as i64);
408 (res
.0 as isize, res
.1)
412 fn overflowing_mul(self, rhs
: isize) -> (isize, bool
) {
414 let res
= i64_mul_with_overflow(self as i64, rhs
as i64);
415 (res
.0 as isize, res
.1)
419 fn overflowing_div(self, rhs
: isize) -> (isize, bool
) {
420 let (r
, f
) = (self as i64).overflowing_div(rhs
as i64);
424 fn overflowing_rem(self, rhs
: isize) -> (isize, bool
) {
425 let (r
, f
) = (self as i64).overflowing_rem(rhs
as i64);
429 fn overflowing_neg(self) -> (isize, bool
) {
430 let (r
, f
) = (self as i64).overflowing_neg();
434 fn overflowing_shl(self, rhs
: u32) -> (isize, bool
) {
435 let (r
, f
) = (self as i64).overflowing_shl(rhs
);
439 fn overflowing_shr(self, rhs
: u32) -> (isize, bool
) {
440 let (r
, f
) = (self as i64).overflowing_shr(rhs
);
445 #[cfg(target_pointer_width = "32")]
446 impl OverflowingOps
for isize {
448 fn overflowing_add(self, rhs
: isize) -> (isize, bool
) {
450 let res
= i32_add_with_overflow(self as i32, rhs
as i32);
451 (res
.0 as isize, res
.1)
455 fn overflowing_sub(self, rhs
: isize) -> (isize, bool
) {
457 let res
= i32_sub_with_overflow(self as i32, rhs
as i32);
458 (res
.0 as isize, res
.1)
462 fn overflowing_mul(self, rhs
: isize) -> (isize, bool
) {
464 let res
= i32_mul_with_overflow(self as i32, rhs
as i32);
465 (res
.0 as isize, res
.1)
469 fn overflowing_div(self, rhs
: isize) -> (isize, bool
) {
470 let (r
, f
) = (self as i32).overflowing_div(rhs
as i32);
474 fn overflowing_rem(self, rhs
: isize) -> (isize, bool
) {
475 let (r
, f
) = (self as i32).overflowing_rem(rhs
as i32);
479 fn overflowing_neg(self) -> (isize, bool
) {
480 let (r
, f
) = (self as i32).overflowing_neg();
484 fn overflowing_shl(self, rhs
: u32) -> (isize, bool
) {
485 let (r
, f
) = (self as i32).overflowing_shl(rhs
);
489 fn overflowing_shr(self, rhs
: u32) -> (isize, bool
) {
490 let (r
, f
) = (self as i32).overflowing_shr(rhs
);