Skip to content

Commit

Permalink
A new test: illustrate use of box with emplacing into back of Vec.
Browse files Browse the repository at this point in the history
  • Loading branch information
pnkfelix committed Oct 23, 2014
1 parent 452ecab commit 731e9ba
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/test/run-pass/placement-box-emplace-back.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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.

// This test illustrates use of `box (<place>) <value>` syntax to
// initialize into the end of a Vec<T>.

#![feature(unsafe_destructor)]

use std::cell::{UnsafeCell};
use std::ops::{Placer,PlacementAgent};

struct EmplaceBack<'a, T:'a> {
vec: &'a mut Vec<T>,
}

pub fn main() {
let mut v : Vec<[f32, ..4]> = vec![];
v.push([10., 20., 30., 40.]);
v.push([11., 21., 31., 41.]);
let mut pv = EmplaceBack { vec: &mut v };
let () = box (pv) [12., 22., 32., 42.];
let v = pv.vec;
assert!(same_contents(
v.as_slice(),
[[10., 20., 30., 40.],
[11., 21., 31., 41.],
[12., 22., 32., 42.],
]));
}

fn same_contents<T:PartialEq>(a: &[[T, ..4]], b: &[[T, ..4]]) -> bool {
assert_eq!(a.len(), b.len());
let len = a.len();
for i in range(0, len) {
if a[i].as_slice() != b[i].as_slice() {
return false;
}
}
return true;
}

struct EmplaceBackAgent<T> {
vec_ptr: *mut Vec<T>,
offset: uint,
}

impl<'a, T> Placer<T, (), EmplaceBackAgent<T>> for EmplaceBack<'a, T> {
fn make_place(&self) -> EmplaceBackAgent<T> {
let len = self.vec.len();
let v = self.vec as *mut Vec<T>;
unsafe {
(*v).reserve_additional(1);
}
EmplaceBackAgent { vec_ptr: v, offset: len }
}
}

impl<T> PlacementAgent<T, ()> for EmplaceBackAgent<T> {
unsafe fn pointer(&self) -> *mut T {
assert_eq!((*self.vec_ptr).len(), self.offset);
assert!(self.offset < (*self.vec_ptr).capacity());
(*self.vec_ptr).as_mut_ptr().offset(self.offset.to_int().unwrap())
}

unsafe fn finalize(self) -> () {
assert_eq!((*self.vec_ptr).len(), self.offset);
assert!(self.offset < (*self.vec_ptr).capacity());
(*self.vec_ptr).set_len(self.offset + 1);
}
}

#[unsafe_destructor]
impl<T> Drop for EmplaceBackAgent<T> {
fn drop(&mut self) {
// Do not need to do anything; all `make_place` did was ensure
// we had some space reserved, it did not touch the state of
// the vector itself.
}
}

0 comments on commit 731e9ba

Please sign in to comment.