<commit_before>/// # Models
///
/// Here lies the data structures that a rocket league replay is decoded into. All of the models
/// are contained in this one file because of serde.
///
/// For serde, we only care about serialization, JSON serialization. Deserialization is not
/// implemented from our JSON output because it is lossy (JSON isn't the best with different
/// numeric/string types). Asking "why JSON" would be next logical step, and that's due to other
/// rocket league replay parsers (like Octane) using JSON; however, the output of this library is
/// not compatible with that of other rocket league replay parsers.
use crate::network::Frame;
use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct};
use serde::{Serialize, Serializer};
use std::collections::HashMap;

/// The structure that a rocket league replay is parsed into.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct Replay {
    pub header_size: i32,
    pub header_crc: u32,
    pub major_version: i32,
    pub minor_version: i32,
    pub net_version: Option<i32>,
    pub game_type: String,

    /// Could use a map to represent properties but I don't want to assume that duplicate keys
    /// can't exist, so to be safe, use a traditional vector.
    #[serde(serialize_with = "pair_vec")]
    pub properties: Vec<(String, HeaderProp)>,
    pub content_size: i32,
    pub content_crc: u32,
    pub network_frames: Option<NetworkFrames>,
    pub levels: Vec<String>,
    pub keyframes: Vec<KeyFrame>,
    pub debug_info: Vec<DebugInfo>,
    pub tick_marks: Vec<TickMark>,
    pub packages: Vec<String>,
    pub objects: Vec<String>,
    pub names: Vec<String>,
    pub class_indices: Vec<ClassIndex>,
    pub net_cache: Vec<ClassNetCache>,
}

/// The frames decoded from the network data
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct NetworkFrames {
    pub frames: Vec<Frame>,
}

/// In Rocket league replays, there are tickmarks that typically represent a significant event in
/// the game (eg. a goal). The tick mark is placed before the event happens so there is a ramp-up
/// time. For instance, a tickmark could be at frame 396 for a goal at frame 441. At 30 fps, this
/// would be 1.5 seconds of ramp up time.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct TickMark {
    pub description: String,
    pub frame: i32,
}

/// Keyframes as defined by the video compression section in the [wikipedia][] article, are the
/// main frames that are derived from in the following frame data. The key frames decoded will
/// match up with the frames decoded from the network data.
///
/// [wikipedia]: https://en.wikipedia.org/wiki/Key_frame#Video_compression
#[derive(Serialize, PartialEq, Debug, Clone, Copy)]
pub struct KeyFrame {
    pub time: f32,
    pub frame: i32,
    pub position: i32,
}

/// All the interesting data are stored as properties in the header, properties such as:
///
/// - When and who scored a goal
/// - Player stats (goals, assists, score, etc).
/// - Date and level played on
///
/// A property can be a number, string, or a more complex object such as an array containing
/// additional properties.
#[derive(PartialEq, Debug, Clone)]
pub enum HeaderProp {
    Array(Vec<Vec<(String, HeaderProp)>>),
    Bool(bool),
    Byte { kind: String, value: Option<String> },
    Float(f32),
    Int(i32),
    Name(String),
    QWord(u64),
    Str(String),
}

impl HeaderProp {
    /// If the `HeaderProp` is an array of properties, returns the array
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Array(vec![
    ///     vec![("abc".to_string(), HeaderProp::QWord(10))]
    /// ]);
    ///
    /// assert_eq!(v.as_array().unwrap().len(), 1);
    /// assert_eq!(v.as_array().unwrap()[0][0].1.as_array(), None);
    /// ```
    pub fn as_array(&self) -> Option<&Vec<Vec<(String, HeaderProp)>>> {
        if let HeaderProp::Array(arr) = self {
            Some(arr)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a boolean, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Bool(true);
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_bool(), Some(true));
    /// assert_eq!(b.as_bool(), None);
    /// ```
    pub fn as_bool(&self) -> Option<bool> {
        if let HeaderProp::Bool(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a float, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Float(2.50);
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_float(), Some(2.50));
    /// assert_eq!(b.as_float(), None);
    /// ```
    pub fn as_float(&self) -> Option<f32> {
        if let HeaderProp::Float(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a QWord, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::QWord(250);
    /// let b = HeaderProp::Bool(true);
    ///
    /// assert_eq!(v.as_u64(), Some(250));
    /// assert_eq!(b.as_u64(), None);
    /// ```
    pub fn as_u64(&self) -> Option<u64> {
        if let HeaderProp::QWord(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is an int, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Int(-250);
    /// let b = HeaderProp::Bool(true);
    ///
    /// assert_eq!(v.as_i32(), Some(-250));
    /// assert_eq!(b.as_i32(), None);
    /// ```
    pub fn as_i32(&self) -> Option<i32> {
        if let HeaderProp::Int(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is an string, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Name("abc".to_string());
    /// let x = HeaderProp::Str("def".to_string());
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_string(), Some("abc"));
    /// assert_eq!(x.as_string(), Some("def"));
    /// assert_eq!(b.as_i32(), None);
    /// ```
    pub fn as_string(&self) -> Option<&str> {
        match self {
            HeaderProp::Name(val) => Some(val.as_str()),
            HeaderProp::Str(val) => Some(val.as_str()),
            _ => None,
        }
    }

    /// Returns if the `HeaderProp` is a byte
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Name("abc".to_string());
    /// let b = HeaderProp::Byte {
    ///     kind: String::from("OnlinePlatform"),
    ///     value: None,
    /// };
    ///
    /// assert_eq!(v.is_byte(), false);
    /// assert_eq!(b.is_byte(), true);
    /// ```
    pub fn is_byte(&self) -> bool {
        if let HeaderProp::Byte { .. } = self {
            true
        } else {
            false
        }
    }
}

/// Debugging info stored in the replay if debugging is enabled.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct DebugInfo {
    pub frame: i32,
    pub user: String,
    pub text: String,
}

/// A mapping between an object's name and its index. Largely redundant
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct ClassIndex {
    /// Should be equivalent to `Replay::objects(self.index)`
    pub class: String,

    /// The index that the object appears in the `Replay::objects`
    pub index: i32,
}

/// A mapping between an object (that's an attribute)'s index and what its id will be when encoded
/// in the network data
#[derive(Serialize, PartialEq, Debug, Clone, Copy)]
pub struct CacheProp {
    /// The index that the object appears in the `Replay::objects`
    pub object_ind: i32,

    /// An attribute / property id that appears in the network data. Stream ids are often re-used
    /// between multiple different properties
    pub stream_id: i32,
}

/// Contains useful information when decoding the network stream
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct ClassNetCache {
    /// The index that the object appears in the `Replay::objects`
    pub object_ind: i32,

    /// The cache id of the parent. The child class inherits all the parent's properties.
    pub parent_id: i32,

    /// The cache id of the object
    pub cache_id: i32,

    /// List of properties that is on the object.
    pub properties: Vec<CacheProp>,
}

/// Serialize a vector of key value tuples into a map. This is useful when the data we're ingesting
/// (rocket league replay data) doesn't have a defined spec, so it may be assuming too much to
/// store it into an associative array, so it's stored as a normal sequence. Here we serialize as a
/// map structure because most replay parser do this, so we should be compliant and the data format
/// doesn't dictate that the keys in a sequence of key value pairs must be distinct. It's true,
/// JSON doesn't need the keys to be unique: <http://stackoverflow.com/q/21832701/433785>
fn pair_vec<K, V, S>(inp: &[(K, V)], serializer: S) -> Result<S::Ok, S::Error>
where
    K: Serialize,
    V: Serialize,
    S: Serializer,
{
    let mut state = serializer.serialize_map(Some(inp.len()))?;
    for &(ref key, ref val) in inp.iter() {
        state.serialize_key(key)?;
        state.serialize_value(val)?;
    }
    state.end()
}

/// By default serde will generate a serialization method that writes out the enum as well as the
/// enum value. Since header values are self describing in JSON, we do not need to serialize the
/// enum type. This is slightly lossy as in the serialized format it will be ambiguous if a value
/// is a `Name` or `Str`, as well as `Byte`, `Float`, `Int`, or `QWord`.
impl Serialize for HeaderProp {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            HeaderProp::Array(ref x) => {
                let mut state = serializer.serialize_seq(Some(x.len()))?;
                for inner in x {
                    // Look for a better way to do this instead of allocating the intermediate map
                    let mut els = HashMap::new();
                    for (key, val) in inner.iter() {
                        els.insert(key, val);
                    }
                    state.serialize_element(&els)?;
                }
                state.end()
            }
            HeaderProp::Bool(ref x) => serializer.serialize_bool(*x),
            HeaderProp::Byte {
                ref kind,
                ref value,
            } => {
                let mut byte = serializer.serialize_struct("Byte", 2)?;
                byte.serialize_field("kind", kind)?;
                byte.serialize_field("value", value)?;
                byte.end()
            }
            HeaderProp::Float(ref x) => serializer.serialize_f32(*x),
            HeaderProp::Int(ref x) => serializer.serialize_i32(*x),
            HeaderProp::QWord(ref x) => serializer.collect_str(x),
            HeaderProp::Name(ref x) | HeaderProp::Str(ref x) => serializer.serialize_str(x),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn to_json<T: serde::Serialize>(input: &T) -> std::string::String {
        serde_json::to_string(input).unwrap()
    }

    #[test]
    fn serialize_header_array() {
        let data = vec![
            vec![
                (String::from("frame"), HeaderProp::Int(441)),
                (
                    String::from("PlayerName"),
                    HeaderProp::Str(String::from("rust is awesome")),
                ),
            ],
            vec![
                (String::from("frame"), HeaderProp::Int(1738)),
                (
                    String::from("PlayerName"),
                    HeaderProp::Str(String::from("rusty")),
                ),
            ],
        ];
        let actual = to_json(&HeaderProp::Array(data));
        assert!(actual.contains("\"PlayerName\":\"rust is awesome\""));
        assert!(actual.contains("\"PlayerName\":\"rusty\""));
        assert!(actual.contains("\"frame\":441"));
        assert!(actual.contains("\"frame\":1738"));
    }

    #[test]
    fn serialize_header_bool() {
        assert_eq!(to_json(&HeaderProp::Bool(false)), "false");
        assert_eq!(to_json(&HeaderProp::Bool(true)), "true");
    }

    #[test]
    fn serialize_header_numbers() {
        assert_eq!(
            to_json(&HeaderProp::Byte {
                kind: String::from("a"),
                value: Some(String::from("B"))
            }),
            r#"{"kind":"a","value":"B"}"#
        );
        assert_eq!(to_json(&HeaderProp::QWord(10)), "\"10\"");
        assert_eq!(to_json(&HeaderProp::Float(10.2)), "10.2");
        assert_eq!(to_json(&HeaderProp::Int(11)), "11");
    }

    #[test]
    fn serialize_header_str() {
        let val = "hello world";
        assert_eq!(
            to_json(&HeaderProp::Str(String::from(val))),
            "\"hello world\""
        );
        assert_eq!(
            to_json(&HeaderProp::Name(String::from(val))),
            "\"hello world\""
        );
    }
}
<commit_msg>Fix clippy matches expression<commit_after>/// # Models
///
/// Here lies the data structures that a rocket league replay is decoded into. All of the models
/// are contained in this one file because of serde.
///
/// For serde, we only care about serialization, JSON serialization. Deserialization is not
/// implemented from our JSON output because it is lossy (JSON isn't the best with different
/// numeric/string types). Asking "why JSON" would be next logical step, and that's due to other
/// rocket league replay parsers (like Octane) using JSON; however, the output of this library is
/// not compatible with that of other rocket league replay parsers.
use crate::network::Frame;
use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct};
use serde::{Serialize, Serializer};
use std::collections::HashMap;

/// The structure that a rocket league replay is parsed into.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct Replay {
    pub header_size: i32,
    pub header_crc: u32,
    pub major_version: i32,
    pub minor_version: i32,
    pub net_version: Option<i32>,
    pub game_type: String,

    /// Could use a map to represent properties but I don't want to assume that duplicate keys
    /// can't exist, so to be safe, use a traditional vector.
    #[serde(serialize_with = "pair_vec")]
    pub properties: Vec<(String, HeaderProp)>,
    pub content_size: i32,
    pub content_crc: u32,
    pub network_frames: Option<NetworkFrames>,
    pub levels: Vec<String>,
    pub keyframes: Vec<KeyFrame>,
    pub debug_info: Vec<DebugInfo>,
    pub tick_marks: Vec<TickMark>,
    pub packages: Vec<String>,
    pub objects: Vec<String>,
    pub names: Vec<String>,
    pub class_indices: Vec<ClassIndex>,
    pub net_cache: Vec<ClassNetCache>,
}

/// The frames decoded from the network data
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct NetworkFrames {
    pub frames: Vec<Frame>,
}

/// In Rocket league replays, there are tickmarks that typically represent a significant event in
/// the game (eg. a goal). The tick mark is placed before the event happens so there is a ramp-up
/// time. For instance, a tickmark could be at frame 396 for a goal at frame 441. At 30 fps, this
/// would be 1.5 seconds of ramp up time.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct TickMark {
    pub description: String,
    pub frame: i32,
}

/// Keyframes as defined by the video compression section in the [wikipedia][] article, are the
/// main frames that are derived from in the following frame data. The key frames decoded will
/// match up with the frames decoded from the network data.
///
/// [wikipedia]: https://en.wikipedia.org/wiki/Key_frame#Video_compression
#[derive(Serialize, PartialEq, Debug, Clone, Copy)]
pub struct KeyFrame {
    pub time: f32,
    pub frame: i32,
    pub position: i32,
}

/// All the interesting data are stored as properties in the header, properties such as:
///
/// - When and who scored a goal
/// - Player stats (goals, assists, score, etc).
/// - Date and level played on
///
/// A property can be a number, string, or a more complex object such as an array containing
/// additional properties.
#[derive(PartialEq, Debug, Clone)]
pub enum HeaderProp {
    Array(Vec<Vec<(String, HeaderProp)>>),
    Bool(bool),
    Byte { kind: String, value: Option<String> },
    Float(f32),
    Int(i32),
    Name(String),
    QWord(u64),
    Str(String),
}

impl HeaderProp {
    /// If the `HeaderProp` is an array of properties, returns the array
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Array(vec![
    ///     vec![("abc".to_string(), HeaderProp::QWord(10))]
    /// ]);
    ///
    /// assert_eq!(v.as_array().unwrap().len(), 1);
    /// assert_eq!(v.as_array().unwrap()[0][0].1.as_array(), None);
    /// ```
    pub fn as_array(&self) -> Option<&Vec<Vec<(String, HeaderProp)>>> {
        if let HeaderProp::Array(arr) = self {
            Some(arr)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a boolean, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Bool(true);
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_bool(), Some(true));
    /// assert_eq!(b.as_bool(), None);
    /// ```
    pub fn as_bool(&self) -> Option<bool> {
        if let HeaderProp::Bool(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a float, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Float(2.50);
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_float(), Some(2.50));
    /// assert_eq!(b.as_float(), None);
    /// ```
    pub fn as_float(&self) -> Option<f32> {
        if let HeaderProp::Float(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is a QWord, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::QWord(250);
    /// let b = HeaderProp::Bool(true);
    ///
    /// assert_eq!(v.as_u64(), Some(250));
    /// assert_eq!(b.as_u64(), None);
    /// ```
    pub fn as_u64(&self) -> Option<u64> {
        if let HeaderProp::QWord(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is an int, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Int(-250);
    /// let b = HeaderProp::Bool(true);
    ///
    /// assert_eq!(v.as_i32(), Some(-250));
    /// assert_eq!(b.as_i32(), None);
    /// ```
    pub fn as_i32(&self) -> Option<i32> {
        if let HeaderProp::Int(val) = self {
            Some(*val)
        } else {
            None
        }
    }

    /// If the `HeaderProp` is an string, returns the value
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Name("abc".to_string());
    /// let x = HeaderProp::Str("def".to_string());
    /// let b = HeaderProp::QWord(10);
    ///
    /// assert_eq!(v.as_string(), Some("abc"));
    /// assert_eq!(x.as_string(), Some("def"));
    /// assert_eq!(b.as_i32(), None);
    /// ```
    pub fn as_string(&self) -> Option<&str> {
        match self {
            HeaderProp::Name(val) => Some(val.as_str()),
            HeaderProp::Str(val) => Some(val.as_str()),
            _ => None,
        }
    }

    /// Returns if the `HeaderProp` is a byte
    /// ```
    /// # use boxcars::HeaderProp;
    /// let v = HeaderProp::Name("abc".to_string());
    /// let b = HeaderProp::Byte {
    ///     kind: String::from("OnlinePlatform"),
    ///     value: None,
    /// };
    ///
    /// assert_eq!(v.is_byte(), false);
    /// assert_eq!(b.is_byte(), true);
    /// ```
    pub fn is_byte(&self) -> bool {
        matches!(self, HeaderProp::Byte { .. })
    }
}

/// Debugging info stored in the replay if debugging is enabled.
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct DebugInfo {
    pub frame: i32,
    pub user: String,
    pub text: String,
}

/// A mapping between an object's name and its index. Largely redundant
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct ClassIndex {
    /// Should be equivalent to `Replay::objects(self.index)`
    pub class: String,

    /// The index that the object appears in the `Replay::objects`
    pub index: i32,
}

/// A mapping between an object (that's an attribute)'s index and what its id will be when encoded
/// in the network data
#[derive(Serialize, PartialEq, Debug, Clone, Copy)]
pub struct CacheProp {
    /// The index that the object appears in the `Replay::objects`
    pub object_ind: i32,

    /// An attribute / property id that appears in the network data. Stream ids are often re-used
    /// between multiple different properties
    pub stream_id: i32,
}

/// Contains useful information when decoding the network stream
#[derive(Serialize, PartialEq, Debug, Clone)]
pub struct ClassNetCache {
    /// The index that the object appears in the `Replay::objects`
    pub object_ind: i32,

    /// The cache id of the parent. The child class inherits all the parent's properties.
    pub parent_id: i32,

    /// The cache id of the object
    pub cache_id: i32,

    /// List of properties that is on the object.
    pub properties: Vec<CacheProp>,
}

/// Serialize a vector of key value tuples into a map. This is useful when the data we're ingesting
/// (rocket league replay data) doesn't have a defined spec, so it may be assuming too much to
/// store it into an associative array, so it's stored as a normal sequence. Here we serialize as a
/// map structure because most replay parser do this, so we should be compliant and the data format
/// doesn't dictate that the keys in a sequence of key value pairs must be distinct. It's true,
/// JSON doesn't need the keys to be unique: <http://stackoverflow.com/q/21832701/433785>
fn pair_vec<K, V, S>(inp: &[(K, V)], serializer: S) -> Result<S::Ok, S::Error>
where
    K: Serialize,
    V: Serialize,
    S: Serializer,
{
    let mut state = serializer.serialize_map(Some(inp.len()))?;
    for &(ref key, ref val) in inp.iter() {
        state.serialize_key(key)?;
        state.serialize_value(val)?;
    }
    state.end()
}

/// By default serde will generate a serialization method that writes out the enum as well as the
/// enum value. Since header values are self describing in JSON, we do not need to serialize the
/// enum type. This is slightly lossy as in the serialized format it will be ambiguous if a value
/// is a `Name` or `Str`, as well as `Byte`, `Float`, `Int`, or `QWord`.
impl Serialize for HeaderProp {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            HeaderProp::Array(ref x) => {
                let mut state = serializer.serialize_seq(Some(x.len()))?;
                for inner in x {
                    // Look for a better way to do this instead of allocating the intermediate map
                    let mut els = HashMap::new();
                    for (key, val) in inner.iter() {
                        els.insert(key, val);
                    }
                    state.serialize_element(&els)?;
                }
                state.end()
            }
            HeaderProp::Bool(ref x) => serializer.serialize_bool(*x),
            HeaderProp::Byte {
                ref kind,
                ref value,
            } => {
                let mut byte = serializer.serialize_struct("Byte", 2)?;
                byte.serialize_field("kind", kind)?;
                byte.serialize_field("value", value)?;
                byte.end()
            }
            HeaderProp::Float(ref x) => serializer.serialize_f32(*x),
            HeaderProp::Int(ref x) => serializer.serialize_i32(*x),
            HeaderProp::QWord(ref x) => serializer.collect_str(x),
            HeaderProp::Name(ref x) | HeaderProp::Str(ref x) => serializer.serialize_str(x),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn to_json<T: serde::Serialize>(input: &T) -> std::string::String {
        serde_json::to_string(input).unwrap()
    }

    #[test]
    fn serialize_header_array() {
        let data = vec![
            vec![
                (String::from("frame"), HeaderProp::Int(441)),
                (
                    String::from("PlayerName"),
                    HeaderProp::Str(String::from("rust is awesome")),
                ),
            ],
            vec![
                (String::from("frame"), HeaderProp::Int(1738)),
                (
                    String::from("PlayerName"),
                    HeaderProp::Str(String::from("rusty")),
                ),
            ],
        ];
        let actual = to_json(&HeaderProp::Array(data));
        assert!(actual.contains("\"PlayerName\":\"rust is awesome\""));
        assert!(actual.contains("\"PlayerName\":\"rusty\""));
        assert!(actual.contains("\"frame\":441"));
        assert!(actual.contains("\"frame\":1738"));
    }

    #[test]
    fn serialize_header_bool() {
        assert_eq!(to_json(&HeaderProp::Bool(false)), "false");
        assert_eq!(to_json(&HeaderProp::Bool(true)), "true");
    }

    #[test]
    fn serialize_header_numbers() {
        assert_eq!(
            to_json(&HeaderProp::Byte {
                kind: String::from("a"),
                value: Some(String::from("B"))
            }),
            r#"{"kind":"a","value":"B"}"#
        );
        assert_eq!(to_json(&HeaderProp::QWord(10)), "\"10\"");
        assert_eq!(to_json(&HeaderProp::Float(10.2)), "10.2");
        assert_eq!(to_json(&HeaderProp::Int(11)), "11");
    }

    #[test]
    fn serialize_header_str() {
        let val = "hello world";
        assert_eq!(
            to_json(&HeaderProp::Str(String::from(val))),
            "\"hello world\""
        );
        assert_eq!(
            to_json(&HeaderProp::Name(String::from(val))),
            "\"hello world\""
        );
    }
}
<|endoftext|>


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

#![stable]

//! Concurrency-enabled mechanisms for sharing mutable and/or immutable state
//! between tasks.

use core::atomic;
use core::clone::Clone;
use core::kinds::{Sync, Send};
use core::mem::{min_align_of, size_of, drop};
use core::mem;
use core::ops::{Drop, Deref};
use core::option::{Some, None, Option};
use core::ptr;
use core::ptr::RawPtr;
use heap::deallocate;

/// An atomically reference counted wrapper for shared state.
///
/// # Example
///
/// In this example, a large vector of floats is shared between several tasks.
/// With simple pipes, without `Arc`, a copy would have to be made for each
/// task.
///
/// ```rust
/// use std::sync::Arc;
///
/// fn main() {
///     let numbers = Vec::from_fn(100, |i| i as f32);
///     let shared_numbers = Arc::new(numbers);
///
///     for _ in range(0u, 10) {
///         let child_numbers = shared_numbers.clone();
///
///         spawn(proc() {
///             let local_numbers = child_numbers.as_slice();
///
///             // Work with the local numbers
///         });
///     }
/// }
/// ```
#[unsafe_no_drop_flag]
#[stable]
pub struct Arc<T> {
    // FIXME #12808: strange name to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut ArcInner<T>,
}

/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
#[unsafe_no_drop_flag]
#[experimental = "Weak pointers may not belong in this module."]
pub struct Weak<T> {
    // FIXME #12808: strange name to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut ArcInner<T>,
}

struct ArcInner<T> {
    strong: atomic::AtomicUint,
    weak: atomic::AtomicUint,
    data: T,
}

impl<T: Sync + Send> Arc<T> {
    /// Creates an atomically reference counted wrapper.
    #[inline]
    #[stable]
    pub fn new(data: T) -> Arc<T> {
        // Start the weak pointer count as 1 which is the weak pointer that's
        // held by all the strong pointers (kinda), see std/rc.rs for more info
        let x = box ArcInner {
            strong: atomic::AtomicUint::new(1),
            weak: atomic::AtomicUint::new(1),
            data: data,
        };
        Arc { _ptr: unsafe { mem::transmute(x) } }
    }

    #[inline]
    fn inner(&self) -> &ArcInner<T> {
        // This unsafety is ok because while this arc is alive we're guaranteed
        // that the inner pointer is valid. Furthermore, we know that the
        // `ArcInner` structure itself is `Sync` because the inner data is
        // `Sync` as well, so we're ok loaning out an immutable pointer to
        // these contents.
        unsafe { &*self._ptr }
    }

    /// Downgrades a strong pointer to a weak pointer.
    ///
    /// Weak pointers will not keep the data alive. Once all strong references
    /// to the underlying data have been dropped, the data itself will be
    /// destroyed.
    #[experimental = "Weak pointers may not belong in this module."]
    pub fn downgrade(&self) -> Weak<T> {
        // See the clone() impl for why this is relaxed
        self.inner().weak.fetch_add(1, atomic::Relaxed);
        Weak { _ptr: self._ptr }
    }
}

#[unstable = "waiting on stability of Clone"]
impl<T: Sync + Send> Clone for Arc<T> {
    /// Duplicate an atomically reference counted wrapper.
    ///
    /// The resulting two `Arc` objects will point to the same underlying data
    /// object. However, one of the `Arc` objects can be sent to another task,
    /// allowing them to share the underlying data.
    #[inline]
    fn clone(&self) -> Arc<T> {
        // Using a relaxed ordering is alright here, as knowledge of the
        // original reference prevents other threads from erroneously deleting
        // the object.
        //
        // As explained in the [Boost documentation][1], Increasing the
        // reference counter can always be done with memory_order_relaxed: New
        // references to an object can only be formed from an existing
        // reference, and passing an existing reference from one thread to
        // another must already provide any required synchronization.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        self.inner().strong.fetch_add(1, atomic::Relaxed);
        Arc { _ptr: self._ptr }
    }
}

#[experimental = "Deref is experimental."]
impl<T: Send + Sync> Deref<T> for Arc<T> {
    #[inline]
    fn deref(&self) -> &T {
        &self.inner().data
    }
}

impl<T: Send + Sync + Clone> Arc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique(&mut self) -> &mut T {
        // Note that we hold a strong reference, which also counts as
        // a weak reference, so we only clone if there is an
        // additional reference of either kind.
        if self.inner().strong.load(atomic::SeqCst) != 1 ||
           self.inner().weak.load(atomic::SeqCst) != 1 {
            *self = Arc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Arc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        let inner = unsafe { &mut *self._ptr };
        &mut inner.data
    }
}

#[unsafe_destructor]
#[experimental = "waiting on stability of Drop"]
impl<T: Sync + Send> Drop for Arc<T> {
    fn drop(&mut self) {
        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
        // more than once (but it is guaranteed to be zeroed after the first if
        // it's run more than once)
        if self._ptr.is_null() { return }

        // Because `fetch_sub` is already atomic, we do not need to synchronize
        // with other threads unless we are going to delete the object. This
        // same logic applies to the below `fetch_sub` to the `weak` count.
        if self.inner().strong.fetch_sub(1, atomic::Release) != 1 { return }

        // This fence is needed to prevent reordering of use of the data and
        // deletion of the data. Because it is marked `Release`, the
        // decreasing of the reference count synchronizes with this `Acquire`
        // fence. This means that use of the data happens before decreasing
        // the reference count, which happens before this fence, which
        // happens before the deletion of the data.
        //
        // As explained in the [Boost documentation][1],
        //
        // It is important to enforce any possible access to the object in
        // one thread (through an existing reference) to *happen before*
        // deleting the object in a different thread. This is achieved by a
        // "release" operation after dropping a reference (any access to the
        // object through this reference must obviously happened before),
        // and an "acquire" operation before deleting the object.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        atomic::fence(atomic::Acquire);

        // Destroy the data at this time, even though we may not free the box
        // allocation itself (there may still be weak pointers lying around).
        unsafe { drop(ptr::read(&self.inner().data)); }

        if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
            atomic::fence(atomic::Acquire);
            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
                                min_align_of::<ArcInner<T>>()) }
        }
    }
}

#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Weak<T> {
    /// Attempts to upgrade this weak reference to a strong reference.
    ///
    /// This method will fail to upgrade this reference if the strong reference
    /// count has already reached 0, but if there are still other active strong
    /// references this function will return a new strong reference to the data.
    pub fn upgrade(&self) -> Option<Arc<T>> {
        // We use a CAS loop to increment the strong count instead of a
        // fetch_add because once the count hits 0 is must never be above 0.
        let inner = self.inner();
        loop {
            let n = inner.strong.load(atomic::SeqCst);
            if n == 0 { return None }
            let old = inner.strong.compare_and_swap(n, n + 1, atomic::SeqCst);
            if old == n { return Some(Arc { _ptr: self._ptr }) }
        }
    }

    #[inline]
    fn inner(&self) -> &ArcInner<T> {
        // See comments above for why this is "safe"
        unsafe { &*self._ptr }
    }
}

#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        // See comments in Arc::clone() for why this is relaxed
        self.inner().weak.fetch_add(1, atomic::Relaxed);
        Weak { _ptr: self._ptr }
    }
}

#[unsafe_destructor]
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Drop for Weak<T> {
    fn drop(&mut self) {
        // see comments above for why this check is here
        if self._ptr.is_null() { return }

        // If we find out that we were the last weak pointer, then its time to
        // deallocate the data entirely. See the discussion in Arc::drop() about
        // the memory orderings
        if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
            atomic::fence(atomic::Acquire);
            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
                                min_align_of::<ArcInner<T>>()) }
        }
    }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use std::clone::Clone;
    use std::comm::channel;
    use std::mem::drop;
    use std::ops::Drop;
    use std::option::{Option, Some, None};
    use std::sync::atomic;
    use std::task;
    use std::vec::Vec;
    use super::{Arc, Weak};
    use std::sync::Mutex;

    struct Canary(*mut atomic::AtomicUint);

    impl Drop for Canary
    {
        fn drop(&mut self) {
            unsafe {
                match *self {
                    Canary(c) => {
                        (*c).fetch_add(1, atomic::SeqCst);
                    }
                }
            }
        }
    }

    #[test]
    fn manually_share_arc() {
        let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        let arc_v = Arc::new(v);

        let (tx, rx) = channel();

        task::spawn(proc() {
            let arc_v: Arc<Vec<int>> = rx.recv();
            assert_eq!((*arc_v)[3], 4);
        });

        tx.send(arc_v.clone());

        assert_eq!((*arc_v)[2], 3);
        assert_eq!((*arc_v)[4], 5);

        info!("{:?}", arc_v);
    }

    #[test]
    fn test_cowarc_clone_make_unique() {
        let mut cow0 = Arc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowarc_clone_unique2() {
        let mut cow0 = Arc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_cowarc_clone_weak() {
        let mut cow0 = Arc::new(75u);
        let cow1_weak = cow0.downgrade();

        assert!(75 == *cow0);
        assert!(75 == *cow1_weak.upgrade().unwrap());

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(cow1_weak.upgrade().is_none());
    }

    #[test]
    fn test_live() {
        let x = Arc::new(5i);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Arc::new(5i);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: Mutex<Option<Weak<Cycle>>>
        }

        let a = Arc::new(Cycle { x: Mutex::new(None) });
        let b = a.clone().downgrade();
        *a.x.lock() = Some(b);

        // hopefully we don't double-free (or leak)...
    }

    #[test]
    fn drop_arc() {
        let mut canary = atomic::AtomicUint::new(0);
        let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
        drop(x);
        assert!(canary.load(atomic::Acquire) == 1);
    }

    #[test]
    fn drop_arc_weak() {
        let mut canary = atomic::AtomicUint::new(0);
        let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
        let arc_weak = arc.downgrade();
        assert!(canary.load(atomic::Acquire) == 0);
        drop(arc);
        assert!(canary.load(atomic::Acquire) == 1);
        drop(arc_weak);
    }
}
<commit_msg>liballoc: Remove all uses of {:?}.<commit_after>// Copyright 2012-2014 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.

#![stable]

//! Concurrency-enabled mechanisms for sharing mutable and/or immutable state
//! between tasks.

use core::atomic;
use core::clone::Clone;
use core::kinds::{Sync, Send};
use core::mem::{min_align_of, size_of, drop};
use core::mem;
use core::ops::{Drop, Deref};
use core::option::{Some, None, Option};
use core::ptr;
use core::ptr::RawPtr;
use heap::deallocate;

/// An atomically reference counted wrapper for shared state.
///
/// # Example
///
/// In this example, a large vector of floats is shared between several tasks.
/// With simple pipes, without `Arc`, a copy would have to be made for each
/// task.
///
/// ```rust
/// use std::sync::Arc;
///
/// fn main() {
///     let numbers = Vec::from_fn(100, |i| i as f32);
///     let shared_numbers = Arc::new(numbers);
///
///     for _ in range(0u, 10) {
///         let child_numbers = shared_numbers.clone();
///
///         spawn(proc() {
///             let local_numbers = child_numbers.as_slice();
///
///             // Work with the local numbers
///         });
///     }
/// }
/// ```
#[unsafe_no_drop_flag]
#[stable]
pub struct Arc<T> {
    // FIXME #12808: strange name to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut ArcInner<T>,
}

/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
#[unsafe_no_drop_flag]
#[experimental = "Weak pointers may not belong in this module."]
pub struct Weak<T> {
    // FIXME #12808: strange name to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut ArcInner<T>,
}

struct ArcInner<T> {
    strong: atomic::AtomicUint,
    weak: atomic::AtomicUint,
    data: T,
}

impl<T: Sync + Send> Arc<T> {
    /// Creates an atomically reference counted wrapper.
    #[inline]
    #[stable]
    pub fn new(data: T) -> Arc<T> {
        // Start the weak pointer count as 1 which is the weak pointer that's
        // held by all the strong pointers (kinda), see std/rc.rs for more info
        let x = box ArcInner {
            strong: atomic::AtomicUint::new(1),
            weak: atomic::AtomicUint::new(1),
            data: data,
        };
        Arc { _ptr: unsafe { mem::transmute(x) } }
    }

    #[inline]
    fn inner(&self) -> &ArcInner<T> {
        // This unsafety is ok because while this arc is alive we're guaranteed
        // that the inner pointer is valid. Furthermore, we know that the
        // `ArcInner` structure itself is `Sync` because the inner data is
        // `Sync` as well, so we're ok loaning out an immutable pointer to
        // these contents.
        unsafe { &*self._ptr }
    }

    /// Downgrades a strong pointer to a weak pointer.
    ///
    /// Weak pointers will not keep the data alive. Once all strong references
    /// to the underlying data have been dropped, the data itself will be
    /// destroyed.
    #[experimental = "Weak pointers may not belong in this module."]
    pub fn downgrade(&self) -> Weak<T> {
        // See the clone() impl for why this is relaxed
        self.inner().weak.fetch_add(1, atomic::Relaxed);
        Weak { _ptr: self._ptr }
    }
}

#[unstable = "waiting on stability of Clone"]
impl<T: Sync + Send> Clone for Arc<T> {
    /// Duplicate an atomically reference counted wrapper.
    ///
    /// The resulting two `Arc` objects will point to the same underlying data
    /// object. However, one of the `Arc` objects can be sent to another task,
    /// allowing them to share the underlying data.
    #[inline]
    fn clone(&self) -> Arc<T> {
        // Using a relaxed ordering is alright here, as knowledge of the
        // original reference prevents other threads from erroneously deleting
        // the object.
        //
        // As explained in the [Boost documentation][1], Increasing the
        // reference counter can always be done with memory_order_relaxed: New
        // references to an object can only be formed from an existing
        // reference, and passing an existing reference from one thread to
        // another must already provide any required synchronization.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        self.inner().strong.fetch_add(1, atomic::Relaxed);
        Arc { _ptr: self._ptr }
    }
}

#[experimental = "Deref is experimental."]
impl<T: Send + Sync> Deref<T> for Arc<T> {
    #[inline]
    fn deref(&self) -> &T {
        &self.inner().data
    }
}

impl<T: Send + Sync + Clone> Arc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique(&mut self) -> &mut T {
        // Note that we hold a strong reference, which also counts as
        // a weak reference, so we only clone if there is an
        // additional reference of either kind.
        if self.inner().strong.load(atomic::SeqCst) != 1 ||
           self.inner().weak.load(atomic::SeqCst) != 1 {
            *self = Arc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Arc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        let inner = unsafe { &mut *self._ptr };
        &mut inner.data
    }
}

#[unsafe_destructor]
#[experimental = "waiting on stability of Drop"]
impl<T: Sync + Send> Drop for Arc<T> {
    fn drop(&mut self) {
        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
        // more than once (but it is guaranteed to be zeroed after the first if
        // it's run more than once)
        if self._ptr.is_null() { return }

        // Because `fetch_sub` is already atomic, we do not need to synchronize
        // with other threads unless we are going to delete the object. This
        // same logic applies to the below `fetch_sub` to the `weak` count.
        if self.inner().strong.fetch_sub(1, atomic::Release) != 1 { return }

        // This fence is needed to prevent reordering of use of the data and
        // deletion of the data. Because it is marked `Release`, the
        // decreasing of the reference count synchronizes with this `Acquire`
        // fence. This means that use of the data happens before decreasing
        // the reference count, which happens before this fence, which
        // happens before the deletion of the data.
        //
        // As explained in the [Boost documentation][1],
        //
        // It is important to enforce any possible access to the object in
        // one thread (through an existing reference) to *happen before*
        // deleting the object in a different thread. This is achieved by a
        // "release" operation after dropping a reference (any access to the
        // object through this reference must obviously happened before),
        // and an "acquire" operation before deleting the object.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        atomic::fence(atomic::Acquire);

        // Destroy the data at this time, even though we may not free the box
        // allocation itself (there may still be weak pointers lying around).
        unsafe { drop(ptr::read(&self.inner().data)); }

        if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
            atomic::fence(atomic::Acquire);
            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
                                min_align_of::<ArcInner<T>>()) }
        }
    }
}

#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Weak<T> {
    /// Attempts to upgrade this weak reference to a strong reference.
    ///
    /// This method will fail to upgrade this reference if the strong reference
    /// count has already reached 0, but if there are still other active strong
    /// references this function will return a new strong reference to the data.
    pub fn upgrade(&self) -> Option<Arc<T>> {
        // We use a CAS loop to increment the strong count instead of a
        // fetch_add because once the count hits 0 is must never be above 0.
        let inner = self.inner();
        loop {
            let n = inner.strong.load(atomic::SeqCst);
            if n == 0 { return None }
            let old = inner.strong.compare_and_swap(n, n + 1, atomic::SeqCst);
            if old == n { return Some(Arc { _ptr: self._ptr }) }
        }
    }

    #[inline]
    fn inner(&self) -> &ArcInner<T> {
        // See comments above for why this is "safe"
        unsafe { &*self._ptr }
    }
}

#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        // See comments in Arc::clone() for why this is relaxed
        self.inner().weak.fetch_add(1, atomic::Relaxed);
        Weak { _ptr: self._ptr }
    }
}

#[unsafe_destructor]
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Sync + Send> Drop for Weak<T> {
    fn drop(&mut self) {
        // see comments above for why this check is here
        if self._ptr.is_null() { return }

        // If we find out that we were the last weak pointer, then its time to
        // deallocate the data entirely. See the discussion in Arc::drop() about
        // the memory orderings
        if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
            atomic::fence(atomic::Acquire);
            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
                                min_align_of::<ArcInner<T>>()) }
        }
    }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use std::clone::Clone;
    use std::comm::channel;
    use std::mem::drop;
    use std::ops::Drop;
    use std::option::{Option, Some, None};
    use std::sync::atomic;
    use std::task;
    use std::vec::Vec;
    use super::{Arc, Weak};
    use std::sync::Mutex;

    struct Canary(*mut atomic::AtomicUint);

    impl Drop for Canary
    {
        fn drop(&mut self) {
            unsafe {
                match *self {
                    Canary(c) => {
                        (*c).fetch_add(1, atomic::SeqCst);
                    }
                }
            }
        }
    }

    #[test]
    fn manually_share_arc() {
        let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        let arc_v = Arc::new(v);

        let (tx, rx) = channel();

        task::spawn(proc() {
            let arc_v: Arc<Vec<int>> = rx.recv();
            assert_eq!((*arc_v)[3], 4);
        });

        tx.send(arc_v.clone());

        assert_eq!((*arc_v)[2], 3);
        assert_eq!((*arc_v)[4], 5);
    }

    #[test]
    fn test_cowarc_clone_make_unique() {
        let mut cow0 = Arc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowarc_clone_unique2() {
        let mut cow0 = Arc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_cowarc_clone_weak() {
        let mut cow0 = Arc::new(75u);
        let cow1_weak = cow0.downgrade();

        assert!(75 == *cow0);
        assert!(75 == *cow1_weak.upgrade().unwrap());

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(cow1_weak.upgrade().is_none());
    }

    #[test]
    fn test_live() {
        let x = Arc::new(5i);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Arc::new(5i);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: Mutex<Option<Weak<Cycle>>>
        }

        let a = Arc::new(Cycle { x: Mutex::new(None) });
        let b = a.clone().downgrade();
        *a.x.lock() = Some(b);

        // hopefully we don't double-free (or leak)...
    }

    #[test]
    fn drop_arc() {
        let mut canary = atomic::AtomicUint::new(0);
        let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
        drop(x);
        assert!(canary.load(atomic::Acquire) == 1);
    }

    #[test]
    fn drop_arc_weak() {
        let mut canary = atomic::AtomicUint::new(0);
        let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUint));
        let arc_weak = arc.downgrade();
        assert!(canary.load(atomic::Acquire) == 0);
        drop(arc);
        assert!(canary.load(atomic::Acquire) == 1);
        drop(arc_weak);
    }
}
<|endoftext|>


<commit_before>// Dynamic Vector
//
// A growable vector that makes use of unique pointers so that the
// result can be sent between tasks and so forth.
//
// Note that recursive use is not permitted.

import dvec_iter::extensions;
import unsafe::reinterpret_cast;
import ptr::{null, extensions};

export dvec;
export from_vec;
export extensions;
export unwrap;

#[doc = "

A growable, modifiable vector type that accumulates elements into a
unique vector.

# Limitations on recursive use

This class works by swapping the unique vector out of the data
structure whenever it is to be used.  Therefore, recursive use is not
permitted.  That is, while iterating through a vector, you cannot
access the vector in any other way or else the program will fail.  If
you wish, you can use the `swap()` method to gain access to the raw
vector and transform it or use it any way you like.  Eventually, we
may permit read-only access during iteration or other use.

# WARNING

For maximum performance, this type is implemented using some rather
unsafe code.  In particular, this innocent looking `[mut A]` pointer
*may be null!*  Therefore, it is important you not reach into the
data structure manually but instead use the provided extensions.

The reason that I did not use an unsafe pointer in the structure
itself is that I wanted to ensure that the vector would be freed when
the dvec is dropped.  The reason that I did not use an `option<T>`
instead of a nullable pointer is that I found experimentally that it
becomes approximately 50% slower. This can probably be improved
through optimization.  You can run your own experiments using
`src/test/bench/vec-append.rs`. My own tests found that using null
pointers achieved about 103 million pushes/second.  Using an option
type could only produce 47 million pushes/second.

"]
type dvec<A> = {

    mut data: [mut A]
};

#[doc = "Creates a new, empty dvec"]
fn dvec<A>() -> dvec<A> {
    {mut data: [mut]}
}

#[doc = "Creates a new dvec with a single element"]
fn from_elt<A>(+e: A) -> dvec<A> {
    {mut data: [mut e]}
}

#[doc = "Creates a new dvec with the contents of a vector"]
fn from_vec<A>(+v: [mut A]) -> dvec<A> {
    {mut data: v}
}

#[doc = "Consumes the vector and returns its contents"]
fn unwrap<A>(-d: dvec<A>) -> [mut A] {
    let {data: v} <- d;
    ret v;
}

impl private_methods<A> for dvec<A> {
    fn check_not_borrowed() {
        unsafe {
            let data: *() = unsafe::reinterpret_cast(self.data);
            if data.is_null() {
                fail "Recursive use of dvec";
            }
        }
    }

    #[inline(always)]
    fn borrow<B>(f: fn(-[mut A]) -> B) -> B {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            ret f(data);
        }
    }

    #[inline(always)]
    fn return(-data: [mut A]) {
        unsafe {
            self.data <- data;
        }
    }
}

// In theory, most everything should work with any A, but in practice
// almost nothing works without the copy bound due to limitations
// around closures.
impl extensions<A> for dvec<A> {
    #[doc = "

    Swaps out the current vector and hands it off to a user-provided
    function `f`.  The function should transform it however is desired
    and return a new vector to replace it with.

    "]
    fn swap(f: fn(-[mut A]) -> [mut A]) {
        self.borrow { |v| self.return(f(v)) }
    }

    #[doc = "Returns the number of elements currently in the dvec"]
    fn len() -> uint {
        self.borrow { |v|
            let l = v.len();
            self.return(v);
            l
        }
    }

    #[doc = "Overwrite the current contents"]
    fn set(+w: [mut A]) {
        self.check_not_borrowed();
        self.data <- w; //FIXME check for recursive use (#2607)
    }
}

impl extensions<A:copy> for dvec<A> {
    #[doc = "Append a single item to the end of the list"]
    fn push(t: A) {
        self.swap { |v|
            let mut v <- v; v += [t]; v // more efficient than v + [t]
        }
    }

    #[doc = "Remove and return the last element"]
    fn pop() -> A {
        self.borrow { |v|
            let mut v <- v;
            let result = vec::pop(v);
            self.return(v);
            result
        }
    }

    #[doc = "
        Append all elements of a vector to the end of the list

        Equivalent to `append_iter()` but potentially more efficient.
    "]
    fn push_all(ts: [const A]/&) {
        self.push_slice(ts, 0u, vec::len(ts));
    }

    #[doc = "
        Appends elements from `from_idx` to `to_idx` (exclusive)
    "]
    fn push_slice(ts: [const A]/&, from_idx: uint, to_idx: uint) {
        self.swap { |v|
            let mut v <- v;
            let new_len = vec::len(v) + to_idx - from_idx;
            vec::reserve(v, new_len);
            let mut i = from_idx;
            while i < to_idx {
                v += [ts[i]];
                i += 1u;
            }
            v
        }
    }

    #[doc = "
        Append all elements of an iterable.

        Failure will occur if the iterable's `each()` method
        attempts to access this vector.
    "]
    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
       self.swap { |v|
           let mut v = alt ts.size_hint() {
             none { v }
             some(h) {
               let len = v.len() + h;
               let mut v <- v;
               vec::reserve(v, len);
               v
            }
           };

           for ts.each { |t| v += [t] };
           v
        }
    }

    #[doc = "
        Gets a copy of the current contents.

        See `unwrap()` if you do not wish to copy the contents.
    "]
    fn get() -> [A] {
        self.borrow { |v|
            let w = vec::from_mut(copy v);
            self.return(v);
            w
        }
    }

    #[doc = "Remove and return the first element"]
    fn shift() -> A {
        self.borrow { |v|
            let mut v = vec::from_mut(v);
            let result = vec::shift(v);
            self.return(vec::to_mut(v));
            result
        }
    }

    #[doc = "Copy out an individual element"]
    #[inline(always)]
    fn [](idx: uint) -> A {
        self.get_elt(idx)
    }

    #[doc = "Copy out an individual element"]
    #[inline(always)]
    fn get_elt(idx: uint) -> A {
        self.check_not_borrowed();
        ret self.data[idx];
    }

    #[doc = "Overwrites the contents of the element at `idx` with `a`"]
    fn set_elt(idx: uint, a: A) {
        self.check_not_borrowed();
        self.data[idx] = a;
    }

    #[doc = "Overwrites the contents of the element at `idx` with `a`,
    growing the vector if necessary.  New elements will be initialized
    with `initval`"]
    fn grow_set_elt(idx: uint, initval: A, val: A) {
        self.swap { |v|
            let mut v <- v;
            vec::grow_set(v, idx, initval, val);
            v
        }
    }

    #[doc = "Returns the last element, failing if the vector is empty"]
    fn last() -> A {
        self.get_elt(self.len() - 1u)
    }
}<commit_msg>remove irrelevant fixme (#2607)<commit_after>// Dynamic Vector
//
// A growable vector that makes use of unique pointers so that the
// result can be sent between tasks and so forth.
//
// Note that recursive use is not permitted.

import dvec_iter::extensions;
import unsafe::reinterpret_cast;
import ptr::{null, extensions};

export dvec;
export from_vec;
export extensions;
export unwrap;

#[doc = "

A growable, modifiable vector type that accumulates elements into a
unique vector.

# Limitations on recursive use

This class works by swapping the unique vector out of the data
structure whenever it is to be used.  Therefore, recursive use is not
permitted.  That is, while iterating through a vector, you cannot
access the vector in any other way or else the program will fail.  If
you wish, you can use the `swap()` method to gain access to the raw
vector and transform it or use it any way you like.  Eventually, we
may permit read-only access during iteration or other use.

# WARNING

For maximum performance, this type is implemented using some rather
unsafe code.  In particular, this innocent looking `[mut A]` pointer
*may be null!*  Therefore, it is important you not reach into the
data structure manually but instead use the provided extensions.

The reason that I did not use an unsafe pointer in the structure
itself is that I wanted to ensure that the vector would be freed when
the dvec is dropped.  The reason that I did not use an `option<T>`
instead of a nullable pointer is that I found experimentally that it
becomes approximately 50% slower. This can probably be improved
through optimization.  You can run your own experiments using
`src/test/bench/vec-append.rs`. My own tests found that using null
pointers achieved about 103 million pushes/second.  Using an option
type could only produce 47 million pushes/second.

"]
type dvec<A> = {

    mut data: [mut A]
};

#[doc = "Creates a new, empty dvec"]
fn dvec<A>() -> dvec<A> {
    {mut data: [mut]}
}

#[doc = "Creates a new dvec with a single element"]
fn from_elt<A>(+e: A) -> dvec<A> {
    {mut data: [mut e]}
}

#[doc = "Creates a new dvec with the contents of a vector"]
fn from_vec<A>(+v: [mut A]) -> dvec<A> {
    {mut data: v}
}

#[doc = "Consumes the vector and returns its contents"]
fn unwrap<A>(-d: dvec<A>) -> [mut A] {
    let {data: v} <- d;
    ret v;
}

impl private_methods<A> for dvec<A> {
    fn check_not_borrowed() {
        unsafe {
            let data: *() = unsafe::reinterpret_cast(self.data);
            if data.is_null() {
                fail "Recursive use of dvec";
            }
        }
    }

    #[inline(always)]
    fn borrow<B>(f: fn(-[mut A]) -> B) -> B {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            ret f(data);
        }
    }

    #[inline(always)]
    fn return(-data: [mut A]) {
        unsafe {
            self.data <- data;
        }
    }
}

// In theory, most everything should work with any A, but in practice
// almost nothing works without the copy bound due to limitations
// around closures.
impl extensions<A> for dvec<A> {
    #[doc = "

    Swaps out the current vector and hands it off to a user-provided
    function `f`.  The function should transform it however is desired
    and return a new vector to replace it with.

    "]
    fn swap(f: fn(-[mut A]) -> [mut A]) {
        self.borrow { |v| self.return(f(v)) }
    }

    #[doc = "Returns the number of elements currently in the dvec"]
    fn len() -> uint {
        self.borrow { |v|
            let l = v.len();
            self.return(v);
            l
        }
    }

    #[doc = "Overwrite the current contents"]
    fn set(+w: [mut A]) {
        self.check_not_borrowed();
        self.data <- w;
    }
}

impl extensions<A:copy> for dvec<A> {
    #[doc = "Append a single item to the end of the list"]
    fn push(t: A) {
        self.swap { |v|
            let mut v <- v; v += [t]; v // more efficient than v + [t]
        }
    }

    #[doc = "Remove and return the last element"]
    fn pop() -> A {
        self.borrow { |v|
            let mut v <- v;
            let result = vec::pop(v);
            self.return(v);
            result
        }
    }

    #[doc = "
        Append all elements of a vector to the end of the list

        Equivalent to `append_iter()` but potentially more efficient.
    "]
    fn push_all(ts: [const A]/&) {
        self.push_slice(ts, 0u, vec::len(ts));
    }

    #[doc = "
        Appends elements from `from_idx` to `to_idx` (exclusive)
    "]
    fn push_slice(ts: [const A]/&, from_idx: uint, to_idx: uint) {
        self.swap { |v|
            let mut v <- v;
            let new_len = vec::len(v) + to_idx - from_idx;
            vec::reserve(v, new_len);
            let mut i = from_idx;
            while i < to_idx {
                v += [ts[i]];
                i += 1u;
            }
            v
        }
    }

    #[doc = "
        Append all elements of an iterable.

        Failure will occur if the iterable's `each()` method
        attempts to access this vector.
    "]
    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
       self.swap { |v|
           let mut v = alt ts.size_hint() {
             none { v }
             some(h) {
               let len = v.len() + h;
               let mut v <- v;
               vec::reserve(v, len);
               v
            }
           };

           for ts.each { |t| v += [t] };
           v
        }
    }

    #[doc = "
        Gets a copy of the current contents.

        See `unwrap()` if you do not wish to copy the contents.
    "]
    fn get() -> [A] {
        self.borrow { |v|
            let w = vec::from_mut(copy v);
            self.return(v);
            w
        }
    }

    #[doc = "Remove and return the first element"]
    fn shift() -> A {
        self.borrow { |v|
            let mut v = vec::from_mut(v);
            let result = vec::shift(v);
            self.return(vec::to_mut(v));
            result
        }
    }

    #[doc = "Copy out an individual element"]
    #[inline(always)]
    fn [](idx: uint) -> A {
        self.get_elt(idx)
    }

    #[doc = "Copy out an individual element"]
    #[inline(always)]
    fn get_elt(idx: uint) -> A {
        self.check_not_borrowed();
        ret self.data[idx];
    }

    #[doc = "Overwrites the contents of the element at `idx` with `a`"]
    fn set_elt(idx: uint, a: A) {
        self.check_not_borrowed();
        self.data[idx] = a;
    }

    #[doc = "Overwrites the contents of the element at `idx` with `a`,
    growing the vector if necessary.  New elements will be initialized
    with `initval`"]
    fn grow_set_elt(idx: uint, initval: A, val: A) {
        self.swap { |v|
            let mut v <- v;
            vec::grow_set(v, idx, initval, val);
            v
        }
    }

    #[doc = "Returns the last element, failing if the vector is empty"]
    fn last() -> A {
        self.get_elt(self.len() - 1u)
    }
}<|endoftext|>


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

/*! Composable internal iterators

Internal iterators are functions implementing the protocol used by the `for` loop.

An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:

~~~~
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~~

An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:

~~~~
use core::iterator::*;

let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for it.advance |&x: &uint| {
    println(x.to_str());
}
~~~~

Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.

*/

#[cfg(not(stage0))] use cmp::Ord;
#[cfg(not(stage0))] use option::{Option, Some, None};
#[cfg(not(stage0))] use vec::OwnedVector;

#[cfg(stage0)]
pub trait Times {
    fn times(&self, it: &fn() -> bool);
}
#[cfg(not(stage0))]
pub trait Times {
    fn times(&self, it: &fn() -> bool) -> bool;
}

/**
 * Transform an internal iterator into an owned vector.
 *
 * # Example:
 *
 * ~~~
 * let xs = ~[1, 2, 3];
 * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
 * assert_eq!(xs, ys);
 * ~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
    let mut v = ~[];
    for iter |x| { v.push(x) }
    v
}

/**
 * Return true if `predicate` is true for any values yielded by an internal iterator.
 *
 * Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5];
 * assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
 * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn any<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    for iter |x| {
        if predicate(x) {
            return true;
        }
    }
    return false;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(stage0)]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool)) -> bool {
    for iter |x| {
        if !predicate(x) {
            return false;
        }
    }
    return true;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    // If we ever break, iter will return false, so this will only return true
    // if predicate returns true for everything.
    iter(|x| predicate(x))
}

/**
 * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5, 6];
 * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn find<T>(predicate: &fn(&T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    for iter |x| {
        if predicate(&x) {
            return Some(x);
        }
    }
    None
}

/**
 * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x > *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x < *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

#[cfg(test)]
mod tests {
    use super::*;
    use prelude::*;

    #[test]
    fn test_to_vec() {
        let xs = ~[1, 2, 3];
        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
        assert_eq!(xs, ys);
    }

    #[test]
    fn test_any() {
        let xs = ~[1u, 2, 3, 4, 5];
        assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
        assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
    }

    #[test]
    fn test_all() {
        assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
        assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
    }

    #[test]
    fn test_find() {
        let xs = ~[1u, 2, 3, 4, 5, 6];
        assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
    }

    #[test]
    fn test_max() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
    }

    #[test]
    fn test_min() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
    }
}
<commit_msg>iter: add fold, sum and product<commit_after>// Copyright 2012-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.

/*! Composable internal iterators

Internal iterators are functions implementing the protocol used by the `for` loop.

An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:

~~~~
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~~

An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:

~~~~
use core::iterator::*;

let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for it.advance |&x: &uint| {
    println(x.to_str());
}
~~~~

Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.

*/

#[cfg(not(stage0))] use cmp::Ord;
#[cfg(not(stage0))] use option::{Option, Some, None};
#[cfg(not(stage0))] use vec::OwnedVector;
#[cfg(not(stage0))] use num::{One, Zero};
#[cfg(not(stage0))] use ops::{Add, Mul};

#[cfg(stage0)]
pub trait Times {
    fn times(&self, it: &fn() -> bool);
}
#[cfg(not(stage0))]
pub trait Times {
    fn times(&self, it: &fn() -> bool) -> bool;
}

/**
 * Transform an internal iterator into an owned vector.
 *
 * # Example:
 *
 * ~~~
 * let xs = ~[1, 2, 3];
 * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
 * assert_eq!(xs, ys);
 * ~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
    let mut v = ~[];
    for iter |x| { v.push(x) }
    v
}

/**
 * Return true if `predicate` is true for any values yielded by an internal iterator.
 *
 * Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5];
 * assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
 * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn any<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    for iter |x| {
        if predicate(x) {
            return true;
        }
    }
    return false;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(stage0)]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool)) -> bool {
    for iter |x| {
        if !predicate(x) {
            return false;
        }
    }
    return true;
}

/**
 * Return true if `predicate` is true for all values yielded by an internal iterator.
 *
 * # Example:
 *
 * ~~~~
 * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
 * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn all<T>(predicate: &fn(T) -> bool,
              iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
    // If we ever break, iter will return false, so this will only return true
    // if predicate returns true for everything.
    iter(|x| predicate(x))
}

/**
 * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[1u, 2, 3, 4, 5, 6];
 * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
 * ~~~~
 */
#[inline(always)]
#[cfg(not(stage0))]
pub fn find<T>(predicate: &fn(&T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    for iter |x| {
        if predicate(&x) {
            return Some(x);
        }
    }
    None
}

/**
 * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x > *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
 *
 * # Example:
 *
 * ~~~~
 * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
 * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
 * ~~~~
 */
#[inline]
#[cfg(not(stage0))]
pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
    let mut result = None;
    for iter |x| {
        match result {
            Some(ref mut y) => {
                if x < *y {
                    *y = x;
                }
            }
            None => result = Some(x)
        }
    }
    result
}

/**
 * Reduce an iterator to an accumulated value.
 *
 * # Example:
 *
 * ~~~~
 * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline]
pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
    let mut result = start;
    for iter |x| {
        f(&mut result, x);
    }
    result
}

/**
 * Reduce an iterator to an accumulated value.
 *
 * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
 * forces the iterator to yield borrowed pointers.
 *
 * # Example:
 *
 * ~~~~
 * fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
 *     fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
 * }
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline]
pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
    let mut result = start;
    for iter |x| {
        f(&mut result, x);
    }
    result
}

/**
 * Return the sum of the items yielding by an iterator.
 *
 * # Example:
 *
 * ~~~~
 * let xs: ~[int] = ~[1, 2, 3, 4];
 * assert_eq!(do sum |f| { xs.each(f) }, 10);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline(always)]
pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
    fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
}

/**
 * Return the product of the items yielded by an iterator.
 *
 * # Example:
 *
 * ~~~~
 * let xs: ~[int] = ~[1, 2, 3, 4];
 * assert_eq!(do product |f| { xs.each(f) }, 24);
 * ~~~~
 */
#[cfg(not(stage0))]
#[inline(always)]
pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
    fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
}

#[cfg(test)]
mod tests {
    use super::*;
    use prelude::*;

    #[test]
    fn test_to_vec() {
        let xs = ~[1, 2, 3];
        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
        assert_eq!(xs, ys);
    }

    #[test]
    fn test_any() {
        let xs = ~[1u, 2, 3, 4, 5];
        assert!(any(|&x: &uint| x > 2, |f| xs.each(f)));
        assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
    }

    #[test]
    fn test_all() {
        assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
        assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
    }

    #[test]
    fn test_find() {
        let xs = ~[1u, 2, 3, 4, 5, 6];
        assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
    }

    #[test]
    fn test_max() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
    }

    #[test]
    fn test_min() {
        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
        assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
    }

    #[test]
    fn test_fold() {
        assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
    }

    #[test]
    fn test_sum() {
        let xs: ~[int] = ~[1, 2, 3, 4];
        assert_eq!(do sum |f| { xs.each(f) }, 10);
    }

    #[test]
    fn test_empty_sum() {
        let xs: ~[int] = ~[];
        assert_eq!(do sum |f| { xs.each(f) }, 0);
    }

    #[test]
    fn test_product() {
        let xs: ~[int] = ~[1, 2, 3, 4];
        assert_eq!(do product |f| { xs.each(f) }, 24);
    }

    #[test]
    fn test_empty_product() {
        let xs: ~[int] = ~[];
        assert_eq!(do product |f| { xs.each(f) }, 1);
    }
}
<|endoftext|>