<commit_before>/*!
 * 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.
 */

/// The option type
enum option<T> {
    none,
    some(T),
}

pure fn get<T: copy>(opt: option<T>) -> T {
    /*!
     * Gets the value out of an option
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */

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

pure fn expect<T: copy>(opt: option<T>, reason: ~str) -> T {
    #[doc = "
    Gets the value out of an option, printing a specified message on failure

    # Failure

    Fails if the value equals `none`
    "];
    match opt { some(x) => x, none => fail reason }
}

pure fn map<T, U>(opt: option<T>, f: fn(T) -> U) -> option<U> {
    //! Maps a `some` value from one type to another

    match opt { some(x) => some(f(x)), none => none }
}

pure fn map_ref<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 }
}

pure fn map_consume<T, U>(+opt: option<T>, f: fn(+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(opt))) } else { none }
}

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

    match opt { some(x) => f(x), none => none }
}

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 }
}

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

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

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

    match opt { none => true, some(_) => false }
}

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

    !is_none(opt)
}

pure fn get_default<T: copy>(opt: option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { some(x) => x, none => def }
}

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

    match opt { none => def, some(t) => f(t) }
}

// This should replace map_default.
pure fn map_default_ref<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 => def, some(ref t) => f(t) }
}

// This should change to by-copy mode; use iter_ref below for by reference
pure fn iter<T>(opt: option<T>, f: fn(T)) {
    //! Performs an operation on the contained value or does nothing

    match opt { none => (), some(t) => f(t) }
}

pure fn iter_ref<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)]
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.
     */

    unsafe {
        let addr = match opt {
          some(x) => ptr::addr_of(x),
          none => fail ~"option::unwrap none"
        };
        let liberated_value = unsafe::reinterpret_cast(*addr);
        unsafe::forget(opt);
        return liberated_value;
    }
}

/// The ubiquitous option dance.
#[inline(always)]
fn swap_unwrap<T>(opt: &mut option<T>) -> T {
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, none))
}

pure fn unwrap_expect<T>(+opt: option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    if opt.is_none() { fail reason.to_unique(); }
    unwrap(opt)
}

// Some of these should change to be &option<T>, some should not. See below.
impl<T> option<T> {
    /**
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */
    pure fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
    /// Applies a function to the contained value or returns a default
    pure fn map_default<U>(+def: U, f: fn(T) -> U) -> U
        { map_default(self, def, f) }
    /// Performs an operation on the contained value or does nothing
    pure fn iter(f: fn(T)) { iter(self, f) }
    /// Returns true if the option equals `none`
    pure fn is_none() -> bool { is_none(self) }
    /// Returns true if the option contains some value
    pure fn is_some() -> bool { is_some(self) }
    /// Maps a `some` value from one type to another
    pure fn map<U>(f: fn(T) -> U) -> option<U> { map(self, f) }
}

impl<T> &option<T> {
    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    pure fn chain_ref<U>(f: fn(x: &T) -> option<U>) -> option<U> {
        chain_ref(self, f)
    }
    /// Applies a function to the contained value or returns a default
    pure fn map_default_ref<U>(+def: U, f: fn(x: &T) -> U) -> U
        { map_default_ref(self, def, f) }
    /// Performs an operation on the contained value by reference
    pure fn iter_ref(f: fn(x: &T)) { iter_ref(self, f) }
    /// Maps a `some` value from one type to another by reference
    pure fn map_ref<U>(f: fn(x: &T) -> U) -> option<U> { map_ref(self, f) }
}

impl<T: copy> option<T> {
    /**
     * Gets the value out of an option
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn get() -> T { get(self) }
    pure fn get_default(def: T) -> T { get_default(self, def) }
    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn expect(reason: ~str) -> T { expect(self, reason) }
    /// Applies a function zero or more times until the result is none.
    pure fn while_some(blk: fn(+T) -> option<T>) { while_some(self, blk) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(*x);
    let opt = some(x);
    let y = unwrap(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| ptr::addr_of(buf));
    let opt = some(x);
    let y = unwrap(opt);
    let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    class r {
       let i: @mut int;
       new(i: @mut int) { self.i = i; }
       drop { *(self.i) += 1; }
    }
    let i = @mut 0;
    {
        let x = r(i);
        let opt = some(x);
        let _y = unwrap(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;
}

// 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>Add option::get_ref<commit_after>/*!
 * 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.
 */

/// The option type
enum option<T> {
    none,
    some(T),
}

pure fn get<T: copy>(opt: option<T>) -> T {
    /*!
     * Gets the value out of an option
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */

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

pure fn get_ref<T>(opt: &option<T>) -> &T {
    /*!
     * Gets an immutable reference to the value inside an option.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    match *opt {
        some(ref x) => x,
        none => fail ~"option::get_ref none"
    }
}

pure fn expect<T: copy>(opt: option<T>, reason: ~str) -> T {
    #[doc = "
    Gets the value out of an option, printing a specified message on failure

    # Failure

    Fails if the value equals `none`
    "];
    match opt { some(x) => x, none => fail reason }
}

pure fn map<T, U>(opt: option<T>, f: fn(T) -> U) -> option<U> {
    //! Maps a `some` value from one type to another

    match opt { some(x) => some(f(x)), none => none }
}

pure fn map_ref<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 }
}

pure fn map_consume<T, U>(+opt: option<T>, f: fn(+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(opt))) } else { none }
}

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

    match opt { some(x) => f(x), none => none }
}

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 }
}

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

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

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

    match opt { none => true, some(_) => false }
}

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

    !is_none(opt)
}

pure fn get_default<T: copy>(opt: option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { some(x) => x, none => def }
}

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

    match opt { none => def, some(t) => f(t) }
}

// This should replace map_default.
pure fn map_default_ref<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 => def, some(ref t) => f(t) }
}

// This should change to by-copy mode; use iter_ref below for by reference
pure fn iter<T>(opt: option<T>, f: fn(T)) {
    //! Performs an operation on the contained value or does nothing

    match opt { none => (), some(t) => f(t) }
}

pure fn iter_ref<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)]
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.
     */

    unsafe {
        let addr = match opt {
          some(x) => ptr::addr_of(x),
          none => fail ~"option::unwrap none"
        };
        let liberated_value = unsafe::reinterpret_cast(*addr);
        unsafe::forget(opt);
        return liberated_value;
    }
}

/// The ubiquitous option dance.
#[inline(always)]
fn swap_unwrap<T>(opt: &mut option<T>) -> T {
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, none))
}

pure fn unwrap_expect<T>(+opt: option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    if opt.is_none() { fail reason.to_unique(); }
    unwrap(opt)
}

// Some of these should change to be &option<T>, some should not. See below.
impl<T> option<T> {
    /**
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */
    pure fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
    /// Applies a function to the contained value or returns a default
    pure fn map_default<U>(+def: U, f: fn(T) -> U) -> U
        { map_default(self, def, f) }
    /// Performs an operation on the contained value or does nothing
    pure fn iter(f: fn(T)) { iter(self, f) }
    /// Returns true if the option equals `none`
    pure fn is_none() -> bool { is_none(self) }
    /// Returns true if the option contains some value
    pure fn is_some() -> bool { is_some(self) }
    /// Maps a `some` value from one type to another
    pure fn map<U>(f: fn(T) -> U) -> option<U> { map(self, f) }
}

impl<T> &option<T> {
    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    pure fn chain_ref<U>(f: fn(x: &T) -> option<U>) -> option<U> {
        chain_ref(self, f)
    }
    /// Applies a function to the contained value or returns a default
    pure fn map_default_ref<U>(+def: U, f: fn(x: &T) -> U) -> U
        { map_default_ref(self, def, f) }
    /// Performs an operation on the contained value by reference
    pure fn iter_ref(f: fn(x: &T)) { iter_ref(self, f) }
    /// Maps a `some` value from one type to another by reference
    pure fn map_ref<U>(f: fn(x: &T) -> U) -> option<U> { map_ref(self, f) }
    /// Gets an immutable reference to the value inside a `some`.
    pure fn get_ref() -> &self/T { get_ref(self) }
}

impl<T: copy> option<T> {
    /**
     * Gets the value out of an option
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn get() -> T { get(self) }
    pure fn get_default(def: T) -> T { get_default(self, def) }
    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn expect(reason: ~str) -> T { expect(self, reason) }
    /// Applies a function zero or more times until the result is none.
    pure fn while_some(blk: fn(+T) -> option<T>) { while_some(self, blk) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(*x);
    let opt = some(x);
    let y = unwrap(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| ptr::addr_of(buf));
    let opt = some(x);
    let y = unwrap(opt);
    let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    class r {
       let i: @mut int;
       new(i: @mut int) { self.i = i; }
       drop { *(self.i) += 1; }
    }
    let i = @mut 0;
    {
        let x = r(i);
        let opt = some(x);
        let _y = unwrap(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;
}

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


<commit_before>//! A type representing either success or failure

import cmp::Eq;
import either::Either;

/// The result type
enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get<T: copy, U>(res: Result<T, U>) -> T {
    match res {
      Ok(t) => t,
      Err(the_err) => unchecked {
        fail fmt!("get called on error result: %?", the_err)
      }
    }
}

/**
 * Get a reference to the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
    match *res {
        Ok(ref t) => t,
        Err(ref the_err) => unchecked {
            fail fmt!("get_ref called on error result: %?", the_err)
        }
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
pure fn get_err<T, U: copy>(res: Result<T, U>) -> U {
    match res {
      Err(u) => u,
      Ok(_) => fail ~"get_err called on ok result"
    }
}

/// Returns true if the result is `ok`
pure fn is_ok<T, U>(res: Result<T, U>) -> bool {
    match res {
      Ok(_) => true,
      Err(_) => false
    }
}

/// Returns true if the result is `err`
pure fn is_err<T, U>(res: Result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
pure fn to_either<T: copy, U: copy>(res: Result<U, T>) -> Either<T, U> {
    match res {
      Ok(res) => either::Right(res),
      Err(fail_) => either::Left(fail_)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_buf(buf))
 *     }
 */
fn chain<T, U: copy, V: copy>(res: Result<T, V>, op: fn(T) -> Result<U, V>)
    -> Result<U, V> {
    match res {
      Ok(t) => op(t),
      Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn chain_err<T: copy, U: copy, V: copy>(
    res: Result<T, V>,
    op: fn(V) -> Result<T, U>)
    -> Result<T, U> {
    match res {
      Ok(t) => Ok(t),
      Err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
fn iter<T, E>(res: Result<T, E>, f: fn(T)) {
    match res {
      Ok(t) => f(t),
      Err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
fn iter_err<T, E>(res: Result<T, E>, f: fn(E)) {
    match res {
      Ok(_) => (),
      Err(e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_buf(buf)
 *     }
 */
fn map<T, E: copy, U: copy>(res: Result<T, E>, op: fn(T) -> U)
  -> Result<U, E> {
    match res {
      Ok(t) => Ok(op(t)),
      Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn map_err<T: copy, E, F: copy>(res: Result<T, E>, op: fn(E) -> F)
  -> Result<T, F> {
    match res {
      Ok(t) => Ok(t),
      Err(e) => Err(op(e))
    }
}

impl<T, E> Result<T, E> {
    fn is_ok() -> bool { is_ok(self) }

    fn is_err() -> bool { is_err(self) }

    fn iter(f: fn(T)) {
        match self {
          Ok(t) => f(t),
          Err(_) => ()
        }
    }

    fn iter_err(f: fn(E)) {
        match self {
          Ok(_) => (),
          Err(e) => f(e)
        }
    }
}

impl<T: copy, E> Result<T, E> {
    fn get() -> T { get(self) }

    fn map_err<F:copy>(op: fn(E) -> F) -> Result<T,F> {
        match self {
          Ok(t) => Ok(t),
          Err(e) => Err(op(e))
        }
    }
}

impl<T, E: copy> Result<T, E> {
    fn get_err() -> E { get_err(self) }

    fn map<U:copy>(op: fn(T) -> U) -> Result<U,E> {
        match self {
          Ok(t) => Ok(op(t)),
          Err(e) => Err(e)
        }
    }
}

impl<T: copy, E: copy> Result<T, E> {
    fn chain<U:copy>(op: fn(T) -> Result<U,E>) -> Result<U,E> {
        chain(self, op)
    }

    fn chain_err<F:copy>(op: fn(E) -> Result<T,F>) -> Result<T,F> {
        chain_err(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert incd == ~[2u, 3u, 4u];
 *     }
 */
fn map_vec<T,U:copy,V:copy>(
    ts: &[T], op: fn(T) -> Result<V,U>) -> Result<~[V],U> {

    let mut vs: ~[V] = ~[];
    vec::reserve(vs, vec::len(ts));
    for vec::each(ts) |t| {
        match op(t) {
          Ok(v) => vec::push(vs, v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

fn map_opt<T,U:copy,V:copy>(
    o_t: Option<T>, op: fn(T) -> Result<V,U>) -> Result<Option<V>,U> {

    match o_t {
      None => Ok(None),
      Some(t) => match op(t) {
        Ok(v) => Ok(Some(v)),
        Err(e) => Err(e)
      }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
fn map_vec2<S,T,U:copy,V:copy>(ss: &[S], ts: &[T],
                               op: fn(S,T) -> Result<V,U>) -> Result<~[V],U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut vs = ~[];
    vec::reserve(vs, n);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          Ok(v) => vec::push(vs, v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map2()` but it is more efficient
 * on its own as no result vector is built.
 */
fn iter_vec2<S,T,U:copy>(ss: &[S], ts: &[T],
                         op: fn(S,T) -> Result<(),U>) -> Result<(),U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
fn unwrap<T, U>(+res: Result<T, U>) -> T {
    match move res {
      Ok(move t) => t,
      Err(_) => fail ~"unwrap called on an err result"
    }
}

impl<T:Eq,U:Eq> Result<T,U> : Eq {
    pure fn eq(&&other: Result<T,U>) -> bool {
        match self {
            Ok(e0a) => {
                match other {
                    Ok(e0b) => e0a == e0b,
                    _ => false
                }
            }
            Err(e0a) => {
                match other {
                    Err(e0b) => e0a == e0b,
                    _ => false
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    fn op2(&&i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    fn chain_success() {
        assert get(chain(op1(), op2)) == 667u;
    }

    #[test]
    fn chain_failure() {
        assert get_err(chain(op3(), op2)) == ~"sadface";
    }

    #[test]
    fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert valid;

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert valid;
    }

    #[test]
    fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert valid;

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert valid;
    }

    #[test]
    fn test_impl_map() {
        assert Ok::<~str, ~str>(~"a").map(|_x| ~"b") == Ok(~"b");
        assert Err::<~str, ~str>(~"a").map(|_x| ~"b") == Err(~"a");
    }

    #[test]
    fn test_impl_map_err() {
        assert Ok::<~str, ~str>(~"a").map_err(|_x| ~"b") == Ok(~"a");
        assert Err::<~str, ~str>(~"a").map_err(|_x| ~"b") == Err(~"b");
    }
}
<commit_msg>libcore: add result::unwrap_err.<commit_after>//! A type representing either success or failure

import cmp::Eq;
import either::Either;

/// The result type
enum Result<T, U> {
    /// Contains the successful result value
    Ok(T),
    /// Contains the error value
    Err(U)
}

/**
 * Get the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get<T: copy, U>(res: Result<T, U>) -> T {
    match res {
      Ok(t) => t,
      Err(the_err) => unchecked {
        fail fmt!("get called on error result: %?", the_err)
      }
    }
}

/**
 * Get a reference to the value out of a successful result
 *
 * # Failure
 *
 * If the result is an error
 */
pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
    match *res {
        Ok(ref t) => t,
        Err(ref the_err) => unchecked {
            fail fmt!("get_ref called on error result: %?", the_err)
        }
    }
}

/**
 * Get the value out of an error result
 *
 * # Failure
 *
 * If the result is not an error
 */
pure fn get_err<T, U: copy>(res: Result<T, U>) -> U {
    match res {
      Err(u) => u,
      Ok(_) => fail ~"get_err called on ok result"
    }
}

/// Returns true if the result is `ok`
pure fn is_ok<T, U>(res: Result<T, U>) -> bool {
    match res {
      Ok(_) => true,
      Err(_) => false
    }
}

/// Returns true if the result is `err`
pure fn is_err<T, U>(res: Result<T, U>) -> bool {
    !is_ok(res)
}

/**
 * Convert to the `either` type
 *
 * `ok` result variants are converted to `either::right` variants, `err`
 * result variants are converted to `either::left`.
 */
pure fn to_either<T: copy, U: copy>(res: Result<U, T>) -> Either<T, U> {
    match res {
      Ok(res) => either::Right(res),
      Err(fail_) => either::Left(fail_)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     let res = chain(read_file(file)) { |buf|
 *         ok(parse_buf(buf))
 *     }
 */
fn chain<T, U: copy, V: copy>(res: Result<T, V>, op: fn(T) -> Result<U, V>)
    -> Result<U, V> {
    match res {
      Ok(t) => op(t),
      Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op`
 * whereupon `op`s result is returned. if `res` is `ok` then it is
 * immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn chain_err<T: copy, U: copy, V: copy>(
    res: Result<T, V>,
    op: fn(V) -> Result<T, U>)
    -> Result<T, U> {
    match res {
      Ok(t) => Ok(t),
      Err(v) => op(v)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `err` then it is immediately
 * returned. This function can be used to compose the results of two
 * functions.
 *
 * Example:
 *
 *     iter(read_file(file)) { |buf|
 *         print_buf(buf)
 *     }
 */
fn iter<T, E>(res: Result<T, E>, f: fn(T)) {
    match res {
      Ok(t) => f(t),
      Err(_) => ()
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is returned. if `res` is `ok` then it is immediately returned.
 * This function can be used to pass through a successful result while
 * handling an error.
 */
fn iter_err<T, E>(res: Result<T, E>, f: fn(E)) {
    match res {
      Ok(_) => (),
      Err(e) => f(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `ok` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
 * immediately returned.  This function can be used to compose the results of
 * two functions.
 *
 * Example:
 *
 *     let res = map(read_file(file)) { |buf|
 *         parse_buf(buf)
 *     }
 */
fn map<T, E: copy, U: copy>(res: Result<T, E>, op: fn(T) -> U)
  -> Result<U, E> {
    match res {
      Ok(t) => Ok(op(t)),
      Err(e) => Err(e)
    }
}

/**
 * Call a function based on a previous result
 *
 * If `res` is `err` then the value is extracted and passed to `op` whereupon
 * `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
 * is immediately returned.  This function can be used to pass through a
 * successful result while handling an error.
 */
fn map_err<T: copy, E, F: copy>(res: Result<T, E>, op: fn(E) -> F)
  -> Result<T, F> {
    match res {
      Ok(t) => Ok(t),
      Err(e) => Err(op(e))
    }
}

impl<T, E> Result<T, E> {
    fn is_ok() -> bool { is_ok(self) }

    fn is_err() -> bool { is_err(self) }

    fn iter(f: fn(T)) {
        match self {
          Ok(t) => f(t),
          Err(_) => ()
        }
    }

    fn iter_err(f: fn(E)) {
        match self {
          Ok(_) => (),
          Err(e) => f(e)
        }
    }
}

impl<T: copy, E> Result<T, E> {
    fn get() -> T { get(self) }

    fn map_err<F:copy>(op: fn(E) -> F) -> Result<T,F> {
        match self {
          Ok(t) => Ok(t),
          Err(e) => Err(op(e))
        }
    }
}

impl<T, E: copy> Result<T, E> {
    fn get_err() -> E { get_err(self) }

    fn map<U:copy>(op: fn(T) -> U) -> Result<U,E> {
        match self {
          Ok(t) => Ok(op(t)),
          Err(e) => Err(e)
        }
    }
}

impl<T: copy, E: copy> Result<T, E> {
    fn chain<U:copy>(op: fn(T) -> Result<U,E>) -> Result<U,E> {
        chain(self, op)
    }

    fn chain_err<F:copy>(op: fn(E) -> Result<T,F>) -> Result<T,F> {
        chain_err(self, op)
    }
}

/**
 * Maps each element in the vector `ts` using the operation `op`.  Should an
 * error occur, no further mappings are performed and the error is returned.
 * Should no error occur, a vector containing the result of each map is
 * returned.
 *
 * Here is an example which increments every integer in a vector,
 * checking for overflow:
 *
 *     fn inc_conditionally(x: uint) -> result<uint,str> {
 *         if x == uint::max_value { return err("overflow"); }
 *         else { return ok(x+1u); }
 *     }
 *     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
 *         assert incd == ~[2u, 3u, 4u];
 *     }
 */
fn map_vec<T,U:copy,V:copy>(
    ts: &[T], op: fn(T) -> Result<V,U>) -> Result<~[V],U> {

    let mut vs: ~[V] = ~[];
    vec::reserve(vs, vec::len(ts));
    for vec::each(ts) |t| {
        match op(t) {
          Ok(v) => vec::push(vs, v),
          Err(u) => return Err(u)
        }
    }
    return Ok(vs);
}

fn map_opt<T,U:copy,V:copy>(
    o_t: Option<T>, op: fn(T) -> Result<V,U>) -> Result<Option<V>,U> {

    match o_t {
      None => Ok(None),
      Some(t) => match op(t) {
        Ok(v) => Ok(Some(v)),
        Err(e) => Err(e)
      }
    }
}

/**
 * Same as map, but it operates over two parallel vectors.
 *
 * A precondition is used here to ensure that the vectors are the same
 * length.  While we do not often use preconditions in the standard
 * library, a precondition is used here because result::t is generally
 * used in 'careful' code contexts where it is both appropriate and easy
 * to accommodate an error like the vectors being of different lengths.
 */
fn map_vec2<S,T,U:copy,V:copy>(ss: &[S], ts: &[T],
                               op: fn(S,T) -> Result<V,U>) -> Result<~[V],U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut vs = ~[];
    vec::reserve(vs, n);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          Ok(v) => vec::push(vs, v),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(vs);
}

/**
 * Applies op to the pairwise elements from `ss` and `ts`, aborting on
 * error.  This could be implemented using `map2()` but it is more efficient
 * on its own as no result vector is built.
 */
fn iter_vec2<S,T,U:copy>(ss: &[S], ts: &[T],
                         op: fn(S,T) -> Result<(),U>) -> Result<(),U> {

    assert vec::same_length(ss, ts);
    let n = vec::len(ts);
    let mut i = 0u;
    while i < n {
        match op(ss[i],ts[i]) {
          Ok(()) => (),
          Err(u) => return Err(u)
        }
        i += 1u;
    }
    return Ok(());
}

/// Unwraps a result, assuming it is an `ok(T)`
fn unwrap<T, U>(+res: Result<T, U>) -> T {
    match move res {
      Ok(move t) => t,
      Err(_) => fail ~"unwrap called on an err result"
    }
}

/// Unwraps a result, assuming it is an `err(U)`
fn unwrap_err<T, U>(+res: Result<T, U>) -> U {
    match move res {
      Err(move u) => u,
      Ok(_) => fail ~"unwrap called on an ok result"
    }
}

impl<T:Eq,U:Eq> Result<T,U> : Eq {
    pure fn eq(&&other: Result<T,U>) -> bool {
        match self {
            Ok(e0a) => {
                match other {
                    Ok(e0b) => e0a == e0b,
                    _ => false
                }
            }
            Err(e0a) => {
                match other {
                    Err(e0b) => e0a == e0b,
                    _ => false
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    fn op1() -> result::Result<int, ~str> { result::Ok(666) }

    fn op2(&&i: int) -> result::Result<uint, ~str> {
        result::Ok(i as uint + 1u)
    }

    fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }

    #[test]
    fn chain_success() {
        assert get(chain(op1(), op2)) == 667u;
    }

    #[test]
    fn chain_failure() {
        assert get_err(chain(op3(), op2)) == ~"sadface";
    }

    #[test]
    fn test_impl_iter() {
        let mut valid = false;
        Ok::<~str, ~str>(~"a").iter(|_x| valid = true);
        assert valid;

        Err::<~str, ~str>(~"b").iter(|_x| valid = false);
        assert valid;
    }

    #[test]
    fn test_impl_iter_err() {
        let mut valid = true;
        Ok::<~str, ~str>(~"a").iter_err(|_x| valid = false);
        assert valid;

        valid = false;
        Err::<~str, ~str>(~"b").iter_err(|_x| valid = true);
        assert valid;
    }

    #[test]
    fn test_impl_map() {
        assert Ok::<~str, ~str>(~"a").map(|_x| ~"b") == Ok(~"b");
        assert Err::<~str, ~str>(~"a").map(|_x| ~"b") == Err(~"a");
    }

    #[test]
    fn test_impl_map_err() {
        assert Ok::<~str, ~str>(~"a").map_err(|_x| ~"b") == Ok(~"a");
        assert Err::<~str, ~str>(~"a").map_err(|_x| ~"b") == Err(~"b");
    }
}
<|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.

// Dynamic arenas.

// Arenas are used to quickly allocate objects that share a
// lifetime. The arena uses ~[u8] vectors as a backing store to
// allocate objects from. For each allocated object, the arena stores
// a pointer to the type descriptor followed by the
// object. (Potentially with alignment padding after each of them.)
// When the arena is destroyed, it iterates through all of its chunks,
// and uses the tydesc information to trace through the objects,
// calling the destructors on them.
// One subtle point that needs to be addressed is how to handle
// failures while running the user provided initializer function. It
// is important to not run the destructor on uninitialized objects, but
// how to detect them is somewhat subtle. Since alloc() can be invoked
// recursively, it is not sufficient to simply exclude the most recent
// object. To solve this without requiring extra space, we use the low
// order bit of the tydesc pointer to encode whether the object it
// describes has been fully initialized.

// As an optimization, objects with destructors are stored in
// different chunks than objects without destructors. This reduces
// overhead when initializing plain-old-data and means we don't need
// to waste time running the destructors of POD.

#[allow(missing_doc)];

use list::{MutList, MutCons, MutNil};

use std::at_vec;
use std::cast::{transmute, transmute_mut, transmute_mut_region};
use std::cast;
use std::num;
use std::ptr;
use std::mem;
use std::uint;
use std::unstable::intrinsics;
use std::unstable::intrinsics::{TyDesc, get_tydesc};

// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
// will always stay at 0.
struct Chunk {
    data: @[u8],
    fill: uint,
    is_pod: bool,
}

#[no_freeze]
pub struct Arena {
    // The head is separated out from the list as a unbenchmarked
    // microoptimization, to avoid needing to case on the list to
    // access the head.
    priv head: Chunk,
    priv pod_head: Chunk,
    priv chunks: @mut MutList<Chunk>,
}

impl Arena {
    pub fn new() -> Arena {
        Arena::new_with_size(32u)
    }

    pub fn new_with_size(initial_size: uint) -> Arena {
        Arena {
            head: chunk(initial_size, false),
            pod_head: chunk(initial_size, true),
            chunks: @mut MutNil,
        }
    }
}

fn chunk(size: uint, is_pod: bool) -> Chunk {
    let mut v: @[u8] = @[];
    unsafe { at_vec::raw::reserve(&mut v, size); }
    Chunk {
        data: unsafe { cast::transmute(v) },
        fill: 0u,
        is_pod: is_pod,
    }
}

#[unsafe_destructor]
impl Drop for Arena {
    fn drop(&mut self) {
        unsafe {
            destroy_chunk(&self.head);
            self.chunks.each(|chunk| {
                if !chunk.is_pod {
                    destroy_chunk(chunk);
                }
                true
            });
        }
    }
}

#[inline]
fn round_up_to(base: uint, align: uint) -> uint {
    (base + (align - 1)) & !(align - 1)
}

// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: &Chunk) {
    let mut idx = 0;
    let buf = chunk.data.as_ptr();
    let fill = chunk.fill;

    while idx < fill {
        let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
        let (size, align) = ((*tydesc).size, (*tydesc).align);

        let after_tydesc = idx + mem::size_of::<*TyDesc>();

        let start = round_up_to(after_tydesc, align);

        //debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
        //       start, size, align, is_done);
        if is_done {
            ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
        }

        // Find where the next tydesc lives
        idx = round_up_to(start + size, mem::pref_align_of::<*TyDesc>());
    }
}

// We encode whether the object a tydesc describes has been
// initialized in the arena in the low bit of the tydesc pointer. This
// is necessary in order to properly do cleanup if a failure occurs
// during an initializer.
#[inline]
unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
    let p_bits: uint = transmute(p);
    p_bits | (is_done as uint)
}
#[inline]
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
    (transmute(p & !1), p & 1 == 1)
}

impl Arena {
    // Functions for the POD part of the arena
    fn alloc_pod_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.pod_head.data);
        let new_min_chunk_size = num::max(n_bytes, chunk_size);
        self.chunks = @mut MutCons(self.pod_head, self.chunks);
        self.pod_head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);

        return self.alloc_pod_inner(n_bytes, align);
    }

    #[inline]
    fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
        unsafe {
            let this = transmute_mut_region(self);
            let start = round_up_to(this.pod_head.fill, align);
            let end = start + n_bytes;
            if end > at_vec::capacity(this.pod_head.data) {
                return this.alloc_pod_grow(n_bytes, align);
            }
            this.pod_head.fill = end;

            //debug!("idx = {}, size = {}, align = {}, fill = {}",
            //       start, n_bytes, align, head.fill);

            ptr::offset(this.pod_head.data.as_ptr(), start as int)
        }
    }

    #[inline]
    fn alloc_pod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
        unsafe {
            let tydesc = get_tydesc::<T>();
            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
            let ptr: *mut T = transmute(ptr);
            intrinsics::move_val_init(&mut (*ptr), op());
            return transmute(ptr);
        }
    }

    // Functions for the non-POD part of the arena
    fn alloc_nonpod_grow(&mut self, n_bytes: uint, align: uint)
                         -> (*u8, *u8) {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.head.data);
        let new_min_chunk_size = num::max(n_bytes, chunk_size);
        self.chunks = @mut MutCons(self.head, self.chunks);
        self.head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);

        return self.alloc_nonpod_inner(n_bytes, align);
    }

    #[inline]
    fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
                          -> (*u8, *u8) {
        unsafe {
            let start;
            let end;
            let tydesc_start;
            let after_tydesc;

            {
                let head = transmute_mut_region(&mut self.head);

                tydesc_start = head.fill;
                after_tydesc = head.fill + mem::size_of::<*TyDesc>();
                start = round_up_to(after_tydesc, align);
                end = start + n_bytes;
            }

            if end > at_vec::capacity(self.head.data) {
                return self.alloc_nonpod_grow(n_bytes, align);
            }

            let head = transmute_mut_region(&mut self.head);
            head.fill = round_up_to(end, mem::pref_align_of::<*TyDesc>());

            //debug!("idx = {}, size = {}, align = {}, fill = {}",
            //       start, n_bytes, align, head.fill);

            let buf = self.head.data.as_ptr();
            return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
        }
    }

    #[inline]
    fn alloc_nonpod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
        unsafe {
            let tydesc = get_tydesc::<T>();
            let (ty_ptr, ptr) =
                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
            let ty_ptr: *mut uint = transmute(ty_ptr);
            let ptr: *mut T = transmute(ptr);
            // Write in our tydesc along with a bit indicating that it
            // has *not* been initialized yet.
            *ty_ptr = transmute(tydesc);
            // Actually initialize it
            intrinsics::move_val_init(&mut(*ptr), op());
            // Now that we are done, update the tydesc to indicate that
            // the object is there.
            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);

            return transmute(ptr);
        }
    }

    // The external interface
    #[inline]
    pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
        unsafe {
            // XXX: Borrow check
            let this = transmute_mut(self);
            if intrinsics::needs_drop::<T>() {
                this.alloc_nonpod(op)
            } else {
                this.alloc_pod(op)
            }
        }
    }
}

#[test]
fn test_arena_destructors() {
    let arena = Arena::new();
    for i in range(0u, 10) {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        arena.alloc(|| @i);
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        arena.alloc(|| [0u8, 1u8, 2u8]);
    }
}

#[test]
#[should_fail]
fn test_arena_destructors_fail() {
    let arena = Arena::new();
    // Put some stuff in the arena.
    for i in range(0u, 10) {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        arena.alloc(|| { @i });
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        arena.alloc(|| { [0u8, 1u8, 2u8] });
    }
    // Now, fail while allocating
    arena.alloc::<@int>(|| {
        // Now fail.
        fail!();
    });
}
<commit_msg>libextra: De-`@mut` the arena<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.

// Dynamic arenas.

// Arenas are used to quickly allocate objects that share a
// lifetime. The arena uses ~[u8] vectors as a backing store to
// allocate objects from. For each allocated object, the arena stores
// a pointer to the type descriptor followed by the
// object. (Potentially with alignment padding after each of them.)
// When the arena is destroyed, it iterates through all of its chunks,
// and uses the tydesc information to trace through the objects,
// calling the destructors on them.
// One subtle point that needs to be addressed is how to handle
// failures while running the user provided initializer function. It
// is important to not run the destructor on uninitialized objects, but
// how to detect them is somewhat subtle. Since alloc() can be invoked
// recursively, it is not sufficient to simply exclude the most recent
// object. To solve this without requiring extra space, we use the low
// order bit of the tydesc pointer to encode whether the object it
// describes has been fully initialized.

// As an optimization, objects with destructors are stored in
// different chunks than objects without destructors. This reduces
// overhead when initializing plain-old-data and means we don't need
// to waste time running the destructors of POD.

#[allow(missing_doc)];

use list::{List, Cons, Nil};
use list;

use std::at_vec;
use std::cast::{transmute, transmute_mut, transmute_mut_region};
use std::cast;
use std::cell::{Cell, RefCell};
use std::num;
use std::ptr;
use std::mem;
use std::uint;
use std::unstable::intrinsics;
use std::unstable::intrinsics::{TyDesc, get_tydesc};

// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
// will always stay at 0.
#[deriving(Clone)]
struct Chunk {
    data: RefCell<@[u8]>,
    fill: Cell<uint>,
    is_pod: Cell<bool>,
}

#[no_freeze]
pub struct Arena {
    // The head is separated out from the list as a unbenchmarked
    // microoptimization, to avoid needing to case on the list to
    // access the head.
    priv head: Chunk,
    priv pod_head: Chunk,
    priv chunks: RefCell<@List<Chunk>>,
}

impl Arena {
    pub fn new() -> Arena {
        Arena::new_with_size(32u)
    }

    pub fn new_with_size(initial_size: uint) -> Arena {
        Arena {
            head: chunk(initial_size, false),
            pod_head: chunk(initial_size, true),
            chunks: RefCell::new(@Nil),
        }
    }
}

fn chunk(size: uint, is_pod: bool) -> Chunk {
    let mut v: @[u8] = @[];
    unsafe { at_vec::raw::reserve(&mut v, size); }
    Chunk {
        data: RefCell::new(unsafe { cast::transmute(v) }),
        fill: Cell::new(0u),
        is_pod: Cell::new(is_pod),
    }
}

#[unsafe_destructor]
impl Drop for Arena {
    fn drop(&mut self) {
        unsafe {
            destroy_chunk(&self.head);

            list::each(self.chunks.get(), |chunk| {
                if !chunk.is_pod.get() {
                    destroy_chunk(chunk);
                }
                true
            });
        }
    }
}

#[inline]
fn round_up_to(base: uint, align: uint) -> uint {
    (base + (align - 1)) & !(align - 1)
}

// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: &Chunk) {
    let mut idx = 0;
    let buf = {
        let data = chunk.data.borrow();
        data.get().as_ptr()
    };
    let fill = chunk.fill.get();

    while idx < fill {
        let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
        let (size, align) = ((*tydesc).size, (*tydesc).align);

        let after_tydesc = idx + mem::size_of::<*TyDesc>();

        let start = round_up_to(after_tydesc, align);

        //debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
        //       start, size, align, is_done);
        if is_done {
            ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
        }

        // Find where the next tydesc lives
        idx = round_up_to(start + size, mem::pref_align_of::<*TyDesc>());
    }
}

// We encode whether the object a tydesc describes has been
// initialized in the arena in the low bit of the tydesc pointer. This
// is necessary in order to properly do cleanup if a failure occurs
// during an initializer.
#[inline]
unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
    let p_bits: uint = transmute(p);
    p_bits | (is_done as uint)
}
#[inline]
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
    (transmute(p & !1), p & 1 == 1)
}

impl Arena {
    // Functions for the POD part of the arena
    fn alloc_pod_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.pod_head.data.get());
        let new_min_chunk_size = num::max(n_bytes, chunk_size);
        self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
        self.pod_head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);

        return self.alloc_pod_inner(n_bytes, align);
    }

    #[inline]
    fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
        unsafe {
            let this = transmute_mut_region(self);
            let start = round_up_to(this.pod_head.fill.get(), align);
            let end = start + n_bytes;
            if end > at_vec::capacity(this.pod_head.data.get()) {
                return this.alloc_pod_grow(n_bytes, align);
            }
            this.pod_head.fill.set(end);

            //debug!("idx = {}, size = {}, align = {}, fill = {}",
            //       start, n_bytes, align, head.fill.get());

            ptr::offset(this.pod_head.data.get().as_ptr(), start as int)
        }
    }

    #[inline]
    fn alloc_pod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
        unsafe {
            let tydesc = get_tydesc::<T>();
            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
            let ptr: *mut T = transmute(ptr);
            intrinsics::move_val_init(&mut (*ptr), op());
            return transmute(ptr);
        }
    }

    // Functions for the non-POD part of the arena
    fn alloc_nonpod_grow(&mut self, n_bytes: uint, align: uint)
                         -> (*u8, *u8) {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.head.data.get());
        let new_min_chunk_size = num::max(n_bytes, chunk_size);
        self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
        self.head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);

        return self.alloc_nonpod_inner(n_bytes, align);
    }

    #[inline]
    fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
                          -> (*u8, *u8) {
        unsafe {
            let start;
            let end;
            let tydesc_start;
            let after_tydesc;

            {
                let head = transmute_mut_region(&mut self.head);

                tydesc_start = head.fill.get();
                after_tydesc = head.fill.get() + mem::size_of::<*TyDesc>();
                start = round_up_to(after_tydesc, align);
                end = start + n_bytes;
            }

            if end > at_vec::capacity(self.head.data.get()) {
                return self.alloc_nonpod_grow(n_bytes, align);
            }

            let head = transmute_mut_region(&mut self.head);
            head.fill.set(round_up_to(end, mem::pref_align_of::<*TyDesc>()));

            //debug!("idx = {}, size = {}, align = {}, fill = {}",
            //       start, n_bytes, align, head.fill);

            let buf = self.head.data.get().as_ptr();
            return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
        }
    }

    #[inline]
    fn alloc_nonpod<'a, T>(&'a mut self, op: || -> T) -> &'a T {
        unsafe {
            let tydesc = get_tydesc::<T>();
            let (ty_ptr, ptr) =
                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
            let ty_ptr: *mut uint = transmute(ty_ptr);
            let ptr: *mut T = transmute(ptr);
            // Write in our tydesc along with a bit indicating that it
            // has *not* been initialized yet.
            *ty_ptr = transmute(tydesc);
            // Actually initialize it
            intrinsics::move_val_init(&mut(*ptr), op());
            // Now that we are done, update the tydesc to indicate that
            // the object is there.
            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);

            return transmute(ptr);
        }
    }

    // The external interface
    #[inline]
    pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
        unsafe {
            // XXX: Borrow check
            let this = transmute_mut(self);
            if intrinsics::needs_drop::<T>() {
                this.alloc_nonpod(op)
            } else {
                this.alloc_pod(op)
            }
        }
    }
}

#[test]
fn test_arena_destructors() {
    let arena = Arena::new();
    for i in range(0u, 10) {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        arena.alloc(|| @i);
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        arena.alloc(|| [0u8, 1u8, 2u8]);
    }
}

#[test]
#[should_fail]
fn test_arena_destructors_fail() {
    let arena = Arena::new();
    // Put some stuff in the arena.
    for i in range(0u, 10) {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        arena.alloc(|| { @i });
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        arena.alloc(|| { [0u8, 1u8, 2u8] });
    }
    // Now, fail while allocating
    arena.alloc::<@int>(|| {
        // Now fail.
        fail!();
    });
}
<|endoftext|>


<commit_before><commit_msg>Added RON vs JSON benchmark<commit_after>#![feature(test)]

extern crate piston_meta;
extern crate test;

use test::Bencher;
use piston_meta::*;

#[bench]
fn json(bencher: &mut Bencher) {
    let text = r#"
    {
       "materials": {
            "metal": {
                "reflectivity": 1.0
            },
            "plastic": {
                "reflectivity": 0.5
            }
       },
       "entities": [
            {
                "name": "hero",
                "material": "metal"
            },
            {
                "name": "moster",
                "material": "plastic"
            }
       ]
    }
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "{" w? "\"reflectivity\"" w? ":" w? $"reflectivity" w? "}"]
2 "materials" ["\"materials\"" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["{" w? s?.(["," w?]){{
    ["\"name\"" w? ":" w? t!"name"]
    ["\"material\"" w? ":" w? t!"material"]
}} w? "}"]
4 "entities" ["\"entities\"" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? "{" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? "}" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseStdErr::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}

#[bench]
fn ron(bencher: &mut Bencher) {
    let text = r#"
    Scene(
        materials: {
            "metal": (
                reflectivity: 1.0,
            ),
            "plastic": (
                reflectivity: 0.5,
            ),
        },
        entities: [
            (
                name: "hero",
                material: "metal",
            ),
            (
                name: "monster",
                material: "plastic",
            ),
        ],
    )
    "#;

    let rules = r#"
1 "material" [t!"name" w? ":" w? "(" w? "reflectivity" w? ":" w? $"reflectivity" ?"," w? ")"]
2 "materials" ["materials" w? ":" w? "{" w? s?.(["," w?]){@"material""material"} w? "}"]
3 "entity" ["(" w? s?.(["," w?]){{
    ["name" w? ":" w? t!"name"]
    ["material" w? ":" w? t!"material"]
}} w? ")"]
4 "entities" ["entities" w? ":" w? "[" w? s?.(["," w?]){@"entity""entity"} w? "]"]
5 "document" [w? ?"Scene" w? "(" w? s?(["," w?]){{
    @"materials""materials"
    @"entities""entities"
}} w? ")" w?]
    "#;
    // Parse rules with meta language and convert to rules for parsing text.
    let rules = bootstrap::convert(
        &parse(&bootstrap::rules(), rules).unwrap(),
        &mut vec![] // stores ignored meta data
    ).unwrap();

    let data = parse(&rules, text);
    match data {
        Err((range, err)) => {
            // Report the error to standard error output.
            ParseStdErr::new(&text).error(range, err);
        }
        _ => {}
    }

    bencher.iter(|| {
        let _ = parse(&rules, text).unwrap();
    });
}
<|endoftext|>


<commit_before><commit_msg>add test for invalid char<commit_after>fn main() {
    assert!(std::char::from_u32(-1_i32 as u32).is_none());
    match unsafe { std::mem::transmute::<i32, char>(-1) } {
        'a' => {}, //~ERROR tried to interpret an invalid 32-bit value as a char: 4294967295
        'b' => {},
        _ => {},
    }
}
<|endoftext|>


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

trait Trait<'a> {
    type A;
    type B;
}

fn foo<'a, T: Trait<'a>>(value: T::A) {
    let new: T::B = unsafe { std::mem::transmute(value) };
//~^ ERROR: cannot transmute to or from a type that contains type parameters in its interior [E0139]
}

fn main() { }
<commit_msg>update compile-fail test for #21174 to account for #27127<commit_after>// Copyright 2015 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.

trait Trait<'a> {
    type A;
    type B;
}

fn foo<'a, T: Trait<'a>>(value: T::A) {
    let new: T::B = unsafe { std::mem::transmute(value) };
//~^ ERROR: cannot transmute to or from a type that contains unsubstituted type parameters [E0139]
}

fn main() { }
<|endoftext|>


<commit_before><commit_msg>Test ordering of glue_drop and glue_takew in self-re-assignment. Closes #3290.<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.

// Ensure assigning an owned or managed variable to itself works. In particular,
// that we do not glue_drop before we glue_take (#3290).

use std::rc::Rc;

pub fn main() {
   let mut x = ~3;
   x = x;
   assert!(*x == 3);

   let mut x = Rc::new(3);
   x = x;
   assert!(*x.borrow() == 3);
}
<|endoftext|>


<commit_before><commit_msg>added single chunk example<commit_after><|endoftext|>


<commit_before><commit_msg>Delayed initialization over mutation<commit_after><|endoftext|>


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

// ignore-android needs extra network permissions
// ignore-bitrig system ulimit (Too many open files)
// ignore-netbsd system ulimit (Too many open files)
// ignore-openbsd system ulimit (Too many open files)
// ignore-emscripten no threads or sockets support

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::process;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::{self, Builder};

const TARGET_CNT: usize = 1000;

fn main() {
    // This test has a chance to time out, try to not let it time out
    thread::spawn(move|| -> () {
        thread::sleep(Duration::from_secs(30));
        process::exit(1);
    });

    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = listener.local_addr().unwrap();
    thread::spawn(move || -> () {
        loop {
            let mut stream = match listener.accept() {
                Ok(stream) => stream.0,
                Err(_) => continue,
            };
            let _ = stream.read(&mut [0]);
            let _ = stream.write(&[2]);
        }
    });

    let (tx, rx) = channel();

    let mut spawned_cnt = 0;
    for _ in 0..TARGET_CNT {
        let tx = tx.clone();
        let res = Builder::new().stack_size(64 * 1024).spawn(move|| {
            match TcpStream::connect(addr) {
                Ok(mut stream) => {
                    let _ = stream.write(&[1]);
                    let _ = stream.read(&mut [0]);
                },
                Err(..) => {}
            }
            tx.send(()).unwrap();
        });
        if let Ok(_) = res {
            spawned_cnt += 1;
        };
    }

    // Wait for all clients to exit, but don't wait for the server to exit. The
    // server just runs infinitely.
    drop(tx);
    for _ in 0..spawned_cnt {
        rx.recv().unwrap();
    }
    assert_eq!(spawned_cnt, TARGET_CNT);
    process::exit(0);
}
<commit_msg>tcp-stress-test.rs: Only spawn 200 threads.<commit_after>// Copyright 2012-2015 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.

// ignore-android needs extra network permissions
// ignore-bitrig system ulimit (Too many open files)
// ignore-netbsd system ulimit (Too many open files)
// ignore-openbsd system ulimit (Too many open files)
// ignore-emscripten no threads or sockets support

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::process;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::{self, Builder};

const TARGET_CNT: usize = 200;

fn main() {
    // This test has a chance to time out, try to not let it time out
    thread::spawn(move|| -> () {
        thread::sleep(Duration::from_secs(30));
        process::exit(1);
    });

    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = listener.local_addr().unwrap();
    thread::spawn(move || -> () {
        loop {
            let mut stream = match listener.accept() {
                Ok(stream) => stream.0,
                Err(_) => continue,
            };
            let _ = stream.read(&mut [0]);
            let _ = stream.write(&[2]);
        }
    });

    let (tx, rx) = channel();

    let mut spawned_cnt = 0;
    for _ in 0..TARGET_CNT {
        let tx = tx.clone();
        let res = Builder::new().stack_size(64 * 1024).spawn(move|| {
            match TcpStream::connect(addr) {
                Ok(mut stream) => {
                    let _ = stream.write(&[1]);
                    let _ = stream.read(&mut [0]);
                },
                Err(..) => {}
            }
            tx.send(()).unwrap();
        });
        if let Ok(_) = res {
            spawned_cnt += 1;
        };
    }

    // Wait for all clients to exit, but don't wait for the server to exit. The
    // server just runs infinitely.
    drop(tx);
    for _ in 0..spawned_cnt {
        rx.recv().unwrap();
    }
    assert_eq!(spawned_cnt, TARGET_CNT);
    process::exit(0);
}
<|endoftext|>


<commit_before>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](trait.Expression.html) or
//! [`AsExpression`](trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html). You can also call
//! numeric operators on types which have been passed to
//! [`operator_allowed!`](../macro.operator_allowed!.html) or
//! [`numeric_expr!`](../macro.numeric_expr!.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod aliased;
#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod count;
pub mod expression_methods;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
pub mod helper_types;
#[doc(hidden)]
pub mod nullable;
#[doc(hidden)]
#[macro_use]
pub mod predicates;
pub mod sql_literal;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)] pub use super::count::{count, count_star};
    #[doc(inline)] pub use super::functions::date_and_time::*;
    #[doc(inline)] pub use super::functions::aggregate_ordering::*;
    #[doc(inline)] pub use super::functions::aggregate_folding::*;
    #[doc(inline)] pub use super::sql_literal::sql;

    #[cfg(feature = "postgres")]
    pub use pg::expression::dsl::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use backend::Backend;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate!.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate!.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType;
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/struct.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that an expression can be selected from a source. The second type
/// argument is optional, but is used to indicate that the right side of a left
/// outer join is nullable, even if it wasn't before.
///
/// Columns will implement this for their table. Certain special types, like
/// `CountStar` and [`Bound`](bound/struct.Bound.html) will implement this for
/// all sources. All other expressions will inherit this from their children.
pub trait SelectableExpression<
    QS,
    Type = <Self as Expression>::SqlType,
>: Expression {
}

impl<T: ?Sized, ST, QS> SelectableExpression<QS, ST> for Box<T> where
    T: SelectableExpression<QS, ST>,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, ST, QS> SelectableExpression<QS, ST> for &'a T where
    T: SelectableExpression<QS, ST>,
    &'a T: Expression,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate: Expression {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

use query_builder::QueryFragment;

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
pub trait BoxableExpression<QS, ST, DB> where
    DB: Backend,
    Self: Expression,
    Self: SelectableExpression<QS, ST>,
    Self: NonAggregate,
    Self: QueryFragment<DB>,
{}

impl<QS, T, ST, DB> BoxableExpression<QS, ST, DB> for T where
    DB: Backend,
    T: Expression,
    T: SelectableExpression<QS, ST>,
    T: NonAggregate,
    T: QueryFragment<DB>,
{
}
<commit_msg>Remove the `Expression` bound from `NonAggregate`<commit_after>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](trait.Expression.html) or
//! [`AsExpression`](trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html). You can also call
//! numeric operators on types which have been passed to
//! [`operator_allowed!`](../macro.operator_allowed!.html) or
//! [`numeric_expr!`](../macro.numeric_expr!.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod aliased;
#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod count;
pub mod expression_methods;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
pub mod helper_types;
#[doc(hidden)]
pub mod nullable;
#[doc(hidden)]
#[macro_use]
pub mod predicates;
pub mod sql_literal;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)] pub use super::count::{count, count_star};
    #[doc(inline)] pub use super::functions::date_and_time::*;
    #[doc(inline)] pub use super::functions::aggregate_ordering::*;
    #[doc(inline)] pub use super::functions::aggregate_folding::*;
    #[doc(inline)] pub use super::sql_literal::sql;

    #[cfg(feature = "postgres")]
    pub use pg::expression::dsl::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use backend::Backend;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate!.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate!.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType;
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/struct.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that an expression can be selected from a source. The second type
/// argument is optional, but is used to indicate that the right side of a left
/// outer join is nullable, even if it wasn't before.
///
/// Columns will implement this for their table. Certain special types, like
/// `CountStar` and [`Bound`](bound/struct.Bound.html) will implement this for
/// all sources. All other expressions will inherit this from their children.
pub trait SelectableExpression<
    QS,
    Type = <Self as Expression>::SqlType,
>: Expression {
}

impl<T: ?Sized, ST, QS> SelectableExpression<QS, ST> for Box<T> where
    T: SelectableExpression<QS, ST>,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, ST, QS> SelectableExpression<QS, ST> for &'a T where
    T: SelectableExpression<QS, ST>,
    &'a T: Expression,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

use query_builder::QueryFragment;

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
pub trait BoxableExpression<QS, ST, DB> where
    DB: Backend,
    Self: Expression,
    Self: SelectableExpression<QS, ST>,
    Self: NonAggregate,
    Self: QueryFragment<DB>,
{}

impl<QS, T, ST, DB> BoxableExpression<QS, ST, DB> for T where
    DB: Backend,
    T: Expression,
    T: SelectableExpression<QS, ST>,
    T: NonAggregate,
    T: QueryFragment<DB>,
{
}
<|endoftext|>


<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use device as d;
use device::Resources;

struct Entry<R: Resources> {
    last_used: u16,
    bound: Option<(d::tex::Kind, R::Texture, Option<(R::Sampler, d::tex::SamplerInfo)>)>,
}

pub struct TextureCache<R: Resources> {
    count: u16,
    textures: Vec<Entry<R>>
}

fn age(now: u16, age: u16) -> u16 {
    use std::num::Wrapping;
    (Wrapping(now) - Wrapping(age)).0
}

impl<R> TextureCache<R> where R: Resources {
    /// Create a TextureCache with `x` slots
    pub fn new(slots: usize) -> TextureCache<R> {
        return TextureCache{
            count: 0,
            textures: (0..slots).map(|_| Entry {
                last_used: 0,
                bound: None
            }).collect()
        }
    }

    /// Returns the number of slots, If a draw call needs
    /// to bind more then this number of slots it will cause
    /// undefined behavior.
    pub fn number_of_slots(&self) -> usize {
        self.textures.len()
    }

    /// Bind a texture, this will look up the texture to see if
    /// it has been bound to a slot, if it has it will return that
    /// slot rather then sending a bind command, iff not it will
    /// release a free slot and bind the texture to it. If there is
    /// no free slots, and there is no bound texture we will throw
    /// away the oldest entries first to make room for the new ones
    pub fn bind_texture<C>(&mut self,
                           kind: d::tex::Kind,
                           tex: R::Texture,
                           samp: Option<(R::Sampler, d::tex::SamplerInfo)>,
                           cb: &mut C) -> d::TextureSlot
        where C: d::draw::CommandBuffer<R>
    {
        self.count += 1;
        let count = self.count;

        let bind = (kind, tex, samp);
        for (i, ent) in self.textures.iter_mut().enumerate() {
            if let Some(ref bound) = ent.bound {
                if bound.0 == bind.0 && bound.1 == bind.1 && bound.2 == bind.2 {
                    // Update the LRU with the current count
                    ent.last_used = count;
                    return i as d::TextureSlot;
                }
            }
        }

        // No texture was found that was bound to the texture slot
        let mut oldest = 0;
        for i in (0..self.textures.len()) {
            if self.textures[i].bound.is_none() {
                oldest = i;
                break;
            }
            if age(count, self.textures[i].last_used) > age(count, self.textures[oldest].last_used) {
                oldest = i;
            }
        }

        cb.bind_texture(oldest as d::TextureSlot, bind.0, bind.1, bind.2);

        self.textures[oldest].last_used = count;
        self.textures[oldest].bound = Some(bind);
        return oldest as d::TextureSlot;
    }

    /// Clear the texture cache
    pub fn clear(&mut self) {
        self.count = 0;
        for ent in self.textures.iter_mut() {
            ent.last_used = 0;
            ent.bound = None;
        }
    }
}

#[test]
fn test_age() {
    assert_eq!(age(100, 0), 100);
    assert_eq!(age(0, 0), 0);
    assert_eq!(age(0, 0xFFFF), 1);
    assert_eq!(age(0, 0xFFFE), 2);
}
<commit_msg>Auto merge of #812 - bvssvni:fix_parens, r=kvark<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use device as d;
use device::Resources;

struct Entry<R: Resources> {
    last_used: u16,
    bound: Option<(d::tex::Kind, R::Texture, Option<(R::Sampler, d::tex::SamplerInfo)>)>,
}

pub struct TextureCache<R: Resources> {
    count: u16,
    textures: Vec<Entry<R>>
}

fn age(now: u16, age: u16) -> u16 {
    use std::num::Wrapping;
    (Wrapping(now) - Wrapping(age)).0
}

impl<R> TextureCache<R> where R: Resources {
    /// Create a TextureCache with `x` slots
    pub fn new(slots: usize) -> TextureCache<R> {
        return TextureCache{
            count: 0,
            textures: (0..slots).map(|_| Entry {
                last_used: 0,
                bound: None
            }).collect()
        }
    }

    /// Returns the number of slots, If a draw call needs
    /// to bind more then this number of slots it will cause
    /// undefined behavior.
    pub fn number_of_slots(&self) -> usize {
        self.textures.len()
    }

    /// Bind a texture, this will look up the texture to see if
    /// it has been bound to a slot, if it has it will return that
    /// slot rather then sending a bind command, iff not it will
    /// release a free slot and bind the texture to it. If there is
    /// no free slots, and there is no bound texture we will throw
    /// away the oldest entries first to make room for the new ones
    pub fn bind_texture<C>(&mut self,
                           kind: d::tex::Kind,
                           tex: R::Texture,
                           samp: Option<(R::Sampler, d::tex::SamplerInfo)>,
                           cb: &mut C) -> d::TextureSlot
        where C: d::draw::CommandBuffer<R>
    {
        self.count += 1;
        let count = self.count;

        let bind = (kind, tex, samp);
        for (i, ent) in self.textures.iter_mut().enumerate() {
            if let Some(ref bound) = ent.bound {
                if bound.0 == bind.0 && bound.1 == bind.1 && bound.2 == bind.2 {
                    // Update the LRU with the current count
                    ent.last_used = count;
                    return i as d::TextureSlot;
                }
            }
        }

        // No texture was found that was bound to the texture slot
        let mut oldest = 0;
        for i in 0..self.textures.len() {
            if self.textures[i].bound.is_none() {
                oldest = i;
                break;
            }
            if age(count, self.textures[i].last_used) > age(count, self.textures[oldest].last_used) {
                oldest = i;
            }
        }

        cb.bind_texture(oldest as d::TextureSlot, bind.0, bind.1, bind.2);

        self.textures[oldest].last_used = count;
        self.textures[oldest].bound = Some(bind);
        return oldest as d::TextureSlot;
    }

    /// Clear the texture cache
    pub fn clear(&mut self) {
        self.count = 0;
        for ent in self.textures.iter_mut() {
            ent.last_used = 0;
            ent.bound = None;
        }
    }
}

#[test]
fn test_age() {
    assert_eq!(age(100, 0), 100);
    assert_eq!(age(0, 0), 0);
    assert_eq!(age(0, 0xFFFF), 1);
    assert_eq!(age(0, 0xFFFE), 2);
}
<|endoftext|>


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

/// Creates a `Vec` containing the arguments.
///
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a `Vec` containing a given list of elements:
///
/// ```
/// let v = vec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// ```
///
/// - Create a `Vec` from a given element and size:
///
/// ```
/// let v = vec![1; 3];
/// assert_eq!(v, [1, 1, 1]);
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement `Clone` and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone()` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[cfg(not(test))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        <[_]>::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
// required for this macro definition, is not available. Instead use the
// `slice::into_vec`  function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        $crate::slice::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See `std::fmt` for more information.
///
/// # Examples
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {
    ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
}
<commit_msg>Rollup merge of #36813 - palango:link-to-fmt, r=steveklabnik<commit_after>// Copyright 2014-2015 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.

/// Creates a `Vec` containing the arguments.
///
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a `Vec` containing a given list of elements:
///
/// ```
/// let v = vec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// ```
///
/// - Create a `Vec` from a given element and size:
///
/// ```
/// let v = vec![1; 3];
/// assert_eq!(v, [1, 1, 1]);
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement `Clone` and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone()` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[cfg(not(test))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        <[_]>::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
// required for this macro definition, is not available. Instead use the
// `slice::into_vec`  function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        $crate::slice::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See [`std::fmt`][fmt] for more information.
///
/// [fmt]: ../std/fmt/index.html
///
/// # Examples
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {
    ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
}
<|endoftext|>