Skip to content

Commit 0384952

Browse files
committed
syntax: add the OwnedSlice vector wrapper.
This is a stand-in until we have a saner `~[T]` type (i.e. a proper owned slice). It's a library version of what `~[T]` will be, i.e. an owned pointer and a length.
1 parent 7785fe1 commit 0384952

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

src/libsyntax/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub mod syntax {
4949
pub use parse;
5050
}
5151

52+
pub mod owned_slice;
5253
pub mod opt_vec;
5354
pub mod attr;
5455
pub mod diagnostic;

src/libsyntax/owned_slice.rs

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::default::Default;
12+
use std::hash::Hash;
13+
use std::{cast, mem, raw, ptr, slice};
14+
use serialize::{Encodable, Decodable, Encoder, Decoder};
15+
16+
/// A non-growable owned slice. This would preferably become `~[T]`
17+
/// under DST.
18+
#[unsafe_no_drop_flag] // data is set to null on destruction
19+
pub struct OwnedSlice<T> {
20+
/// null iff len == 0
21+
priv data: *mut T,
22+
priv len: uint,
23+
}
24+
25+
#[unsafe_destructor]
26+
impl<T> Drop for OwnedSlice<T> {
27+
fn drop(&mut self) {
28+
if self.data.is_null() { return }
29+
30+
// extract the vector
31+
let v = mem::replace(self, OwnedSlice::empty());
32+
// free via the Vec destructor
33+
v.into_vec();
34+
}
35+
}
36+
37+
impl<T> OwnedSlice<T> {
38+
pub fn empty() -> OwnedSlice<T> {
39+
OwnedSlice { data: ptr::mut_null(), len: 0 }
40+
}
41+
42+
#[inline(never)]
43+
pub fn from_vec(mut v: Vec<T>) -> OwnedSlice<T> {
44+
let len = v.len();
45+
46+
if len == 0 {
47+
OwnedSlice::empty()
48+
} else {
49+
let p = v.as_mut_ptr();
50+
// we own the allocation now
51+
unsafe {cast::forget(v)}
52+
53+
OwnedSlice { data: p, len: len }
54+
}
55+
}
56+
57+
#[inline(never)]
58+
pub fn into_vec(self) -> Vec<T> {
59+
// null is ok, because len == 0 in that case, as required by Vec.
60+
unsafe {
61+
let ret = Vec::from_raw_parts(self.len, self.len, self.data);
62+
// the vector owns the allocation now
63+
cast::forget(self);
64+
ret
65+
}
66+
}
67+
68+
pub fn as_slice<'a>(&'a self) -> &'a [T] {
69+
static PTR_MARKER: u8 = 0;
70+
let ptr = if self.data.is_null() {
71+
// length zero, i.e. this will never be read as a T.
72+
&PTR_MARKER as *u8 as *T
73+
} else {
74+
self.data as *T
75+
};
76+
77+
let slice: &[T] = unsafe {cast::transmute(raw::Slice {
78+
data: ptr,
79+
len: self.len
80+
})};
81+
82+
slice
83+
}
84+
85+
pub fn get<'a>(&'a self, i: uint) -> &'a T {
86+
self.as_slice().get(i).expect("OwnedSlice: index out of bounds")
87+
}
88+
89+
pub fn iter<'r>(&'r self) -> slice::Items<'r, T> {
90+
self.as_slice().iter()
91+
}
92+
93+
pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
94+
self.iter().map(f).collect()
95+
}
96+
}
97+
98+
impl<T> Default for OwnedSlice<T> {
99+
fn default() -> OwnedSlice<T> {
100+
OwnedSlice::empty()
101+
}
102+
}
103+
104+
impl<T: Clone> Clone for OwnedSlice<T> {
105+
fn clone(&self) -> OwnedSlice<T> {
106+
OwnedSlice::from_vec(Vec::from_slice(self.as_slice()))
107+
}
108+
}
109+
110+
impl<S: Writer, T: Hash<S>> Hash<S> for OwnedSlice<T> {
111+
fn hash(&self, state: &mut S) {
112+
self.as_slice().hash(state)
113+
}
114+
}
115+
116+
impl<T: Eq> Eq for OwnedSlice<T> {
117+
fn eq(&self, other: &OwnedSlice<T>) -> bool {
118+
self.as_slice() == other.as_slice()
119+
}
120+
}
121+
122+
impl<T> Container for OwnedSlice<T> {
123+
fn len(&self) -> uint { self.len }
124+
}
125+
126+
impl<T> FromIterator<T> for OwnedSlice<T> {
127+
fn from_iterator<I: Iterator<T>>(iter: &mut I) -> OwnedSlice<T> {
128+
OwnedSlice::from_vec(iter.collect())
129+
}
130+
}
131+
132+
impl<S: Encoder, T: Encodable<S>> Encodable<S> for OwnedSlice<T> {
133+
fn encode(&self, s: &mut S) {
134+
self.as_slice().encode(s)
135+
}
136+
}
137+
138+
impl<D: Decoder, T: Decodable<D>> Decodable<D> for OwnedSlice<T> {
139+
fn decode(d: &mut D) -> OwnedSlice<T> {
140+
OwnedSlice::from_vec(Decodable::decode(d))
141+
}
142+
}

0 commit comments

Comments
 (0)