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.

`