<commit_before>use tag;

/// Provides ASN.1 information about a Rust type, including the BER tag and ASN.1 type.
pub trait Asn1Info {
  /// Get the ASN.1 tag (if defined) for this Rust type. Some types don't have a tag, eg. CHOICE.
  fn asn1_tag() -> Option<tag::Tag>;

  /// Get the ASN.1 type for this Rust type.
  fn asn1_type() -> tag::Type;
}

#[macro_export]
/// This macro defines the Asn1Info trait for a rust type.
///
/// This information is used to match tag information during deserialization,
/// so it should match the expected values in the ASN.1 stream.
macro_rules! asn1_info {
  ($rs_type:ty => $gen:ident, $($args:tt)*) => (
    impl<$gen> $crate::Asn1Info for $rs_type {
      asn1_info!{__impl $($args)*}
    }
  );
  (__impl [$($args:tt)*], $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      Some(asn1_spec_tag!([$($args)*]))
    }
    asn1_info!(__type $asn1_ty);
  );
  (__impl $class:expr, $tagnum:expr, $constructed:expr, $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      Some($crate::tag::Tag {
        class: ($class as u8).into(),
        tagnum: $tagnum as $crate::tag::TagNum,
        constructed: $constructed,
      })
    }
    asn1_info!(__type $asn1_ty);
  );
  (__impl $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      None
    }
    asn1_info!(__type $asn1_ty);
  );
  (__type $asn1_ty:expr) => (
    fn asn1_type() -> $crate::tag::Type {
      $crate::tag::Type::from($asn1_ty)
    }
  );
  ($rs_type:ty, $($args:tt)*) => (
    impl $crate::Asn1Info for $rs_type {
      asn1_info!{__impl $($args)*}
    }
  );
}

#[macro_export]
/// This macro parses an ASN.1 tag specification, and returns the appropriate Tag.
macro_rules! asn1_spec_tag {
  ({ $count:ident }) => (
    asn1_spec_tag!([])
  );
  ({ $count:ident } []) => ({
    let _count = $count;
    $count += 1;
    asn1_spec_tag!([CONTEXT _count])
  });
  ({ $count:ident } [$($args:tt)*]) => (
    asn1_spec_tag!([$($args)*])
  );
  ([$tagnum:expr]) => (
    asn1_spec_tag!([CONTEXT $tagnum]);
  );
  ([CONTEXT $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::ContextSpecific,
      tagnum: $tagnum,
      constructed: true,
    }
  );
  ([APPLICATION $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::Application,
      tagnum: $tagnum,
      constructed: true,
    }
  );
  ([PRIVATE $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::Private,
      tagnum: $tagnum,
      constructed: true,
    }
  );
}
<commit_msg>Allow UNIVERSAL tags to be specified<commit_after>use tag;

/// Provides ASN.1 information about a Rust type, including the BER tag and ASN.1 type.
pub trait Asn1Info {
  /// Get the ASN.1 tag (if defined) for this Rust type. Some types don't have a tag, eg. CHOICE.
  fn asn1_tag() -> Option<tag::Tag>;

  /// Get the ASN.1 type for this Rust type.
  fn asn1_type() -> tag::Type;
}

#[macro_export]
/// This macro defines the Asn1Info trait for a rust type.
///
/// This information is used to match tag information during deserialization,
/// so it should match the expected values in the ASN.1 stream.
///
/// ```
/// #[macro_use] extern crate asn1_cereal; fn main() {
/// // For A ::= [APPLICATION 3] u64
/// struct A(u64);
/// asn1_info!(A, [APPLICATION 3], "A");
///
/// // For B ::= [PRIVATE 3] u64
/// struct B(u64);
/// asn1_info!(B, [PRIVATE 3], "B");
///
/// // For a primitive type, with application tag 3.
/// struct C(u64);
/// // (The false here sets the constructed flag).
/// asn1_info!(C, asn1_cereal::tag::Class::Application, 3, false, "C");
/// }
/// ```
macro_rules! asn1_info {
  ($rs_type:ty => $gen:ident, $($args:tt)*) => (
    impl<$gen> $crate::Asn1Info for $rs_type {
      asn1_info!{__impl $($args)*}
    }
  );
  (__impl [$($args:tt)*], $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      Some(asn1_spec_tag!([$($args)*]))
    }
    asn1_info!(__type $asn1_ty);
  );
  (__impl $class:expr, $tagnum:expr, $constructed:expr, $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      Some($crate::tag::Tag {
        class: ($class as u8).into(),
        tagnum: $tagnum as $crate::tag::TagNum,
        constructed: $constructed,
      })
    }
    asn1_info!(__type $asn1_ty);
  );
  (__impl $asn1_ty:expr) => (
    fn asn1_tag() -> Option<$crate::tag::Tag> {
      None
    }
    asn1_info!(__type $asn1_ty);
  );
  (__type $asn1_ty:expr) => (
    fn asn1_type() -> $crate::tag::Type {
      $crate::tag::Type::from($asn1_ty)
    }
  );
  ($rs_type:ty, $($args:tt)*) => (
    impl $crate::Asn1Info for $rs_type {
      asn1_info!{__impl $($args)*}
    }
  );
}

#[macro_export]
/// This macro parses an ASN.1 tag specification, and returns the appropriate Tag.
macro_rules! asn1_spec_tag {
  ({ $count:ident }) => (
    asn1_spec_tag!([])
  );
  ({ $count:ident } []) => ({
    let _count = $count;
    $count += 1;
    asn1_spec_tag!([CONTEXT _count])
  });
  ({ $count:ident } [$($args:tt)*]) => (
    asn1_spec_tag!([$($args)*])
  );
  ([$tagnum:expr]) => (
    asn1_spec_tag!([CONTEXT $tagnum]);
  );
  ([UNIVERSAL $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::Universal,
      tagnum: $tagnum,
      constructed: true,
    }
  );
  ([CONTEXT $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::ContextSpecific,
      tagnum: $tagnum,
      constructed: true,
    }
  );
  ([APPLICATION $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::Application,
      tagnum: $tagnum,
      constructed: true,
    }
  );
  ([PRIVATE $tagnum:expr]) => (
    $crate::tag::Tag {
      class: $crate::tag::Class::Private,
      tagnum: $tagnum,
      constructed: true,
    }
  );
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

extern crate gj;

#[test]
fn hello() {
    use gj::io::{AsyncRead, AsyncWrite};
    gj::EventLoop::top_level(|wait_scope| {

        let addr = ::std::str::FromStr::from_str("127.0.0.1:10000").unwrap();
        let listener = gj::io::tcp::Listener::bind(addr).unwrap();

        let _write_promise = listener.accept().lift::<::std::io::Error>().then(move |(_, stream)| {
            stream.write(vec![0,1,2,3,4,5]).lift()
        });

        let read_promise = gj::io::tcp::Stream::connect(addr).lift::<::std::io::Error>().then(move |stream| {
            stream.read(vec![0u8; 6], 6).lift()
        });

        let (_, buf, _) = read_promise.wait(wait_scope).unwrap();

        assert_eq!(&buf[..], [0,1,2,3,4,5]);
        Ok(())
    }).unwrap();
}

#[test]
fn echo() {
    use gj::io::{AsyncRead, AsyncWrite};
    gj::EventLoop::top_level(|wait_scope| {

        let addr = ::std::str::FromStr::from_str("127.0.0.1:10001").unwrap();
        let listener = gj::io::tcp::Listener::bind(addr).unwrap();

        let _server_promise = listener.accept().lift::<::std::io::Error>().then(move |(_, stream)| {
            stream.read(vec![0u8; 6], 6).lift().then(move |(stream, mut v, _)| {
                assert_eq!(&v[..], [7,6,5,4,3,2]);
                for x in &mut v {
                    *x += 1;
                }
                stream.write(v).lift()
            })
        });

        let client_promise = gj::io::tcp::Stream::connect(addr).lift::<::std::io::Error>().then(move |stream| {
            stream.write(vec![7,6,5,4,3,2]).lift().then(move |(stream, v)| {
                stream.read(v, 6).lift()
            })
        });

        let (_, buf, _) = client_promise.wait(wait_scope).unwrap();
        assert_eq!(&buf[..], [8,7,6,5,4,3]);
        Ok(())
    }).unwrap();
}
<commit_msg>deregister_dupped() test<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#[macro_use]
extern crate gj;
use gj::{EventLoop, Promise};
use gj::io::{AsyncRead, AsyncWrite, tcp, unix};

#[test]
fn hello() {
    EventLoop::top_level(|wait_scope| {

        let addr = ::std::str::FromStr::from_str("127.0.0.1:10000").unwrap();
        let listener = tcp::Listener::bind(addr).unwrap();

        let _write_promise = listener.accept().lift::<::std::io::Error>().then(move |(_, stream)| {
            stream.write(vec![0,1,2,3,4,5]).lift()
        });

        let read_promise = tcp::Stream::connect(addr).lift::<::std::io::Error>().then(move |stream| {
            stream.read(vec![0u8; 6], 6).lift()
        });

        let (_, buf, _) = read_promise.wait(wait_scope).unwrap();

        assert_eq!(&buf[..], [0,1,2,3,4,5]);
        Ok(())
    }).unwrap();
}

#[test]
fn echo() {
    EventLoop::top_level(|wait_scope| {

        let addr = ::std::str::FromStr::from_str("127.0.0.1:10001").unwrap();
        let listener = tcp::Listener::bind(addr).unwrap();

        let _server_promise = listener.accept().lift::<::std::io::Error>().then(move |(_, stream)| {
            stream.read(vec![0u8; 6], 6).lift().then(move |(stream, mut v, _)| {
                assert_eq!(&v[..], [7,6,5,4,3,2]);
                for x in &mut v {
                    *x += 1;
                }
                stream.write(v).lift()
            })
        });

        let client_promise = tcp::Stream::connect(addr).lift::<::std::io::Error>().then(move |stream| {
            stream.write(vec![7,6,5,4,3,2]).lift().then(move |(stream, v)| {
                stream.read(v, 6).lift()
            })
        });

        let (_, buf, _) = client_promise.wait(wait_scope).unwrap();
        assert_eq!(&buf[..], [8,7,6,5,4,3]);
        Ok(())
    }).unwrap();
}

#[test]
fn deregister_dupped() {
    EventLoop::top_level(|wait_scope| {
        let (stream1, stream2) = try!(unix::Stream::new_pair());
        let stream1_dupped = try!(stream1.try_clone());
        drop(stream1);

        let promise1 = stream1_dupped.read(vec![0u8; 6], 6).then(|(stream, v, _)| {
            Promise::ok(())
        });
        let promise2 = stream2.write(vec![1,2,3,4,5,6]);

        promise1.wait(wait_scope);

        Ok(())
    }).unwrap();
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::VecDeque;
use std::io::{self, ErrorKind, Write};
use std::net::SocketAddr;
use std::rc::Rc;
use std::time::{Duration, Instant};

use bytes::Bytes;
use bytes::buf::FromBuf;
use futures::{Async, Future, Poll};
use futures::task::{self, Task};
use kcp::{Error as KcpError, Kcp, KcpResult, get_conv};
use tokio_core::net::UdpSocket;
use tokio_core::reactor::Handle;

use config::KcpConfig;

struct KcpOutputInner {
    udp: Rc<UdpSocket>,
    task: Option<Task>,
    pkt_queue: VecDeque<(SocketAddr, Bytes)>,
    is_finished: bool,
}

impl KcpOutputInner {
    fn new(udp: Rc<UdpSocket>) -> KcpOutputInner {
        KcpOutputInner {
            udp: udp,
            task: None,
            pkt_queue: VecDeque::new(),
            is_finished: false,
        }
    }

    fn notify(&mut self) {
        if let Some(task) = self.task.take() {
            task.notify();
        }
    }

    fn push_packet(&mut self, pkt: Bytes, peer: SocketAddr) {
        self.pkt_queue.push_back((peer, pkt));
        self.notify();
    }

    fn close(&mut self) {
        self.is_finished = true;
        self.notify();
    }

    fn is_empty(&self) -> bool {
        self.pkt_queue.is_empty()
    }

    fn send_or_push(&mut self, buf: &[u8], peer: &SocketAddr) -> io::Result<usize> {
        if self.is_empty() {
            match self.udp.send_to(buf, peer) {
                Ok(n) => {
                    trace!("[SEND] UDP peer={} conv={} size={} {:?}",
                           peer,
                           get_conv(buf),
                           buf.len(),
                           ::debug::BsDebug(buf));
                    if n != buf.len() {
                        error!("[SEND] UDP Sent size={}, but packet is size={}", n, buf.len());
                    }
                    return Ok(n);
                }
                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}
                Err(err) => return Err(err),
            }
        }

        trace!("[SEND] Delay UDP peer={} conv={} size={} qsize={} {:?}",
               peer,
               get_conv(buf),
               buf.len(),
               self.pkt_queue.len(),
               ::debug::BsDebug(buf));

        self.push_packet(Bytes::from_buf(buf), *peer);
        Ok(buf.len())
    }
}

impl Drop for KcpOutputInner {
    fn drop(&mut self) {
        self.close();
    }
}

struct KcpOutputQueue {
    inner: Rc<RefCell<KcpOutputInner>>,
}

impl Future for KcpOutputQueue {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        let mut inner = self.inner.borrow_mut();

        while !inner.pkt_queue.is_empty() {
            {
                let &(ref peer, ref pkt) = &inner.pkt_queue[0];
                let n = try_nb!(inner.udp.send_to(&*pkt, peer));
                trace!("[SEND] Delayed UDP peer={} conv={} size={} {:?}", peer, get_conv(pkt), pkt.len(), pkt);
                if n != pkt.len() {
                    error!("[SEND] Delayed Sent size={}, but packet is size={}", n, pkt.len());
                }
            }

            let _ = inner.pkt_queue.pop_front();
        }

        if inner.is_finished {
            Ok(Async::Ready(()))
        } else {
            inner.task = Some(task::current());
            Ok(Async::NotReady)
        }
    }
}

#[derive(Clone)]
pub struct KcpOutputHandle {
    inner: Rc<RefCell<KcpOutputInner>>,
}

impl KcpOutputHandle {
    pub fn new(udp: Rc<UdpSocket>, handle: &Handle) -> KcpOutputHandle {
        let inner = KcpOutputInner::new(udp);
        let inner = Rc::new(RefCell::new(inner));
        let queue = KcpOutputQueue { inner: inner.clone() };
        handle.spawn(queue.map_err(move |err| {
                                       error!("[SEND] UDP output queue failed, err: {:?}", err);
                                   }));
        KcpOutputHandle { inner: inner }
    }

    fn send_to(&mut self, buf: &[u8], peer: &SocketAddr) -> io::Result<usize> {
        let mut inner = self.inner.borrow_mut();
        inner.send_or_push(buf, peer)
    }

    fn udp(&self) -> Rc<UdpSocket> {
        let inner = self.inner.borrow();
        inner.udp.clone()
    }
}

pub struct KcpOutput {
    inner: KcpOutputHandle,
    peer: SocketAddr,
}

impl KcpOutput {
    pub fn new(udp: Rc<UdpSocket>, peer: SocketAddr, handle: &Handle) -> KcpOutput {
        KcpOutput::new_with_handle(KcpOutputHandle::new(udp, handle), peer)
    }

    pub fn new_with_handle(h: KcpOutputHandle, peer: SocketAddr) -> KcpOutput {
        KcpOutput {
            inner: h,
            peer: peer,
        }
    }

    fn udp(&self) -> Rc<UdpSocket> {
        self.inner.udp()
    }
}

impl Write for KcpOutput {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.send_to(buf, &self.peer)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

struct KcpCell {
    kcp: Kcp<KcpOutput>,
    last_update: Instant,
    is_closed: bool,
    send_task: Option<Task>,
    udp: Rc<UdpSocket>,
    recv_buf: Vec<u8>,
    expired: bool,
    sent_first: bool,
    flush_write: bool,
    flush_ack_input: bool,
}

impl Drop for KcpCell {
    fn drop(&mut self) {
        let _ = self.kcp.flush();
    }
}

impl KcpCell {
    fn input(&mut self, buf: &[u8]) -> KcpResult<()> {
        match self.kcp.input(buf) {
            Ok(..) => {}
            Err(KcpError::ConvInconsistent(expected, actual)) => {
                trace!("[INPUT] Conv expected={} actual={} ignored", expected, actual);
                return Ok(());
            }
            Err(err) => return Err(err),
        }
        // self.kcp.input(buf)?;
        self.last_update = Instant::now();

        if self.flush_ack_input {
            self.kcp.flush_ack()?;
        }

        Ok(())
    }

    fn input_self(&mut self, n: usize) -> KcpResult<()> {
        match self.kcp.input(&self.recv_buf[..n]) {
            Ok(..) => {}
            Err(KcpError::ConvInconsistent(expected, actual)) => {
                trace!("[INPUT] Conv expected={} actual={} ignored", expected, actual);
                return Ok(());
            }
            Err(err) => return Err(err),
        }
        // self.kcp.input(&self.recv_buf[..n])?;
        self.last_update = Instant::now();

        if self.flush_ack_input {
            self.kcp.flush_ack()?;
        }

        Ok(())
    }

    fn fetch(&mut self) -> KcpResult<()> {
        if let Async::NotReady = self.udp.poll_read() {
            return Ok(());
        }

        // Initialize with MTU
        if self.recv_buf.len() < self.kcp.mtu() {
            let mtu = self.kcp.mtu();
            self.recv_buf.resize(mtu, 0);
        }

        let n = match self.udp.recv_from(&mut self.recv_buf) {
            Ok((n, _)) => n,
            Err(ref err) if err.kind() == ErrorKind::WouldBlock => {
                return Ok(());
            }
            Err(err) => return Err(From::from(err)),
        };

        // Ah, we got something
        trace!("[RECV] Fetch. SharedKcp recv size={} {:?}", n, ::debug::BsDebug(&self.recv_buf[..n]));
        self.input_self(n)
    }
}

#[derive(Clone)]
pub struct SharedKcp {
    inner: Rc<RefCell<KcpCell>>,
}

impl SharedKcp {
    pub fn new(c: &KcpConfig,
               conv: u32,
               udp: Rc<UdpSocket>,
               peer: SocketAddr,
               handle: &Handle,
               stream: bool)
               -> SharedKcp {
        let output = KcpOutput::new(udp, peer, handle);
        SharedKcp::new_with_output(c, conv, output, stream)
    }

    pub fn new_with_output(c: &KcpConfig, conv: u32, output: KcpOutput, stream: bool) -> SharedKcp {
        let udp = output.udp();
        let mut kcp = if stream {
            Kcp::new_stream(conv, output)
        } else {
            Kcp::new(conv, output)
        };
        c.apply_config(&mut kcp);

        // Ask server to allocate one
        if conv == 0 {
            kcp.input_conv();
        }

        SharedKcp {
            inner: Rc::new(RefCell::new(KcpCell {
                                            kcp: kcp,
                                            last_update: Instant::now(),
                                            is_closed: false,
                                            send_task: None,
                                            udp: udp,
                                            recv_buf: Vec::new(), // Do not initialize it yet.
                                            expired: false,
                                            sent_first: false,
                                            flush_write: true,
                                            flush_ack_input: true,
                                        })),
        }
    }

    /// Call every time you got data from transmission
    pub fn input(&mut self, buf: &[u8]) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.input(buf)
    }

    /// Recv then input, ignore WouldBlock
    pub fn fetch(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.fetch()
    }

    /// Call if you want to send some data
    pub fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        let mut inner = self.inner.borrow_mut();

        // If:
        //     1. Have sent the first packet (asking for conv)
        //     2. Too many pending packets
        if inner.sent_first && (inner.kcp.wait_snd() >= inner.kcp.snd_wnd() as usize || inner.kcp.waiting_conv()) {
            trace!("[SEND] waitsnd={} sndwnd={} excceeded or waiting conv={}",
                   inner.kcp.wait_snd(),
                   inner.kcp.snd_wnd(),
                   inner.kcp.waiting_conv());
            inner.send_task = Some(task::current());
            return Err(From::from(io::Error::new(ErrorKind::WouldBlock, "too many pending packets")));
        }

        let n = inner.kcp.send(buf)?;
        inner.sent_first = true;
        inner.last_update = Instant::now();

        if inner.flush_write {
            inner.kcp.flush()?;
        }

        Ok(n)
    }

    /// Try to notify writable
    pub fn try_notify_writable(&mut self) {
        let mut inner = self.inner.borrow_mut();
        if inner.kcp.wait_snd() < inner.kcp.snd_wnd() as usize && !inner.kcp.waiting_conv() {
            if let Some(task) = inner.send_task.take() {
                task.notify();
            }
        }
    }

    /// Call if you want to get some data
    /// Always call right after input
    pub fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        let mut inner = self.inner.borrow_mut();
        if inner.expired {
            // If it is already expired, return EOF
            return Ok(0);
        }

        let n = inner.kcp.recv(buf)?;
        inner.last_update = Instant::now();
        Ok(n)
    }

    /// Call if you want to flush all pending data in queue
    pub fn flush(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.kcp.flush()?;
        inner.last_update = Instant::now();
        Ok(())
    }

    /// Tell me how long this session have no interaction
    pub fn elapsed(&self) -> Duration {
        let inner = self.inner.borrow();
        inner.last_update.elapsed()
    }

    /// Make this session expire, all read apis will return 0 (EOF)
    /// It will flush the buffer when it is called
    pub fn set_expired(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.expired = true;
        inner.kcp.flush()
    }

    /// Call in every tick
    /// Returns when to call this function again
    pub fn update(&mut self) -> KcpResult<Instant> {
        let mut inner = self.inner.borrow_mut();
        inner.kcp.update(::current())?;
        let next = inner.kcp.check(::current());
        Ok(Instant::now() + Duration::from_millis(next as u64))
        // Ok(Instant::now() + Duration::from_millis(5))
    }

    /// Check if send queue is empty
    pub fn has_waitsnd(&self) -> bool {
        let inner = self.inner.borrow();
        inner.kcp.wait_snd() != 0
    }

    /// Get mtu
    pub fn mtu(&self) -> usize {
        let inner = self.inner.borrow();
        inner.kcp.mtu()
    }

    /// Set is close
    pub fn close(&mut self) {
        let mut inner = self.inner.borrow_mut();
        trace!("[KCP] Set close, conv={}", inner.kcp.conv());
        inner.is_closed = true;
    }

    /// Check if it is closed
    pub fn is_closed(&self) -> bool {
        let inner = self.inner.borrow();
        inner.is_closed
    }

    /// Check if it can read
    pub fn can_read(&self) -> bool {
        let inner = self.inner.borrow();
        inner.kcp.peeksize().unwrap_or(0) != 0
    }

    /// Peek
    pub fn peeksize(&self) -> usize {
        let inner = self.inner.borrow();
        inner.kcp.peeksize().unwrap_or(0)
    }

    /// Get conv
    pub fn conv(&self) -> u32 {
        let inner = self.inner.borrow();
        inner.kcp.conv()
    }
}
<commit_msg>Read flush_write and flush_ack_input from config<commit_after>use std::cell::RefCell;
use std::collections::VecDeque;
use std::io::{self, ErrorKind, Write};
use std::net::SocketAddr;
use std::rc::Rc;
use std::time::{Duration, Instant};

use bytes::Bytes;
use bytes::buf::FromBuf;
use futures::{Async, Future, Poll};
use futures::task::{self, Task};
use kcp::{Error as KcpError, Kcp, KcpResult, get_conv};
use tokio_core::net::UdpSocket;
use tokio_core::reactor::Handle;

use config::KcpConfig;

struct KcpOutputInner {
    udp: Rc<UdpSocket>,
    task: Option<Task>,
    pkt_queue: VecDeque<(SocketAddr, Bytes)>,
    is_finished: bool,
}

impl KcpOutputInner {
    fn new(udp: Rc<UdpSocket>) -> KcpOutputInner {
        KcpOutputInner {
            udp: udp,
            task: None,
            pkt_queue: VecDeque::new(),
            is_finished: false,
        }
    }

    fn notify(&mut self) {
        if let Some(task) = self.task.take() {
            task.notify();
        }
    }

    fn push_packet(&mut self, pkt: Bytes, peer: SocketAddr) {
        self.pkt_queue.push_back((peer, pkt));
        self.notify();
    }

    fn close(&mut self) {
        self.is_finished = true;
        self.notify();
    }

    fn is_empty(&self) -> bool {
        self.pkt_queue.is_empty()
    }

    fn send_or_push(&mut self, buf: &[u8], peer: &SocketAddr) -> io::Result<usize> {
        if self.is_empty() {
            match self.udp.send_to(buf, peer) {
                Ok(n) => {
                    trace!("[SEND] UDP peer={} conv={} size={} {:?}",
                           peer,
                           get_conv(buf),
                           buf.len(),
                           ::debug::BsDebug(buf));
                    if n != buf.len() {
                        error!("[SEND] UDP Sent size={}, but packet is size={}", n, buf.len());
                    }
                    return Ok(n);
                }
                Err(ref err) if err.kind() == ErrorKind::WouldBlock => {}
                Err(err) => return Err(err),
            }
        }

        trace!("[SEND] Delay UDP peer={} conv={} size={} qsize={} {:?}",
               peer,
               get_conv(buf),
               buf.len(),
               self.pkt_queue.len(),
               ::debug::BsDebug(buf));

        self.push_packet(Bytes::from_buf(buf), *peer);
        Ok(buf.len())
    }
}

impl Drop for KcpOutputInner {
    fn drop(&mut self) {
        self.close();
    }
}

struct KcpOutputQueue {
    inner: Rc<RefCell<KcpOutputInner>>,
}

impl Future for KcpOutputQueue {
    type Item = ();
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(), io::Error> {
        let mut inner = self.inner.borrow_mut();

        while !inner.pkt_queue.is_empty() {
            {
                let &(ref peer, ref pkt) = &inner.pkt_queue[0];
                let n = try_nb!(inner.udp.send_to(&*pkt, peer));
                trace!("[SEND] Delayed UDP peer={} conv={} size={} {:?}", peer, get_conv(pkt), pkt.len(), pkt);
                if n != pkt.len() {
                    error!("[SEND] Delayed Sent size={}, but packet is size={}", n, pkt.len());
                }
            }

            let _ = inner.pkt_queue.pop_front();
        }

        if inner.is_finished {
            Ok(Async::Ready(()))
        } else {
            inner.task = Some(task::current());
            Ok(Async::NotReady)
        }
    }
}

#[derive(Clone)]
pub struct KcpOutputHandle {
    inner: Rc<RefCell<KcpOutputInner>>,
}

impl KcpOutputHandle {
    pub fn new(udp: Rc<UdpSocket>, handle: &Handle) -> KcpOutputHandle {
        let inner = KcpOutputInner::new(udp);
        let inner = Rc::new(RefCell::new(inner));
        let queue = KcpOutputQueue { inner: inner.clone() };
        handle.spawn(queue.map_err(move |err| {
                                       error!("[SEND] UDP output queue failed, err: {:?}", err);
                                   }));
        KcpOutputHandle { inner: inner }
    }

    fn send_to(&mut self, buf: &[u8], peer: &SocketAddr) -> io::Result<usize> {
        let mut inner = self.inner.borrow_mut();
        inner.send_or_push(buf, peer)
    }

    fn udp(&self) -> Rc<UdpSocket> {
        let inner = self.inner.borrow();
        inner.udp.clone()
    }
}

pub struct KcpOutput {
    inner: KcpOutputHandle,
    peer: SocketAddr,
}

impl KcpOutput {
    pub fn new(udp: Rc<UdpSocket>, peer: SocketAddr, handle: &Handle) -> KcpOutput {
        KcpOutput::new_with_handle(KcpOutputHandle::new(udp, handle), peer)
    }

    pub fn new_with_handle(h: KcpOutputHandle, peer: SocketAddr) -> KcpOutput {
        KcpOutput {
            inner: h,
            peer: peer,
        }
    }

    fn udp(&self) -> Rc<UdpSocket> {
        self.inner.udp()
    }
}

impl Write for KcpOutput {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.send_to(buf, &self.peer)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

struct KcpCell {
    kcp: Kcp<KcpOutput>,
    last_update: Instant,
    is_closed: bool,
    send_task: Option<Task>,
    udp: Rc<UdpSocket>,
    recv_buf: Vec<u8>,
    expired: bool,
    sent_first: bool,
    flush_write: bool,
    flush_ack_input: bool,
}

impl Drop for KcpCell {
    fn drop(&mut self) {
        let _ = self.kcp.flush();
    }
}

impl KcpCell {
    fn input(&mut self, buf: &[u8]) -> KcpResult<()> {
        match self.kcp.input(buf) {
            Ok(..) => {}
            Err(KcpError::ConvInconsistent(expected, actual)) => {
                trace!("[INPUT] Conv expected={} actual={} ignored", expected, actual);
                return Ok(());
            }
            Err(err) => return Err(err),
        }
        // self.kcp.input(buf)?;
        self.last_update = Instant::now();

        if self.flush_ack_input {
            self.kcp.flush_ack()?;
        }

        Ok(())
    }

    fn input_self(&mut self, n: usize) -> KcpResult<()> {
        match self.kcp.input(&self.recv_buf[..n]) {
            Ok(..) => {}
            Err(KcpError::ConvInconsistent(expected, actual)) => {
                trace!("[INPUT] Conv expected={} actual={} ignored", expected, actual);
                return Ok(());
            }
            Err(err) => return Err(err),
        }
        // self.kcp.input(&self.recv_buf[..n])?;
        self.last_update = Instant::now();

        if self.flush_ack_input {
            self.kcp.flush_ack()?;
        }

        Ok(())
    }

    fn fetch(&mut self) -> KcpResult<()> {
        if let Async::NotReady = self.udp.poll_read() {
            return Ok(());
        }

        // Initialize with MTU
        if self.recv_buf.len() < self.kcp.mtu() {
            let mtu = self.kcp.mtu();
            self.recv_buf.resize(mtu, 0);
        }

        let n = match self.udp.recv_from(&mut self.recv_buf) {
            Ok((n, _)) => n,
            Err(ref err) if err.kind() == ErrorKind::WouldBlock => {
                return Ok(());
            }
            Err(err) => return Err(From::from(err)),
        };

        // Ah, we got something
        trace!("[RECV] Fetch. SharedKcp recv size={} {:?}", n, ::debug::BsDebug(&self.recv_buf[..n]));
        self.input_self(n)
    }
}

#[derive(Clone)]
pub struct SharedKcp {
    inner: Rc<RefCell<KcpCell>>,
}

impl SharedKcp {
    pub fn new(c: &KcpConfig,
               conv: u32,
               udp: Rc<UdpSocket>,
               peer: SocketAddr,
               handle: &Handle,
               stream: bool)
               -> SharedKcp {
        let output = KcpOutput::new(udp, peer, handle);
        SharedKcp::new_with_output(c, conv, output, stream)
    }

    pub fn new_with_output(c: &KcpConfig, conv: u32, output: KcpOutput, stream: bool) -> SharedKcp {
        let udp = output.udp();
        let mut kcp = if stream {
            Kcp::new_stream(conv, output)
        } else {
            Kcp::new(conv, output)
        };
        c.apply_config(&mut kcp);

        // Ask server to allocate one
        if conv == 0 {
            kcp.input_conv();
        }

        SharedKcp {
            inner: Rc::new(RefCell::new(KcpCell {
                                            kcp: kcp,
                                            last_update: Instant::now(),
                                            is_closed: false,
                                            send_task: None,
                                            udp: udp,
                                            recv_buf: Vec::new(), // Do not initialize it yet.
                                            expired: false,
                                            sent_first: false,
                                            flush_write: c.flush_write,
                                            flush_ack_input: c.flush_acks_input,
                                        })),
        }
    }

    /// Call every time you got data from transmission
    pub fn input(&mut self, buf: &[u8]) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.input(buf)
    }

    /// Recv then input, ignore WouldBlock
    pub fn fetch(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.fetch()
    }

    /// Call if you want to send some data
    pub fn send(&mut self, buf: &[u8]) -> KcpResult<usize> {
        let mut inner = self.inner.borrow_mut();

        // If:
        //     1. Have sent the first packet (asking for conv)
        //     2. Too many pending packets
        if inner.sent_first && (inner.kcp.wait_snd() >= inner.kcp.snd_wnd() as usize || inner.kcp.waiting_conv()) {
            trace!("[SEND] waitsnd={} sndwnd={} excceeded or waiting conv={}",
                   inner.kcp.wait_snd(),
                   inner.kcp.snd_wnd(),
                   inner.kcp.waiting_conv());
            inner.send_task = Some(task::current());
            return Err(From::from(io::Error::new(ErrorKind::WouldBlock, "too many pending packets")));
        }

        let n = inner.kcp.send(buf)?;
        inner.sent_first = true;
        inner.last_update = Instant::now();

        if inner.flush_write {
            inner.kcp.flush()?;
        }

        Ok(n)
    }

    /// Try to notify writable
    pub fn try_notify_writable(&mut self) {
        let mut inner = self.inner.borrow_mut();
        if inner.kcp.wait_snd() < inner.kcp.snd_wnd() as usize && !inner.kcp.waiting_conv() {
            if let Some(task) = inner.send_task.take() {
                task.notify();
            }
        }
    }

    /// Call if you want to get some data
    /// Always call right after input
    pub fn recv(&mut self, buf: &mut [u8]) -> KcpResult<usize> {
        let mut inner = self.inner.borrow_mut();
        if inner.expired {
            // If it is already expired, return EOF
            return Ok(0);
        }

        let n = inner.kcp.recv(buf)?;
        inner.last_update = Instant::now();
        Ok(n)
    }

    /// Call if you want to flush all pending data in queue
    pub fn flush(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.kcp.flush()?;
        inner.last_update = Instant::now();
        Ok(())
    }

    /// Tell me how long this session have no interaction
    pub fn elapsed(&self) -> Duration {
        let inner = self.inner.borrow();
        inner.last_update.elapsed()
    }

    /// Make this session expire, all read apis will return 0 (EOF)
    /// It will flush the buffer when it is called
    pub fn set_expired(&mut self) -> KcpResult<()> {
        let mut inner = self.inner.borrow_mut();
        inner.expired = true;
        inner.kcp.flush()
    }

    /// Call in every tick
    /// Returns when to call this function again
    pub fn update(&mut self) -> KcpResult<Instant> {
        let mut inner = self.inner.borrow_mut();
        inner.kcp.update(::current())?;
        let next = inner.kcp.check(::current());
        Ok(Instant::now() + Duration::from_millis(next as u64))
        // Ok(Instant::now() + Duration::from_millis(5))
    }

    /// Check if send queue is empty
    pub fn has_waitsnd(&self) -> bool {
        let inner = self.inner.borrow();
        inner.kcp.wait_snd() != 0
    }

    /// Get mtu
    pub fn mtu(&self) -> usize {
        let inner = self.inner.borrow();
        inner.kcp.mtu()
    }

    /// Set is close
    pub fn close(&mut self) {
        let mut inner = self.inner.borrow_mut();
        trace!("[KCP] Set close, conv={}", inner.kcp.conv());
        inner.is_closed = true;
    }

    /// Check if it is closed
    pub fn is_closed(&self) -> bool {
        let inner = self.inner.borrow();
        inner.is_closed
    }

    /// Check if it can read
    pub fn can_read(&self) -> bool {
        let inner = self.inner.borrow();
        inner.kcp.peeksize().unwrap_or(0) != 0
    }

    /// Peek
    pub fn peeksize(&self) -> usize {
        let inner = self.inner.borrow();
        inner.kcp.peeksize().unwrap_or(0)
    }

    /// Get conv
    pub fn conv(&self) -> u32 {
        let inner = self.inner.borrow();
        inner.kcp.conv()
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix/
pub fn min_flips(mat: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!("{}", min_flips(vec![vec![0, 0], vec![0, 1]])); // 3
    println!("{}", min_flips(vec![vec![0]])); // 0
    println!("{}", min_flips(vec![vec![1, 0, 0], vec![1, 0, 0]])); // -1
    println!(
        "{}",
        min_flips(vec![vec![0, 0, 1], vec![0, 1, 0], vec![1, 0, 1]])
    ); // 4
}
<commit_msg>Update problem 1284<commit_after>// https://leetcode.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix/
pub fn min_flips(mat: Vec<Vec<i32>>) -> i32 {
    fn is_binary(mat: &Vec<Vec<i32>>) -> bool {
        for i in 0..mat.len() {
            for j in 0..mat[i].len() {
                if mat[i][j] != 0 {
                    return false;
                }
            }
        }
        true
    }

    fn flip(mat: &mut Vec<Vec<i32>>, row: i32, col: i32) {
        let max_row = mat.len() as i32;
        let max_col = if max_row > 0 { mat[0].len() } else { 0 } as i32;
        mat[row as usize][col as usize] ^= 1;
        if row - 1 >= 0 {
            mat[(row - 1) as usize][col as usize] ^= 1;
        }
        if col - 1 >= 0 {
            mat[row as usize][(col - 1) as usize] ^= 1;
        }
        if row + 1 < max_row {
            mat[(row + 1) as usize][col as usize] ^= 1;
        }
        if col + 1 < max_col {
            mat[row as usize][(col + 1) as usize] ^= 1;
        }
    }

    fn min_flips(mat: &mut Vec<Vec<i32>>, row: i32, col: i32, visited: &mut Vec<Vec<bool>>) -> i32 {
        let max_row = mat.len() as i32;
        let max_col = if max_row > 0 { mat[0].len() } else { 0 } as i32;
        if row < 0 || row == max_row || col < 0 || col == max_col {
            return i32::MAX;
        }
        if visited[row as usize][col as usize] {
            return i32::MAX;
        }
        if is_binary(mat) {
            return 0;
        }
        flip(mat, row, col);
        println!("{} {} -> {:?}", row, col, mat);
        visited[row as usize][col as usize] = true;
        let mut min = i32::MAX;
        for (r, c) in [(-1, 0), (0, 1), (1, 0), (0, -1)] {
            let m = min_flips(mat, row + r, col + c, visited);
            if m != i32::MAX {
                min = min.min(m + 1);
            }
        }
        flip(mat, row, col);
        visited[row as usize][col as usize] = false;
        min
    }

    let mut answer = i32::MAX;
    let max_row = mat.len();
    let max_col = if max_row > 0 { mat[0].len() } else { 0 };
    let mut mat = mat.clone();
    let mut visited = vec![vec![false; max_col]; max_row];
    for i in 0..mat.len() {
        for j in 0..mat[0].len() {
            answer = answer.min(min_flips(&mut mat, i as i32, j as i32, &mut visited));
        }
    }
    if answer == i32::MAX {
        -1
    } else {
        answer
    }
}

fn main() {
    // println!("{}", min_flips(vec![vec![0, 0], vec![0, 1]])); // 3
    // println!("{}", min_flips(vec![vec![0]])); // 0
    // println!("{}", min_flips(vec![vec![1, 0, 0], vec![1, 0, 0]])); // -1
    println!(
        "{}",
        min_flips(vec![vec![0, 0, 1], vec![0, 1, 0], vec![1, 0, 1]])
    ); // 4
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/check-if-move-is-legal/
pub fn check_move(board: Vec<Vec<char>>, r_move: i32, c_move: i32, color: char) -> bool {
    todo!()
}

fn main() {
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['W', 'B', 'B', '.', 'W', 'W', 'W', 'B'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.']
            ],
            4,
            3,
            'B'
        )
    ); // true
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['W', 'B', 'B', '.', 'B', 'W', 'W', 'B'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.']
            ],
            4,
            3,
            'B'
        )
    ); // false
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', 'B', '.', '.', 'W', '.', '.', '.'],
                vec!['.', '.', 'W', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', 'B', '.', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', '.', 'B', 'W', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', 'W', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', 'B']
            ],
            4,
            4,
            'W'
        )
    ); // false
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', 'B', '.', '.', 'W', '.', '.', '.'],
                vec!['.', '.', 'W', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', 'B', '.', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', '.', 'B', 'W', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', 'W', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', 'B']
            ],
            4,
            4,
            'B'
        )
    ); // true
}
<commit_msg>Solve problem 1958<commit_after>// https://leetcode.com/problems/check-if-move-is-legal/
pub fn check_move(board: Vec<Vec<char>>, r_move: i32, c_move: i32, color: char) -> bool {
    fn opposite(c: char) -> char {
        if c == 'W' {
            'B'
        } else {
            'W'
        }
    }

    fn check(
        board: &Vec<Vec<char>>,
        row: i32,
        col: i32,
        color: char,
        row_fn: fn(i32) -> i32,
        col_fn: fn(i32) -> i32,
    ) -> bool {
        let n = 8;
        let mut r = row;
        let mut c = col;
        let mut count = 0;
        while r >= 0
            && r < n
            && c >= 0
            && c < n
            && &board[r as usize][c as usize] == &opposite(color)
        {
            count += 1;
            r = row_fn(r);
            c = col_fn(c);
        }
        count >= 1 && r >= 0 && r < n && c >= 0 && c < n && &board[r as usize][c as usize] == &color
    }

    let n = 8;
    // Top
    if check(&board, r_move - 1, c_move, color, |r| r - 1, |c| c) {
        return true;
    }
    // Upper right diagonal
    if check(&board, r_move - 1, c_move + 1, color, |r| r - 1, |c| c + 1) {
        return true;
    }
    // Right
    if check(&board, r_move, c_move + 1, color, |r| r, |c| c + 1) {
        return true;
    }
    // Lower right diagonal
    if check(&board, r_move + 1, c_move + 1, color, |r| r + 1, |c| c + 1) {
        return true;
    }
    // Bottom
    if check(&board, r_move + 1, c_move, color, |r| r + 1, |c| c) {
        return true;
    }
    // Lower left diagonal
    if check(&board, r_move + 1, c_move - 1, color, |r| r + 1, |c| c - 1) {
        return true;
    }
    // Left
    if check(&board, r_move, c_move - 1, color, |r| r, |c| c - 1) {
        return true;
    }
    // Upper left diagonal
    if check(&board, r_move - 1, c_move - 1, color, |r| r - 1, |c| c - 1) {
        return true;
    }
    false
}

fn main() {
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['W', 'B', 'B', '.', 'W', 'W', 'W', 'B'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.']
            ],
            4,
            3,
            'B'
        )
    ); // true
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['W', 'B', 'B', '.', 'B', 'W', 'W', 'B'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.']
            ],
            4,
            3,
            'B'
        )
    ); // true
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['W', 'B', 'B', '.', 'B', 'W', 'W', 'B'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'B', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', '.', '.', '.', '.']
            ],
            4,
            3,
            'B'
        )
    ); // false
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', 'B', '.', '.', 'W', '.', '.', '.'],
                vec!['.', '.', 'W', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', 'B', '.', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', '.', 'B', 'W', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', 'W', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', 'B']
            ],
            4,
            4,
            'W'
        )
    ); // false
    println!(
        "{}",
        check_move(
            vec![
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', 'B', '.', '.', 'W', '.', '.', '.'],
                vec!['.', '.', 'W', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', 'W', 'B', '.', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', '.'],
                vec!['.', '.', '.', '.', 'B', 'W', '.', '.'],
                vec!['.', '.', '.', '.', '.', '.', 'W', '.'],
                vec!['.', '.', '.', '.', '.', '.', '.', 'B']
            ],
            4,
            4,
            'B'
        )
    ); // true
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The `Default` trait for types which may have meaningful default values.
//!
//! Sometimes, you want to fall back to some kind of default value, and
//! don't particularly care what it is. This comes up often with `struct`s
//! that define a set of options:
//!
//! ```
//! # #[allow(dead_code)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//! ```
//!
//! How can we define some default values? You can use `Default`:
//!
//! ```
//! # #[allow(dead_code)]
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! Now, you get all of the default values. Rust implements `Default` for various primitives types.
//! If you have your own type, you need to implement `Default` yourself:
//!
//! ```
//! # #![allow(dead_code)]
//! enum Kind {
//!     A,
//!     B,
//!     C,
//! }
//!
//! impl Default for Kind {
//!     fn default() -> Kind { Kind::A }
//! }
//!
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//!     baz: Kind,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! If you want to override a particular option, but still retain the other defaults:
//!
//! ```
//! # #[allow(dead_code)]
//! # #[derive(Default)]
//! # struct SomeOptions {
//! #     foo: i32,
//! #     bar: f32,
//! # }
//! fn main() {
//!     let options = SomeOptions { foo: 42, ..Default::default() };
//! }
//! ```

#![stable(feature = "rust1", since = "1.0.0")]

use marker::Sized;

/// A trait for giving a type a useful default value.
///
/// For more information, see
/// [the module-level documentation][module].
///
/// [module]: ../../std/default/index.html
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), () }
default_impl! { bool, false }
default_impl! { char, '\x00' }

default_impl! { usize, 0 }
default_impl! { u8, 0 }
default_impl! { u16, 0 }
default_impl! { u32, 0 }
default_impl! { u64, 0 }

default_impl! { isize, 0 }
default_impl! { i8, 0 }
default_impl! { i16, 0 }
default_impl! { i32, 0 }
default_impl! { i64, 0 }

default_impl! { f32, 0.0f32 }
default_impl! { f64, 0.0f64 }
<commit_msg>Move all `Default` docs from module to trait<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The `Default` trait for types which may have meaningful default values.

#![stable(feature = "rust1", since = "1.0.0")]

use marker::Sized;

/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
/// don't particularly care what it is. This comes up often with `struct`s
/// that define a set of options:
///
/// ```
/// # #[allow(dead_code)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
///
/// How can we define some default values? You can use `Default`:
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
///
///
/// fn main() {
///     let options: SomeOptions = Default::default();
/// }
/// ```
///
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
///
/// If you want to override a particular option, but still retain the other defaults:
///
/// ```
/// # #[allow(dead_code)]
/// # #[derive(Default)]
/// # struct SomeOptions {
/// #     foo: i32,
/// #     bar: f32,
/// # }
/// fn main() {
///     let options = SomeOptions { foo: 42, ..Default::default() };
/// }
/// ```
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), () }
default_impl! { bool, false }
default_impl! { char, '\x00' }

default_impl! { usize, 0 }
default_impl! { u8, 0 }
default_impl! { u16, 0 }
default_impl! { u32, 0 }
default_impl! { u64, 0 }

default_impl! { isize, 0 }
default_impl! { i8, 0 }
default_impl! { i16, 0 }
default_impl! { i32, 0 }
default_impl! { i64, 0 }

default_impl! { f32, 0.0f32 }
default_impl! { f64, 0.0f64 }
<|endoftext|>


<commit_before>use std::collections::BinaryHeap;
use std::cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
use std::sync::{Arc, Mutex, Condvar};
use std::thread::Thread;
use std::thunk::Thunk;
use std::time::Duration;

use time;

enum JobType {
    Once(Thunk),
    FixedRate {
        f: Box<FnMut() + Send>,
        rate: Duration,
    },
}

struct Job {
    type_: JobType,
    time: u64,
}

impl PartialOrd for Job {
    fn partial_cmp(&self, other: &Job) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Job {
    fn cmp(&self, other: &Job) -> Ordering {
        // reverse because BinaryHeap's a max heap
        self.time.cmp(&other.time).reverse()
    }
}

impl PartialEq for Job {
    fn eq(&self, other: &Job) -> bool {
        self.time == other.time
    }
}

impl Eq for Job {}

struct InnerPool {
    queue: BinaryHeap<Job>,
    shutdown: bool,
}

struct SharedPool {
    inner: Mutex<InnerPool>,
    cvar: Condvar,
}

impl SharedPool {
    fn execute(&self, job: Job) {
        let mut inner = self.inner.lock().unwrap();

        // Calls from the pool itself will never hit this, but calls from workers might
        if inner.shutdown {
            return;
        }

        match inner.queue.peek() {
            None => self.cvar.notify_all(),
            Some(e) if e.time > job.time => self.cvar.notify_all(),
            _ => {}
        };
        inner.queue.push(job);
    }
}

pub struct ScheduledTaskPool {
    shared: Arc<SharedPool>,
}

impl Drop for ScheduledTaskPool {
    fn drop(&mut self) {
        self.shared.inner.lock().unwrap().shutdown = true;
        self.shared.cvar.notify_all();
    }
}

impl ScheduledTaskPool {
    pub fn new(size: usize) -> ScheduledTaskPool {
        assert!(size > 0, "size must be positive");

        let inner = InnerPool {
            queue: BinaryHeap::new(),
            shutdown: false,
        };

        let shared = SharedPool {
            inner: Mutex::new(inner),
            cvar: Condvar::new(),
        };

        let pool = ScheduledTaskPool {
            shared: Arc::new(shared),
        };

        for _ in (0..size) {
            let mut worker = Worker {
                shared: pool.shared.clone(),
            };

            Thread::spawn(move || worker.run());
        }

        pool
    }

    pub fn execute<F>(&self, f: F) where F: FnOnce() + Send {
        self.execute_after(Duration::zero(), f)
    }

    pub fn execute_after<F>(&self, dur: Duration, f: F) where F: FnOnce() + Send {
        let job = Job {
            type_: JobType::Once(Thunk::new(f)),
            time: (time::precise_time_ns() as i64 + dur.num_nanoseconds().unwrap()) as u64,
        };
        self.shared.execute(job)
    }

    pub fn execute_at_fixed_rate<F>(&self, rate: Duration, f: F) where F: FnMut() + Send {
        let job = Job {
            type_: JobType::FixedRate { f: Box::new(f), rate: rate },
            time: (time::precise_time_ns() as i64 + rate.num_nanoseconds().unwrap()) as u64,
        };
        self.shared.execute(job)
    }
}

struct Worker {
    shared: Arc<SharedPool>,
}

impl Drop for Worker {
    fn drop(&mut self) {
        // Start up a new worker if this one's going away due to a panic from a job
        if Thread::panicking() {
            let mut worker = Worker {
                shared: self.shared.clone(),
            };
            Thread::spawn(move || worker.run());
        }
    }
}

impl Worker {
    fn run(&mut self) {
        loop {
            match self.get_job() {
                Some(job) => self.run_job(job),
                None => break,
            }
        }
    }

    fn get_job(&self) -> Option<Job> {
        enum Need {
            Wait,
            WaitTimeout(Duration),
        }

        let mut inner = self.shared.inner.lock().unwrap();
        loop {
            let now = time::precise_time_ns();

            let need = match inner.queue.peek() {
                None if inner.shutdown => return None,
                None => Need::Wait,
                Some(e) if e.time <= now => break,
                Some(e) => Need::WaitTimeout(Duration::nanoseconds(e.time as i64 - now as i64)),
            };

            inner = match need {
                Need::Wait => self.shared.cvar.wait(inner).unwrap(),
                Need::WaitTimeout(t) => self.shared.cvar.wait_timeout(inner, t).unwrap().0,
            };
        }

        Some(inner.queue.pop().unwrap())
    }

    fn run_job(&self, job: Job) {
        match job.type_ {
            JobType::Once(f) => f.invoke(()),
            JobType::FixedRate { mut f, rate } => {
                f();
                let new_job = Job {
                    type_: JobType::FixedRate { f: f, rate: rate },
                    time: (job.time as i64 + rate.num_nanoseconds().unwrap()) as u64,
                };
                self.shared.execute(new_job)
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::iter::AdditiveIterator;
    use std::sync::mpsc::channel;
    use std::sync::{Arc, Barrier};
    use std::time::Duration;

    use super::ScheduledTaskPool;

    const TEST_TASKS: usize = 4;

    #[test]
    fn test_works() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);

        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.execute(move|| {
                tx.send(1us).unwrap();
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    #[should_fail(expected = "size must be positive")]
    fn test_zero_tasks_panic() {
        ScheduledTaskPool::new(0);
    }

    #[test]
    fn test_recovery_from_subtask_panic() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);

        // Panic all the existing threads.
        let waiter = Arc::new(Barrier::new(TEST_TASKS as usize));
        for _ in range(0, TEST_TASKS) {
            let waiter = waiter.clone();
            pool.execute(move || -> () {
                waiter.wait();
                panic!();
            });
        }

        // Ensure new threads were spawned to compensate.
        let (tx, rx) = channel();
        let waiter = Arc::new(Barrier::new(TEST_TASKS as usize));
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            let waiter = waiter.clone();
            pool.execute(move || {
                waiter.wait();
                tx.send(1us).unwrap();
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    fn test_execute_after() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);
        let (tx, rx) = channel();

        let tx1 = tx.clone();
        pool.execute_after(Duration::seconds(1), move || tx1.send(1us).unwrap());
        pool.execute_after(Duration::milliseconds(500), move || tx.send(2us).unwrap());

        assert_eq!(2, rx.recv().unwrap());
        assert_eq!(1, rx.recv().unwrap());
    }

    #[test]
    fn test_jobs_complete_after_drop() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);
        let (tx, rx) = channel();

        let tx1 = tx.clone();
        pool.execute_after(Duration::seconds(1), move || tx1.send(1us).unwrap());
        pool.execute_after(Duration::milliseconds(500), move || tx.send(2us).unwrap());

        drop(pool);

        assert_eq!(2, rx.recv().unwrap());
        assert_eq!(1, rx.recv().unwrap());
    }

    #[test]
    fn test_fixed_delay_jobs_stop_after_drop() {
        let pool = Arc::new(ScheduledTaskPool::new(TEST_TASKS));
        let (tx, rx) = channel();
        let (tx2, rx2) = channel();

        let mut pool2 = Some(pool.clone());
        let mut i = 0i32;
        pool.execute_at_fixed_rate(Duration::milliseconds(500), move || {
            i += 1;
            tx.send(i).unwrap();
            rx2.recv().unwrap();
            if i == 2 {
                drop(pool2.take().unwrap());
            }
        });
        drop(pool);

        assert_eq!(Ok(1), rx.recv());
        tx2.send(()).unwrap();
        assert_eq!(Ok(2), rx.recv());
        tx2.send(()).unwrap();
        assert!(rx.recv().is_err());
    }
}
<commit_msg>execute -> run<commit_after>use std::collections::BinaryHeap;
use std::cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
use std::sync::{Arc, Mutex, Condvar};
use std::thread::Thread;
use std::thunk::Thunk;
use std::time::Duration;

use time;

enum JobType {
    Once(Thunk),
    FixedRate {
        f: Box<FnMut() + Send>,
        rate: Duration,
    },
}

struct Job {
    type_: JobType,
    time: u64,
}

impl PartialOrd for Job {
    fn partial_cmp(&self, other: &Job) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Job {
    fn cmp(&self, other: &Job) -> Ordering {
        // reverse because BinaryHeap's a max heap
        self.time.cmp(&other.time).reverse()
    }
}

impl PartialEq for Job {
    fn eq(&self, other: &Job) -> bool {
        self.time == other.time
    }
}

impl Eq for Job {}

struct InnerPool {
    queue: BinaryHeap<Job>,
    shutdown: bool,
}

struct SharedPool {
    inner: Mutex<InnerPool>,
    cvar: Condvar,
}

impl SharedPool {
    fn run(&self, job: Job) {
        let mut inner = self.inner.lock().unwrap();

        // Calls from the pool itself will never hit this, but calls from workers might
        if inner.shutdown {
            return;
        }

        match inner.queue.peek() {
            None => self.cvar.notify_all(),
            Some(e) if e.time > job.time => self.cvar.notify_all(),
            _ => {}
        };
        inner.queue.push(job);
    }
}

pub struct ScheduledTaskPool {
    shared: Arc<SharedPool>,
}

impl Drop for ScheduledTaskPool {
    fn drop(&mut self) {
        self.shared.inner.lock().unwrap().shutdown = true;
        self.shared.cvar.notify_all();
    }
}

impl ScheduledTaskPool {
    pub fn new(size: usize) -> ScheduledTaskPool {
        assert!(size > 0, "size must be positive");

        let inner = InnerPool {
            queue: BinaryHeap::new(),
            shutdown: false,
        };

        let shared = SharedPool {
            inner: Mutex::new(inner),
            cvar: Condvar::new(),
        };

        let pool = ScheduledTaskPool {
            shared: Arc::new(shared),
        };

        for _ in (0..size) {
            let mut worker = Worker {
                shared: pool.shared.clone(),
            };

            Thread::spawn(move || worker.run());
        }

        pool
    }

    pub fn run<F>(&self, f: F) where F: FnOnce() + Send {
        self.run_after(Duration::zero(), f)
    }

    pub fn run_after<F>(&self, dur: Duration, f: F) where F: FnOnce() + Send {
        let job = Job {
            type_: JobType::Once(Thunk::new(f)),
            time: (time::precise_time_ns() as i64 + dur.num_nanoseconds().unwrap()) as u64,
        };
        self.shared.run(job)
    }

    pub fn run_at_fixed_rate<F>(&self, rate: Duration, f: F) where F: FnMut() + Send {
        let job = Job {
            type_: JobType::FixedRate { f: Box::new(f), rate: rate },
            time: (time::precise_time_ns() as i64 + rate.num_nanoseconds().unwrap()) as u64,
        };
        self.shared.run(job)
    }
}

struct Worker {
    shared: Arc<SharedPool>,
}

impl Drop for Worker {
    fn drop(&mut self) {
        // Start up a new worker if this one's going away due to a panic from a job
        if Thread::panicking() {
            let mut worker = Worker {
                shared: self.shared.clone(),
            };
            Thread::spawn(move || worker.run());
        }
    }
}

impl Worker {
    fn run(&mut self) {
        loop {
            match self.get_job() {
                Some(job) => self.run_job(job),
                None => break,
            }
        }
    }

    fn get_job(&self) -> Option<Job> {
        enum Need {
            Wait,
            WaitTimeout(Duration),
        }

        let mut inner = self.shared.inner.lock().unwrap();
        loop {
            let now = time::precise_time_ns();

            let need = match inner.queue.peek() {
                None if inner.shutdown => return None,
                None => Need::Wait,
                Some(e) if e.time <= now => break,
                Some(e) => Need::WaitTimeout(Duration::nanoseconds(e.time as i64 - now as i64)),
            };

            inner = match need {
                Need::Wait => self.shared.cvar.wait(inner).unwrap(),
                Need::WaitTimeout(t) => self.shared.cvar.wait_timeout(inner, t).unwrap().0,
            };
        }

        Some(inner.queue.pop().unwrap())
    }

    fn run_job(&self, job: Job) {
        match job.type_ {
            JobType::Once(f) => f.invoke(()),
            JobType::FixedRate { mut f, rate } => {
                f();
                let new_job = Job {
                    type_: JobType::FixedRate { f: f, rate: rate },
                    time: (job.time as i64 + rate.num_nanoseconds().unwrap()) as u64,
                };
                self.shared.run(new_job)
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::iter::AdditiveIterator;
    use std::sync::mpsc::channel;
    use std::sync::{Arc, Barrier};
    use std::time::Duration;

    use super::ScheduledTaskPool;

    const TEST_TASKS: usize = 4;

    #[test]
    fn test_works() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);

        let (tx, rx) = channel();
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            pool.run(move|| {
                tx.send(1us).unwrap();
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    #[should_fail(expected = "size must be positive")]
    fn test_zero_tasks_panic() {
        ScheduledTaskPool::new(0);
    }

    #[test]
    fn test_recovery_from_subtask_panic() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);

        // Panic all the existing threads.
        let waiter = Arc::new(Barrier::new(TEST_TASKS as usize));
        for _ in range(0, TEST_TASKS) {
            let waiter = waiter.clone();
            pool.run(move || -> () {
                waiter.wait();
                panic!();
            });
        }

        // Ensure new threads were spawned to compensate.
        let (tx, rx) = channel();
        let waiter = Arc::new(Barrier::new(TEST_TASKS as usize));
        for _ in range(0, TEST_TASKS) {
            let tx = tx.clone();
            let waiter = waiter.clone();
            pool.run(move || {
                waiter.wait();
                tx.send(1us).unwrap();
            });
        }

        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
    }

    #[test]
    fn test_run_after() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);
        let (tx, rx) = channel();

        let tx1 = tx.clone();
        pool.run_after(Duration::seconds(1), move || tx1.send(1us).unwrap());
        pool.run_after(Duration::milliseconds(500), move || tx.send(2us).unwrap());

        assert_eq!(2, rx.recv().unwrap());
        assert_eq!(1, rx.recv().unwrap());
    }

    #[test]
    fn test_jobs_complete_after_drop() {
        let pool = ScheduledTaskPool::new(TEST_TASKS);
        let (tx, rx) = channel();

        let tx1 = tx.clone();
        pool.run_after(Duration::seconds(1), move || tx1.send(1us).unwrap());
        pool.run_after(Duration::milliseconds(500), move || tx.send(2us).unwrap());

        drop(pool);

        assert_eq!(2, rx.recv().unwrap());
        assert_eq!(1, rx.recv().unwrap());
    }

    #[test]
    fn test_fixed_delay_jobs_stop_after_drop() {
        let pool = Arc::new(ScheduledTaskPool::new(TEST_TASKS));
        let (tx, rx) = channel();
        let (tx2, rx2) = channel();

        let mut pool2 = Some(pool.clone());
        let mut i = 0i32;
        pool.run_at_fixed_rate(Duration::milliseconds(500), move || {
            i += 1;
            tx.send(i).unwrap();
            rx2.recv().unwrap();
            if i == 2 {
                drop(pool2.take().unwrap());
            }
        });
        drop(pool);

        assert_eq!(Ok(1), rx.recv());
        tx2.send(()).unwrap();
        assert_eq!(Ok(2), rx.recv());
        tx2.send(()).unwrap();
        assert!(rx.recv().is_err());
    }
}
<|endoftext|>


<commit_before>//! [Lambda terms](https://en.wikipedia.org/wiki/Lambda_calculus#Lambda_terms)

use self::Term::*;
use self::Error::*;
use std::fmt;
use std::borrow::Cow;

/// A lambda term that is either a variable with a De Bruijn index, an abstraction over a term or
/// an applicaction of one term to another.
#[derive(Debug, PartialEq, Clone)]
pub enum Term {
    Var(usize),
    Abs(Box<Term>),
    App(Box<Term>, Box<Term>)
}

/// An error that can be returned when an inapplicable function is applied to a term.
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
    NotAVar,
    NotAnAbs,
    NotAnApp,
    NotANum,
    NotAPair,
    NotAList
}

impl Term {
    /// Applies `self` to another term without substitution or reduction.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::arithmetic::{zero, succ};
    ///
    /// assert_eq!(succ().app(zero()), App(Box::new(succ()), Box::new(zero())));
    /// ```
    pub fn app(self, argument: Term) -> Term { App(Box::new(self), Box::new(argument)) }

    /// Consumes a lambda variable and returns its De Bruijn index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar(), Ok(1));
    /// ```
    pub fn unvar(self) -> Result<usize, Error> {
        match self {
            Var(n) => Ok(n),
            _ => Err(NotAVar)
        }
    }

    /// Returns a reference to a variable's index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar_ref(), Ok(&1));
    /// ```
    pub fn unvar_ref(&self) -> Result<&usize, Error> {
        match *self {
            Var(ref n) => Ok(&n),
            _ => Err(NotAVar)
        }
    }

    /// Consumes an abstraction and returns its underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs(), Ok(Var(1)));
    /// ```
    pub fn unabs(self) -> Result<Term, Error> {
        match self {
            Abs(x) => Ok(*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref(), Ok(&Var(1)));
    /// ```
    pub fn unabs_ref(&self) -> Result<&Term, Error> {
        match *self {
            Abs(ref x) => Ok(&*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a mutable reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn unabs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        match *self {
            Abs(ref mut x) => Ok(&mut *x),
            _ => Err(NotAnAbs)
        }
    }

    /// Consumes an application and returns a pair containing its underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp(), Ok((Var(0), Var(1))));
    /// ```
    pub fn unapp(self) -> Result<(Term, Term), Error> {
        match self {
            App(lhs, rhs) => Ok((*lhs, *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref(), Ok((&Var(0), &Var(1))));
    /// ```
    pub fn unapp_ref(&self) -> Result<(&Term, &Term), Error> {
        match *self {
            App(ref lhs, ref rhs) => Ok((&*lhs, &*rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing mutable references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref_mut(), Ok((&mut Var(0), &mut Var(1))));
    /// ```
    pub fn unapp_ref_mut(&mut self) -> Result<(&mut Term, &mut Term), Error> {
        match *self {
            App(ref mut lhs, ref mut rhs) => Ok((&mut *lhs, &mut *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns the left-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs(), Ok(Var(0)));
    /// ```
    pub fn lhs(self) -> Result<Term, Error> {
        if let Ok((lhs, _)) = self.unapp() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref(), Ok(&Var(0)));
    /// ```
    pub fn lhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref_mut(), Ok(&mut Var(0)));
    /// ```
    pub fn lhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref_mut() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns the right-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs(), Ok(Var(1)));
    /// ```
    pub fn rhs(self) -> Result<Term, Error> {
        if let Ok((_, rhs)) = self.unapp() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref(), Ok(&Var(1)));
    /// ```
    pub fn rhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn rhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref_mut() { Ok(rhs) } else { Err(NotAnApp) }
    }
}

/// Wraps a term in an abstraction. Consumes its argument.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::abs;
///
/// assert_eq!(abs(Var(1)), Abs(Box::new(Var(1))));
/// ```
pub fn abs(term: Term) -> Term { Abs(Box::new(term)) }

/// Produces an application of its arguments without substitution or reduction, consuming them in
/// the process.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::app;
///
/// assert_eq!(app(Var(0), Var(1)), App(Box::new(Var(0)), Box::new(Var(1))));
/// ```
pub fn app(lhs: Term, rhs: Term) -> Term { App(Box::new(lhs), Box::new(rhs)) }

/// Set to `true` for λ or `false` for \ when displaying lambda terms. The default is `true`.
pub const DISPLAY_PRETTY: bool = true;

impl fmt::Display for Term {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", show_precedence(0, self))
    }
}

fn show_precedence(context_precedence: usize, term: &Term) -> String {
    match *term {
        Var(i) => format!("{:X}", i), // max. index = 15
        Abs(ref t) => {
            let ret = format!("{}{}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, t);
            parenthesize_if(context_precedence > 1, &ret).into()
        },
        App(ref t1, ref t2) => {
            let ret = format!("{}{}", show_precedence(2, t1), show_precedence(3, t2));
            parenthesize_if(context_precedence == 3, &ret).into()
        }
    }
}

fn parenthesize_if(condition: bool, input: &str) -> Cow<str> {
    if condition {
        format!("({})", input).into()
    } else {
        input.into()
    }
}

#[cfg(test)]
mod test {
    use arithmetic::{zero, succ, pred};

    #[test]
    fn displaying_terms() {
        assert_eq!(&format!("{}", zero()), "λλ1");
        assert_eq!(&format!("{}", succ()), "λλλ2(321)");
        assert_eq!(&format!("{}", pred()), "λλλ3(λλ1(24))(λ2)(λ1)");
    }
}
<commit_msg>reorder some function arguments<commit_after>//! [Lambda terms](https://en.wikipedia.org/wiki/Lambda_calculus#Lambda_terms)

use self::Term::*;
use self::Error::*;
use std::fmt;
use std::borrow::Cow;

/// A lambda term that is either a variable with a De Bruijn index, an abstraction over a term or
/// an applicaction of one term to another.
#[derive(Debug, PartialEq, Clone)]
pub enum Term {
    Var(usize),
    Abs(Box<Term>),
    App(Box<Term>, Box<Term>)
}

/// An error that can be returned when an inapplicable function is applied to a term.
#[derive(Debug, PartialEq, Clone)]
pub enum Error {
    NotAVar,
    NotAnAbs,
    NotAnApp,
    NotANum,
    NotAPair,
    NotAList
}

impl Term {
    /// Applies `self` to another term without substitution or reduction.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::arithmetic::{zero, succ};
    ///
    /// assert_eq!(succ().app(zero()), App(Box::new(succ()), Box::new(zero())));
    /// ```
    pub fn app(self, argument: Term) -> Term { App(Box::new(self), Box::new(argument)) }

    /// Consumes a lambda variable and returns its De Bruijn index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar(), Ok(1));
    /// ```
    pub fn unvar(self) -> Result<usize, Error> {
        match self {
            Var(n) => Ok(n),
            _ => Err(NotAVar)
        }
    }

    /// Returns a reference to a variable's index.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(1).unvar_ref(), Ok(&1));
    /// ```
    pub fn unvar_ref(&self) -> Result<&usize, Error> {
        match *self {
            Var(ref n) => Ok(&n),
            _ => Err(NotAVar)
        }
    }

    /// Consumes an abstraction and returns its underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs(), Ok(Var(1)));
    /// ```
    pub fn unabs(self) -> Result<Term, Error> {
        match self {
            Abs(x) => Ok(*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref(), Ok(&Var(1)));
    /// ```
    pub fn unabs_ref(&self) -> Result<&Term, Error> {
        match *self {
            Abs(ref x) => Ok(&*x),
            _ => Err(NotAnAbs)
        }
    }

    /// Returns a mutable reference to an abstraction's underlying term.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    /// use lambda_calculus::term::abs;
    ///
    /// assert_eq!(abs(Var(1)).unabs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn unabs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        match *self {
            Abs(ref mut x) => Ok(&mut *x),
            _ => Err(NotAnAbs)
        }
    }

    /// Consumes an application and returns a pair containing its underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp(), Ok((Var(0), Var(1))));
    /// ```
    pub fn unapp(self) -> Result<(Term, Term), Error> {
        match self {
            App(lhs, rhs) => Ok((*lhs, *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref(), Ok((&Var(0), &Var(1))));
    /// ```
    pub fn unapp_ref(&self) -> Result<(&Term, &Term), Error> {
        match *self {
            App(ref lhs, ref rhs) => Ok((&*lhs, &*rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns a pair containing mutable references to an application's underlying terms.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).unapp_ref_mut(), Ok((&mut Var(0), &mut Var(1))));
    /// ```
    pub fn unapp_ref_mut(&mut self) -> Result<(&mut Term, &mut Term), Error> {
        match *self {
            App(ref mut lhs, ref mut rhs) => Ok((&mut *lhs, &mut *rhs)),
            _ => Err(NotAnApp)
        }
    }

    /// Returns the left-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs(), Ok(Var(0)));
    /// ```
    pub fn lhs(self) -> Result<Term, Error> {
        if let Ok((lhs, _)) = self.unapp() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref(), Ok(&Var(0)));
    /// ```
    pub fn lhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the left-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).lhs_ref_mut(), Ok(&mut Var(0)));
    /// ```
    pub fn lhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((lhs, _)) = self.unapp_ref_mut() { Ok(lhs) } else { Err(NotAnApp) }
    }

    /// Returns the right-hand side term of an application. Consumes `self`.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs(), Ok(Var(1)));
    /// ```
    pub fn rhs(self) -> Result<Term, Error> {
        if let Ok((_, rhs)) = self.unapp() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref(), Ok(&Var(1)));
    /// ```
    pub fn rhs_ref(&self) -> Result<&Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref() { Ok(rhs) } else { Err(NotAnApp) }
    }

    /// Returns a mutable reference to the right-hand side term of an application.
    ///
    /// # Example
    /// ```
    /// use lambda_calculus::term::Term::*;
    ///
    /// assert_eq!(Var(0).app(Var(1)).rhs_ref_mut(), Ok(&mut Var(1)));
    /// ```
    pub fn rhs_ref_mut(&mut self) -> Result<&mut Term, Error> {
        if let Ok((_, rhs)) = self.unapp_ref_mut() { Ok(rhs) } else { Err(NotAnApp) }
    }
}

/// Wraps a term in an abstraction. Consumes its argument.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::abs;
///
/// assert_eq!(abs(Var(1)), Abs(Box::new(Var(1))));
/// ```
pub fn abs(term: Term) -> Term { Abs(Box::new(term)) }

/// Produces an application of its arguments without substitution or reduction, consuming them in
/// the process.
///
/// # Example
/// ```
/// use lambda_calculus::term::Term::*;
/// use lambda_calculus::term::app;
///
/// assert_eq!(app(Var(0), Var(1)), App(Box::new(Var(0)), Box::new(Var(1))));
/// ```
pub fn app(lhs: Term, rhs: Term) -> Term { App(Box::new(lhs), Box::new(rhs)) }

/// Set to `true` for λ or `false` for \ when displaying lambda terms. The default is `true`.
pub const DISPLAY_PRETTY: bool = true;

impl fmt::Display for Term {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", show_precedence(self, 0))
    }
}

fn show_precedence(term: &Term, context_precedence: usize) -> String {
    match *term {
        Var(i) => format!("{:X}", i), // max. index = 15
        Abs(ref t) => {
            let ret = format!("{}{}", if DISPLAY_PRETTY { 'λ' } else { '\\' }, t);
            parenthesize_if(&ret, context_precedence > 1).into()
        },
        App(ref t1, ref t2) => {
            let ret = format!("{}{}", show_precedence(t1, 2), show_precedence(t2, 3));
            parenthesize_if(&ret, context_precedence == 3).into()
        }
    }
}

fn parenthesize_if(input: &str, condition: bool) -> Cow<str> {
    if condition {
        format!("({})", input).into()
    } else {
        input.into()
    }
}

#[cfg(test)]
mod test {
    use arithmetic::{zero, succ, pred};

    #[test]
    fn displaying_terms() {
        assert_eq!(&format!("{}", zero()), "λλ1");
        assert_eq!(&format!("{}", succ()), "λλλ2(321)");
        assert_eq!(&format!("{}", pred()), "λλλ3(λλ1(24))(λ2)(λ1)");
    }
}
<|endoftext|>