parent
bfccf7a426
commit
6a2aefc1d9
@ -1,207 +0,0 @@
|
|||||||
//! Extensions
|
|
||||||
use std::iter::{
|
|
||||||
self,
|
|
||||||
FusedIterator,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// An iterator adaptor for taking two items off an iterator
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TakeTwo<I: ?Sized>(I);
|
|
||||||
|
|
||||||
impl<I: ?Sized, T> Iterator for TakeTwo<I>
|
|
||||||
where I: Iterator<Item=T>
|
|
||||||
{
|
|
||||||
type Item = (T, Option<T>);
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Self::Item>
|
|
||||||
{
|
|
||||||
let first = self.0.next()?;
|
|
||||||
Some((first, self.0.next()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
let (low, high) = self.0.size_hint();
|
|
||||||
(low / 2, high.map(|x| x/2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: ?Sized + ExactSizeIterator> ExactSizeIterator for TakeTwo<I>{}
|
|
||||||
impl<I: ?Sized + FusedIterator> FusedIterator for TakeTwo<I> {}
|
|
||||||
|
|
||||||
pub trait TakeTwoExt: Sized {
|
|
||||||
/// Create an adaptor from `T` to `(T, Option<T>)`, taking the next available value if one exists in the iterator
|
|
||||||
fn take_two(self) -> TakeTwo<Self>;
|
|
||||||
}
|
|
||||||
pub trait TakeTwoBoxedExt {
|
|
||||||
/// Create an adaptor from `T` to `(T, Option<T>)`, taking the next available value if one exists in the iterator
|
|
||||||
fn take_two(self: Box<Self>) -> TakeTwo<Box<Self>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: Iterator> TakeTwoExt for I
|
|
||||||
{
|
|
||||||
#[inline(always)]
|
|
||||||
fn take_two(self) -> TakeTwo<Self> {
|
|
||||||
TakeTwo(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: ?Sized + Iterator> TakeTwoBoxedExt for I
|
|
||||||
{
|
|
||||||
#[inline(always)]
|
|
||||||
fn take_two(self: Box<Self>) -> TakeTwo<Box<Self>> {
|
|
||||||
TakeTwo(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Tuple2OptExt<T, U>: Sized
|
|
||||||
{
|
|
||||||
/// The unwrapped type for the option in the tuple
|
|
||||||
type OptionType;
|
|
||||||
/// Unwrap a tuple containing an option into an option containing the full tuple if the `Option` value in the tuple is `Some`
|
|
||||||
fn unwrap_two(self) -> Option<(T, U)>;
|
|
||||||
|
|
||||||
/// Unwrap the option value or get the value from `f`
|
|
||||||
fn unwrap_two_or_else<F>(self, f: F) -> (T, U)
|
|
||||||
where F: FnOnce() -> Self::OptionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Tuple2OptExt<T, U> for (T, Option<U>)
|
|
||||||
{
|
|
||||||
type OptionType = U;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two(self) -> Option<(T, U)> {
|
|
||||||
self.1.map(move |u| (self.0, u))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two_or_else<F>(self, f: F) -> (T, U)
|
|
||||||
where F: FnOnce() -> Self::OptionType {
|
|
||||||
match self.1 {
|
|
||||||
Some(u) => (self.0, u),
|
|
||||||
None => (self.0, f()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Tuple2OptExt<T, U> for (Option<T>, U)
|
|
||||||
{
|
|
||||||
type OptionType = T;
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two(self) -> Option<(T, U)> {
|
|
||||||
self.0.map(move |u| (u, self.1))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two_or_else<F>(self, f: F) -> (T, U)
|
|
||||||
where F: FnOnce() -> Self::OptionType {
|
|
||||||
match self.0 {
|
|
||||||
Some(u) => (u, self.1),
|
|
||||||
None => (f(), self.1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Tuple2OptExt<T, U> for (Option<T>, Option<U>)
|
|
||||||
{
|
|
||||||
type OptionType = (T, U);
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two(self) -> Option<(T, U)> {
|
|
||||||
self.0.and_then(move |u| self.1.map(move |v| (u, v)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unwrap_two_or_else<F>(self, f: F) -> (T, U)
|
|
||||||
where F: FnOnce() -> Self::OptionType {
|
|
||||||
match self {
|
|
||||||
//XXX: This is not ideal...
|
|
||||||
(Some(u), Some(v)) => (u, v),
|
|
||||||
(Some(u), None) => (u, f().1),
|
|
||||||
(None, Some(v)) => (f().0, v),
|
|
||||||
_ => f()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Tuple2Ext<T,U>: Sized
|
|
||||||
{
|
|
||||||
/// Swap the elements in a 2-tuple
|
|
||||||
fn swap(self) -> (U, T);
|
|
||||||
|
|
||||||
/// Reduce the tuple elements into `V`
|
|
||||||
fn reduce<V>(self, into: V) -> V
|
|
||||||
where V: Extend<T> + Extend<U>;
|
|
||||||
|
|
||||||
/// Collect the tuple elements into `O`
|
|
||||||
fn collect<V, O>(self) -> O
|
|
||||||
where V: From<T> + From<U> + FromIterator<V>,
|
|
||||||
O: FromIterator<V>;
|
|
||||||
|
|
||||||
/// Consume into `V`
|
|
||||||
fn consume<V>(self) -> V
|
|
||||||
where V: FromIterator<T> + Extend<U>;
|
|
||||||
|
|
||||||
/// Consume both elements into a new single type.
|
|
||||||
fn into<V>(self) -> (V, V)
|
|
||||||
where V: From<T> + From<U>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Tuple2STExt<T>: Sized
|
|
||||||
{
|
|
||||||
/// Consume into an array of two elements.
|
|
||||||
fn into_array(self) -> [T; 2];
|
|
||||||
|
|
||||||
/// Consume into an iterator of both elements
|
|
||||||
fn into_iter(self) -> <[T; 2] as IntoIterator>::IntoIter;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Tuple2Ext<T, U> for (T, U)
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn swap(self) -> (U, T) {
|
|
||||||
(self.1, self.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn reduce<V>(self, mut into: V) -> V
|
|
||||||
where V: Extend<T> + Extend<U> {
|
|
||||||
into.extend(iter::once(self.0));
|
|
||||||
into.extend(iter::once(self.1));
|
|
||||||
into
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn collect<V, O>(self) -> O
|
|
||||||
where V: From<T> + From<U>,
|
|
||||||
O: FromIterator<V> {
|
|
||||||
[self.0.into(), self.1.into()].into_iter().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn consume<V>(self) -> V
|
|
||||||
where V: FromIterator<T> + Extend<U> {
|
|
||||||
let mut o: V = iter::once(self.0).collect();
|
|
||||||
o.extend(iter::once(self.1));
|
|
||||||
o
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn into<V>(self) -> (V, V)
|
|
||||||
where V: From<T> + From<U> {
|
|
||||||
(self.0.into(), self.1.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Tuple2STExt<T> for (T, T)
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn into_array(self) -> [T; 2] {
|
|
||||||
[self.0, self.1]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn into_iter(self) -> <[T; 2] as IntoIterator>::IntoIter {
|
|
||||||
self.into_array().into_iter()
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue