use std::io::{Read, Write};
use std::ops::Shr;
use super::as_read::AsRead;
use super::{Cin, IStream};
use crate::ostream::as_write::AsWrite;
use crate::ostream::into_ostream::IntoOStream;
#[inline]
fn copy_from_read_to_write(
read: &mut impl Read,
write: &mut impl std::io::Write,
) -> std::io::Result<()> {
let mut buffer = [0u8; 100];
loop {
let read = read.read(&mut buffer[..])?;
if read == 0 {
break;
}
write.write_all(&buffer[..read])?;
}
Ok(())
}
macro_rules! impl_istream_into_ostream {
($writer:ty, $reader:ty, $($t:ident : $n:ident )*) => {
impl<$($t : $n,)*> Shr<$writer> for $reader {
type Output = $crate::OStream<<$writer as IntoOStream>::Writer>;
#[inline]
#[allow(unused_mut)]
fn shr(mut self, mut rhs: $writer) -> Self::Output {
let mut ostream = rhs.into_ostream();
copy_from_read_to_write(&mut self.as_read(), &mut ostream.as_write()).unwrap();
ostream
}
}
impl<'a, $($t : $n,)*> Shr<&'a mut $writer> for $reader {
type Output = &'a mut $writer;
#[inline]
#[allow(unused_mut)]
fn shr(mut self, mut rhs: &'a mut $writer) -> Self::Output {
copy_from_read_to_write(&mut self.as_read(), &mut rhs.as_write()).unwrap();
rhs
}
}
};
}
impl_istream_into_ostream!(crate::Cout, Cin,);
impl_istream_into_ostream!(crate::Cerr, Cin,);
impl_istream_into_ostream!(crate::StringStream, Cin,);
impl_istream_into_ostream!(crate::OStream<W>, Cin, W : Write);
impl_istream_into_ostream!(crate::Cout, crate::StringStream,);
impl_istream_into_ostream!(crate::Cerr, crate::StringStream,);
impl_istream_into_ostream!(crate::StringStream, crate::StringStream,);
impl_istream_into_ostream!(crate::OStream<W>, crate::StringStream, W : Write);
impl_istream_into_ostream!(crate::Cout, IStream<R>, R : Read);
impl_istream_into_ostream!(crate::Cerr, IStream<R>, R : Read);
impl_istream_into_ostream!(crate::StringStream, IStream<R>, R : Read);
impl_istream_into_ostream!(crate::OStream<W>, IStream<R>, R : Read W : Write);
impl_istream_into_ostream!(crate::Cout, &mut Cin,);
impl_istream_into_ostream!(crate::Cerr, &mut Cin,);
impl_istream_into_ostream!(crate::StringStream, &mut Cin,);
impl_istream_into_ostream!(crate::OStream<W>, &mut Cin, W : Write);
impl_istream_into_ostream!(crate::Cout, &mut crate::StringStream,);
impl_istream_into_ostream!(crate::Cerr, &mut crate::StringStream,);
impl_istream_into_ostream!(crate::StringStream, &mut crate::StringStream,);
impl_istream_into_ostream!(crate::OStream<W>, &mut crate::StringStream, W : Write);
impl_istream_into_ostream!(crate::Cout, &mut IStream<R>, R : Read);
impl_istream_into_ostream!(crate::Cerr, &mut IStream<R>, R : Read);
impl_istream_into_ostream!(crate::StringStream, &mut IStream<R>, R : Read);
impl_istream_into_ostream!(crate::OStream<W>, &mut IStream<R>, R : Read W : Write);