vec.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //! Vector primitive.
  2. use core::mem::size_of;
  3. use core::{slice, ops, ptr, mem};
  4. use block::Block;
  5. use ptr::Pointer;
  6. /// A low-level vector primitive.
  7. ///
  8. /// This does not perform allocation nor reallaction, thus these have to be done manually.
  9. /// Moreover, no destructors are called, making it possible to leak memory.
  10. pub struct Vec<T: NoDrop> {
  11. /// A pointer to the start of the buffer.
  12. ptr: Pointer<T>,
  13. /// The capacity of the buffer.
  14. ///
  15. /// This demonstrates the lengths before reallocation is necessary.
  16. cap: usize,
  17. /// The length of the vector.
  18. ///
  19. /// This is the number of elements from the start, that is initialized, and can be read safely.
  20. len: usize,
  21. }
  22. impl<T: NoDrop> Vec<T> {
  23. /// Create a new empty vector.
  24. ///
  25. /// This won't allocate a buffer, thus it will have a capacity of zero.
  26. #[inline]
  27. pub const fn new() -> Vec<T> {
  28. Vec {
  29. ptr: Pointer::empty(),
  30. len: 0,
  31. cap: 0,
  32. }
  33. }
  34. /// Create a vector from a block.
  35. ///
  36. /// # Safety
  37. ///
  38. /// This is unsafe, since it won't initialize the buffer in any way, possibly breaking type
  39. /// safety, memory safety, and so on. Thus, care must be taken upon usage.
  40. #[inline]
  41. pub unsafe fn from_raw_parts(block: Block, len: usize) -> Vec<T> {
  42. // Make some handy assertions.
  43. debug_assert!(block.size() % size_of::<T>() == 0, "The size of T does not divide the \
  44. block's size.");
  45. Vec {
  46. cap: block.size() / size_of::<T>(),
  47. ptr: Pointer::new(*block.into_ptr() as *mut T),
  48. len: len,
  49. }
  50. }
  51. /// Replace the inner buffer with a new one, and return the old.
  52. ///
  53. /// This will memcpy the vectors buffer to the new block, and update the pointer and capacity
  54. /// to match the given block.
  55. ///
  56. /// # Panics
  57. ///
  58. /// This panics if the vector is bigger than the block. Additional checks might be done in
  59. /// debug mode.
  60. pub fn refill(&mut self, block: Block) -> Block {
  61. // Calculate the new capacity.
  62. let new_cap = block.size() / size_of::<T>();
  63. // Make some assertions.
  64. assert!(self.len <= new_cap, "Block not large enough to cover the vector.");
  65. debug_assert!(new_cap * size_of::<T>() == block.size(), "The size of T does not divide the \
  66. block's size.");
  67. let old = mem::replace(self, Vec::new());
  68. unsafe {
  69. ptr::copy_nonoverlapping(*self.ptr, *old.ptr, self.len);
  70. }
  71. // Update the fields of `self`.
  72. self.cap = new_cap;
  73. self.ptr = unsafe { Pointer::new(*block.into_ptr() as *mut T) };
  74. self.len = old.len;
  75. Block::from(old)
  76. }
  77. /// Get the inner pointer.
  78. ///
  79. /// Do not perform mutation or any form of manipulation through this pointer, since doing so
  80. /// might break invariants.
  81. #[inline]
  82. pub fn ptr(&self) -> &Pointer<T> {
  83. &self.ptr
  84. }
  85. /// Get the capacity of this vector.
  86. #[inline]
  87. pub fn capacity(&self) -> usize {
  88. self.cap
  89. }
  90. /// Push an element to the end of this vector.
  91. ///
  92. /// On success, return `Ok(())`. On failure (not enough capacity), return `Err(())`.
  93. #[inline]
  94. pub fn push(&mut self, elem: T) -> Result<(), ()> {
  95. if self.len == self.cap {
  96. Err(())
  97. } else {
  98. // Place the element in the end of the vector.
  99. unsafe {
  100. ptr::write((*self.ptr).offset(self.len as isize), elem);
  101. }
  102. // Increment the length.
  103. self.len += 1;
  104. Ok(())
  105. }
  106. }
  107. }
  108. /// Cast this vector to the respective block.
  109. impl<T: NoDrop> From<Vec<T>> for Block {
  110. fn from(from: Vec<T>) -> Block {
  111. unsafe { Block::from_raw_parts(from.ptr.cast(), from.cap * size_of::<T>()) }
  112. }
  113. }
  114. impl<T: NoDrop> ops::Deref for Vec<T> {
  115. #[inline]
  116. type Target = [T];
  117. fn deref(&self) -> &[T] {
  118. unsafe {
  119. slice::from_raw_parts(*self.ptr as *const _, self.len)
  120. }
  121. }
  122. }
  123. impl<T: NoDrop> ops::DerefMut for Vec<T> {
  124. #[inline]
  125. fn deref_mut(&mut self) -> &mut [T] {
  126. unsafe {
  127. slice::from_raw_parts_mut(*self.ptr as *mut _, self.len)
  128. }
  129. }
  130. }
  131. /// Types that have no destructor.
  132. ///
  133. /// This trait act as a simple static assertions catching dumb logic errors and memory leaks.
  134. ///
  135. /// Since one cannot define mutually exclusive traits, we have this as a temporary hack.
  136. pub trait NoDrop {}
  137. impl NoDrop for Block {}
  138. impl NoDrop for u8 {}
  139. #[cfg(test)]
  140. mod test {
  141. use super::*;
  142. use block::Block;
  143. use ptr::Pointer;
  144. #[test]
  145. fn test_vec() {
  146. let mut buffer = [b'a'; 32];
  147. let mut vec = unsafe {
  148. Vec::from_raw_parts(
  149. Block::from_raw_parts(Pointer::new(&mut buffer[0] as *mut u8), 32),
  150. 16
  151. )
  152. };
  153. assert_eq!(&*vec, b"aaaaaaaaaaaaaaaa");
  154. vec.push(b'b').unwrap();
  155. assert_eq!(&*vec, b"aaaaaaaaaaaaaaaab");
  156. vec.push(b'c').unwrap();
  157. assert_eq!(&*vec, b"aaaaaaaaaaaaaaaabc");
  158. vec[0] = b'.';
  159. assert_eq!(&*vec, b".aaaaaaaaaaaaaaabc");
  160. unsafe {
  161. assert_eq!(vec.refill(
  162. Block::from_raw_parts(Pointer::new(&mut buffer[0] as *mut u8), 32)).size(),
  163. 32
  164. );
  165. }
  166. assert_eq!(&*vec, b".aaaaaaaaaaaaaaabc");
  167. for _ in 0..14 {
  168. vec.push(b'_').unwrap();
  169. }
  170. vec.push(b'!').unwrap_err();
  171. assert_eq!(&*vec, b".aaaaaaaaaaaaaaabc______________");
  172. assert_eq!(vec.capacity(), 32);
  173. }
  174. }