<commit_before>//! This module provides a Beckmann microfacet distribution with a
//! Smith shadowing-masking term

use std::f32;

use bxdf;
use linalg::{self, Vector};
use bxdf::microfacet::MicrofacetDistribution;

/// Beckmann microfacet distribution with Smith shadowing-masking. This is the
/// microfacet model described by [Walter et al.](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
pub struct Beckmann {
    width: f32,
}

impl Beckmann {
    /// Create a new Beckmann distribution with the desired width
    pub fn new(w: f32) -> Beckmann {
        // From pbrt-v3, conversion from Blinn-Phong style roughness to approximately
        // equivalent Beckmann alpha
        let roughness = f32::max(w, 0.001);
        let x = f32::ln(roughness);
        let alpha = 1.62142 + 0.819955 * x + 0.173 * f32::powf(x, 2.0)
            + 0.0171201 * f32::powf(x, 3.0) + 0.000640711 * f32::powf(x, 4.0);
        Beckmann { width: alpha }
    }
}

// In walter et al. chi^+(a) = 1 if a > 0 and 0 if a <= 0
// bold n is the macrosurface normal. In shading space this is +z
// theta is angle between the dir and the macrosurface normal (a.k.a +z)
// phi is angle between the dir and a vector perpindicular to the macrosurface normal, like tangent
// or bitangent

impl MicrofacetDistribution for Beckmann {
    fn normal_distribution(&self, w_h: &Vector) -> f32 {
        if bxdf::cos_theta(w_h) > 0.0 {
            //println!("cos theta passed");
            let e = f32::exp(-f32::powf(bxdf::tan_theta(&w_h) / self.width, 2.0));
            e / (f32::consts::PI * f32::powf(self.width, 2.0) * f32::powf(bxdf::cos_theta(&w_h), 4.0))
        } else {
            0.0
        }
    }
    fn sample(&self, w_o: &Vector, samples: &(f32, f32)) -> Vector {
        let log_sample = match f32::ln(1.0 - samples.0) {
            x if f32::is_infinite(x) => { println!("it was inf!"); 0.0 },
            x => x,
        };
        let tan_theta_sqr = f32::powf(self.width, 2.0) * log_sample;
        let phi = 2.0 * f32::consts::PI * samples.1;
        let cos_theta = 1.0 / f32::sqrt(1.0 + tan_theta_sqr);
        let sin_theta = f32::sqrt(f32::max(0.0, 1.0 - cos_theta * cos_theta));
        let w_h = linalg::spherical_dir(sin_theta, cos_theta, phi);
        // TODO: Can move this check to callers, then we can have microfacet transmission
        if !bxdf::same_hemisphere(w_o, &w_h) {
            -w_h
        } else {
            w_h
        }
    }
    fn pdf(&self, w_h: &Vector) -> f32 {
        f32::abs(bxdf::cos_theta(w_h)) * self.normal_distribution(w_h)
    }
    fn shadowing_masking(&self, w_i: &Vector, w_o: &Vector, w_h: &Vector) -> f32 {
        self.monodir_shadowing(w_i, w_h) * self.monodir_shadowing(w_o, w_h)
    }
    /// Monodirectional shadowing function from Walter et al., we use the Smith
    /// shadowing-masking which uses the reciprocity of this function.
    /// `w` is the incident/outgoing light direction and `w_h` is the microfacet normal
    fn monodir_shadowing(&self, v: &Vector, w_h: &Vector) -> f32 {
        if linalg::dot(v, w_h) / bxdf::cos_theta(v) > 0.0 {
            let a = 1.0 / (self.width * bxdf::tan_theta(v));
            if a < 1.6 {
                let a_sqr = f32::powf(a, 2.0);
                (3.535 * a + 2.181 * a_sqr) / (1.0 + 2.276 * a + 2.577 * a_sqr)
            } else {
                1.0
            }
        } else {
            0.0
        }
    }
}

<commit_msg>Fix Beckmann microfacet distribution<commit_after>//! This module provides a Beckmann microfacet distribution with a
//! Smith shadowing-masking term

use std::f32;

use bxdf;
use linalg::{self, Vector};
use bxdf::microfacet::MicrofacetDistribution;

/// Beckmann microfacet distribution with Smith shadowing-masking. This is the
/// microfacet model described by [Walter et al.](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
pub struct Beckmann {
    width: f32,
}

impl Beckmann {
    /// Create a new Beckmann distribution with the desired width
    pub fn new(w: f32) -> Beckmann {
        // From pbrt-v3, conversion from Blinn-Phong style roughness to approximately
        // equivalent Beckmann alpha
        let roughness = f32::max(w, 0.000001);
        Beckmann { width: roughness }
    }
}

impl MicrofacetDistribution for Beckmann {
    fn normal_distribution(&self, w_h: &Vector) -> f32 {
        if bxdf::cos_theta(w_h) > 0.0 {
            let e = f32::exp(-f32::powf(bxdf::tan_theta(&w_h) / self.width, 2.0));
            e / (f32::consts::PI * f32::powf(self.width, 2.0) * f32::powf(bxdf::cos_theta(&w_h), 4.0))
        } else {
            0.0
        }
    }
    fn sample(&self, w_o: &Vector, samples: &(f32, f32)) -> Vector {
        let log_sample = match f32::ln(1.0 - samples.0) {
            x if f32::is_infinite(x) => { println!("it was inf!"); 0.0 },
            x => x,
        };
        let tan_theta_sqr = -f32::powf(self.width, 2.0) * log_sample;
        let phi = 2.0 * f32::consts::PI * samples.1;
        let cos_theta = 1.0 / f32::sqrt(1.0 + tan_theta_sqr);
        let sin_theta = f32::sqrt(f32::max(0.0, 1.0 - cos_theta * cos_theta));
        let w_h = linalg::spherical_dir(sin_theta, cos_theta, phi);
        // TODO: Can move this check to callers, then we can have microfacet transmission
        if !bxdf::same_hemisphere(w_o, &w_h) {
            -w_h
        } else {
            w_h
        }
    }
    fn pdf(&self, w_h: &Vector) -> f32 {
        f32::abs(bxdf::cos_theta(w_h)) * self.normal_distribution(w_h)
    }
    fn shadowing_masking(&self, w_i: &Vector, w_o: &Vector, w_h: &Vector) -> f32 {
        self.monodir_shadowing(w_i, w_h) * self.monodir_shadowing(w_o, w_h)
    }
    /// Monodirectional shadowing function from Walter et al., we use the Smith
    /// shadowing-masking which uses the reciprocity of this function.
    /// `w` is the incident/outgoing light direction and `w_h` is the microfacet normal
    fn monodir_shadowing(&self, v: &Vector, w_h: &Vector) -> f32 {
        if linalg::dot(v, w_h) / bxdf::cos_theta(v) > 0.0 {
            let a = 1.0 / (self.width * bxdf::tan_theta(v));
            if a < 1.6 {
                let a_sqr = f32::powf(a, 2.0);
                (3.535 * a + 2.181 * a_sqr) / (1.0 + 2.276 * a + 2.577 * a_sqr)
            } else {
                1.0
            }
        } else {
            0.0
        }
    }
}

<|endoftext|>


<commit_before>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone, Debug)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Debug, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if <Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone, Debug)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, ref right } =>
                left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}
<commit_msg>feat(node): nicer fmt::Debug implementation for lazy fields<commit_after>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> fmt::Debug for Lazy<T>
where T: fmt::Debug
    , T: Copy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.get() { Some(value) => value.fmt(f)
                           , None => write!(f, "?")

        }
    }
}
macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Debug, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if <Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone, Debug)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, ref right } =>
                left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}
<|endoftext|>


<commit_before>use hash::KEY_SIZE;
use hash::Hash160;
use std::net;
use std::collections::VecDeque;
use std::mem;

const K : usize = 20;
const BUCKET_DEPTH : usize = K;

/// Kademlia routing table, with 160 buckets of `BUCKET_DEPTH` (k) node
/// identifiers each.
///
/// The structure employs least-recently seen eviction. Conflicts generated
/// by evicting a node by inserting a newer one remain tracked, so they can
/// can be resolved later.
pub struct RoutingTable {
   parent_key : Hash160,
   buckets    : Vec<Bucket>,
   conflicts  : Vec<EvictionConflict>,
}

/// Bucket size is estimated to be small enough not to warrant
/// the downsides of using a linked list.
#[derive(Debug, Clone)]
struct Bucket {
   entries  : VecDeque<NodeInfo>,
}

/// Represents a conflict derived from attempting to insert a node in a full
/// bucket.
#[derive(Debug,Clone)]
struct EvictionConflict {
   evicted  : NodeInfo,
   inserted : NodeInfo
}

#[derive(Debug, Clone, PartialEq)]
pub struct NodeInfo {
   pub key  : Hash160,
   pub ip   : net::IpAddr,
   pub port : u16,
}

#[derive(Debug, PartialEq)]
pub enum LookupResult {
   Found(NodeInfo),
   ClosestNodes(Vec<NodeInfo>),
   Myself,
}

impl RoutingTable {
   pub fn new(parent_key : Hash160) -> RoutingTable {
      let mut buckets = Vec::<Bucket>::with_capacity(KEY_SIZE);
      for _ in 0..KEY_SIZE {
         buckets.push(Bucket::new());
      }

      RoutingTable {
         parent_key : parent_key,
         buckets : buckets,
         conflicts  : Vec::new()
      }
   }

   /// Inserts a node in the routing table. Employs least-recently-seen eviction
   /// by kicking out the oldest node in case the bucket is full, and registering
   /// an eviction conflict that can be revised later.
   pub fn insert_node(&mut self, info : NodeInfo) {
      if let Some(index) = self.bucket_for_node(&info.key) {
         let bucket = &mut self.buckets[index];
         bucket.entries.retain(|ref stored_info| info.key != stored_info.key);
         if bucket.entries.len() == BUCKET_DEPTH {
            let conflict = EvictionConflict {
               evicted  : bucket.entries.pop_front().unwrap(),
               inserted : info.clone()
            };
            self.conflicts.push(conflict);
         }
         bucket.entries.push_back(info);
      }
   }

   /// Performs a node lookup on the routing table. The lookup result may
   /// contain the specific node, a list of up to the N closest nodes, or
   /// report that the parent node itself was requested.
   pub fn lookup(&self, key : &Hash160, n : usize) -> LookupResult {
      if *key == self.parent_key {
         return LookupResult::Myself;
      }

      match self.specific_node(key) {
         Some(info) => LookupResult::Found(info),
         None => LookupResult::ClosestNodes(self.closest_n_nodes_to(key, n)),
      }
   }

   /// Returns a table entry for the specific node with a given hash.
   fn specific_node(&self, key : &Hash160) -> Option<NodeInfo> {
      if let Some(index) = self.bucket_for_node(key){
         let bucket = &self.buckets[index];
         return bucket.entries.iter().find(|ref info| *key == info.key).cloned();
      }
      None
   }

   fn closest_n_nodes_to(&self, key : &Hash160, n : usize) -> Vec<NodeInfo>{
      let mut closest = Vec::with_capacity(n);
      let mut master_key = key ^ &self.parent_key;
      let ideal_bucket = master_key.height().unwrap();
      let mut floor = ideal_bucket;
      let mut ceiling = floor + 1;

      while ceiling > 1 {
         println!("Trying buckets {} to {}", floor, ceiling);
         for bucket_index in floor..ceiling {
            print!(" doot");
            let mut nodes_from_bucket = self.buckets[bucket_index].clone().entries.into_iter().collect::<Vec<NodeInfo>>();
            nodes_from_bucket.sort_by_key(|ref info| &info.key ^ key);
            let space_left = closest.capacity() - closest.len();
            nodes_from_bucket.truncate(space_left);
            closest.append(&mut nodes_from_bucket);
            if closest.capacity() == closest.len() {
               break;
            }
         }
         ceiling = floor;
         master_key.flip_bit(floor);
         floor = match master_key.height() {
            Some(height) => height,
            None => 1
         }
      }

      // If the master key algorithm wasn't enough, just pour from the higher buckets
      for bucket_index in (ideal_bucket+1)..KEY_SIZE {
         if closest.capacity() == closest.len() {
            break;
         }
         let mut nodes_from_bucket = self.buckets[bucket_index].clone().entries.into_iter().collect::<Vec<NodeInfo>>();
         nodes_from_bucket.sort_by_key(|ref info| &info.key ^ key);
         let space_left = closest.capacity() - closest.len();
         nodes_from_bucket.truncate(space_left);
         closest.append(&mut nodes_from_bucket);
      }
      closest
   }

   /// Returns the appropriate position for a node, by computing
   /// the last bit of their distance set to 1. None if we are
   /// attempting to add the parent key.
   fn bucket_for_node(&self, key : &Hash160) -> Option<usize> {
       (&self.parent_key ^ key).height()
   }

   fn revert_conflict(&mut self, conflict : EvictionConflict) {
      if let Some(index) = self.bucket_for_node(&conflict.inserted.key) {
         let bucket  = &mut self.buckets[index];
         let evictor = &mut bucket.entries.iter_mut().find(|ref info| conflict.inserted.key == info.key).unwrap();
         mem::replace::<NodeInfo>(evictor, conflict.evicted);
      }
   }
}

impl Bucket {
   pub fn new() -> Bucket {
      Bucket { entries : VecDeque::<NodeInfo>::with_capacity(BUCKET_DEPTH) }
   }

}

#[cfg(test)]
mod tests {
    use super::*;
    use hash::Hash160;
    use std::net;
    use std::str::FromStr;

    #[test]
    fn new_routing_table_is_empty() {
       let parent_key = Hash160::random();
       let table = RoutingTable::new(parent_key);
       let test_hash = Hash160::random();

       assert!(table.specific_node(&test_hash).is_none());
    }

    #[test]
    fn inserting_and_retrieving_specific_node() {
       let node_info = NodeInfo {
          key  : Hash160::random(),
          ip   : net::IpAddr::from_str("0.0.0.0").unwrap(),
          port : 50000
       };

       let mut table = RoutingTable::new(Hash160::random());
       table.insert_node(node_info.clone());
       assert_eq!(table.specific_node(&node_info.key), Some(node_info));
    }

    impl RoutingTable {
       pub fn fill_bucket(&mut self, bucket_index : usize, fill_quantity : u8) {
          // Otherwise this helper function becomes quite complex.
          assert!(bucket_index > 7);
          let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();
          for i in 0..fill_quantity {
             let mut key = self.parent_key.clone();
             key.flip_bit(bucket_index);

             key.raw[0] = i as u8;
             let info = NodeInfo {
                key  : key,
                ip   : any_ip.clone(),
                port : 0
             };
             self.insert_node(info);
          }
       }
    }

    #[test]
    fn inserting_in_a_full_bucket_causes_eviction_conflict() {
       let mut parent_key = Hash160::blank();
       parent_key.raw[1] = 1; // This will guarantee all nodes will fall on the same bucket.
       let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();

       let mut table = RoutingTable::new(parent_key);

       table.fill_bucket(8, super::BUCKET_DEPTH as u8);
       assert!(table.conflicts.is_empty());

       // When we add another node to the same bucket, we cause a conflict.
       let mut key = Hash160::blank();
       key.raw[0] = 0xFF;
       let info = NodeInfo {
          key  : key,
          ip   : any_ip.clone(),
          port : 0
       };
       table.insert_node(info);
       assert_eq!(table.conflicts.len(), 1);

       let conflict = table.conflicts.first().unwrap();
       // We evicted the oldest node, which has a blank key.
       assert!(table.specific_node(&conflict.inserted.key).is_some());
    }

    #[test]
    fn reverting_an_eviction_conflict_reinserts_the_evicted_node_in_place_of_evictor() {
       let mut parent_key = Hash160::blank();
       parent_key.raw[1] = 1; // This will guarantee all nodes will fall on the same bucket.
       let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();

       let mut table = RoutingTable::new(parent_key);

       table.fill_bucket(8, super::BUCKET_DEPTH as u8);
       assert!(table.conflicts.is_empty());

       // When we add another node to the same bucket, we cause a conflict.
       let mut key = Hash160::blank();
       key.raw[0] = 0xFF;
       let info = NodeInfo {
          key  : key,
          ip   : any_ip.clone(),
          port : 0
       };
       table.insert_node(info);
       assert_eq!(table.conflicts.len(), 1);
       let conflict = table.conflicts.pop().unwrap();

       table.revert_conflict(conflict.clone());
       // The evictor has been removed.
       assert!(table.specific_node(&conflict.inserted.key).is_none());
       // And the evicted has been reinserted.
       assert!(table.specific_node(&conflict.evicted.key).is_some());
    }

    #[test]
    fn lookup_for_a_stored_node() {
       let mut table = RoutingTable::new(Hash160::random());
       let node = NodeInfo {
          key  : Hash160::random(),
          ip   : net::IpAddr::from_str("0.0.0.0").unwrap(),
          port : 0,
       };
       table.insert_node(node.clone());

       assert_eq!(table.lookup(&node.key, 20), LookupResult::Found(node));
    }

    #[test]
    fn lookup_for_a_not_stored_node() {
       let mut table = RoutingTable::new(Hash160::random());
       table.fill_bucket(11, 5);
       table.fill_bucket(12, 5);
       table.fill_bucket(13, 5);

       // We construct a node key that would fall in bucket 12, but isn't stored.
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(12);
       node_key.raw[0] = 0xFF;

       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,20) {
          assert_eq!(nodes.len(), 15);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn ascending_lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(8); // Bucket 8
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn descending_lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(51); // Bucket 51
       node_key.raw[0] = 0xFF;
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(25); // Bucket 25
       node_key.raw[0] = 0xFF;
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

}
<commit_msg>Randomized table test<commit_after>use hash::KEY_SIZE;
use hash::Hash160;
use std::net;
use std::collections::VecDeque;
use std::mem;

const K : usize = 20;
const BUCKET_DEPTH : usize = K;

/// Kademlia routing table, with 160 buckets of `BUCKET_DEPTH` (k) node
/// identifiers each.
///
/// The structure employs least-recently seen eviction. Conflicts generated
/// by evicting a node by inserting a newer one remain tracked, so they can
/// can be resolved later.
pub struct RoutingTable {
   parent_key : Hash160,
   buckets    : Vec<Bucket>,
   conflicts  : Vec<EvictionConflict>,
}

/// Bucket size is estimated to be small enough not to warrant
/// the downsides of using a linked list.
#[derive(Debug, Clone)]
struct Bucket {
   entries  : VecDeque<NodeInfo>,
}

/// Represents a conflict derived from attempting to insert a node in a full
/// bucket.
#[derive(Debug,Clone)]
struct EvictionConflict {
   evicted  : NodeInfo,
   inserted : NodeInfo
}

#[derive(Debug, Clone, PartialEq)]
pub struct NodeInfo {
   pub key  : Hash160,
   pub ip   : net::IpAddr,
   pub port : u16,
}

#[derive(Debug, PartialEq)]
pub enum LookupResult {
   Found(NodeInfo),
   ClosestNodes(Vec<NodeInfo>),
   Myself,
}

impl RoutingTable {
   pub fn new(parent_key : Hash160) -> RoutingTable {
      let mut buckets = Vec::<Bucket>::with_capacity(KEY_SIZE);
      for _ in 0..KEY_SIZE {
         buckets.push(Bucket::new());
      }

      RoutingTable {
         parent_key : parent_key,
         buckets : buckets,
         conflicts  : Vec::new()
      }
   }

   /// Inserts a node in the routing table. Employs least-recently-seen eviction
   /// by kicking out the oldest node in case the bucket is full, and registering
   /// an eviction conflict that can be revised later.
   pub fn insert_node(&mut self, info : NodeInfo) {
      if let Some(index) = self.bucket_for_node(&info.key) {
         let bucket = &mut self.buckets[index];
         bucket.entries.retain(|ref stored_info| info.key != stored_info.key);
         if bucket.entries.len() == BUCKET_DEPTH {
            let conflict = EvictionConflict {
               evicted  : bucket.entries.pop_front().unwrap(),
               inserted : info.clone()
            };
            self.conflicts.push(conflict);
         }
         bucket.entries.push_back(info);
      }
   }

   /// Performs a node lookup on the routing table. The lookup result may
   /// contain the specific node, a list of up to the N closest nodes, or
   /// report that the parent node itself was requested.
   pub fn lookup(&self, key : &Hash160, n : usize) -> LookupResult {
      if *key == self.parent_key {
         return LookupResult::Myself;
      }

      match self.specific_node(key) {
         Some(info) => LookupResult::Found(info),
         None => LookupResult::ClosestNodes(self.closest_n_nodes_to(key, n)),
      }
   }

   /// Returns a table entry for the specific node with a given hash.
   fn specific_node(&self, key : &Hash160) -> Option<NodeInfo> {
      if let Some(index) = self.bucket_for_node(key){
         let bucket = &self.buckets[index];
         return bucket.entries.iter().find(|ref info| *key == info.key).cloned();
      }
      None
   }

   fn closest_n_nodes_to(&self, key : &Hash160, n : usize) -> Vec<NodeInfo>{
      let mut closest = Vec::with_capacity(n);
      let mut master_key = key ^ &self.parent_key;
      let ideal_bucket = master_key.height().unwrap();
      let mut floor = ideal_bucket;
      let mut ceiling = floor + 1;

      while ceiling > 1 {
         println!("Trying buckets {} to {}", floor, ceiling);
         for bucket_index in floor..ceiling {
            print!(" doot");
            let mut nodes_from_bucket = self.buckets[bucket_index].clone().entries.into_iter().collect::<Vec<NodeInfo>>();
            nodes_from_bucket.sort_by_key(|ref info| &info.key ^ key);
            let space_left = closest.capacity() - closest.len();
            nodes_from_bucket.truncate(space_left);
            closest.append(&mut nodes_from_bucket);
            if closest.capacity() == closest.len() {
               break;
            }
         }
         ceiling = floor;
         master_key.flip_bit(floor);
         floor = match master_key.height() {
            Some(height) => height,
            None => 1
         }
      }

      // If the master key algorithm wasn't enough, just pour from the higher buckets
      for bucket_index in (ideal_bucket+1)..KEY_SIZE {
         if closest.capacity() == closest.len() {
            break;
         }
         let mut nodes_from_bucket = self.buckets[bucket_index].clone().entries.into_iter().collect::<Vec<NodeInfo>>();
         nodes_from_bucket.sort_by_key(|ref info| &info.key ^ key);
         let space_left = closest.capacity() - closest.len();
         nodes_from_bucket.truncate(space_left);
         closest.append(&mut nodes_from_bucket);
      }
      closest
   }

   /// Returns the appropriate position for a node, by computing
   /// the last bit of their distance set to 1. None if we are
   /// attempting to add the parent key.
   fn bucket_for_node(&self, key : &Hash160) -> Option<usize> {
       (&self.parent_key ^ key).height()
   }

   fn revert_conflict(&mut self, conflict : EvictionConflict) {
      if let Some(index) = self.bucket_for_node(&conflict.inserted.key) {
         let bucket  = &mut self.buckets[index];
         let evictor = &mut bucket.entries.iter_mut().find(|ref info| conflict.inserted.key == info.key).unwrap();
         mem::replace::<NodeInfo>(evictor, conflict.evicted);
      }
   }
}

impl Bucket {
   pub fn new() -> Bucket {
      Bucket { entries : VecDeque::<NodeInfo>::with_capacity(BUCKET_DEPTH) }
   }
}

#[cfg(test)]
mod tests {
    use super::*;
    use hash::Hash160;
    use std::net;
    use std::str::FromStr;

    #[test]
    fn new_routing_table_is_empty() {
       let parent_key = Hash160::random();
       let table = RoutingTable::new(parent_key);
       let test_hash = Hash160::random();

       assert!(table.specific_node(&test_hash).is_none());
    }

    #[test]
    fn inserting_and_retrieving_specific_node() {
       let node_info = NodeInfo {
          key  : Hash160::random(),
          ip   : net::IpAddr::from_str("0.0.0.0").unwrap(),
          port : 50000
       };

       let mut table = RoutingTable::new(Hash160::random());
       table.insert_node(node_info.clone());
       assert_eq!(table.specific_node(&node_info.key), Some(node_info));
    }

    impl RoutingTable {
       pub fn fill_bucket(&mut self, bucket_index : usize, fill_quantity : u8) {
          // Otherwise this helper function becomes quite complex.
          assert!(bucket_index > 7);
          let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();
          for i in 0..fill_quantity {
             let mut key = self.parent_key.clone();
             key.flip_bit(bucket_index);

             key.raw[0] = i as u8;
             let info = NodeInfo {
                key  : key,
                ip   : any_ip.clone(),
                port : 0
             };
             self.insert_node(info);
          }
       }
    }

    #[test]
    fn inserting_in_a_full_bucket_causes_eviction_conflict() {
       let mut parent_key = Hash160::blank();
       parent_key.raw[1] = 1; // This will guarantee all nodes will fall on the same bucket.
       let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();

       let mut table = RoutingTable::new(parent_key);

       table.fill_bucket(8, super::BUCKET_DEPTH as u8);
       assert!(table.conflicts.is_empty());

       // When we add another node to the same bucket, we cause a conflict.
       let mut key = Hash160::blank();
       key.raw[0] = 0xFF;
       let info = NodeInfo {
          key  : key,
          ip   : any_ip.clone(),
          port : 0
       };
       table.insert_node(info);
       assert_eq!(table.conflicts.len(), 1);

       let conflict = table.conflicts.first().unwrap();
       // We evicted the oldest node, which has a blank key.
       assert!(table.specific_node(&conflict.inserted.key).is_some());
    }

    #[test]
    fn reverting_an_eviction_conflict_reinserts_the_evicted_node_in_place_of_evictor() {
       let mut parent_key = Hash160::blank();
       parent_key.raw[1] = 1; // This will guarantee all nodes will fall on the same bucket.
       let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();

       let mut table = RoutingTable::new(parent_key);

       table.fill_bucket(8, super::BUCKET_DEPTH as u8);
       assert!(table.conflicts.is_empty());

       // When we add another node to the same bucket, we cause a conflict.
       let mut key = Hash160::blank();
       key.raw[0] = 0xFF;
       let info = NodeInfo {
          key  : key,
          ip   : any_ip.clone(),
          port : 0
       };
       table.insert_node(info);
       assert_eq!(table.conflicts.len(), 1);
       let conflict = table.conflicts.pop().unwrap();

       table.revert_conflict(conflict.clone());
       // The evictor has been removed.
       assert!(table.specific_node(&conflict.inserted.key).is_none());
       // And the evicted has been reinserted.
       assert!(table.specific_node(&conflict.evicted.key).is_some());
    }

    #[test]
    fn lookup_for_a_stored_node() {
       let mut table = RoutingTable::new(Hash160::random());
       let node = NodeInfo {
          key  : Hash160::random(),
          ip   : net::IpAddr::from_str("0.0.0.0").unwrap(),
          port : 0,
       };
       table.insert_node(node.clone());

       assert_eq!(table.lookup(&node.key, 20), LookupResult::Found(node));
    }

    #[test]
    fn lookup_for_self() {
       let parent_key = Hash160::random();
       let table = RoutingTable::new(parent_key.clone());
       assert_eq!(table.lookup(&parent_key, 20), LookupResult::Myself);
    }

    #[test]
    fn ascending_lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(8); // Bucket 8
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn descending_lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(51); // Bucket 51
       node_key.raw[0] = 0xFF;
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn lookup_on_a_sparse_table() {
       let mut table = RoutingTable::new(Hash160::random());
       for i in (10..50).filter(|x| x%2 == 0) {
         table.fill_bucket(i, 2);
       }
       let mut node_key = table.parent_key.clone();
       node_key.flip_bit(25); // Bucket 25
       node_key.raw[0] = 0xFF;
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key,5) {
          assert_eq!(nodes.len(), 5);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("We shouldn't have found the node!");
       }
    }

    #[test]
    fn lookup_on_a_randomized_table() {
       let mut table = RoutingTable::new(Hash160::random());
       let any_ip = net::IpAddr::from_str("0.0.0.0").unwrap();
       for _ in 0..100 {
          table.insert_node(NodeInfo {
             key  : Hash160::random(),
             ip   : any_ip.clone(),
             port : 0
          });
       }

       let node_key = Hash160::random();
       if let LookupResult::ClosestNodes(nodes) = table.lookup(&node_key, 30) {
          assert_eq!(nodes.len(), 30);

          // Ensure they are ordered by ascending distance
          for (current_node, next_node) in nodes.iter().zip(nodes.iter().skip(1)) {
             assert!((&current_node.key ^ &node_key) <= (&next_node.key ^ &node_key));
          }
       }
       else {
          panic!("You should go play the lottery...");
       }
    }

}
<|endoftext|>


<commit_before><commit_msg>fix unit tests<commit_after><|endoftext|>


<commit_before><commit_msg>(fix) mark error as Send<commit_after><|endoftext|>


<commit_before><commit_msg>Progresses #1373: Adds can_write & updates can_read implementation<commit_after><|endoftext|>


<commit_before>use compositor::{Action, Server, Shell, View};
use wlroots::{CompositorHandle, Origin, SurfaceHandle, XdgV6ShellHandler,
              XdgV6ShellManagerHandler, XdgV6ShellState::*, XdgV6ShellSurfaceHandle};

use wlroots::xdg_shell_v6_events::MoveEvent;

#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct XdgV6 {
    shell_surface: XdgV6ShellSurfaceHandle
}

impl XdgV6 {
    pub fn new() -> Self {
        XdgV6 { ..XdgV6::default() }
    }
}

impl XdgV6ShellHandler for XdgV6 {
    fn move_request(&mut self,
                    compositor: CompositorHandle,
                    _surface: SurfaceHandle,
                    shell_surface: XdgV6ShellSurfaceHandle,
                    _event: &MoveEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let ref mut seat = server.seat;
            let ref mut cursor = server.cursor;

            if let Some(ref mut view) = seat.focused {
                let shell: Shell = shell_surface.into();
                let action = &mut seat.action;
                if view.shell == shell {
                    with_handles!([(cursor: {cursor})] => {
                        let (lx, ly) = cursor.coords();
                        let Origin { x: shell_x, y: shell_y } = view.origin;
                        let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                        let start = Origin::new(view_sx as _, view_sy as _);
                        *action = Some(Action::Moving { start: start });
                    }).unwrap();
                }
            }
        }).unwrap();
    }
}

pub struct XdgV6ShellManager;

impl XdgV6ShellManagerHandler for XdgV6ShellManager {
    fn new_surface(&mut self,
                   compositor: CompositorHandle,
                   mut shell_surface: XdgV6ShellSurfaceHandle)
                   -> Option<Box<XdgV6ShellHandler>> {
        let is_toplevel = with_handles!([(shell_surface: {&mut shell_surface})] => {
            match shell_surface.state().unwrap() {
                TopLevel(_) => true,
                _ => false
            }
        }).unwrap();

        if is_toplevel {
            with_handles!([(compositor: {compositor})] => {
                let server: &mut Server = compositor.into();
                server.views
                    .insert(0, View::new(Shell::XdgV6(shell_surface.into())));
            }).unwrap();
        }

        Some(Box::new(XdgV6::new()))
    }

    fn surface_destroyed(&mut self,
                         compositor: CompositorHandle,
                         shell_surface: XdgV6ShellSurfaceHandle) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut seat,
                         ref mut views,
                         .. } = *server;
            let destroyed_shell = shell_surface.into();
            if let Some(pos) = views.iter().position(|view| view.shell == destroyed_shell) {
                views.remove(pos);
            }

            seat.focused = seat.focused.take().and_then(|mut focused| {
                if focused.shell == destroyed_shell {
                    with_handles!([(seat: {&mut seat.seat})] => {
                        if views.len() > 0 {
                            if let Some(keyboard) = seat.get_keyboard() {
                                with_handles!([(keyboard: {keyboard}),
                                    (surface: {focused.surface()})] => {
                                    seat.keyboard_notify_enter(surface,
                                                               &mut keyboard.keycodes(),
                                                               &mut keyboard.get_modifier_masks());
                                }).unwrap();
                            }
                            views[0].activate(true);
                            Some(views[0].clone())
                        } else {
                            seat.keyboard_clear_focus();
                            None
                        }
                    }).unwrap()
                } else {
                    Some(focused)
                }
            });

        }).unwrap();
    }
}
<commit_msg>set focus on new view<commit_after>use compositor::{Action, Server, Shell, View};
use wlroots::{CompositorHandle, Origin, SurfaceHandle, XdgV6ShellHandler,
              XdgV6ShellManagerHandler, XdgV6ShellState::*, XdgV6ShellSurfaceHandle};

use wlroots::xdg_shell_v6_events::MoveEvent;

#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct XdgV6 {
    shell_surface: XdgV6ShellSurfaceHandle
}

impl XdgV6 {
    pub fn new() -> Self {
        XdgV6 { ..XdgV6::default() }
    }
}

impl XdgV6ShellHandler for XdgV6 {
    fn move_request(&mut self,
                    compositor: CompositorHandle,
                    _surface: SurfaceHandle,
                    shell_surface: XdgV6ShellSurfaceHandle,
                    _event: &MoveEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let ref mut seat = server.seat;
            let ref mut cursor = server.cursor;

            if let Some(ref mut view) = seat.focused {
                let shell: Shell = shell_surface.into();
                let action = &mut seat.action;
                if view.shell == shell {
                    with_handles!([(cursor: {cursor})] => {
                        let (lx, ly) = cursor.coords();
                        let Origin { x: shell_x, y: shell_y } = view.origin;
                        let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                        let start = Origin::new(view_sx as _, view_sy as _);
                        *action = Some(Action::Moving { start: start });
                    }).unwrap();
                }
            }
        }).unwrap();
    }
}

pub struct XdgV6ShellManager;

impl XdgV6ShellManagerHandler for XdgV6ShellManager {
    fn new_surface(&mut self,
                   compositor: CompositorHandle,
                   mut shell_surface: XdgV6ShellSurfaceHandle)
                   -> Option<Box<XdgV6ShellHandler>> {
        let is_toplevel = with_handles!([(shell_surface: {&mut shell_surface})] => {
            match shell_surface.state().unwrap() {
                TopLevel(_) => true,
                _ => false
            }
        }).unwrap();

        if is_toplevel {
            with_handles!([(compositor: {compositor})] => {
                let server: &mut Server = compositor.into();
                let Server { ref mut seat,
                             ref mut views,
                             .. } = *server;
                views.insert(0, View::new(Shell::XdgV6(shell_surface.into())));

                with_handles!([(seat: {&mut seat.seat})] => {
                    if let Some(keyboard) = seat.get_keyboard() {
                        with_handles!([(keyboard: {keyboard}),
                                       (surface: {views[0].surface()})] => {
                                           seat.keyboard_notify_enter(surface,
                                                                      &mut keyboard.keycodes(),
                                                                      &mut keyboard.get_modifier_masks());
                        }).unwrap();
                    }
                    views[0].activate(true);
                }).unwrap();
            }).unwrap();
        }

        Some(Box::new(XdgV6::new()))
    }

    fn surface_destroyed(&mut self,
                         compositor: CompositorHandle,
                         shell_surface: XdgV6ShellSurfaceHandle) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut seat,
                         ref mut views,
                         .. } = *server;
            let destroyed_shell = shell_surface.into();
            if let Some(pos) = views.iter().position(|view| view.shell == destroyed_shell) {
                views.remove(pos);
            }

            seat.focused = seat.focused.take().and_then(|mut focused| {
                if focused.shell == destroyed_shell {
                    with_handles!([(seat: {&mut seat.seat})] => {
                        if views.len() > 0 {
                            if let Some(keyboard) = seat.get_keyboard() {
                                with_handles!([(keyboard: {keyboard}),
                                    (surface: {focused.surface()})] => {
                                    seat.keyboard_notify_enter(surface,
                                                               &mut keyboard.keycodes(),
                                                               &mut keyboard.get_modifier_masks());
                                }).unwrap();
                            }
                            views[0].activate(true);
                            Some(views[0].clone())
                        } else {
                            seat.keyboard_clear_focus();
                            None
                        }
                    }).unwrap()
                } else {
                    Some(focused)
                }
            });

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


<commit_before>// Generic x86-64 target for bare-metal code - Floating point disabled
//
// Can be used in conjunction with the `target-feature` and
// `target-cpu` compiler flags to opt-in more hardware-specific
// features.

use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};

pub fn target() -> Target {
    let opts = TargetOptions {
        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
        linker: Some("rust-lld".to_owned()),
        features: "-mmx,-sse,+soft-float".to_string(),
        executables: true,
        disable_redzone: true,
        panic_strategy: PanicStrategy::Abort,
        code_model: Some(CodeModel::Kernel),
        ..Default::default()
    };
    Target {
        llvm_target: "x86_64-unknown-none-elf".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
            .to_string(),
        arch: "x86_64".to_string(),
        options: opts,
    }
}
<commit_msg>x86_64-unknown-none: Disable more target features<commit_after>// Generic x86-64 target for bare-metal code - Floating point disabled
//
// Can be used in conjunction with the `target-feature` and
// `target-cpu` compiler flags to opt-in more hardware-specific
// features.

use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};

pub fn target() -> Target {
    let opts = TargetOptions {
        linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
        linker: Some("rust-lld".to_owned()),
        features:
            "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
                .to_string(),
        executables: true,
        disable_redzone: true,
        panic_strategy: PanicStrategy::Abort,
        code_model: Some(CodeModel::Kernel),
        ..Default::default()
    };
    Target {
        llvm_target: "x86_64-unknown-none-elf".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
            .to_string(),
        arch: "x86_64".to_string(),
        options: opts,
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;
use kinds::Copy;
use option;
use ptr;
use str;
use util;
use num::Zero;

/// The option type
#[deriving_eq]
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match move opta {
        Some(move opta) => Some(move opta),
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_or_zero<T: Copy Zero>(opt: Option<T>) -> T {
    //! Returns the contained value or zero (for this type)

    match opt { Some(copy x) => x, None => Zero::zero() }
}

pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    match move opt {
        Some(move val) => val,
        None => fail reason.to_owned(),
    }
}

impl<T> Option<T> {
    /// Returns true if the option equals `none`
    #[inline(always)]
    pure fn is_none(&self) -> bool { is_none(self) }

    /// Returns true if the option contains some value
    #[inline(always)]
    pure fn is_some(&self) -> bool { is_some(self) }

    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    #[inline(always)]
    pure fn chain_ref<U>(&self, f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }

    /// Maps a `some` value from one type to another by reference
    #[inline(always)]
    pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline(always)]
    pure fn map_consume<U>(self, f: fn(v: T) -> U) -> Option<U> {
        map_consume(self, f)
    }

    /// Applies a function to the contained value or returns a default
    #[inline(always)]
    pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
        map_default(self, move def, f)
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline(always)]
    pure fn map_consume_default<U>(self, def: U, f: fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Performs an operation on the contained value by reference
    #[inline(always)]
    pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline(always)]
    pure fn get_ref(&self) -> &self/T { get_ref(self) }

    /**
     * Gets the value out of an option without copying.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn unwrap(self) -> T { unwrap(self) }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline(always)]
    fn swap_unwrap(&mut self) -> T { swap_unwrap(self) }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn expect(self, reason: &str) -> T { expect(self, reason) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline(always)]
    pure fn get(self) -> T { get(self) }

    #[inline(always)]
    pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) }

    /// Applies a function zero or more times until the result is none.
    #[inline(always)]
    pure fn while_some(self, blk: fn(v: T) -> Option<T>) {
        while_some(self, blk)
    }
}

impl<T: Copy Zero> Option<T> {
    #[inline(always)]
    pure fn get_or_zero(self) -> T { get_or_zero(self) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert some_stuff.get_or_zero() == 42;
    let no_stuff: Option<int> = None;
    assert no_stuff.get_or_zero() == 0;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>avoid unwrap in Option::map_consume implementation<commit_after>// Copyright 2012 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.

/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;
use kinds::Copy;
use option;
use ptr;
use str;
use util;
use num::Zero;

/// The option type
#[deriving_eq]
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    match opt { None => None, Some(v) => Some(f(v)) }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match move opta {
        Some(move opta) => Some(move opta),
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_or_zero<T: Copy Zero>(opt: Option<T>) -> T {
    //! Returns the contained value or zero (for this type)

    match opt { Some(copy x) => x, None => Zero::zero() }
}

pub pure fn get_or_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    match move opt {
        Some(move val) => val,
        None => fail reason.to_owned(),
    }
}

impl<T> Option<T> {
    /// Returns true if the option equals `none`
    #[inline(always)]
    pure fn is_none(&self) -> bool { is_none(self) }

    /// Returns true if the option contains some value
    #[inline(always)]
    pure fn is_some(&self) -> bool { is_some(self) }

    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    #[inline(always)]
    pure fn chain_ref<U>(&self, f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }

    /// Maps a `some` value from one type to another by reference
    #[inline(always)]
    pure fn map<U>(&self, f: fn(x: &T) -> U) -> Option<U> { map(self, f) }

    /// As `map`, but consumes the option and gives `f` ownership to avoid
    /// copying.
    #[inline(always)]
    pure fn map_consume<U>(self, f: fn(v: T) -> U) -> Option<U> {
        map_consume(self, f)
    }

    /// Applies a function to the contained value or returns a default
    #[inline(always)]
    pure fn map_default<U>(&self, def: U, f: fn(x: &T) -> U) -> U {
        map_default(self, move def, f)
    }

    /// As `map_default`, but consumes the option and gives `f`
    /// ownership to avoid copying.
    #[inline(always)]
    pure fn map_consume_default<U>(self, def: U, f: fn(v: T) -> U) -> U {
        match self { None => def, Some(v) => f(v) }
    }

    /// Performs an operation on the contained value by reference
    #[inline(always)]
    pure fn iter(&self, f: fn(x: &T)) { iter(self, f) }

    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    #[inline(always)]
    pure fn get_ref(&self) -> &self/T { get_ref(self) }

    /**
     * Gets the value out of an option without copying.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn unwrap(self) -> T { unwrap(self) }

    /**
     * The option dance. Moves a value out of an option type and returns it,
     * replacing the original with `None`.
     *
     * # Failure
     *
     * Fails if the value equals `None`.
     */
    #[inline(always)]
    fn swap_unwrap(&mut self) -> T { swap_unwrap(self) }

    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    #[inline(always)]
    pure fn expect(self, reason: &str) -> T { expect(self, reason) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    #[inline(always)]
    pure fn get(self) -> T { get(self) }

    #[inline(always)]
    pure fn get_or_default(self, def: T) -> T { get_or_default(self, def) }

    /// Applies a function zero or more times until the result is none.
    #[inline(always)]
    pure fn while_some(self, blk: fn(v: T) -> Option<T>) {
        while_some(self, blk)
    }
}

impl<T: Copy Zero> Option<T> {
    #[inline(always)]
    pure fn get_or_zero(self) -> T { get_or_zero(self) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

#[test]
fn test_get_or_zero() {
    let some_stuff = Some(42);
    assert some_stuff.get_or_zero() == 42;
    let no_stuff: Option<int> = None;
    assert no_stuff.get_or_zero() == 0;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>