Moved extensions into `linebuffer`

Fortune for day14's current commit: Blessing − 吉
master
Avril 1 year ago
parent bfccf7a426
commit 6a2aefc1d9
Signed by: flanchan
GPG Key ID: 284488987C31F630

2
day14/Cargo.lock generated

@ -176,7 +176,7 @@ checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "linebuffer"
version = "0.1.0"
version = "0.1.1"
[[package]]
name = "log"

@ -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()
}
}

@ -17,11 +17,7 @@ use color_eyre::{
Help as _, SectionExt as _,
};
use linebuffer::{
FromBuf, TryFromBuf,
ParsedLines,
buf::forward,
};
use linebuffer::prelude::*;
#[cfg(feature="jemallocator")]
const _:() = {
@ -31,15 +27,6 @@ const _:() = {
static GLOBAL: Jemalloc = Jemalloc;
};
mod ext;
use ext::{
TakeTwoExt as _,
TakeTwoBoxedExt as _,
Tuple2Ext as _,
Tuple2OptExt as _,
Tuple2STExt as _,
};
mod grid;
/// A point is a vector
@ -96,11 +83,16 @@ impl Lines {
self.lines.extend(next);
self
}
#[inline(always)]
pub fn flattening<'a>(lines: impl IntoIterator<Item = Self> + 'a) -> impl IntoIterator<Item = Line> + 'a
{
lines.into_iter().map(|x| x.lines.into_iter()).flatten()
}
#[inline]
pub fn flatten(lines: impl IntoIterator<Item = Self>) -> Self
{
Self {
lines: lines.into_iter().map(|x| x.lines.into_iter()).flatten().collect(),
lines: Self::flattening(lines).into_iter().collect(),
}
}
}
@ -155,6 +147,7 @@ impl Input {
{
Self::from_parser(ParsedLines::new(reader))
}
#[inline]
pub fn from_parser<R: io::Read>(lines: ParsedLines<R, forward::FromStr<Lines>>) -> eyre::Result<Self>
{
struct ParsedIter<T: io::Read>(ParsedLines<T, forward::FromStr<Lines>>);
@ -167,6 +160,8 @@ impl Input {
self.0.try_next()
}
}
impl<T: io::Read> iter::FusedIterator for ParsedIter<T>
where ParsedLines<T, forward::FromStr<Lines>>: iter::FusedIterator{}
ParsedIter(lines).enumerate().map(|(i,x)| x.wrap_err("Failed to parse single line").with_section(move || i.header("Line number is"))).collect()
}

Loading…
Cancel
Save