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 data: *mut T,
22 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: TotalEq> TotalEq for OwnedSlice<T> {}
123
124 impl<T> Container for OwnedSlice<T> {
125 fn len(&self) -> uint { self.len }
126 }
127
128 impl<T> FromIterator<T> for OwnedSlice<T> {
129 fn from_iter<I: Iterator<T>>(mut iter: I) -> OwnedSlice<T> {
130 OwnedSlice::from_vec(iter.collect())
131 }
132 }
133
134 impl<S: Encoder<E>, T: Encodable<S, E>, E> Encodable<S, E> for OwnedSlice<T> {
135 fn encode(&self, s: &mut S) -> Result<(), E> {
136 self.as_slice().encode(s)
137 }
138 }
139
140 impl<D: Decoder<E>, T: Decodable<D, E>, E> Decodable<D, E> for OwnedSlice<T> {
141 fn decode(d: &mut D) -> Result<OwnedSlice<T>, E> {
142 Ok(OwnedSlice::from_vec(match Decodable::decode(d) {
143 Ok(t) => t,
144 Err(e) => return Err(e)
145 }))
146 }
147 }