]> git.proxmox.com Git - rustc.git/blame - src/libcore/num/wrapping.rs
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / libcore / num / wrapping.rs
CommitLineData
c34b1796
AL
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.
4//
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.
10
11#![allow(missing_docs)]
12#![allow(deprecated)]
13
14use super::Wrapping;
15
16use ops::*;
17
c34b1796
AL
18use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
19use intrinsics::{i16_add_with_overflow, u16_add_with_overflow};
20use intrinsics::{i32_add_with_overflow, u32_add_with_overflow};
21use intrinsics::{i64_add_with_overflow, u64_add_with_overflow};
22use intrinsics::{i8_sub_with_overflow, u8_sub_with_overflow};
23use intrinsics::{i16_sub_with_overflow, u16_sub_with_overflow};
24use intrinsics::{i32_sub_with_overflow, u32_sub_with_overflow};
25use intrinsics::{i64_sub_with_overflow, u64_sub_with_overflow};
26use intrinsics::{i8_mul_with_overflow, u8_mul_with_overflow};
27use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow};
28use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow};
29use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow};
30
31use ::{i8,i16,i32,i64};
32
c34b1796
AL
33#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
34pub 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);
38
39 fn overflowing_div(self, rhs: Self) -> (Self, bool);
40 fn overflowing_rem(self, rhs: Self) -> (Self, bool);
41
42 fn overflowing_shl(self, rhs: u32) -> (Self, bool);
43 fn overflowing_shr(self, rhs: u32) -> (Self, bool);
44}
45
46macro_rules! sh_impl {
47 ($t:ty, $f:ty) => (
48 #[stable(feature = "rust1", since = "1.0.0")]
49 impl Shl<$f> for Wrapping<$t> {
50 type Output = Wrapping<$t>;
51
52 #[inline(always)]
53 fn shl(self, other: $f) -> Wrapping<$t> {
54 Wrapping(self.0 << other)
55 }
56 }
57
58 #[stable(feature = "rust1", since = "1.0.0")]
59 impl Shr<$f> for Wrapping<$t> {
60 type Output = Wrapping<$t>;
61
62 #[inline(always)]
63 fn shr(self, other: $f) -> Wrapping<$t> {
64 Wrapping(self.0 >> other)
65 }
66 }
67 )
68}
69
70// FIXME (#23545): uncomment the remaining impls
71macro_rules! sh_impl_all {
72 ($($t:ty)*) => ($(
73 // sh_impl! { $t, u8 }
74 // sh_impl! { $t, u16 }
75 // sh_impl! { $t, u32 }
76 // sh_impl! { $t, u64 }
77 sh_impl! { $t, usize }
78
79 // sh_impl! { $t, i8 }
80 // sh_impl! { $t, i16 }
81 // sh_impl! { $t, i32 }
82 // sh_impl! { $t, i64 }
83 // sh_impl! { $t, isize }
84 )*)
85}
86
87sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
88
89macro_rules! wrapping_impl {
90 ($($t:ty)*) => ($(
c34b1796
AL
91 #[stable(feature = "rust1", since = "1.0.0")]
92 impl Add for Wrapping<$t> {
93 type Output = Wrapping<$t>;
94
95 #[inline(always)]
96 fn add(self, other: Wrapping<$t>) -> Wrapping<$t> {
97 Wrapping(self.0.wrapping_add(other.0))
98 }
99 }
100
101 #[stable(feature = "rust1", since = "1.0.0")]
102 impl Sub for Wrapping<$t> {
103 type Output = Wrapping<$t>;
104
105 #[inline(always)]
106 fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> {
107 Wrapping(self.0.wrapping_sub(other.0))
108 }
109 }
110
111 #[stable(feature = "rust1", since = "1.0.0")]
112 impl Mul for Wrapping<$t> {
113 type Output = Wrapping<$t>;
114
115 #[inline(always)]
116 fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> {
117 Wrapping(self.0.wrapping_mul(other.0))
118 }
119 }
120
121 #[stable(feature = "rust1", since = "1.0.0")]
122 impl Not for Wrapping<$t> {
123 type Output = Wrapping<$t>;
124
125 fn not(self) -> Wrapping<$t> {
126 Wrapping(!self.0)
127 }
128 }
129
130 #[stable(feature = "rust1", since = "1.0.0")]
131 impl BitXor for Wrapping<$t> {
132 type Output = Wrapping<$t>;
133
134 #[inline(always)]
135 fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> {
136 Wrapping(self.0 ^ other.0)
137 }
138 }
139
140 #[stable(feature = "rust1", since = "1.0.0")]
141 impl BitOr for Wrapping<$t> {
142 type Output = Wrapping<$t>;
143
144 #[inline(always)]
145 fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> {
146 Wrapping(self.0 | other.0)
147 }
148 }
149
150 #[stable(feature = "rust1", since = "1.0.0")]
151 impl BitAnd for Wrapping<$t> {
152 type Output = Wrapping<$t>;
153
154 #[inline(always)]
155 fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
156 Wrapping(self.0 & other.0)
157 }
158 }
159 )*)
160}
161
162wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
163
164mod shift_max {
165 #![allow(non_upper_case_globals)]
166
167 pub const i8: u32 = (1 << 3) - 1;
168 pub const i16: u32 = (1 << 4) - 1;
169 pub const i32: u32 = (1 << 5) - 1;
170 pub const i64: u32 = (1 << 6) - 1;
171
172 pub const u8: u32 = i8;
173 pub const u16: u32 = i16;
174 pub const u32: u32 = i32;
175 pub const u64: u32 = i64;
176}
177
178macro_rules! signed_overflowing_impl {
179 ($($t:ident)*) => ($(
180 impl OverflowingOps for $t {
181 #[inline(always)]
182 fn overflowing_add(self, rhs: $t) -> ($t, bool) {
183 unsafe {
184 concat_idents!($t, _add_with_overflow)(self, rhs)
185 }
186 }
187 #[inline(always)]
188 fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
189 unsafe {
190 concat_idents!($t, _sub_with_overflow)(self, rhs)
191 }
192 }
193 #[inline(always)]
194 fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
195 unsafe {
196 concat_idents!($t, _mul_with_overflow)(self, rhs)
197 }
198 }
199
200 #[inline(always)]
201 fn overflowing_div(self, rhs: $t) -> ($t, bool) {
202 if self == $t::MIN && rhs == -1 {
203 (1, true)
204 } else {
205 (self/rhs, false)
206 }
207 }
208 #[inline(always)]
209 fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
210 if self == $t::MIN && rhs == -1 {
211 (0, true)
212 } else {
213 (self % rhs, false)
214 }
215 }
216
217 #[inline(always)]
218 fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
219 (self << (rhs & self::shift_max::$t),
220 (rhs > self::shift_max::$t))
221 }
222 #[inline(always)]
223 fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
224 (self >> (rhs & self::shift_max::$t),
225 (rhs > self::shift_max::$t))
226 }
227 }
228 )*)
229}
230
231macro_rules! unsigned_overflowing_impl {
232 ($($t:ident)*) => ($(
233 impl OverflowingOps for $t {
234 #[inline(always)]
235 fn overflowing_add(self, rhs: $t) -> ($t, bool) {
236 unsafe {
237 concat_idents!($t, _add_with_overflow)(self, rhs)
238 }
239 }
240 #[inline(always)]
241 fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
242 unsafe {
243 concat_idents!($t, _sub_with_overflow)(self, rhs)
244 }
245 }
246 #[inline(always)]
247 fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
248 unsafe {
249 concat_idents!($t, _mul_with_overflow)(self, rhs)
250 }
251 }
252
253 #[inline(always)]
254 fn overflowing_div(self, rhs: $t) -> ($t, bool) {
255 (self/rhs, false)
256 }
257 #[inline(always)]
258 fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
259 (self % rhs, false)
260 }
261
262 #[inline(always)]
263 fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
264 (self << (rhs & self::shift_max::$t),
265 (rhs > self::shift_max::$t))
266 }
267 #[inline(always)]
268 fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
269 (self >> (rhs & self::shift_max::$t),
270 (rhs > self::shift_max::$t))
271 }
272 }
273 )*)
274}
275
276signed_overflowing_impl! { i8 i16 i32 i64 }
277unsigned_overflowing_impl! { u8 u16 u32 u64 }
278
279#[cfg(target_pointer_width = "64")]
280impl OverflowingOps for usize {
281 #[inline(always)]
282 fn overflowing_add(self, rhs: usize) -> (usize, bool) {
283 unsafe {
284 let res = u64_add_with_overflow(self as u64, rhs as u64);
285 (res.0 as usize, res.1)
286 }
287 }
288 #[inline(always)]
289 fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
290 unsafe {
291 let res = u64_sub_with_overflow(self as u64, rhs as u64);
292 (res.0 as usize, res.1)
293 }
294 }
295 #[inline(always)]
296 fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
297 unsafe {
298 let res = u64_mul_with_overflow(self as u64, rhs as u64);
299 (res.0 as usize, res.1)
300 }
301 }
302 #[inline(always)]
303 fn overflowing_div(self, rhs: usize) -> (usize, bool) {
304 let (r, f) = (self as u64).overflowing_div(rhs as u64);
305 (r as usize, f)
306 }
307 #[inline(always)]
308 fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
309 let (r, f) = (self as u64).overflowing_rem(rhs as u64);
310 (r as usize, f)
311 }
312 #[inline(always)]
313 fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
314 let (r, f) = (self as u64).overflowing_shl(rhs);
315 (r as usize, f)
316 }
317 #[inline(always)]
318 fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
319 let (r, f) = (self as u64).overflowing_shr(rhs);
320 (r as usize, f)
321 }
322}
323
324#[cfg(target_pointer_width = "32")]
325impl OverflowingOps for usize {
326 #[inline(always)]
327 fn overflowing_add(self, rhs: usize) -> (usize, bool) {
328 unsafe {
329 let res = u32_add_with_overflow(self as u32, rhs as u32);
330 (res.0 as usize, res.1)
331 }
332 }
333 #[inline(always)]
334 fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
335 unsafe {
336 let res = u32_sub_with_overflow(self as u32, rhs as u32);
337 (res.0 as usize, res.1)
338 }
339 }
340 #[inline(always)]
341 fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
342 unsafe {
343 let res = u32_mul_with_overflow(self as u32, rhs as u32);
344 (res.0 as usize, res.1)
345 }
346 }
347 #[inline(always)]
348 fn overflowing_div(self, rhs: usize) -> (usize, bool) {
349 let (r, f) = (self as u32).overflowing_div(rhs as u32);
350 (r as usize, f)
351 }
352 #[inline(always)]
353 fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
354 let (r, f) = (self as u32).overflowing_rem(rhs as u32);
355 (r as usize, f)
356 }
357 #[inline(always)]
358 fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
359 let (r, f) = (self as u32).overflowing_shl(rhs);
360 (r as usize, f)
361 }
362 #[inline(always)]
363 fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
364 let (r, f) = (self as u32).overflowing_shr(rhs);
365 (r as usize, f)
366 }
367}
368
369#[cfg(target_pointer_width = "64")]
370impl OverflowingOps for isize {
371 #[inline(always)]
372 fn overflowing_add(self, rhs: isize) -> (isize, bool) {
373 unsafe {
374 let res = i64_add_with_overflow(self as i64, rhs as i64);
375 (res.0 as isize, res.1)
376 }
377 }
378 #[inline(always)]
379 fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
380 unsafe {
381 let res = i64_sub_with_overflow(self as i64, rhs as i64);
382 (res.0 as isize, res.1)
383 }
384 }
385 #[inline(always)]
386 fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
387 unsafe {
388 let res = i64_mul_with_overflow(self as i64, rhs as i64);
389 (res.0 as isize, res.1)
390 }
391 }
392 #[inline(always)]
393 fn overflowing_div(self, rhs: isize) -> (isize, bool) {
394 let (r, f) = (self as i64).overflowing_div(rhs as i64);
395 (r as isize, f)
396 }
397 #[inline(always)]
398 fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
399 let (r, f) = (self as i64).overflowing_rem(rhs as i64);
400 (r as isize, f)
401 }
402 #[inline(always)]
403 fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
404 let (r, f) = (self as i64).overflowing_shl(rhs);
405 (r as isize, f)
406 }
407 #[inline(always)]
408 fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
409 let (r, f) = (self as i64).overflowing_shr(rhs);
410 (r as isize, f)
411 }
412}
413
414#[cfg(target_pointer_width = "32")]
415impl OverflowingOps for isize {
416 #[inline(always)]
417 fn overflowing_add(self, rhs: isize) -> (isize, bool) {
418 unsafe {
419 let res = i32_add_with_overflow(self as i32, rhs as i32);
420 (res.0 as isize, res.1)
421 }
422 }
423 #[inline(always)]
424 fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
425 unsafe {
426 let res = i32_sub_with_overflow(self as i32, rhs as i32);
427 (res.0 as isize, res.1)
428 }
429 }
430 #[inline(always)]
431 fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
432 unsafe {
433 let res = i32_mul_with_overflow(self as i32, rhs as i32);
434 (res.0 as isize, res.1)
435 }
436 }
437 #[inline(always)]
438 fn overflowing_div(self, rhs: isize) -> (isize, bool) {
439 let (r, f) = (self as i32).overflowing_div(rhs as i32);
440 (r as isize, f)
441 }
442 #[inline(always)]
443 fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
444 let (r, f) = (self as i32).overflowing_rem(rhs as i32);
445 (r as isize, f)
446 }
447 #[inline(always)]
448 fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
449 let (r, f) = (self as i32).overflowing_shl(rhs);
450 (r as isize, f)
451 }
452 #[inline(always)]
453 fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
454 let (r, f) = (self as i32).overflowing_shr(rhs);
455 (r as isize, f)
456 }
457}