(index<- )        ./libsyntax/owned_slice.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Apr  9 17:27:03 2014
   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 vVec<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, iuint) -> &'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 iterI) -> 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  }