You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
reverse/src/main.rs

94 lines
2.6 KiB

//#[inline]
fn reverse<T>(slice: &mut [T])
{
match slice {
[ref mut a, ref mut rest @ .., ref mut b] => {
std::mem::swap(a, b);
reverse(rest)
},
[] | [_] => (),
}
}
/// This actually works! And is so easily parallelisable with something like rayon, or asyncing by spawning/creating the tail-call into a new task, then either waiting them concurrently or in parallen (spawn or created future from just calling the function without awaiting it)
#[allow(dead_code)]
fn binsearch<'a, V: ?Sized, T: PartialEq<V> + 'a>(slice: &'a [T], find: &V) -> Option<&'a T>
{
match slice {
[ref a, pivot @ .., ref b] => {
match (a==find, b==find) {
(true, _) => Some(a),
(_, true) => Some(b),
_ => binsearch(pivot, find),
}
},
[ref a] if a == find => Some(a),
_ => None,
}
}
fn collect_input() -> Box<dyn Iterator<Item=String> + 'static>
{
//! TODO: Use non-panicking functions for both reading lines and reading args, just skip invalid lines/args
if std::env::args_os().len() <= 1 {
use std::io::{
self,
BufRead,
};
// No args, collect stdin lines
Box::new(io::BufReader::new(io::stdin()
.lock())
.lines()
.filter_map(Result::ok))
} else {
// Has arguments, return them
Box::new(std::env::args().skip(1))
}
}
#[cfg_attr(feature="ignore-output-errors", inline(always))]
fn handle_fmt_err<T>(res: std::io::Result<T>)
{
#[cfg(not(feature="ignore-output-errors"))]
if let Err(e) = res {
eprintln!("[!] failed to write line: {e}");
}
let _ = res;
}
fn main() {
let mut args: Vec<String> = collect_input().collect();
reverse(&mut args[..]);
//eprintln!("{:?}", binsearch(&args[..], "1")); // It works!
#[cfg(feature="output-lines")]
{
#[allow(unused_imports)]
use std::io::{
Write, BufWriter,
};
#[cfg(feature="buffer-output")]
let mut out = BufWriter::new(std::io::stdout().lock());
#[cfg(not(feature="buffer-output"))]
let mut out = std::io::stdout().lock();
for x in args.iter() {
handle_fmt_err({
if cfg!(feature="output-quoted") {
//XXX: This doesn't flush, right? It shouldn't, but maybe we should test it?
writeln!(&mut out, "{:?}", x)
}
else {
//writeln!(&mut out, "{}", x)
out.write(x.as_bytes())
.and_then(|_| out.write(b"\n"))
.map(|_| {})
}
});
}
//#[cfg(feature="buffer-output")]
handle_fmt_err(out.flush()); //XXX: Do we need to flush when not buffering output? Does it matter since buffering output will be enabled by default and should almost always be enabled?
}
#[cfg(not(feature="output-lines"))]
println!("{:?}", args);
}