Auto merge of #132191 - Urgau:midpoint_signed_towards_zero, r=dtolnay · qinheping/verify-rust-std@c667683 (original) (raw)
`@@ -124,6 +124,37 @@ macro_rules! midpoint_impl {
`
124
124
`((self ^ rhs) >> 1) + (self & rhs)
`
125
125
`}
`
126
126
`};
`
``
127
`+
($SelfT:ty, signed) => {
`
``
128
`` +
/// Calculates the middle point of self
and rhs
.
``
``
129
`+
///
`
``
130
`` +
/// midpoint(a, b)
is (a + b) / 2
as if it were performed in a
``
``
131
`+
/// sufficiently-large signed integral type. This implies that the result is
`
``
132
`+
/// always rounded towards zero and that no overflow will ever occur.
`
``
133
`+
///
`
``
134
`+
/// # Examples
`
``
135
`+
///
`
``
136
/// ```
``
137
`+
/// #![feature(num_midpoint)]
`
``
138
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
`
``
139
`+
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")]
`
``
140
`+
#[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")]
`
``
141
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
`
``
142
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
`
``
143
/// ```
``
144
`+
#[unstable(feature = "num_midpoint", issue = "110840")]
`
``
145
`+
#[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
`
``
146
`+
#[must_use = "this returns the result of the operation, \
`
``
147
`+
without modifying the original"]
`
``
148
`+
#[inline]
`
``
149
`+
pub const fn midpoint(self, rhs: Self) -> Self {
`
``
150
`+
// Use the well known branchless algorithm from Hacker's Delight to compute
`
``
151
`` +
// (a + b) / 2
without overflowing: ((a ^ b) >> 1) + (a & b)
.
``
``
152
`+
let t = ((self ^ rhs) >> 1) + (self & rhs);
`
``
153
`+
// Except that it fails for integers whose sum is an odd negative number as
`
``
154
`+
// their floor is one less than their average. So we adjust the result.
`
``
155
`+
t + (if t < 0 { 1 } else { 0 } & (self ^ rhs))
`
``
156
`+
}
`
``
157
`+
};
`
127
158
`($SelfT:ty, $WideT:ty, unsigned) => {
`
128
159
`` /// Calculates the middle point of self
and rhs
.
``
129
160
`///
`
`@@ -147,6 +178,32 @@ macro_rules! midpoint_impl {
`
147
178
`((self as WideT+rhsasWideT + rhs as WideT+rhsasWideT) / 2) as $SelfT
`
148
179
`}
`
149
180
`};
`
``
181
`+
($SelfT:ty, $WideT:ty, signed) => {
`
``
182
`` +
/// Calculates the middle point of self
and rhs
.
``
``
183
`+
///
`
``
184
`` +
/// midpoint(a, b)
is (a + b) / 2
as if it were performed in a
``
``
185
`+
/// sufficiently-large signed integral type. This implies that the result is
`
``
186
`+
/// always rounded towards zero and that no overflow will ever occur.
`
``
187
`+
///
`
``
188
`+
/// # Examples
`
``
189
`+
///
`
``
190
/// ```
``
191
`+
/// #![feature(num_midpoint)]
`
``
192
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
`
``
193
`+
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")]
`
``
194
`+
#[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")]
`
``
195
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")]
`
``
196
`+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")]
`
``
197
/// ```
``
198
`+
#[unstable(feature = "num_midpoint", issue = "110840")]
`
``
199
`+
#[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
`
``
200
`+
#[must_use = "this returns the result of the operation, \
`
``
201
`+
without modifying the original"]
`
``
202
`+
#[inline]
`
``
203
`+
pub const fn midpoint(self, rhs: SelfT)−>SelfT) -> SelfT)−>SelfT {
`
``
204
`+
((self as WideT+rhsasWideT + rhs as WideT+rhsasWideT) / 2) as $SelfT
`
``
205
`+
}
`
``
206
`+
};
`
150
207
`}
`
151
208
``
152
209
`macro_rules! widening_impl {
`
`@@ -300,6 +357,7 @@ impl i8 {
`
300
357
` from_xe_bytes_doc = "",
`
301
358
` bound_condition = "",
`
302
359
`}
`
``
360
`+
midpoint_impl! { i8, i16, signed }
`
303
361
`}
`
304
362
``
305
363
`impl i16 {
`
`@@ -323,6 +381,7 @@ impl i16 {
`
323
381
` from_xe_bytes_doc = "",
`
324
382
` bound_condition = "",
`
325
383
`}
`
``
384
`+
midpoint_impl! { i16, i32, signed }
`
326
385
`}
`
327
386
``
328
387
`impl i32 {
`
`@@ -346,6 +405,7 @@ impl i32 {
`
346
405
` from_xe_bytes_doc = "",
`
347
406
` bound_condition = "",
`
348
407
`}
`
``
408
`+
midpoint_impl! { i32, i64, signed }
`
349
409
`}
`
350
410
``
351
411
`impl i64 {
`
`@@ -369,6 +429,7 @@ impl i64 {
`
369
429
` from_xe_bytes_doc = "",
`
370
430
` bound_condition = "",
`
371
431
`}
`
``
432
`+
midpoint_impl! { i64, i128, signed }
`
372
433
`}
`
373
434
``
374
435
`impl i128 {
`
`@@ -394,6 +455,7 @@ impl i128 {
`
394
455
` from_xe_bytes_doc = "",
`
395
456
` bound_condition = "",
`
396
457
`}
`
``
458
`+
midpoint_impl! { i128, signed }
`
397
459
`}
`
398
460
``
399
461
`#[cfg(target_pointer_width = "16")]
`
`@@ -418,6 +480,7 @@ impl isize {
`
418
480
` from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
`
419
481
` bound_condition = " on 16-bit targets",
`
420
482
`}
`
``
483
`+
midpoint_impl! { isize, i32, signed }
`
421
484
`}
`
422
485
``
423
486
`#[cfg(target_pointer_width = "32")]
`
`@@ -442,6 +505,7 @@ impl isize {
`
442
505
` from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
`
443
506
` bound_condition = " on 32-bit targets",
`
444
507
`}
`
``
508
`+
midpoint_impl! { isize, i64, signed }
`
445
509
`}
`
446
510
``
447
511
`#[cfg(target_pointer_width = "64")]
`
`@@ -466,6 +530,7 @@ impl isize {
`
466
530
` from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(),
`
467
531
` bound_condition = " on 64-bit targets",
`
468
532
`}
`
``
533
`+
midpoint_impl! { isize, i128, signed }
`
469
534
`}
`
470
535
``
471
536
`/// If the 6th bit is set ascii is lower case.
`