1use std::convert::TryInto;
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6
7#[cfg(debug_assertions)]
8use crate::checked_mutex::{
9 CheckedMutex as Mutex, CheckedMutexGuard as MutexGuard,
10};
11#[cfg(not(debug_assertions))]
12use std::sync::{Mutex, MutexGuard};
13
14#[derive(Debug)]
15pub struct Region<'region, T> {
16 region_phantom: PhantomData<&'region T>,
17 region: Mutex<Vec<T>>,
18}
19
20#[derive(Debug, PartialEq)]
25pub struct RegionId<'region, T> {
26 region_phantom: PhantomData<&'region T>,
27 id: u32,
28}
29
30impl<'region, T> RegionId<'region, T> {
31 pub fn as_index(self) -> usize {
33 self.id as usize
34 }
35}
36
37impl<'region, T> Clone for RegionId<'region, T> {
38 fn clone(&self) -> Self {
39 *self
40 }
41}
42
43impl<'region, T> Copy for RegionId<'region, T> {}
44
45pub struct MutexRef<'m, T: 'm, R, M: for<'g> Fn(&'g T) -> &'g R> {
47 guard: MutexGuard<'m, T>,
48 mapper: M,
49}
50
51impl<'m, T: 'm, R, M: for<'g> Fn(&'g T) -> &'g R> MutexRef<'m, T, R, M> {
52 pub fn map(guard: MutexGuard<'m, T>, mapper: M) -> Self {
53 MutexRef { guard, mapper }
54 }
55}
56
57impl<'m, T: 'm, R, M: for<'g> Fn(&'g T) -> &'g R> Deref
58 for MutexRef<'m, T, R, M>
59{
60 type Target = R;
61
62 fn deref(&self) -> &Self::Target {
63 (self.mapper)(&self.guard)
64 }
65}
66
67pub struct MutexRefMut<'m, T: 'm, R, M: for<'g> Fn(&'g mut T) -> &'g mut R> {
68 guard: MutexGuard<'m, T>,
69 mapper: M,
70}
71
72impl<'m, T: 'm, R, M: for<'g> Fn(&'g mut T) -> &'g mut R>
73 MutexRefMut<'m, T, R, M>
74{
75 pub fn map(guard: MutexGuard<'m, T>, mapper: M) -> Self {
76 MutexRefMut { guard, mapper }
77 }
78}
79
80impl<'m, T: 'm, R, M: for<'g> Fn(&'g mut T) -> &'g mut R> Deref
84 for MutexRefMut<'m, T, R, M>
85{
86 type Target = R;
87
88 fn deref(&self) -> &Self::Target {
89 panic!("can't actually make deref workable for MutexRefMut?")
91 }
92}
93
94impl<'m, T: 'm, R, M: for<'g> Fn(&'g mut T) -> &'g mut R> DerefMut
95 for MutexRefMut<'m, T, R, M>
96{
97 fn deref_mut(&mut self) -> &mut Self::Target {
98 (self.mapper)(&mut self.guard)
99 }
100}
101
102impl<'region, T> Region<'region, T> {
103 pub fn new() -> Self {
104 Self {
105 region_phantom: Default::default(),
106 region: Mutex::new(Vec::new()),
107 }
108 }
109
110 pub fn store(&self, value: T) -> RegionId<'region, T> {
112 let mut region = self.region.lock().unwrap();
113 let id = RegionId {
114 region_phantom: Default::default(),
115 id: region.len().try_into().expect("fewer than 2^32 items"),
116 };
117 region.push(value);
118 id
119 }
120
121 pub fn get<'m>(
125 &'m self,
126 id: RegionId<'m, T>,
127 ) -> MutexRef<'m, Vec<T>, T, impl for<'g> Fn(&'g Vec<T>) -> &'g T + 'm>
128 {
129 MutexRef::map(self.region.lock().unwrap(), move |r| &r[id.as_index()])
130 }
131
132 pub fn get_mut<'m>(
136 &'m self,
137 id: RegionId<'m, T>,
138 ) -> MutexRefMut<
139 'm,
140 Vec<T>,
141 T,
142 impl for<'g> Fn(&'g mut Vec<T>) -> &'g mut T + 'm,
143 > {
144 MutexRefMut::map(self.region.lock().unwrap(), move |r| {
145 &mut r[id.as_index()]
146 })
147 }
148
149 pub fn lock<'m>(&'m self) -> RegionGuard<'m, T> {
153 RegionGuard {
154 region_guard: self.region.lock().unwrap(),
155 }
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 struct Pair<'region, T> {
179 value: T,
180 prev: Option<RegionId<'region, Pair<'region, T>>>,
181 next: Option<RegionId<'region, Pair<'region, T>>>,
182 }
183
184 fn cons_left<'region, T>(
208 region: &Region<'region, Pair<'region, T>>,
209 value: T,
210 next: Option<RegionId<'region, Pair<'region, T>>>,
211 ) -> RegionId<'region, Pair<'region, T>> {
212 let id = region.store(Pair {
213 value,
214 next,
215 prev: None,
216 });
217 if let Some(next) = next {
218 let mut n = region.get_mut(next);
219 n.prev = Some(id);
220 }
221 id
222 }
223
224 #[test]
225 fn t_() {
226 let region = Region::new();
227 let c5 = cons_left(®ion, 5, None);
228 let c4 = cons_left(®ion, 4, Some(c5));
229 let c3 = cons_left(®ion, 3, Some(c4));
230 assert_eq!(region.get(c3).value, 3);
231 let c3_next = region.get(c3).next.unwrap();
236 assert_eq!(region.get(c3_next).value, 4);
237
238 let c5_prev = region.get(c5).prev.unwrap();
239 assert_eq!(region.get(c5_prev).value, 4);
240
241 assert_eq!(
242 region
243 .get({
244 let x = region.get(c3).next.unwrap();
245 x
246 })
247 .value,
248 4
249 );
250 }
251}
252
253pub struct RegionGuard<'m, T> {
257 region_guard: MutexGuard<'m, Vec<T>>,
258}
259
260impl<'m, T> RegionGuard<'m, T> {
261 pub fn get(&'m self, id: RegionId<'m, T>) -> &'m T {
263 &(*self.region_guard)[id.as_index()]
264 }
265
266 pub fn get_mut(&'m mut self, id: RegionId<'m, T>) -> &'m mut T {
268 &mut (*self.region_guard)[id.as_index()]
269 }
270}