storage.rs (3944B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use std::{ops, marker::PhantomData, u32}; 6 use crate::util::Recycler; 7 8 #[derive(Debug, Hash)] 9 #[cfg_attr(feature = "capture", derive(Serialize))] 10 #[cfg_attr(feature = "replay", derive(Deserialize))] 11 pub struct Index<T>(u32, PhantomData<T>); 12 13 // We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)] 14 // because we don't want to require that T implements Clone + Copy. 15 impl<T> Clone for Index<T> { 16 fn clone(&self) -> Self { *self } 17 } 18 19 impl<T> Copy for Index<T> {} 20 21 impl<T> PartialEq for Index<T> { 22 fn eq(&self, other: &Self) -> bool { 23 self.0 == other.0 24 } 25 } 26 27 impl<T> Index<T> { 28 fn new(idx: usize) -> Self { 29 debug_assert!(idx < u32::max_value() as usize); 30 Index(idx as u32, PhantomData) 31 } 32 33 pub const INVALID: Index<T> = Index(u32::MAX, PhantomData); 34 pub const UNUSED: Index<T> = Index(u32::MAX-1, PhantomData); 35 } 36 37 #[derive(Debug)] 38 pub struct OpenRange<T> { 39 start: Index<T>, 40 } 41 42 #[derive(Debug)] 43 #[cfg_attr(feature = "capture", derive(Serialize))] 44 pub struct Range<T> { 45 pub start: Index<T>, 46 pub end: Index<T>, 47 } 48 49 // We explicitly implement Copy + Clone instead of using #[derive(Copy, Clone)] 50 // because we don't want to require that T implements Clone + Copy. 51 impl<T> Clone for Range<T> { 52 fn clone(&self) -> Self { 53 Range { start: self.start, end: self.end } 54 } 55 } 56 impl<T> Copy for Range<T> {} 57 58 impl<T> Range<T> { 59 /// Create an empty `Range` 60 pub fn empty() -> Self { 61 Range { 62 start: Index::new(0), 63 end: Index::new(0), 64 } 65 } 66 67 /// Check for an empty `Range` 68 pub fn is_empty(self) -> bool { 69 self.start.0 >= self.end.0 70 } 71 } 72 73 #[cfg_attr(feature = "capture", derive(Serialize))] 74 pub struct Storage<T> { 75 data: Vec<T>, 76 } 77 78 impl<T> Storage<T> { 79 pub fn new(initial_capacity: usize) -> Self { 80 Storage { 81 data: Vec::with_capacity(initial_capacity), 82 } 83 } 84 85 pub fn len(&self) -> usize { 86 self.data.len() 87 } 88 89 pub fn clear(&mut self) { 90 self.data.clear(); 91 } 92 93 pub fn push(&mut self, t: T) -> Index<T> { 94 let index = self.data.len(); 95 self.data.push(t); 96 Index(index as u32, PhantomData) 97 } 98 99 pub fn reserve(&mut self, count: usize) { 100 self.data.reserve(count); 101 } 102 103 pub fn recycle(&mut self, recycler: &mut Recycler) { 104 recycler.recycle_vec(&mut self.data); 105 } 106 107 pub fn extend<II: IntoIterator<Item=T>>(&mut self, iter: II) -> Range<T> { 108 let range = self.open_range(); 109 self.data.extend(iter); 110 111 self.close_range(range) 112 } 113 114 pub fn open_range(&self) -> OpenRange<T> { 115 OpenRange { 116 start: Index::new(self.data.len()) 117 } 118 } 119 120 pub fn close_range(&self, range: OpenRange<T>) -> Range<T> { 121 Range { 122 start: range.start, 123 end: Index::new(self.data.len()), 124 } 125 } 126 } 127 128 impl<T> ops::Index<Index<T>> for Storage<T> { 129 type Output = T; 130 fn index(&self, index: Index<T>) -> &Self::Output { 131 &self.data[index.0 as usize] 132 } 133 } 134 135 impl<T> ops::IndexMut<Index<T>> for Storage<T> { 136 fn index_mut(&mut self, index: Index<T>) -> &mut Self::Output { 137 &mut self.data[index.0 as usize] 138 } 139 } 140 141 impl<T> ops::Index<Range<T>> for Storage<T> { 142 type Output = [T]; 143 fn index(&self, index: Range<T>) -> &Self::Output { 144 let start = index.start.0 as _; 145 let end = index.end.0 as _; 146 &self.data[start..end] 147 } 148 } 149 150 impl<T> ops::IndexMut<Range<T>> for Storage<T> { 151 fn index_mut(&mut self, index: Range<T>) -> &mut Self::Output { 152 let start = index.start.0 as _; 153 let end = index.end.0 as _; 154 &mut self.data[start..end] 155 } 156 }