// Copyright 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 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::fmt; use std::default::Default; use std::hash; use std::{mem, raw, ptr, slice, vec}; use std::rt::heap::EMPTY; use serialize::{Encodable, Decodable, Encoder, Decoder}; /// A non-growable owned slice. This would preferably become `~[T]` /// under DST. #[unsafe_no_drop_flag] // data is set to null on destruction pub struct OwnedSlice { /// null iff len == 0 data: *mut T, len: uint, } impl fmt::Show for OwnedSlice { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!("OwnedSlice {{".fmt(fmt)); for i in self.iter() { try!(i.fmt(fmt)); } try!("}}".fmt(fmt)); Ok(()) } } #[unsafe_destructor] impl Drop for OwnedSlice { fn drop(&mut self) { if self.data.is_null() { return } // extract the vector let v = mem::replace(self, OwnedSlice::empty()); // free via the Vec destructor v.into_vec(); } } impl OwnedSlice { pub fn empty() -> OwnedSlice { OwnedSlice { data: ptr::null_mut(), len: 0 } } #[inline(never)] pub fn from_vec(mut v: Vec) -> OwnedSlice { let len = v.len(); if len == 0 { OwnedSlice::empty() } else { // drop excess capacity to avoid breaking sized deallocation v.shrink_to_fit(); let p = v.as_mut_ptr(); // we own the allocation now unsafe { mem::forget(v) } OwnedSlice { data: p, len: len } } } #[inline(never)] pub fn into_vec(self) -> Vec { // null is ok, because len == 0 in that case, as required by Vec. unsafe { let ret = Vec::from_raw_parts(self.data, self.len, self.len); // the vector owns the allocation now mem::forget(self); ret } } pub fn as_slice<'a>(&'a self) -> &'a [T] { let ptr = if self.data.is_null() { // length zero, i.e. this will never be read as a T. EMPTY as *const T } else { self.data as *const T }; let slice: &[T] = unsafe {mem::transmute(raw::Slice { data: ptr, len: self.len })}; slice } pub fn get<'a>(&'a self, i: uint) -> &'a T { self.as_slice().get(i).expect("OwnedSlice: index out of bounds") } pub fn iter<'r>(&'r self) -> slice::Items<'r, T> { self.as_slice().iter() } pub fn move_iter(self) -> vec::MoveItems { self.into_vec().into_iter() } pub fn map(&self, f: |&T| -> U) -> OwnedSlice { self.iter().map(f).collect() } pub fn len(&self) -> uint { self.len } pub fn is_empty(&self) -> bool { self.len == 0 } } impl Default for OwnedSlice { fn default() -> OwnedSlice { OwnedSlice::empty() } } impl Clone for OwnedSlice { fn clone(&self) -> OwnedSlice { OwnedSlice::from_vec(self.as_slice().to_vec()) } } impl> hash::Hash for OwnedSlice { fn hash(&self, state: &mut S) { self.as_slice().hash(state) } } impl PartialEq for OwnedSlice { fn eq(&self, other: &OwnedSlice) -> bool { self.as_slice() == other.as_slice() } } impl Eq for OwnedSlice {} impl FromIterator for OwnedSlice { fn from_iter>(mut iter: I) -> OwnedSlice { OwnedSlice::from_vec(iter.collect()) } } impl, T: Encodable, E> Encodable for OwnedSlice { fn encode(&self, s: &mut S) -> Result<(), E> { self.as_slice().encode(s) } } impl, T: Decodable, E> Decodable for OwnedSlice { fn decode(d: &mut D) -> Result, E> { Ok(OwnedSlice::from_vec(match Decodable::decode(d) { Ok(t) => t, Err(e) => return Err(e) })) } }