(index<- )        ./libcore/should_not_exist.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 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 cast;
  12  use char::Char;
  13  use clone::Clone;
  14  use container::Container;
  15  use default::Default;
  16  use finally::try_finally;
  17  use intrinsics;
  18  use iter::{range, Iterator, FromIterator};
  19  use mem;
  20  use num::{CheckedMul, CheckedAdd};
  21  use option::{Some, None};
  22  use ptr::RawPtr;
  23  use ptr;
  24  use raw::Vec;
  25  use slice::ImmutableVector;
  26  use str::StrSlice;
  27  
  28  #[cfg(not(test))] use ops::Add;
  29  
  30  #[allow(ctypes)]
  31  extern {
  32      fn malloc(size: uint) -> *u8;
  33      fn free(ptr: *u8);
  34  }
  35  
  36  unsafe fn alloc(cap: uint) -> *mut Vec<()> {
  37      let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).unwrap();
  38      let ret = malloc(cap) as *mut Vec<()>;
  39      if ret.is_null() {
  40          intrinsics::abort();
  41      }
  42      (*ret).fill = 0;
  43      (*ret).alloc = cap;
  44      ret
  45  }
  46  
  47  // Strings
  48  
  49  impl Default for ~str {
  50      fn default() -> ~str {
  51          unsafe {
  52              // Get some memory
  53              let ptr = alloc(0);
  54  
  55              // Initialize the memory
  56              (*ptr).fill = 0;
  57              (*ptr).alloc = 0;
  58  
  59              cast::transmute(ptr)
  60          }
  61      }
  62  }
  63  
  64  impl Clone for ~str {
  65      fn clone(&self) -> ~str {
  66          // Don't use the clone() implementation above because it'll start
  67          // requiring the eh_personality lang item (no fun)
  68          unsafe {
  69              let bytes = self.as_bytes().as_ptr();
  70              let len = self.len();
  71  
  72              let ptr = alloc(len) as *mut Vec<u8>;
  73              ptr::copy_nonoverlapping_memory(&mut (*ptr).data, bytes, len);
  74              (*ptr).fill = len;
  75              (*ptr).alloc = len;
  76  
  77              cast::transmute(ptr)
  78          }
  79      }
  80  }
  81  
  82  impl FromIterator<char> for ~str {
  83      #[inline]
  84      fn from_iter<T: Iterator<char>>(mut iteratorT) -> ~str {
  85          let (lower, _) = iterator.size_hint();
  86          let mut cap = if lower == 0 {16} else {lower};
  87          let mut len = 0;
  88          let mut tmp = [0u8, ..4];
  89  
  90          unsafe {
  91              let mut ptr = alloc(cap) as *mut Vec<u8>;
  92              let mut ret = cast::transmute(ptr);
  93              for ch in iterator {
  94                  let amt = ch.encode_utf8(tmp);
  95  
  96                  if len + amt > cap {
  97                      cap = cap.checked_mul(&2).unwrap();
  98                      if cap < len + amt {
  99                          cap = len + amt;
 100                      }
 101                      let ptr2 = alloc(cap) as *mut Vec<u8>;
 102                      ptr::copy_nonoverlapping_memory(&mut (*ptr2).data,
 103                                                      &(*ptr).data,
 104                                                      len);
 105                      free(ptr as *u8);
 106                      cast::forget(ret);
 107                      ret = cast::transmute(ptr2);
 108                      ptr = ptr2;
 109                  }
 110  
 111                  let base = &mut (*ptr).data as *mut u8;
 112                  for byte in tmp.slice_to(amt).iter() {
 113                      *base.offset(len as int) = *byte;
 114                      len += 1;
 115                  }
 116                  (*ptr).fill = len;
 117              }
 118              ret
 119          }
 120      }
 121  }
 122  
 123  #[cfg(not(test))]
 124  impl<'a> Add<&'a str,~str> for &'a str {
 125      #[inline]
 126      fn add(&self, rhs& &'a str) -> ~str {
 127          let amt = self.len().checked_add(&rhs.len()).unwrap();
 128          unsafe {
 129              let ptr = alloc(amt) as *mut Vec<u8>;
 130              let base = &mut (*ptr).data as *mut _;
 131              ptr::copy_nonoverlapping_memory(base,
 132                                              self.as_bytes().as_ptr(),
 133                                              self.len());
 134              let base = base.offset(self.len() as int);
 135              ptr::copy_nonoverlapping_memory(base,
 136                                              rhs.as_bytes().as_ptr(),
 137                                              rhs.len());
 138              (*ptr).fill = amt;
 139              (*ptr).alloc = amt;
 140              cast::transmute(ptr)
 141          }
 142      }
 143  }
 144  
 145  // Arrays
 146  
 147  impl<A: Clone> Clone for ~[A{
 148      #[inline]
 149      fn clone(&self) -> ~[A] {
 150          let len = self.len();
 151          let data_size = len.checked_mul(&mem::size_of::<A>()).unwrap();
 152          let size = mem::size_of::<Vec<()>>().checked_add(&data_size).unwrap();
 153  
 154          unsafe {
 155              let ret = alloc(size) as *mut Vec<A>;
 156  
 157              (*ret).fill = len * mem::nonzero_size_of::<A>();
 158              (*ret).alloc = len * mem::nonzero_size_of::<A>();
 159  
 160              let mut i = 0;
 161              let p = &mut (*ret).data as *mut _ as *mut A;
 162              try_finally(
 163                  &mut i, (),
 164                  |i, ()| while *i < len {
 165                      mem::move_val_init(
 166                          &mut(*p.offset(*i as int)),
 167                          self.unsafe_ref(*i).clone());
 168                      *i += 1;
 169                  },
 170                  |i| if *i < len {
 171                      // we must be failing, clean up after ourselves
 172                      for j in range(0, *i as int) {
 173                          ptr::read(&*p.offset(j));
 174                      }
 175                      free(ret as *u8);
 176                  });
 177              cast::transmute(ret)
 178          }
 179      }
 180  }