Skip to content

Commit

Permalink
Rust 1.51 support
Browse files Browse the repository at this point in the history
  • Loading branch information
jhpratt committed Mar 19, 2021
1 parent 5e4f2a4 commit 5da2c3f
Show file tree
Hide file tree
Showing 5 changed files with 459 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "standback"
version = "0.2.15"
version = "0.2.16"
authors = ["Jacob Pratt <open-source@jhpratt.dev>", "The Rust Project Developers"]
edition = "2018"
repository = "https://github.com/jhpratt/standback"
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use version_check::{Channel, Version};
// We assume that features are never stabilized in patch versions.
// If a "Rust 2.0" is ever released, we'll have to handle that explicitly.
const MSRV_MINOR: u16 = 31;
const CURRENT_MINOR: u16 = 50;
const CURRENT_MINOR: u16 = 51;

fn main() {
let msrv = Version::from_mmp(1, MSRV_MINOR, 0);
Expand Down
35 changes: 34 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(rust_2018_idioms, unused_qualifications)]
#![allow(non_camel_case_types, unstable_name_collisions)]
#![allow(
non_camel_case_types,
unstable_name_collisions,
clippy::missing_safety_doc
)]

/*!
Standback backports a number of methods, structs, and macros that have been stabilized in the Rust
Expand Down Expand Up @@ -41,6 +45,25 @@ will be gated under an `alloc` feature.
The following methods and constants are available via the prelude. For brevity, `i*` is `i8`, `i16`,
`i32`, `i64`, `i128`, and `isize`; `u*` is `u8`, `u16`, `u32`, `u64`, `u128`, and `usize`.
## 1.51
```text
Arc::decrement_strong_count
Arc::increment_strong_count
Peekable::next_if_eq
Peekable::next_if
Seek::stream_position
slice::fill_with
slice::split_inclusive_mut
slice::split_inclusive
slice::strip_prefix
slice::strip_suffix
task::Wake // requires rustc 1.33
i*::unsigned_abs
Poll::map_ok
Poll::map_err
```
## 1.50
```text
Expand Down Expand Up @@ -349,6 +372,8 @@ mod v1_48;
mod v1_49;
#[cfg(__standback_before_1_50)]
mod v1_50;
#[cfg(__standback_before_1_51)]
mod v1_51;

#[doc(hidden)]
pub mod prelude {
Expand Down Expand Up @@ -416,6 +441,10 @@ pub mod prelude {
pub use crate::v1_50::{
Bool_v1_50, Float_v1_50, Ord_v1_50, RefCell_v1_50, Slice_v1_50, UnsafeCell_v1_50,
};
#[cfg(all(__standback_before_1_51, feature = "std"))]
pub use crate::v1_51::{Arc_v1_51, Seek_v1_51};
#[cfg(__standback_before_1_51)]
pub use crate::v1_51::{Integer_v1_51, Peekable_v1_51, Poll_v1_51, Slice_v1_51};
}
#[doc(hidden)]
pub mod mem {
Expand Down Expand Up @@ -487,11 +516,15 @@ pub mod pin {
}
#[doc(hidden)]
pub mod task {
#[cfg(all(__standback_since_1_51, feature = "std"))]
pub use core::task::Wake;
#[cfg(__standback_since_1_36)]
pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};

#[cfg(__standback_before_1_36)]
pub use crate::v1_36::{Context, Poll, RawWaker, RawWakerVTable, Waker};
#[cfg(all(__standback_before_1_51, __standback_since_1_33, feature = "std"))]
pub use crate::v1_51::Wake;
}
#[doc(hidden)]
pub mod ptr {
Expand Down
211 changes: 211 additions & 0 deletions src/v1_51.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
mod slice;

use core::iter::Peekable;
#[cfg(feature = "std")]
use core::mem;
#[cfg(feature = "std")]
use std::io::{Seek, SeekFrom};
#[cfg(feature = "std")]
use std::sync::Arc;

use crate::task::Poll;
#[cfg(__standback_before_1_40)]
use crate::v1_40::Option_v1_40_;
#[cfg(__standback_before_1_50)]
use crate::v1_50::Bool_v1_50;

#[cfg(feature = "std")]
pub trait Arc_v1_51<T> {
unsafe fn decrement_strong_count(ptr: *const T);
unsafe fn increment_strong_count(ptr: *const T);
}

#[cfg(feature = "std")]
impl<T> Arc_v1_51<T> for Arc<T> {
#[inline]
unsafe fn decrement_strong_count(ptr: *const T) {
drop(Arc::from_raw(ptr));
}

#[inline]
unsafe fn increment_strong_count(ptr: *const T) {
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(ptr));
let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
}
}

pub trait Peekable_v1_51<I: Iterator> {
fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item>;
fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
where
T: ?Sized,
I::Item: PartialEq<T>;
}

impl<I: Iterator> Peekable_v1_51<I> for Peekable<I> {
fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
func(self.peek()?).then(|| self.next()).flatten()
}

fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
where
T: ?Sized,
I::Item: PartialEq<T>,
{
self.next_if(|next| next == expected)
}
}

#[cfg(feature = "std")]
pub trait Seek_v1_51 {
fn stream_position(&mut self) -> std::io::Result<u64>;
}

#[cfg(feature = "std")]
impl<T: Seek> Seek_v1_51 for T {
fn stream_position(&mut self) -> std::io::Result<u64> {
self.seek(SeekFrom::Current(0))
}
}

pub trait Slice_v1_51<T> {
fn fill_with<F>(&mut self, f: F)
where
F: FnMut() -> T;
fn split_inclusive_mut<F>(&mut self, pred: F) -> slice::SplitInclusiveMut<'_, T, F>
where
F: FnMut(&T) -> bool;
fn split_inclusive<F>(&self, pred: F) -> slice::SplitInclusive<'_, T, F>
where
F: FnMut(&T) -> bool;
fn strip_prefix(&self, prefix: &[T]) -> Option<&[T]>
where
T: PartialEq;
fn strip_suffix(&self, suffix: &[T]) -> Option<&[T]>
where
T: PartialEq;
}

impl<T> Slice_v1_51<T> for [T] {
fn fill_with<F>(&mut self, mut f: F)
where
F: FnMut() -> T,
{
for el in self {
*el = f();
}
}

#[inline]
fn split_inclusive_mut<F>(&mut self, pred: F) -> slice::SplitInclusiveMut<'_, T, F>
where
F: FnMut(&T) -> bool,
{
slice::SplitInclusiveMut::new(self, pred)
}

#[inline]
fn split_inclusive<F>(&self, pred: F) -> slice::SplitInclusive<'_, T, F>
where
F: FnMut(&T) -> bool,
{
slice::SplitInclusive::new(self, pred)
}

#[must_use = "returns the subslice without modifying the original"]
fn strip_prefix(&self, prefix: &[T]) -> Option<&[T]>
where
T: PartialEq,
{
let n = prefix.len();
if n <= self.len() {
let (head, tail) = self.split_at(n);
if head == prefix {
return Some(tail);
}
}
None
}

#[must_use = "returns the subslice without modifying the original"]
fn strip_suffix(&self, suffix: &[T]) -> Option<&[T]>
where
T: PartialEq,
{
let (len, n) = (self.len(), suffix.len());
if n <= len {
let (head, tail) = self.split_at(len - n);
if tail == suffix {
return Some(head);
}
}
None
}
}

#[cfg(all(__standback_since_1_33, feature = "std"))]
pub trait Wake {
fn wake(self: Arc<Self>);
#[cfg(__standback_since_v1_41)]
fn wake_by_ref(self: &Arc<Self>) {
self.clone().wake();
}
}

pub trait Integer_v1_51 {
type __StandbackUnsigned;
fn unsigned_abs(self) -> Self::__StandbackUnsigned;
}

macro_rules! impl_integer {
($($int:ty => $uint:ty)*) => {$(
impl Integer_v1_51 for $int {
type __StandbackUnsigned = $uint;
#[inline]
fn unsigned_abs(self) -> Self::__StandbackUnsigned {
self.wrapping_abs() as $uint
}
}
)*};
}

impl_integer! {
i8 => u8
i16 => u16
i32 => u32
i64 => u64
i128 => u128
}

pub trait Poll_v1_51<T, E> {
fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
where
F: FnOnce(T) -> U;
fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
where
F: FnOnce(E) -> U;
}

impl<T, E> Poll_v1_51<T, E> for Poll<Result<T, E>> {
fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
where
F: FnOnce(T) -> U,
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
}

fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
where
F: FnOnce(E) -> U,
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
Poll::Pending => Poll::Pending,
}
}
}
Loading

0 comments on commit 5da2c3f

Please sign in to comment.