]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/owned_slice.rs
rollup merge of #18407 : thestinger/arena
[rust.git] / src / libsyntax / owned_slice.rs
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::fmt;
12 use std::default::Default;
13 use std::hash;
14 use std::{mem, raw, ptr, slice, vec};
15 use std::rt::heap::EMPTY;
16 use serialize::{Encodable, Decodable, Encoder, Decoder};
17
18 /// A non-growable owned slice. This would preferably become `~[T]`
19 /// under DST.
20 #[unsafe_no_drop_flag] // data is set to null on destruction
21 pub struct OwnedSlice<T> {
22     /// null iff len == 0
23     data: *mut T,
24     len: uint,
25 }
26
27 impl<T:fmt::Show> fmt::Show for OwnedSlice<T> {
28     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
29         try!("OwnedSlice {{".fmt(fmt));
30         for i in self.iter() {
31             try!(i.fmt(fmt));
32         }
33         try!("}}".fmt(fmt));
34         Ok(())
35     }
36 }
37
38 #[unsafe_destructor]
39 impl<T> Drop for OwnedSlice<T> {
40     fn drop(&mut self) {
41         if self.data.is_null() { return }
42
43         // extract the vector
44         let v = mem::replace(self, OwnedSlice::empty());
45         // free via the Vec destructor
46         v.into_vec();
47     }
48 }
49
50 impl<T> OwnedSlice<T> {
51     pub fn empty() -> OwnedSlice<T> {
52         OwnedSlice  { data: ptr::null_mut(), len: 0 }
53     }
54
55     #[inline(never)]
56     pub fn from_vec(mut v: Vec<T>) -> OwnedSlice<T> {
57         let len = v.len();
58
59         if len == 0 {
60             OwnedSlice::empty()
61         } else {
62             // drop excess capacity to avoid breaking sized deallocation
63             v.shrink_to_fit();
64
65             let p = v.as_mut_ptr();
66             // we own the allocation now
67             unsafe { mem::forget(v) }
68
69             OwnedSlice { data: p, len: len }
70         }
71     }
72
73     #[inline(never)]
74     pub fn into_vec(self) -> Vec<T> {
75         // null is ok, because len == 0 in that case, as required by Vec.
76         unsafe {
77             let ret = Vec::from_raw_parts(self.data, self.len, self.len);
78             // the vector owns the allocation now
79             mem::forget(self);
80             ret
81         }
82     }
83
84     pub fn as_slice<'a>(&'a self) -> &'a [T] {
85         let ptr = if self.data.is_null() {
86             // length zero, i.e. this will never be read as a T.
87             EMPTY as *const T
88         } else {
89             self.data as *const T
90         };
91
92         let slice: &[T] = unsafe {mem::transmute(raw::Slice {
93             data: ptr,
94             len: self.len
95         })};
96
97         slice
98     }
99
100     pub fn get<'a>(&'a self, i: uint) -> &'a T {
101         self.as_slice().get(i).expect("OwnedSlice: index out of bounds")
102     }
103
104     pub fn iter<'r>(&'r self) -> slice::Items<'r, T> {
105         self.as_slice().iter()
106     }
107
108     pub fn move_iter(self) -> vec::MoveItems<T> {
109         self.into_vec().into_iter()
110     }
111
112     pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
113         self.iter().map(f).collect()
114     }
115 }
116
117 impl<T> Default for OwnedSlice<T> {
118     fn default() -> OwnedSlice<T> {
119         OwnedSlice::empty()
120     }
121 }
122
123 impl<T: Clone> Clone for OwnedSlice<T> {
124     fn clone(&self) -> OwnedSlice<T> {
125         OwnedSlice::from_vec(self.as_slice().to_vec())
126     }
127 }
128
129 impl<S: hash::Writer, T: hash::Hash<S>> hash::Hash<S> for OwnedSlice<T> {
130     fn hash(&self, state: &mut S) {
131         self.as_slice().hash(state)
132     }
133 }
134
135 impl<T: PartialEq> PartialEq for OwnedSlice<T> {
136     fn eq(&self, other: &OwnedSlice<T>) -> bool {
137         self.as_slice() == other.as_slice()
138     }
139 }
140
141 impl<T: Eq> Eq for OwnedSlice<T> {}
142
143 impl<T> Collection for OwnedSlice<T> {
144     fn len(&self) -> uint { self.len }
145 }
146
147 impl<T> FromIterator<T> for OwnedSlice<T> {
148     fn from_iter<I: Iterator<T>>(mut iter: I) -> OwnedSlice<T> {
149         OwnedSlice::from_vec(iter.collect())
150     }
151 }
152
153 impl<S: Encoder<E>, T: Encodable<S, E>, E> Encodable<S, E> for OwnedSlice<T> {
154     fn encode(&self, s: &mut S) -> Result<(), E> {
155        self.as_slice().encode(s)
156     }
157 }
158
159 impl<D: Decoder<E>, T: Decodable<D, E>, E> Decodable<D, E> for OwnedSlice<T> {
160     fn decode(d: &mut D) -> Result<OwnedSlice<T>, E> {
161         Ok(OwnedSlice::from_vec(match Decodable::decode(d) {
162             Ok(t) => t,
163             Err(e) => return Err(e)
164         }))
165     }
166 }