grit_data_prison/
single_threaded.rs

1use crate::{
2    extract_true_start_end, internal, major_malfunction, mem_replace, unreachable_unchecked,
3    AccessError, Borrow, BorrowMut, CellKey, Debug, Deref, DerefMut, MaybeUninit, RangeBounds,
4    UnsafeCell,
5};
6
7#[cfg(test)]
8 mod tests;
9
10//====== Misc Types ======
11//STRUCT Refs
12struct Refs {}
13impl Refs {
14    const MUT: usize = usize::MAX;
15    const MAX_IMMUT: usize = Self::MUT - 1;
16}
17
18//STRUCT IdxD
19#[allow(non_camel_case_types)]
20struct IdxD {}
21#[allow(dead_code)]
22impl IdxD {
23    const MAX_CAP: usize = usize::MAX >> 1;
24    const MAX_GEN: usize = Self::MAX_CAP;
25    const MAX_IDX: usize = Self::MAX_CAP - 1;
26    const INVALID: usize = Self::MAX_CAP;
27    const DISCRIMINANT_MASK: usize = Self::MAX_CAP + 1;
28    const DISCRIMINANT_SHIFT: u32 = usize::BITS - 1;
29    const VALUE_MASK: usize = Self::MAX_CAP;
30
31    const fn val(val: usize) -> usize {
32        val & Self::VALUE_MASK
33    }
34
35    const fn is_type_a(val: usize) -> bool {
36        val & Self::DISCRIMINANT_MASK == 0
37    }
38
39    const fn is_type_b(val: usize) -> bool {
40        val & Self::DISCRIMINANT_MASK == Self::DISCRIMINANT_MASK
41    }
42
43    const fn new_type_a(val: usize) -> usize {
44        val & Self::VALUE_MASK
45    }
46
47    const fn new_type_b(val: usize) -> usize {
48        (val & Self::VALUE_MASK) | Self::DISCRIMINANT_MASK
49    }
50}
51
52//====== Prison ======
53//------ Prison Public ------
54//STRUCT Prison
55/// The single-threaded implementation of [Prison]
56///
57/// This struct uses an underlying [Vec<T>] to store data, but provides full interior mutability
58/// for each of its elements. It primarily acts like a Generational Arena using [CellKey]'s to index
59/// into the vector, but allows accessing elements with only a plain [usize] as well.
60///
61/// It does this by using [UnsafeCell] to wrap its internals, a ref-counting [usize] on each element,
62/// and a master [usize] access-counter that are used to determine what cells (indexes) are currently
63/// being accessed to prevent violating Rust's memory management rules.
64/// Each element also has a [usize] generation counter to determine if the value being requested
65/// was created in the same context it is being requested in.
66///
67/// Removing elements does not shift all elements that come after it like a normal [Vec]. Instead,
68/// it marks the element as "free", meaning the value was deleted or removed. Subsequent inserts into
69/// the [Prison] will insert values into free spaces before they consider extending the [Vec],
70/// minimizing reallocations when possible.
71///
72/// See the crate-level documentation or individual methods for more info
73#[derive(Debug)] //COV_IGNORE
74pub struct Prison<T> {
75    internal: UnsafeCell<PrisonInternal<T>>,
76}
77
78impl<T> Prison<T> {
79    //FN Prison::new()
80    /// Create a new [Prison] with the default allocation strategy ([Vec::new()])
81    ///
82    /// Because [Prison] accepts values that may or may not be implement [Copy], [Clone],
83    /// or [Default] and because indexes are simply marked as "free" when their values are removed
84    /// from the [Prison], a closure must be provided upon creation of a new prison
85    /// that supplies it default values to replace the removed ones with safely ([mem::replace()](mem_replace))
86    /// without running into double-frees or use-after-frees or resorting to things like
87    /// [ManuallyDrop](std::mem::ManuallyDrop) or [MaybeUninit](std::mem::MaybeUninit)
88    ///
89    /// Because re-allocating the internal [Vec] comes with many restrictions when
90    /// accessing references to its elements, it is recommended to use [Prison::with_capacity()]
91    /// with a suitable best-guess starting value rather than [Prison::new()]
92    /// ### Example
93    /// ```rust
94    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
95    /// # fn main() {
96    /// let my_prison: Prison<u32> = Prison::new();
97    /// assert!(my_prison.vec_cap() < 100)
98    /// # }
99    /// ```
100    #[inline(always)]
101    pub fn new() -> Self {
102        return Self {
103            internal: UnsafeCell::new(PrisonInternal {
104                access_count: 0,
105                free_count: 0,
106                generation: 0,
107                next_free: IdxD::INVALID,
108                vec: Vec::new(),
109            }),
110        };
111    }
112
113    //FN Prison::with_capacity()
114    /// Create a new [Prison<T>] with a specific starting capacity ([Vec::with_capacity()])
115    ///
116    /// Because [Prison<T>] accepts values that may or may not be implement [Copy], [Clone],
117    /// or [Default] and because indexes are simply marked as "free" when their values are removed
118    /// from the [Prison], a closure must be provided upon creation of a new prison
119    /// that supplies it default values to replace the removed ones with safely ([mem::replace()](mem_replace))
120    /// without running into double-frees or use-after-frees or resorting to things like
121    /// [ManuallyDrop](std::mem::ManuallyDrop) or [MaybeUninit](std::mem::MaybeUninit)
122    ///
123    /// Because re-allocating the internal [Vec] comes with many restrictions when
124    /// accessing references to its elements, it is recommended to use [Prison::with_capacity()]
125    /// with a suitable best-guess starting value rather than [Prison::new()]
126    /// ### Example
127    /// ```rust
128    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
129    /// # fn main() {
130    /// let my_prison: Prison<u32> = Prison::with_capacity(1000);
131    /// assert!(my_prison.vec_cap() == 1000)
132    /// # }
133    /// ```
134    #[inline(always)]
135    pub fn with_capacity(size: usize) -> Self {
136        return Self {
137            internal: UnsafeCell::new(PrisonInternal {
138                access_count: 0,
139                free_count: 0,
140                generation: 0,
141                next_free: IdxD::INVALID,
142                vec: Vec::with_capacity(size),
143            }),
144        };
145    }
146
147    //FN Prison::vec_len()
148    /// Return the length of the underlying [Vec]
149    ///
150    /// Because a [Prison] may have values that are free/deleted that are still counted
151    /// within the length of the [Vec], this value should not be used to determine how many
152    /// *valid* elements exist in the [Prison]
153    #[inline(always)]
154    pub fn vec_len(&self) -> usize {
155        return internal!(self).vec.len();
156    }
157
158    //FN Prison::vec_cap()
159    /// Return the capacity of the underlying [Vec]
160    ///
161    /// Capacity refers to the number of total spaces in memory reserved for the [Vec]
162    ///
163    /// Because a [Prison] may have values that are free/deleted that are *not* counted
164    /// withing the capacity of the [Vec], this value should not be used to determine how many
165    /// *empty* spots exist to add elements into the [Prison]
166    #[inline(always)]
167    pub fn vec_cap(&self) -> usize {
168        return internal!(self).vec.capacity();
169    }
170
171    //FN Prison::num_free()
172    /// Return the number of spaces available for elements to be added to the [Prison]
173    /// without reallocating more memory.
174    #[inline(always)]
175    pub fn num_free(&self) -> usize {
176        let internal = internal!(self);
177        return internal.free_count + internal.vec.capacity() - internal.vec.len();
178    }
179
180    //FN Prison::num_used()
181    /// Return the number of spaces currently occupied by valid elements in the [Prison]
182    #[inline(always)]
183    pub fn num_used(&self) -> usize {
184        let internal = internal!(self);
185        return internal.vec.len() - internal.free_count;
186    }
187
188    //FN Prison::density()
189    /// Return the ratio of used space to total space in the [Prison]
190    ///
191    /// 0.0 = 0% used, 1.0 = 100% used
192    pub fn density(&self) -> f32 {
193        let internal = internal!(self);
194        let used = internal.vec.len() - internal.free_count;
195        let cap = internal.vec.capacity();
196        return (used as f32) / (cap as f32);
197    }
198
199    //FN Prison::insert()
200    /// Insert a value into the [Prison] and recieve a [CellKey] that can be used to
201    /// reference it in the future
202    ///
203    /// As long as there are sufficient free cells or vector capacity to do so,
204    /// you may `insert()` to the [Prison] while any of its elements have active references
205    /// ### Example
206    /// ```rust
207    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
208    /// # fn main() -> Result<(), AccessError> {
209    /// let string_prison: Prison<String> = Prison::with_capacity(10);
210    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
211    /// string_prison.visit_ref(key_0, |first_string| {
212    ///     let key_1 = string_prison.insert(String::from("World!"))?;
213    ///     string_prison.visit_ref(key_1, |second_string| {
214    ///         let hello_world = format!("{}{}", first_string, second_string);
215    ///         assert_eq!(hello_world, "Hello, World!");
216    ///         Ok(())
217    ///     });
218    ///     Ok(())
219    /// });
220    /// # Ok(())
221    /// # }
222    /// ```
223    /// However, if the [Prison] is at maxumum capacity, attempting to `insert()`
224    /// during while there are active references to any element will cause the operation to fail and a
225    /// [AccessError::InsertAtMaxCapacityWhileAValueIsReferenced] to be returned
226    /// ### Example
227    /// ```rust
228    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
229    /// # fn main() -> Result<(), AccessError> {
230    /// let string_prison: Prison<String> = Prison::with_capacity(1);
231    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
232    /// string_prison.visit_ref(key_0, |first_string| {
233    ///     assert!(string_prison.insert(String::from("World!")).is_err());
234    ///     Ok(())
235    /// })?;
236    /// # Ok(())
237    /// # }
238    /// ```
239    #[inline(always)]
240    pub fn insert(&self, value: T) -> Result<CellKey, AccessError> {
241        let internal = internal!(self);
242        if internal.next_free == IdxD::INVALID {
243            if internal.vec.capacity() <= internal.vec.len() {
244                if internal.access_count > 0 {
245                    return Err(AccessError::InsertAtMaxCapacityWhileAValueIsReferenced);
246                }
247                if internal.vec.capacity() == IdxD::MAX_CAP {
248                    return Err(AccessError::MaximumCapacityReached);
249                }
250            }
251            internal
252                .vec
253                .push(PrisonCell::new_cell(value, internal.generation));
254            return Ok(CellKey {
255                idx: internal.vec.len() - 1,
256                gen: internal.generation,
257            });
258        }
259        let new_idx = internal.next_free;
260        match &mut internal.vec[new_idx] {
261            free if free.is_free() => {
262                internal.free_count -= 1;
263                internal.next_free = free.refs_or_next;
264                free.make_cell_unchecked(value, internal.generation);
265                Ok(CellKey {
266                    idx: new_idx,
267                    gen: internal.generation,
268                })
269            }
270            _ => major_malfunction!( //COV_IGNORE
271                "`Prison` had a recorded `next_free` index ({}) that WAS NOT FREE", //COV_IGNORE
272                new_idx //COV_IGNORE
273            ), //COV_IGNORE
274        }
275    }
276
277    //FN Prison::insert_at()
278    /// #### This operation has O(N) time complexity
279    ///
280    /// Insert a value into the [Prison] at the specified index and recieve a
281    /// [CellKey] that can be used to reference it in the future
282    ///
283    /// The index *must* be within range of the underlying [Vec] *AND* must reference
284    /// a space tagged as free/deleted.
285    /// ### Example
286    /// ```rust
287    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
288    /// # fn main() -> Result<(), AccessError> {
289    /// let string_prison: Prison<String> = Prison::with_capacity(10);
290    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
291    /// let key_1 = string_prison.insert(String::from("World!"))?;
292    /// string_prison.remove(key_1)?;
293    /// let key_1 = string_prison.insert_at(1, String::from("Rust!!"))?;
294    /// string_prison.visit_many_ref(&[key_0, key_1], |vals| {
295    ///     let hello_world = format!("{}{}", vals[0], vals[1]);
296    ///     assert_eq!(hello_world, "Hello, Rust!!");
297    ///     Ok(())
298    /// })?;
299    /// # Ok(())
300    /// # }
301    /// ```
302    /// If the index is out of range the function will return an [AccessError::IndexOutOfRange(idx)],
303    /// and if the index is not free/deleted, it will return an [AccessError::IndexIsNotFree(idx)]
304    /// ### Example
305    /// ```rust
306    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
307    /// # fn main() -> Result<(), AccessError> {
308    /// let string_prison: Prison<String> = Prison::with_capacity(10);
309    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
310    /// let key_1 = string_prison.insert(String::from("World!"))?;
311    /// assert!(string_prison.insert_at(1, String::from("Rust!!")).is_err());
312    /// assert!(string_prison.insert_at(10, String::from("Oops...")).is_err());
313    /// # Ok(())
314    /// # }
315    /// ```
316    #[inline(always)]
317    pub fn insert_at(&self, idx: usize, value: T) -> Result<CellKey, AccessError> {
318        let internal: &mut PrisonInternal<T> = internal!(self);
319        if idx >= internal.vec.len() {
320            return Err(AccessError::IndexOutOfRange(idx));
321        }
322        match &mut internal.vec[idx] {
323            free if free.is_free() => {
324                let prev = IdxD::val(free.d_gen_or_prev);
325                if prev != IdxD::INVALID {
326                    match &mut internal!(self).vec[prev] {
327                        prev_free if prev_free.is_free() => prev_free.refs_or_next = free.refs_or_next,
328                        _ => major_malfunction!("a `Free` index ({}) had a `prev_free` that pointed to an index ({}) that WAS NOT FREE", idx, prev) //COV_IGNORE
329                    }
330                } else if internal.next_free == idx {
331                    internal.next_free = free.refs_or_next;
332                } else {
333                    major_malfunction!("a `Free` index ({}) had a `prev_free` value that indicated `INVALID`, meaning it should have been the top of the `free` stack, but `Prison.next_free` ({}) did not match its index", prev, internal.next_free) //COV_IGNORE
334                }
335                if free.refs_or_next != IdxD::INVALID {
336                    match &mut internal!(self).vec[free.refs_or_next] {
337                        next_free if next_free.is_free() => next_free.d_gen_or_prev = IdxD::new_type_b(prev),
338                        _ => major_malfunction!("a `Free` index ({}) had a `next_free` that pointed to an index ({}) that WAS NOT FREE", idx, free.refs_or_next) //COV_IGNORE
339                    }
340                }
341                internal.free_count -= 1;
342                free.make_cell_unchecked(value, internal.generation);
343                return Ok(CellKey {
344                    idx,
345                    gen: internal.generation,
346                });
347            }
348            _ => return Err(AccessError::IndexIsNotFree(idx)),
349        }
350    }
351
352    //FN Prison::overwrite()
353    /// Insert or overwrite a value in the [Prison] at the specified index and recieve a
354    /// [CellKey] that can be used to reference it in the future
355    ///
356    /// Similar to [Prison::insert_at()] but does not require the space be marked as free.
357    ///
358    /// Note: Overwriting a value that isn't marked as free will invalidate any [CellKey]
359    /// that could have been used to reference it and cause a lookup using the old
360    /// key(s) to return an [AccessError::ValueDeleted(idx, gen)]
361    /// ### Example
362    /// ```rust
363    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
364    /// # fn main() -> Result<(), AccessError> {
365    /// let string_prison: Prison<String> = Prison::with_capacity(10);
366    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
367    /// let key_1_a = string_prison.insert(String::from("World!"))?;
368    /// // string_prison.remove(key_1)?; // removal not needed
369    /// let key_1_b = string_prison.overwrite(1, String::from("Rust!!"))?;
370    /// string_prison.visit_many_ref(&[key_0, key_1_b], |vals| {
371    ///     let hello_world = format!("{}{}", vals[0], vals[1]);
372    ///     assert_eq!(hello_world, "Hello, Rust!!");
373    ///     Ok(())
374    /// });
375    /// assert!(string_prison.visit_ref(key_1_a, |deleted_val| Ok(())).is_err());
376    /// assert!(string_prison.overwrite(10, String::from("Oops...")).is_err());
377    /// # Ok(())
378    /// # }
379    #[inline(always)]
380    pub fn overwrite(&self, idx: usize, value: T) -> Result<CellKey, AccessError> {
381        let internal: &mut PrisonInternal<T> = internal!(self);
382        if idx >= internal.vec.len() {
383            return Err(AccessError::IndexOutOfRange(idx));
384        }
385        match &mut internal.vec[idx] {
386            cell if cell.is_cell() => {
387                if cell.refs_or_next > 0 {
388                    return Err(AccessError::OverwriteWhileValueReferenced(idx));
389                }
390                let cell_gen = IdxD::val(cell.d_gen_or_prev);
391                if cell_gen >= internal.generation {
392                    if cell_gen == IdxD::MAX_GEN {
393                        return Err(AccessError::MaxValueForGenerationReached);
394                    }
395                    internal.generation = cell_gen + 1;
396                }
397                cell.overwrite_cell_unchecked(value, internal.generation);
398                return Ok(CellKey {
399                    idx,
400                    gen: internal.generation,
401                });
402            }
403            free => {
404                let prev = IdxD::val(free.d_gen_or_prev);
405                if prev != IdxD::INVALID {
406                    match &mut internal!(self).vec[prev] {
407                        prev_free if prev_free.is_free() => prev_free.refs_or_next = free.refs_or_next,
408                        _ => major_malfunction!("a `Free` index ({}) had a `prev_free` that pointed to an index ({}) that WAS NOT FREE", idx, prev) //COV_IGNORE
409                    }
410                } else if internal.next_free == idx {
411                    internal.next_free = free.refs_or_next;
412                } else {
413                    major_malfunction!("a `free` index ({}) had a `prev_free` value that indicated `INVALID`, meaning it should have been the top of the `free` stack, but `Prison.next_free` ({}) did not match its index", prev, internal.next_free) //COV_IGNORE
414                }
415                if free.refs_or_next != IdxD::INVALID {
416                    match &mut internal!(self).vec[free.refs_or_next] {
417                        next_free if next_free.is_free() => next_free.d_gen_or_prev = IdxD::new_type_b(prev),
418                        _ => major_malfunction!("a `Free` index ({}) had a `next_free` that pointed to an index ({}) that WAS NOT FREE", idx, free.refs_or_next) //COV_IGNORE
419                    }
420                }
421                internal.free_count -= 1;
422                free.make_cell_unchecked(value, internal.generation);
423                return Ok(CellKey {
424                    idx,
425                    gen: internal.generation,
426                });
427            }
428        }
429    }
430
431    //FN Prison::remove()
432    /// Remove and return the element indexed by the provided [CellKey]
433    ///
434    /// As long as the element doesn't have an active reference you can `.remove()` it
435    /// ### Example
436    /// ```rust
437    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
438    /// # fn main() -> Result<(), AccessError> {
439    /// let string_prison: Prison<String> = Prison::with_capacity(15);
440    /// let key_0 = string_prison.insert(String::from("Hello, "))?;
441    /// let key_1 = string_prison.insert(String::from("World!"))?;
442    /// let mut take_world = String::new();
443    /// string_prison.visit_ref(key_0, |hello| {
444    ///     take_world = string_prison.remove(key_1)?;
445    ///     Ok(())
446    /// })?;
447    /// assert_eq!(take_world, "World!");
448    /// # Ok(())
449    /// # }
450    /// ```
451    /// However, if the element *does* have an active reference, either from `visit()` or `guard()`,
452    /// `remove()` will return an [AccessError::RemoveWhileValueReferenced(idx)] with the index in question
453    /// ### Example
454    /// ```rust
455    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
456    /// # fn main() -> Result<(), AccessError>  {
457    /// let string_prison: Prison<String> = Prison::with_capacity(15);
458    /// let key_0 = string_prison.insert(String::from("Everything"))?;
459    /// string_prison.visit_ref(key_0, |everything| {
460    ///     assert!(string_prison.remove(key_0).is_err());
461    ///     Ok(())
462    /// })?;
463    /// # Ok(())
464    /// # }
465    /// ```
466    #[inline(always)]
467    pub fn remove(&self, key: CellKey) -> Result<T, AccessError> {
468        let internal = internal!(self);
469        if key.idx >= internal.vec.len() {
470            return Err(AccessError::IndexOutOfRange(key.idx));
471        }
472        let removed_val = match &mut internal.vec[key.idx] {
473            cell if cell.is_cell_and_gen_match(key.gen) => {
474                if cell.refs_or_next > 0 {
475                    return Err(AccessError::RemoveWhileValueReferenced(key.idx));
476                }
477                let cell_gen = IdxD::val(cell.d_gen_or_prev);
478                if cell_gen >= internal.generation {
479                    if cell_gen == IdxD::MAX_GEN {
480                        return Err(AccessError::MaxValueForGenerationReached);
481                    }
482                    internal.generation = cell_gen + 1;
483                }
484                cell.make_free_unchecked(internal.next_free, IdxD::INVALID)
485            }
486            _ => return Err(AccessError::ValueDeleted(key.idx, key.gen)),
487        };
488        if internal.next_free != IdxD::INVALID {
489            match &mut internal.vec[internal.next_free] {
490                free if free.is_free() => {
491                    free.d_gen_or_prev = IdxD::new_type_b(key.idx);
492                }
493                _ => major_malfunction!( //COV_IGNORE
494                    "the `prison.next_free` index ({}) pointed to an element that WAS NOT FREE", //COV_IGNORE
495                    internal.next_free //COV_IGNORE
496                ), //COV_IGNORE
497            }
498        }
499        internal.next_free = key.idx;
500        internal.free_count += 1;
501        return Ok(removed_val);
502    }
503
504    //FN Prison::remove_idx()
505    /// Remove and return the element at the specified index
506    ///
507    /// Like `remove()` but disregards the generation counter
508    ///
509    /// As long as the element doesnt have an active reference you can `.remove_idx()` it
510    /// ### Example
511    /// ```rust
512    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
513    /// # fn main() -> Result<(), AccessError> {
514    /// let string_prison: Prison<String> = Prison::with_capacity(15);
515    /// string_prison.insert(String::from("Hello, "))?;
516    /// string_prison.insert(String::from("World!"))?;
517    /// let mut take_world = String::new();
518    /// string_prison.visit_ref_idx(0, |hello| {
519    ///     take_world = string_prison.remove_idx(1)?;
520    ///     Ok(())
521    /// })?;
522    /// assert_eq!(take_world, "World!");
523    /// # Ok(())
524    /// # }
525    /// ```
526    /// However, if the element *does* have an active reference, either from `visit()` or `guard()`,
527    /// `.remove_idx()` will return an [AccessError::RemoveWhileValueReferenced(idx)] with the index in question
528    /// ### Example
529    /// ```rust
530    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
531    /// # fn main() -> Result<(), AccessError>  {
532    /// let string_prison: Prison<String> = Prison::with_capacity(15);
533    /// string_prison.insert(String::from("Everything"))?;
534    /// string_prison.visit_ref_idx(0, |everything| {
535    ///     assert!(string_prison.remove_idx(0).is_err());
536    ///     Ok(())
537    /// })?;
538    /// # Ok(())
539    /// # }
540    /// ```
541    #[inline(always)]
542    pub fn remove_idx(&self, idx: usize) -> Result<T, AccessError> {
543        let internal = internal!(self);
544        if idx >= internal.vec.len() {
545            return Err(AccessError::IndexOutOfRange(idx));
546        }
547        let removed_val = match &mut internal.vec[idx] {
548            cell if cell.is_cell() => {
549                if cell.refs_or_next > 0 {
550                    return Err(AccessError::RemoveWhileValueReferenced(idx));
551                }
552                let cell_gen = IdxD::val(cell.d_gen_or_prev);
553                if cell_gen >= internal.generation {
554                    if cell_gen == IdxD::MAX_GEN {
555                        return Err(AccessError::MaxValueForGenerationReached);
556                    }
557                    internal.generation = cell_gen + 1;
558                }
559                cell.make_free_unchecked(internal.next_free, IdxD::INVALID)
560            }
561            _ => return Err(AccessError::ValueDeleted(idx, 0)),
562        };
563        if internal.next_free != IdxD::INVALID {
564            match &mut internal.vec[internal.next_free] {
565                free if free.is_free() => {
566                    free.d_gen_or_prev = IdxD::new_type_b(idx);
567                }
568                _ => major_malfunction!( //COV_IGNORE
569                    "the `prison.next_free` index ({}) pointed to an element that WAS NOT FREE", //COV_IGNORE
570                    internal.next_free //COV_IGNORE
571                ),
572            }
573        }
574        internal.next_free = idx;
575        internal.free_count += 1;
576        return Ok(removed_val);
577    }
578
579    //FN Prison::visit_mut()
580    /// Visit a single value in the [Prison], obtaining a mutable reference to the
581    /// value that is passed into a closure you provide.
582    ///
583    /// You can only obtain a single mutable reference to an element at any given time, and cannot move the mutable
584    /// reference out of the closure, meaning there is only one mutable reference to it at
585    /// any time (and zero immutable references).
586    /// ### Example
587    /// ```rust
588    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
589    /// # fn main() -> Result<(), AccessError> {
590    /// let u32_prison: Prison<u32> = Prison::new();
591    /// let key_0 = u32_prison.insert(42)?;
592    /// u32_prison.visit_mut(key_0, |mut_ref_42| {
593    ///     *mut_ref_42 = 69; // nice
594    ///     Ok(())
595    /// });
596    /// # Ok(())
597    /// # }
598    /// ```
599    /// ## Errors
600    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
601    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if element has any number of immutable references
602    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
603    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted *OR* the [CellKey] generation doe not match
604    /// ### Example
605    /// ```rust
606    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
607    /// # fn main() -> Result<(), AccessError> {
608    /// let u32_prison: Prison<u32> = Prison::new();
609    /// let key_0 = u32_prison.insert(42)?;
610    /// let key_1 = u32_prison.insert(69)?;
611    /// u32_prison.remove(key_1)?;
612    /// u32_prison.visit_mut(key_0, |mut_ref_42| {
613    ///     assert!(u32_prison.visit_mut(key_0, |mut_ref_42_again| Ok(())).is_err());
614    ///     assert!(u32_prison.visit_ref(key_0, |mut_ref_42_again| Ok(())).is_err());
615    ///     assert!(u32_prison.visit_mut(CellKey::from_raw_parts(5, 5), |doesnt_exist| Ok(())).is_err());
616    ///     assert!(u32_prison.visit_mut(key_1, |deleted| Ok(())).is_err());
617    ///     Ok(())
618    /// })?;
619    /// # Ok(())
620    /// # }
621    /// ```
622    /// ### Example
623    /// ```compile_fail
624    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
625    /// # fn main() -> Result<(), AccessError> {
626    /// let u32_prison: Prison<u32> = Prison::new();
627    /// let key_0 = u32_prison.insert(42)?;
628    /// let mut try_to_take_the_ref: &mut u32 = &mut 0;
629    /// u32_prison.visit_mut(key_0, |mut_ref_42| {
630    ///     // will not compile: (error[E0521]: borrowed data escapes outside of closure)
631    ///     try_to_take_the_ref = mut_ref_42;
632    ///     Ok(())
633    /// })?;
634    /// # Ok(())
635    /// # }
636    /// ```
637    #[inline(always)]
638    pub fn visit_mut<F>(&self, key: CellKey, mut operation: F) -> Result<(), AccessError>
639    where
640        F: FnMut(&mut T) -> Result<(), AccessError>,
641    {
642        let (cell, accesses) = self._add_mut_ref(key.idx, key.gen, true)?;
643        let res = operation(unsafe { cell.val.assume_init_mut() });
644        _remove_mut_ref(&mut cell.refs_or_next, accesses);
645        return res;
646    }
647
648    //FN Prison::visit_ref()
649    /// Visit a single value in the [Prison], obtaining an immutable reference to the
650    /// value that is passed into a closure you provide.
651    ///
652    /// You obtain any number of simultaneous immutable references to an element,
653    /// cannot obtain a mutable reference while any immutable references are active,
654    /// and cannot move the immutable references out of the closure,
655    /// ### Example
656    /// ```rust
657    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
658    /// # fn main() -> Result<(), AccessError> {
659    /// let u32_prison: Prison<u32> = Prison::new();
660    /// let key_0 = u32_prison.insert(42)?;
661    /// u32_prison.visit_ref(key_0, |ref_42_a| {
662    ///     u32_prison.visit_ref(key_0, |ref_42_b| {
663    ///         assert_eq!(*ref_42_a, *ref_42_b);
664    ///         Ok(())
665    ///     });
666    ///     Ok(())
667    /// });
668    /// # Ok(())
669    /// # }
670    /// ```
671    /// ## Errors
672    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
673    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references already
674    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
675    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted *OR* the [CellKey] generation doe not match
676    /// ### Example
677    /// ```rust
678    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
679    /// # fn main() -> Result<(), AccessError> {
680    /// let u32_prison: Prison<u32> = Prison::new();
681    /// let key_0 = u32_prison.insert(42)?;
682    /// let key_1 = u32_prison.insert(69)?;
683    /// u32_prison.remove(key_1)?;
684    /// u32_prison.visit_ref(key_0, |ref_42| {
685    ///     assert!(u32_prison.visit_mut(key_0, |mut_ref_42| Ok(())).is_err());
686    ///     assert!(u32_prison.visit_ref(CellKey::from_raw_parts(5, 5), |doesnt_exist| Ok(())).is_err());
687    ///     assert!(u32_prison.visit_ref(key_1, |deleted| Ok(())).is_err());
688    ///     Ok(())
689    /// })?;
690    /// # Ok(())
691    /// # }
692    /// ```
693    /// ### Example
694    /// ```compile_fail
695    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
696    /// # fn main() -> Result<(), AccessError> {
697    /// let u32_prison: Prison<u32> = Prison::new();
698    /// let key_0 = u32_prison.insert(42)?;
699    /// let mut try_to_take_the_ref: & u32 = & 0;
700    /// u32_prison.visit_ref(key_0, |ref_42| {
701    ///     // will not compile: (error[E0521]: borrowed data escapes outside of closure)
702    ///     try_to_take_the_ref = ref_42;
703    ///     Ok(())
704    /// })?;
705    /// # Ok(())
706    /// # }
707    /// ```
708    #[inline(always)]
709    pub fn visit_ref<F>(&self, key: CellKey, mut operation: F) -> Result<(), AccessError>
710    where
711        F: FnMut(&T) -> Result<(), AccessError>,
712    {
713        let (cell, accesses) = self._add_imm_ref(key.idx, key.gen, true)?;
714        let res = operation(unsafe { cell.val.assume_init_ref() });
715        _remove_imm_ref(&mut cell.refs_or_next, accesses);
716        return res;
717    }
718
719    //FN Prison::visit_mut_idx()
720    /// Visit a single value in the [Prison], obtaining a mutable reference to the
721    /// value that is passed into a closure you provide.
722    ///
723    /// Similar to `visit_mut()` but ignores the generation counter
724    ///
725    /// You can only obtain a single mutable reference to an element at any given time, and cannot move the mutable
726    /// reference out of the closure, meaning there is only one mutable reference to it at
727    /// any time (and zero immutable references).
728    /// ### Example
729    /// ```rust
730    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
731    /// # fn main() -> Result<(), AccessError> {
732    /// let u32_prison: Prison<u32> = Prison::new();
733    /// u32_prison.insert(42)?;
734    /// u32_prison.visit_mut_idx(0, |mut_ref_42| {
735    ///     *mut_ref_42 = 69; // nice
736    ///     Ok(())
737    /// });
738    /// # Ok(())
739    /// # }
740    /// ```
741    /// ## Errors
742    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
743    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if element has any number of immutable references
744    /// - [AccessError::IndexOutOfRange(idx)] if the index is out of range
745    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted
746    /// ### Example
747    /// ```rust
748    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
749    /// # fn main() -> Result<(), AccessError> {
750    /// let u32_prison: Prison<u32> = Prison::new();
751    /// u32_prison.insert(42)?;
752    /// u32_prison.insert(69)?;
753    /// u32_prison.remove_idx(1)?;
754    /// u32_prison.visit_mut_idx(0, |mut_ref_42| {
755    ///     assert!(u32_prison.visit_mut_idx(0, |mut_ref_42_again| Ok(())).is_err());
756    ///     assert!(u32_prison.visit_ref_idx(0, |mut_ref_42_again| Ok(())).is_err());
757    ///     assert!(u32_prison.visit_mut_idx(5, |doesnt_exist| Ok(())).is_err());
758    ///     assert!(u32_prison.visit_mut_idx(1, |deleted| Ok(())).is_err());
759    ///     Ok(())
760    /// })?;
761    /// # Ok(())
762    /// # }
763    /// ```
764    /// ### Example
765    /// ```compile_fail
766    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
767    /// # fn main() -> Result<(), AccessError> {
768    /// let u32_prison: Prison<u32> = Prison::new();
769    /// u32_prison.insert(42)?;
770    /// let mut try_to_take_the_ref: &mut u32 = &mut 0;
771    /// u32_prison.visit_mut_idx(0, |mut_ref_42| {
772    ///     // will not compile: (error[E0521]: borrowed data escapes outside of closure)
773    ///     try_to_take_the_ref = mut_ref_42;
774    ///     Ok(())
775    /// })?;
776    /// # Ok(())
777    /// # }
778    /// ```
779    #[inline(always)]
780    pub fn visit_mut_idx<F>(&self, idx: usize, mut operation: F) -> Result<(), AccessError>
781    where
782        F: FnMut(&mut T) -> Result<(), AccessError>,
783    {
784        let (cell, accesses) = self._add_mut_ref(idx, 0, false)?;
785        let res = operation(unsafe { cell.val.assume_init_mut() });
786        _remove_mut_ref(&mut cell.refs_or_next, accesses);
787        return res;
788    }
789
790    //FN Prison::visit_ref_idx()
791    /// Visit a single value in the [Prison], obtaining an immutable reference to the
792    /// value that is passed into a closure you provide.
793    ///
794    /// Similar to `visit_ref()` but ignores the generation counter
795    ///
796    /// You obtain any number of simultaneous immutable references to an element,
797    /// cannot obtain a mutable reference while any immutable references are active,
798    /// and cannot move the immutable references out of the closure,
799    /// ### Example
800    /// ```rust
801    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
802    /// # fn main() -> Result<(), AccessError> {
803    /// let u32_prison: Prison<u32> = Prison::new();
804    /// u32_prison.insert(42)?;
805    /// u32_prison.visit_ref_idx(0, |ref_42_a| {
806    ///     u32_prison.visit_ref_idx(0, |ref_42_b| {
807    ///         assert_eq!(*ref_42_a, *ref_42_b);
808    ///         Ok(())
809    ///     });
810    ///     Ok(())
811    /// });
812    /// # Ok(())
813    /// # }
814    /// ```
815    /// ## Errors
816    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
817    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references already
818    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
819    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted
820    /// ### Example
821    /// ```rust
822    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
823    /// # fn main() -> Result<(), AccessError> {
824    /// let u32_prison: Prison<u32> = Prison::new();
825    /// u32_prison.insert(42)?;
826    /// u32_prison.insert(69)?;
827    /// u32_prison.remove_idx(1)?;
828    /// u32_prison.visit_ref_idx(0, |ref_42| {
829    ///     assert!(u32_prison.visit_mut_idx(0, |mut_ref_42| Ok(())).is_err());
830    ///     assert!(u32_prison.visit_ref_idx(5, |doesnt_exist| Ok(())).is_err());
831    ///     assert!(u32_prison.visit_ref_idx(1, |deleted| Ok(())).is_err());
832    ///     Ok(())
833    /// })?;
834    /// # Ok(())
835    /// # }
836    /// ```
837    /// ### Example
838    /// ```compile_fail
839    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
840    /// # fn main() -> Result<(), AccessError> {
841    /// let u32_prison: Prison<u32> = Prison::new();
842    /// u32_prison.insert(42)?;
843    /// let mut try_to_take_the_ref: & u32 = & 0;
844    /// u32_prison.visit_ref_idx(0, |ref_42| {
845    ///     // will not compile: (error[E0521]: borrowed data escapes outside of closure)
846    ///     try_to_take_the_ref = ref_42;
847    ///     Ok(())
848    /// })?;
849    /// # Ok(())
850    /// # }
851    /// ```
852    #[inline(always)]
853    pub fn visit_ref_idx<F>(&self, idx: usize, mut operation: F) -> Result<(), AccessError>
854    where
855        F: FnMut(&T) -> Result<(), AccessError>,
856    {
857        let (cell, accesses) = self._add_imm_ref(idx, 0, false)?;
858        let res = operation(unsafe { cell.val.assume_init_ref() });
859        _remove_imm_ref(&mut cell.refs_or_next, accesses);
860        return res;
861    }
862
863    //FN Prison::visit_many_mut()
864    /// Visit many values in the [Prison] at the same time, obtaining a mutable reference
865    /// to all of them in the same closure and in the same order they were requested.
866    ///
867    /// While you can obtain multiple unrelated mutable references simultaneously,
868    /// you can only obtain a single mutable reference to the same element at any given time, and cannot move the mutable
869    /// reference out of the closure, meaning there is only one mutable reference to it at
870    /// any time (and zero immutable references).
871    /// ### Example
872    /// ```rust
873    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
874    /// # fn main() -> Result<(), AccessError> {
875    /// let u32_prison: Prison<u32> = Prison::new();
876    /// let key_0 = u32_prison.insert(42)?;
877    /// let key_1 = u32_prison.insert(43)?;
878    /// let key_2 = u32_prison.insert(44)?;
879    /// let key_3 = u32_prison.insert(45)?;
880    /// u32_prison.visit_many_mut(&[key_3, key_2, key_1, key_0], |first_four_reversed| {
881    ///     assert_eq!(*first_four_reversed[0], 45);
882    ///     assert_eq!(*first_four_reversed[1], 44);
883    ///     assert_eq!(*first_four_reversed[2], 43);
884    ///     assert_eq!(*first_four_reversed[3], 42);
885    ///     Ok(())
886    /// })?;
887    /// # Ok(())
888    /// # }
889    /// ```
890    /// Just like `.visit_mut()`, any particular element can only have one mutable reference,
891    /// but as long as the elements requested don't overlap you may make nested
892    /// `visit()` or `guard()` calls
893    /// ### Example
894    /// ```rust
895    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
896    /// # fn main() -> Result<(), AccessError> {
897    /// let u32_prison: Prison<u32> = Prison::new();
898    /// let key_0 = u32_prison.insert(42)?;
899    /// let key_1 = u32_prison.insert(43)?;
900    /// let key_2 = u32_prison.insert(44)?;
901    /// let key_3 = u32_prison.insert(45)?;
902    /// u32_prison.visit_many_mut(&[key_0, key_2], |evens| {
903    ///     u32_prison.visit_many_mut(&[key_1, key_3], |odds| {
904    ///         assert_eq!(*evens[1], 44);
905    ///         assert_eq!(*odds[1], 45);
906    ///         Ok(())
907    ///     });
908    ///     Ok(())
909    /// });
910    /// # Ok(())
911    /// # }
912    /// ```
913    /// ## Errors
914    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
915    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if any element has any number of immutable references
916    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
917    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted *OR* the [CellKey] generation doesnt match
918    /// ### Example
919    /// ```rust
920    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
921    /// # fn main() -> Result<(), AccessError> {
922    /// let u32_prison: Prison<u32> = Prison::new();
923    /// let key_0 = u32_prison.insert(42)?;
924    /// let key_1 = u32_prison.insert(43)?;
925    /// let key_2 = u32_prison.insert(44)?;
926    /// let key_3 = u32_prison.insert(45)?;
927    /// u32_prison.remove(key_1)?;
928    /// let key_4 = CellKey::from_raw_parts(4, 1);
929    /// assert!(u32_prison.visit_many_mut(&[key_0, key_0], |double_key_zero| Ok(())).is_err());
930    /// assert!(u32_prison.visit_many_mut(&[key_1, key_2, key_3], |key_1_removed| Ok(())).is_err());
931    /// assert!(u32_prison.visit_many_mut(&[key_2, key_3, key_4], |key_4_invalid| Ok(())).is_err());
932    /// # Ok(())
933    /// # }
934    /// ```
935    pub fn visit_many_mut<F>(&self, keys: &[CellKey], mut operation: F) -> Result<(), AccessError>
936    where
937        F: FnMut(&mut [&mut T]) -> Result<(), AccessError>,
938    {
939        let (mut vals, mut refs, accesses) = self._add_many_mut_refs(keys)?;
940        let result = operation(&mut vals);
941        _remove_many_mut_refs(&mut refs, accesses);
942        return result;
943    }
944
945    //FN Prison::visit_many_ref()
946    /// Visit many values in the [Prison] at the same time, obtaining an immutable reference
947    /// to all of them in the same closure and in the same order they were requested.
948    ///
949    /// As long as the element does not have any mutable references, you can obtain multiple
950    /// immutable references to the same element
951    /// ### Example
952    /// ```rust
953    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
954    /// # fn main() -> Result<(), AccessError> {
955    /// let u32_prison: Prison<u32> = Prison::new();
956    /// let key_0 = u32_prison.insert(42)?;
957    /// let key_1 = u32_prison.insert(43)?;
958    /// let key_2 = u32_prison.insert(44)?;
959    /// let key_3 = u32_prison.insert(45)?;
960    /// u32_prison.visit_many_ref(&[key_3, key_2, key_1, key_0], |first_four_reversed| {
961    ///     assert_eq!(*first_four_reversed[0], 45);
962    ///     assert_eq!(*first_four_reversed[1], 44);
963    ///     assert_eq!(*first_four_reversed[2], 43);
964    ///     assert_eq!(*first_four_reversed[3], 42);
965    ///     u32_prison.visit_many_ref(&[key_0, key_1, key_2, key_3], |first_four_original| {
966    ///         assert_eq!(*first_four_original[0], 42);
967    ///         assert_eq!(*first_four_original[1], 43);
968    ///         assert_eq!(*first_four_original[2], 44);
969    ///         assert_eq!(*first_four_original[3], 45);
970    ///         Ok(())
971    ///     })?;
972    ///     Ok(())
973    /// })?;
974    /// # Ok(())
975    /// # }
976    /// ```
977    /// Just like `.visit_ref()`, any particular element can have multile immutable references to
978    /// it as long as it has no mutable, meaning you can make nested
979    /// `visit()` or `guard()` calls to the same element if desired
980    /// ### Example
981    /// ```rust
982    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
983    /// # fn main() -> Result<(), AccessError> {
984    /// let u32_prison: Prison<u32> = Prison::new();
985    /// let key_0 = u32_prison.insert(42)?;
986    /// let key_1 = u32_prison.insert(43)?;
987    /// let key_2 = u32_prison.insert(44)?;
988    /// let key_3 = u32_prison.insert(45)?;
989    /// u32_prison.visit_many_ref(&[key_0, key_2], |evens| {
990    ///     u32_prison.visit_many_ref(&[key_1, key_3], |odds| {
991    ///         assert_eq!(*evens[1], 44);
992    ///         assert_eq!(*odds[1], 45);
993    ///         assert!(u32_prison.visit_many_ref(&[key_0, key_1, key_2, key_3], |all| Ok(())).is_ok());
994    ///         Ok(())
995    ///     });
996    ///     Ok(())
997    /// });
998    /// # Ok(())
999    /// # }
1000    /// ```
1001    /// ## Errors
1002    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1003    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references to any element
1004    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1005    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted *OR* if the [CellKey] generation doesn't match
1006    /// ### Example
1007    /// ```rust
1008    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1009    /// # fn main() -> Result<(), AccessError> {
1010    /// let u32_prison: Prison<u32> = Prison::new();
1011    /// let key_0 = u32_prison.insert(42)?;
1012    /// let key_1 = u32_prison.insert(43)?;
1013    /// let key_2 = u32_prison.insert(44)?;
1014    /// let key_3 = u32_prison.insert(45)?;
1015    /// u32_prison.remove(key_1)?;
1016    /// let key_4 = CellKey::from_raw_parts(4, 1);
1017    /// u32_prison.visit_mut(key_0, |mut_0| {
1018    ///     assert!(u32_prison.visit_many_ref(&[key_0], |zero_already_mut| Ok(())).is_err());
1019    ///     assert!(u32_prison.visit_many_ref(&[key_1, key_2, key_3], |key_1_removed| Ok(())).is_err());
1020    ///     assert!(u32_prison.visit_many_ref(&[key_2, key_3, key_4], |key_4_invalid| Ok(())).is_err());
1021    ///     Ok(())
1022    /// })?;
1023    /// # Ok(())
1024    /// # }
1025    /// ```
1026    pub fn visit_many_ref<F>(&self, keys: &[CellKey], mut operation: F) -> Result<(), AccessError>
1027    where
1028        F: FnMut(&[&T]) -> Result<(), AccessError>,
1029    {
1030        let (vals, mut refs, accesses) = self._add_many_imm_refs(keys)?;
1031        let result = operation(&vals);
1032        _remove_many_imm_refs(&mut refs, accesses);
1033        return result;
1034    }
1035
1036    //FN Prison::visit_many_mut_idx()
1037    /// Visit many values in the [Prison] at the same time, obtaining a mutable reference
1038    /// to all of them in the same closure and in the same order they were requested.
1039    ///
1040    /// Similar to `visit_many_mut()` but ignores the generation counter
1041    ///
1042    /// While you can obtain multiple unrelated mutable references simultaneously,
1043    /// you can only obtain a single mutable reference to the same element at any given time, and cannot move the mutable
1044    /// reference out of the closure, meaning there is only one mutable reference to it at
1045    /// any time (and zero immutable references).
1046    /// ### Example
1047    /// ```rust
1048    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1049    /// # fn main() -> Result<(), AccessError> {
1050    /// let u32_prison: Prison<u32> = Prison::new();
1051    /// u32_prison.insert(42)?;
1052    /// u32_prison.insert(43)?;
1053    /// u32_prison.insert(44)?;
1054    /// u32_prison.insert(45)?;
1055    /// u32_prison.visit_many_mut_idx(&[3, 2, 1, 0], |first_four_reversed| {
1056    ///     assert_eq!(*first_four_reversed[0], 45);
1057    ///     assert_eq!(*first_four_reversed[1], 44);
1058    ///     assert_eq!(*first_four_reversed[2], 43);
1059    ///     assert_eq!(*first_four_reversed[3], 42);
1060    ///     Ok(())
1061    /// })?;
1062    /// # Ok(())
1063    /// # }
1064    /// ```
1065    /// Just like `.visit_mut_idx()`, any particular element can only have one mutable reference,
1066    /// but as long as the elements requested don't overlap you may make nested
1067    /// `visit()` or `guard()` calls
1068    /// ### Example
1069    /// ```rust
1070    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1071    /// # fn main() -> Result<(), AccessError> {
1072    /// let u32_prison: Prison<u32> = Prison::new();
1073    /// u32_prison.insert(42)?;
1074    /// u32_prison.insert(43)?;
1075    /// u32_prison.insert(44)?;
1076    /// u32_prison.insert(45)?;
1077    /// u32_prison.visit_many_mut_idx(&[0, 2], |evens| {
1078    ///     u32_prison.visit_many_mut_idx(&[1, 3], |odds| {
1079    ///         assert_eq!(*evens[1], 44);
1080    ///         assert_eq!(*odds[1], 45);
1081    ///         Ok(())
1082    ///     });
1083    ///     Ok(())
1084    /// });
1085    /// # Ok(())
1086    /// # }
1087    /// ```
1088    /// ## Errors
1089    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1090    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if any element has any number of immutable references
1091    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1092    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted
1093    /// ### Example
1094    /// ```rust
1095    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1096    /// # fn main() -> Result<(), AccessError> {
1097    /// let u32_prison: Prison<u32> = Prison::new();
1098    /// u32_prison.insert(42)?;
1099    /// u32_prison.insert(43)?;
1100    /// u32_prison.insert(44)?;
1101    /// u32_prison.insert(45)?;
1102    /// u32_prison.remove_idx(1)?;
1103    /// assert!(u32_prison.visit_many_mut_idx(&[0, 0], |double_idx_zero| Ok(())).is_err());
1104    /// assert!(u32_prison.visit_many_mut_idx(&[1, 2, 3], |idx_1_removed| Ok(())).is_err());
1105    /// assert!(u32_prison.visit_many_mut_idx(&[2, 3, 4], |idx_4_invalid| Ok(())).is_err());
1106    /// # Ok(())
1107    /// # }
1108    /// ```
1109    pub fn visit_many_mut_idx<F>(
1110        &self,
1111        indexes: &[usize],
1112        mut operation: F,
1113    ) -> Result<(), AccessError>
1114    where
1115        F: FnMut(&mut [&mut T]) -> Result<(), AccessError>,
1116    {
1117        let (mut vals, mut refs, accesses) = self._add_many_mut_refs_idx(indexes)?;
1118        let result = operation(&mut vals);
1119        _remove_many_mut_refs(&mut refs, accesses);
1120        return result;
1121    }
1122
1123    //FN Prison::visit_many_ref_idx()
1124    /// Visit many values in the [Prison] at the same time, obtaining an immutable reference
1125    /// to all of them in the same closure and in the same order they were requested.
1126    ///
1127    /// Similar to `visit_many_ref()` but ignores the generation counter
1128    ///
1129    /// As long as the element does not have any mutable references, you can obtain multiple
1130    /// immutable references to the same element
1131    /// ### Example
1132    /// ```rust
1133    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1134    /// # fn main() -> Result<(), AccessError> {
1135    /// let u32_prison: Prison<u32> = Prison::new();
1136    /// u32_prison.insert(42)?;
1137    /// u32_prison.insert(43)?;
1138    /// u32_prison.insert(44)?;
1139    /// u32_prison.insert(45)?;
1140    /// u32_prison.visit_many_ref_idx(&[3, 2, 1, 0], |first_four_reversed| {
1141    ///     assert_eq!(*first_four_reversed[0], 45);
1142    ///     assert_eq!(*first_four_reversed[1], 44);
1143    ///     assert_eq!(*first_four_reversed[2], 43);
1144    ///     assert_eq!(*first_four_reversed[3], 42);
1145    ///     u32_prison.visit_many_ref_idx(&[0, 1, 2, 3], |first_four_original| {
1146    ///         assert_eq!(*first_four_original[0], 42);
1147    ///         assert_eq!(*first_four_original[1], 43);
1148    ///         assert_eq!(*first_four_original[2], 44);
1149    ///         assert_eq!(*first_four_original[3], 45);
1150    ///         Ok(())
1151    ///     })?;
1152    ///     Ok(())
1153    /// })?;
1154    /// # Ok(())
1155    /// # }
1156    /// ```
1157    /// Just like `.visit_ref_idx()`, any particular element can have multiple immutable references to
1158    /// it as long as it has no mutable references, meaning you can make nested
1159    /// `visit()` or `guard()` calls to the same element if desired
1160    /// ### Example
1161    /// ```rust
1162    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1163    /// # fn main() -> Result<(), AccessError> {
1164    /// let u32_prison: Prison<u32> = Prison::new();
1165    /// u32_prison.insert(42)?;
1166    /// u32_prison.insert(43)?;
1167    /// u32_prison.insert(44)?;
1168    /// u32_prison.insert(45)?;
1169    /// u32_prison.visit_many_ref_idx(&[0, 2], |evens| {
1170    ///     u32_prison.visit_many_ref_idx(&[1, 3], |odds| {
1171    ///         assert_eq!(*evens[1], 44);
1172    ///         assert_eq!(*odds[1], 45);
1173    ///         assert!(u32_prison.visit_many_ref_idx(&[0, 1, 2, 3], |all| Ok(())).is_ok());
1174    ///         Ok(())
1175    ///     });
1176    ///     Ok(())
1177    /// });
1178    /// # Ok(())
1179    /// # }
1180    /// ```
1181    /// ## Errors
1182    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1183    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references to any element
1184    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1185    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted
1186    /// ### Example
1187    /// ```rust
1188    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1189    /// # fn main() -> Result<(), AccessError> {
1190    /// let u32_prison: Prison<u32> = Prison::new();
1191    /// u32_prison.insert(42)?;
1192    /// u32_prison.insert(43)?;
1193    /// u32_prison.insert(44)?;
1194    /// u32_prison.insert(45)?;
1195    /// u32_prison.remove_idx(1)?;
1196    /// u32_prison.visit_mut_idx(0, |mut_0| {
1197    ///     assert!(u32_prison.visit_many_ref_idx(&[0], |zero_already_mut| Ok(())).is_err());
1198    ///     assert!(u32_prison.visit_many_ref_idx(&[1, 2, 3], |idx_1_removed| Ok(())).is_err());
1199    ///     assert!(u32_prison.visit_many_ref_idx(&[2, 3, 4], |idx_4_invalid| Ok(())).is_err());
1200    ///     Ok(())
1201    /// })?;
1202    /// # Ok(())
1203    /// # }
1204    /// ```
1205    pub fn visit_many_ref_idx<F>(
1206        &self,
1207        indexes: &[usize],
1208        mut operation: F,
1209    ) -> Result<(), AccessError>
1210    where
1211        F: FnMut(&[&T]) -> Result<(), AccessError>,
1212    {
1213        let (vals, mut refs, accesses) = self._add_many_imm_refs_idx(indexes)?;
1214        let result = operation(&vals);
1215        _remove_many_imm_refs(&mut refs, accesses);
1216        return result;
1217    }
1218
1219    //FN Prison::visit_slice_mut()
1220    /// Visit a slice of values in the [Prison] at the same time, obtaining a mutable reference
1221    /// to all of them in the same closure.
1222    ///
1223    /// Internally this is strictly identical to passing [Prison::visit_many_mut_idx()] a list of all
1224    /// indexes in the slice range, and is subject to all the same restrictions and errors
1225    /// ### Example
1226    /// ```rust
1227    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1228    /// # fn main() -> Result<(), AccessError> {
1229    /// let u32_prison: Prison<u32> = Prison::new();
1230    /// u32_prison.insert(42)?;
1231    /// u32_prison.insert(43)?;
1232    /// u32_prison.insert(44)?;
1233    /// u32_prison.insert(45)?;
1234    /// u32_prison.insert(46)?;
1235    /// u32_prison.visit_slice_mut(2..5, |last_three| {
1236    ///     assert_eq!(*last_three[0], 44);
1237    ///     assert_eq!(*last_three[1], 45);
1238    ///     assert_eq!(*last_three[2], 46);
1239    ///     Ok(())
1240    /// });
1241    /// # Ok(())
1242    /// # }
1243    /// ```
1244    /// Any standard [Range<usize>](std::ops::Range) notation is allowed as the first paramater,
1245    /// but care must be taken because it is not guaranteed every index within range is a valid
1246    /// value or does not have any other references to it that would violate Rust's memory safety.
1247    /// ### Example
1248    /// ```rust
1249    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1250    /// # fn main() -> Result<(), AccessError> {
1251    /// let u32_prison: Prison<u32> = Prison::new();
1252    /// u32_prison.insert(42)?;
1253    /// u32_prison.insert(43)?;
1254    /// u32_prison.insert(44)?;
1255    /// u32_prison.insert(45)?;
1256    /// u32_prison.insert(46)?;
1257    /// assert!(u32_prison.visit_slice_mut(2..5,  |last_three| Ok(())).is_ok());
1258    /// assert!(u32_prison.visit_slice_mut(2..=4, |also_last_three| Ok(())).is_ok());
1259    /// assert!(u32_prison.visit_slice_mut(2..,   |again_last_three| Ok(())).is_ok());
1260    /// assert!(u32_prison.visit_slice_mut(..3,   |first_three| Ok(())).is_ok());
1261    /// assert!(u32_prison.visit_slice_mut(..=3,  |first_four| Ok(())).is_ok());
1262    /// assert!(u32_prison.visit_slice_mut(..,    |all| Ok(())).is_ok());
1263    /// u32_prison.remove_idx(2)?;
1264    /// assert!(u32_prison.visit_slice_mut(..,    |all| Ok(())).is_err());
1265    /// # Ok(())
1266    /// # }
1267    /// ```
1268    /// See [Prison::visit_many_mut_idx()] for more info
1269    pub fn visit_slice_mut<R, F>(&self, range: R, operation: F) -> Result<(), AccessError>
1270    where
1271        R: RangeBounds<usize>,
1272        F: FnMut(&mut [&mut T]) -> Result<(), AccessError>,
1273    {
1274        let (start, end) = extract_true_start_end(range, self.vec_len());
1275        let idxs: Vec<usize> = (start..end).collect();
1276        self.visit_many_mut_idx(&idxs, operation)
1277    }
1278
1279    //FN Prison::visit_slice_ref()
1280    /// Visit a slice of values in the [Prison] at the same time, obtaining an immutable reference
1281    /// to all of them in the same closure.
1282    ///
1283    /// Internally this is strictly identical to passing [Prison::visit_many_ref_idx()] a list of all
1284    /// indexes in the slice range, and is subject to all the same restrictions and errors
1285    /// ### Example
1286    /// ```rust
1287    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1288    /// # fn main() -> Result<(), AccessError> {
1289    /// let u32_prison: Prison<u32> = Prison::new();
1290    /// u32_prison.insert(42)?;
1291    /// u32_prison.insert(43)?;
1292    /// u32_prison.insert(44)?;
1293    /// u32_prison.insert(45)?;
1294    /// u32_prison.insert(46)?;
1295    /// u32_prison.visit_slice_ref(2..5, |last_three| {
1296    ///     assert_eq!(*last_three[0], 44);
1297    ///     assert_eq!(*last_three[1], 45);
1298    ///     assert_eq!(*last_three[2], 46);
1299    ///     u32_prison.visit_slice_ref(0..3, |first_three| {
1300    ///         assert_eq!(*first_three[0], 42);
1301    ///         assert_eq!(*first_three[1], 43);
1302    ///         assert_eq!(*first_three[2], 44);
1303    ///         Ok(())
1304    ///     });
1305    ///     Ok(())
1306    /// });
1307    /// # Ok(())
1308    /// # }
1309    /// ```
1310    /// Any standard [Range<usize>](std::ops::Range) notation is allowed as the first paramater,
1311    /// but care must be taken because it is not guaranteed every index within range is a valid
1312    /// value or does not have any other references to it that would violate Rust's memory safety.
1313    /// ### Example
1314    /// ```rust
1315    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1316    /// # fn main() -> Result<(), AccessError> {
1317    /// let u32_prison: Prison<u32> = Prison::new();
1318    /// u32_prison.insert(42)?;
1319    /// u32_prison.insert(43)?;
1320    /// u32_prison.insert(44)?;
1321    /// u32_prison.insert(45)?;
1322    /// u32_prison.insert(46)?;
1323    /// assert!(u32_prison.visit_slice_ref(2..5,  |last_three| Ok(())).is_ok());
1324    /// assert!(u32_prison.visit_slice_ref(2..=4, |also_last_three| Ok(())).is_ok());
1325    /// assert!(u32_prison.visit_slice_ref(2..,   |again_last_three| Ok(())).is_ok());
1326    /// assert!(u32_prison.visit_slice_ref(..3,   |first_three| Ok(())).is_ok());
1327    /// assert!(u32_prison.visit_slice_ref(..=3,  |first_four| Ok(())).is_ok());
1328    /// assert!(u32_prison.visit_slice_ref(..,    |all| Ok(())).is_ok());
1329    /// u32_prison.remove_idx(2)?;
1330    /// assert!(u32_prison.visit_slice_ref(..,    |all| Ok(())).is_err());
1331    /// # Ok(())
1332    /// # }
1333    /// ```
1334    /// See [Prison::visit_many_ref_idx()] for more info
1335    pub fn visit_slice_ref<R, F>(&self, range: R, operation: F) -> Result<(), AccessError>
1336    where
1337        R: RangeBounds<usize>,
1338        F: FnMut(&[&T]) -> Result<(), AccessError>,
1339    {
1340        let (start, end) = extract_true_start_end(range, self.vec_len());
1341        let idxs: Vec<usize> = (start..end).collect();
1342        self.visit_many_ref_idx(&idxs, operation)
1343    }
1344
1345    //FN Prison::guard_mut()
1346    /// Return a [PrisonValueMut] that contains a mutable reference to the element and wraps it in
1347    /// guarding data that automatically frees its reference count it when it goes out of scope.
1348    ///
1349    /// [PrisonValueMut<T>] implements [Deref<Target = T>], [DerefMut<Target = T>], [AsRef<T>], [AsMut<T>],
1350    /// [Borrow<T>], and [BorrowMut<T>] to allow transparent access to its underlying value
1351    ///
1352    /// As long as the [PrisonValueMut] remains in scope, the element where it's value resides in the
1353    /// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
1354    /// You can manually drop the [PrisonValueMut] out of scope by passing it as the first parameter
1355    /// to the function [PrisonValueMut::unguard(p_val_mut)]
1356    /// ### Example
1357    /// ```rust
1358    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1359    /// # fn main() -> Result<(), AccessError> {
1360    /// let prison: Prison<u32> = Prison::new();
1361    /// let key_0 = prison.insert(10)?;
1362    /// let mut grd_0 = prison.guard_mut(key_0)?;
1363    /// assert_eq!(*grd_0, 10);
1364    /// *grd_0 = 20;
1365    /// PrisonValueMut::unguard(grd_0);
1366    /// prison.visit_ref(key_0, |val_0| {
1367    ///     assert_eq!(*val_0, 20);
1368    ///     Ok(())
1369    /// });
1370    /// # Ok(())
1371    /// # }
1372    /// ```
1373    /// ## Errors
1374    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
1375    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if element has any number of immutable references
1376    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
1377    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted *OR* the [CellKey] generation does not match
1378    /// ### Example
1379    /// ```rust
1380    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1381    /// # fn main() -> Result<(), AccessError> {
1382    /// let prison: Prison<u32> = Prison::with_capacity(2);
1383    /// let key_0 = prison.insert(10)?;
1384    /// let key_1_a = prison.insert(20)?;
1385    /// let key_out_of_bounds = CellKey::from_raw_parts(10, 0);
1386    /// prison.remove(key_1_a)?;
1387    /// let key_1_b = prison.insert(30)?;
1388    /// let mut grd_0 = prison.guard_mut(key_0)?;
1389    /// assert!(prison.guard_mut(key_0).is_err());
1390    /// assert!(prison.guard_mut(key_out_of_bounds).is_err());
1391    /// assert!(prison.guard_mut(key_1_a).is_err());
1392    /// # Ok(())
1393    /// # }
1394    /// ```
1395    #[must_use = "guarded reference will immediately fall out of scope"]
1396    pub fn guard_mut<'a>(&'a self, key: CellKey) -> Result<PrisonValueMut<'a, T>, AccessError> {
1397        let (cell, visits) = self._add_mut_ref(key.idx, key.gen, true)?;
1398        return Ok(PrisonValueMut {
1399            cell,
1400            prison_accesses: visits,
1401        });
1402    }
1403
1404    //FN Prison::guard_ref()
1405    /// Return a [PrisonValueRef] that contains an immutable reference to the element and wraps it in
1406    /// guarding data that automatically decrements its reference count it when it goes out of scope.
1407    ///
1408    /// [PrisonValueRef<T>] implements [Deref<Target = T>], [AsRef<T>], and
1409    /// [Borrow<T>] to allow transparent access to its underlying value
1410    ///
1411    /// As long as the [PrisonValueRef] remains in scope, the element where it's value resides in the
1412    /// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
1413    /// You can manually drop the [PrisonValueRef] out of scope by passing it as the first parameter
1414    /// to the function [PrisonValueRef::unguard(p_val_ref)]
1415    /// ### Example
1416    /// ```rust
1417    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
1418    /// # fn main() -> Result<(), AccessError> {
1419    /// let prison: Prison<u32> = Prison::new();
1420    /// let key_0 = prison.insert(10)?;
1421    /// let grd_0 = prison.guard_ref(key_0)?;
1422    /// assert_eq!(*grd_0, 10);
1423    /// prison.visit_ref(key_0, |val_0| {
1424    ///     assert_eq!(*val_0, 10);
1425    ///     Ok(())
1426    /// });
1427    /// assert_eq!(*grd_0, 10);
1428    /// PrisonValueRef::unguard(grd_0);
1429    /// # Ok(())
1430    /// # }
1431    /// ```
1432    /// ## Errors
1433    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
1434    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references already
1435    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
1436    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted *OR* the [CellKey] generation doe not match
1437    /// ### Example
1438    /// ```rust
1439    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
1440    /// # fn main() -> Result<(), AccessError> {
1441    /// let prison: Prison<u32> = Prison::with_capacity(2);
1442    /// let key_0 = prison.insert(10)?;
1443    /// let key_1_a = prison.insert(20)?;
1444    /// let key_out_of_bounds = CellKey::from_raw_parts(10, 0);
1445    /// prison.remove(key_1_a)?;
1446    /// let key_1_b = prison.insert(30)?;
1447    /// let grd_0 = prison.guard_ref(key_0)?;
1448    /// assert!(prison.guard_mut(key_0).is_err());
1449    /// assert!(prison.guard_ref(key_out_of_bounds).is_err());
1450    /// assert!(prison.guard_ref(key_1_a).is_err());
1451    /// # Ok(())
1452    /// # }
1453    /// ```
1454    #[must_use = "guarded reference will immediately fall out of scope"]
1455    pub fn guard_ref<'a>(&'a self, key: CellKey) -> Result<PrisonValueRef<'a, T>, AccessError> {
1456        let (cell, visits) = self._add_imm_ref(key.idx, key.gen, true)?;
1457        return Ok(PrisonValueRef {
1458            cell,
1459            prison_accesses: visits,
1460        });
1461    }
1462
1463    //FN Prison::guard_mut_idx()
1464    /// Return a [PrisonValueMut] that contains a mutable reference to the element and wraps it in
1465    /// guarding data that automatically frees its reference count it when it goes out of scope.
1466    ///
1467    /// Smilar to `guard_mut()` but ignores the generation counter
1468    ///
1469    /// [PrisonValueMut<T>] implements [Deref<Target = T>], [DerefMut<Target = T>], [AsRef<T>], [AsMut<T>],
1470    /// [Borrow<T>], and [BorrowMut<T>] to allow transparent access to its underlying value
1471    ///
1472    /// As long as the [PrisonValueMut] remains in scope, the element where it's value resides in the
1473    /// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
1474    /// You can manually drop the [PrisonValueMut] out of scope by passing it as the first parameter
1475    /// to the function [PrisonValueMut::unguard(p_val_mut)]
1476    /// ### Example
1477    /// ```rust
1478    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1479    /// # fn main() -> Result<(), AccessError> {
1480    /// let prison: Prison<u32> = Prison::new();
1481    /// prison.insert(10)?;
1482    /// let mut grd_0 = prison.guard_mut_idx(0)?;
1483    /// assert_eq!(*grd_0, 10);
1484    /// *grd_0 = 20;
1485    /// PrisonValueMut::unguard(grd_0);
1486    /// prison.visit_ref_idx(0, |val_0| {
1487    ///     assert_eq!(*val_0, 20);
1488    ///     Ok(())
1489    /// });
1490    /// # Ok(())
1491    /// # }
1492    /// ```
1493    /// ## Errors
1494    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
1495    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if element has any number of immutable references
1496    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
1497    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted
1498    /// ### Example
1499    /// ```rust
1500    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1501    /// # fn main() -> Result<(), AccessError> {
1502    /// let prison: Prison<u32> = Prison::with_capacity(2);
1503    /// prison.insert(10)?;
1504    /// prison.insert(20)?;
1505    /// prison.remove_idx(1)?;
1506    /// let mut grd_0 = prison.guard_mut_idx(0)?;
1507    /// assert!(prison.guard_mut_idx(0).is_err());
1508    /// assert!(prison.guard_mut_idx(5).is_err());
1509    /// assert!(prison.guard_mut_idx(1).is_err());
1510    /// # Ok(())
1511    /// # }
1512    /// ```
1513    #[must_use = "guarded reference will immediately fall out of scope"]
1514    pub fn guard_mut_idx<'a>(&'a self, idx: usize) -> Result<PrisonValueMut<'a, T>, AccessError> {
1515        let (cell, visits) = self._add_mut_ref(idx, 0, false)?;
1516        return Ok(PrisonValueMut {
1517            cell,
1518            prison_accesses: visits,
1519        });
1520    }
1521
1522    //FN Prison::guard_ref_idx()
1523    /// Return a [PrisonValueRef] that contains an immutable reference to the element and wraps it in
1524    /// guarding data that automatically decrements its reference count it when it goes out of scope.
1525    ///
1526    /// Similar to `guard_ref()` but ignores the generation counter
1527    ///
1528    /// [PrisonValueRef<T>] implements [Deref<Target = T>], [AsRef<T>], and
1529    /// [Borrow<T>] to allow transparent access to its underlying value
1530    ///
1531    /// As long as the [PrisonValueRef] remains in scope, the element where it's value resides in the
1532    /// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
1533    /// You can manually drop the [PrisonValueRef] out of scope by passing it as the first parameter
1534    /// to the function [PrisonValueRef::unguard(p_val_ref)]
1535    /// ### Example
1536    /// ```rust
1537    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
1538    /// # fn main() -> Result<(), AccessError> {
1539    /// let prison: Prison<u32> = Prison::new();
1540    /// prison.insert(10)?;
1541    /// let grd_0 = prison.guard_ref_idx(0)?;
1542    /// assert_eq!(*grd_0, 10);
1543    /// prison.visit_ref_idx(0, |val_0| {
1544    ///     assert_eq!(*val_0, 10);
1545    ///     Ok(())
1546    /// });
1547    /// assert_eq!(*grd_0, 10);
1548    /// PrisonValueRef::unguard(grd_0);
1549    /// # Ok(())
1550    /// # }
1551    /// ```
1552    /// ## Errors
1553    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if element is already mutably referenced
1554    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references already
1555    /// - [AccessError::IndexOutOfRange(idx)] if the [CellKey] index is out of range
1556    /// - [AccessError::ValueDeleted(idx, gen)] if the cell is marked as free/deleted *OR* the [CellKey] generation doe not match
1557    /// ### Example
1558    /// ```rust
1559    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
1560    /// # fn main() -> Result<(), AccessError> {
1561    /// let prison: Prison<u32> = Prison::with_capacity(2);
1562    /// prison.insert(10)?;
1563    /// prison.insert(20)?;
1564    /// prison.remove_idx(1)?;
1565    /// let grd_0 = prison.guard_ref_idx(0)?;
1566    /// assert!(prison.guard_mut_idx(0).is_err());
1567    /// assert!(prison.guard_ref_idx(5).is_err());
1568    /// assert!(prison.guard_ref_idx(1).is_err());
1569    /// # Ok(())
1570    /// # }
1571    /// ```
1572    #[must_use = "guarded reference will immediately fall out of scope"]
1573    pub fn guard_ref_idx<'a>(&'a self, idx: usize) -> Result<PrisonValueRef<'a, T>, AccessError> {
1574        let (cell, visits) = self._add_imm_ref(idx, 0, false)?;
1575        return Ok(PrisonValueRef {
1576            cell,
1577            prison_accesses: visits,
1578        });
1579    }
1580
1581    //FN Prison::guard_many_mut()
1582    /// Return a [PrisonSliceMut] that marks all the elements as mutably referenced and wraps
1583    /// them in guarding data that automatically frees their mutable reference counts when it goes out of range.
1584    ///
1585    /// [PrisonSliceMut<T>] implements [Deref<Target = \[&mut T\]>](Deref), [DerefMut<Target = \[&mut T\]>](DerefMut), [AsRef<\[&mut T\]>](AsRef), [AsMut<\[&mut T\]>](AsMut),
1586    /// [Borrow<\[&mut T\]>](Borrow), and [BorrowMut<\[&mut T\]>](BorrowMut) to allow transparent access to its underlying slice of values
1587    ///
1588    /// As long as the [PrisonSliceMut] remains in scope, the elements where it's values reside in the
1589    /// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
1590    /// You can manually drop the [PrisonSliceMut] out of scope by passing it as the first parameter
1591    /// to the function [PrisonSliceMut::unguard(p_sli_mut)]
1592    /// ### Example
1593    /// ```rust
1594    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
1595    /// # fn main() -> Result<(), AccessError> {
1596    /// let prison: Prison<u32> = Prison::new();
1597    /// let key_0 = prison.insert(10)?;
1598    /// let key_1 = prison.insert(20)?;
1599    /// let key_2 = prison.insert(30)?;
1600    /// let mut grd_0_1_2 = prison.guard_many_mut(&[key_0, key_1, key_2])?;
1601    /// assert_eq!(*grd_0_1_2[0], 10);
1602    /// *grd_0_1_2[0] = 20;
1603    /// PrisonSliceMut::unguard(grd_0_1_2);
1604    /// prison.visit_many_ref(&[key_0, key_1, key_2], |vals_0_1_2| {
1605    ///     assert_eq!(*vals_0_1_2[0], 20);
1606    ///     Ok(())
1607    /// });
1608    /// # Ok(())
1609    /// # }
1610    /// ```
1611    /// ## Errors
1612    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1613    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if any element has any number of immutable references
1614    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1615    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted *OR* the [CellKey] generation doesnt match
1616    /// ### Example
1617    /// ```rust
1618    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
1619    /// # fn main() -> Result<(), AccessError> {
1620    /// let prison: Prison<u32> = Prison::new();
1621    /// let key_0 = prison.insert(10)?;
1622    /// let key_1 = prison.insert(20)?;
1623    /// let key_2 = prison.insert(30)?;
1624    /// let key_4_a = prison.insert(40)?;
1625    /// prison.remove(key_4_a)?;
1626    /// let key_4_b = prison.insert(44)?;
1627    /// let key_out_of_bounds = CellKey::from_raw_parts(10, 1);
1628    /// let mut grd_0_1_2 = prison.guard_many_mut(&[key_0, key_1, key_2])?;
1629    /// assert!(prison.guard_many_mut(&[key_0, key_1, key_2, key_4_b]).is_err());
1630    /// assert!(prison.guard_many_mut(&[key_out_of_bounds]).is_err());
1631    /// assert!(prison.guard_many_mut(&[key_4_a]).is_err());
1632    /// # Ok(())
1633    /// # }
1634    /// ```
1635    #[must_use = "guarded reference will immediately fall out of scope"]
1636    pub fn guard_many_mut<'a>(
1637        &'a self,
1638        keys: &[CellKey],
1639    ) -> Result<PrisonSliceMut<'a, T>, AccessError> {
1640        let (vals, refs, prison_accesses) = self._add_many_mut_refs(keys)?;
1641        return Ok(PrisonSliceMut {
1642            vals,
1643            refs,
1644            prison_accesses,
1645        });
1646    }
1647
1648    //FN Prison::guard_many_ref()
1649    /// Return a [PrisonSliceRef] that marks all the elements as immutably referenced and wraps
1650    /// them in guarding data that automatically decreases their immutable reference counts when it goes out of range.
1651    ///
1652    /// [PrisonSliceRef<T>] implements [Deref<Target = \[&T\]>](Deref), [AsRef<\[&T\]>](AsRef),
1653    /// and [Borrow<\[&T\]>](Borrow), to allow transparent access to its underlying slice of values
1654    ///
1655    /// As long as the [PrisonSliceRef] remains in scope, the elements where it's values reside in the
1656    /// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
1657    /// You can manually drop the [PrisonSliceRef] out of scope by passing it as the first parameter
1658    /// to the function [PrisonSliceRef::unguard(p_sli_ref)]
1659    /// ### Example
1660    /// ```rust
1661    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
1662    /// # fn main() -> Result<(), AccessError> {
1663    /// let prison: Prison<u32> = Prison::new();
1664    /// let key_0 = prison.insert(10)?;
1665    /// let key_1 = prison.insert(20)?;
1666    /// let key_2 = prison.insert(30)?;
1667    /// let mut grd_0_1_2 = prison.guard_many_ref(&[key_0, key_1, key_2])?;
1668    /// assert_eq!(*grd_0_1_2[0], 10);
1669    /// prison.visit_many_ref(&[key_0, key_1, key_2], |vals_0_1_2| {
1670    ///     assert_eq!(*vals_0_1_2[0], 10);
1671    ///     Ok(())
1672    /// });
1673    /// PrisonSliceRef::unguard(grd_0_1_2);
1674    /// # Ok(())
1675    /// # }
1676    /// ```
1677    /// ## Errors
1678    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1679    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references to any element
1680    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1681    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted *OR* if the [CellKey] generation doesn't match
1682    /// ### Example
1683    /// ```rust
1684    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1685    /// # fn main() -> Result<(), AccessError> {
1686    /// let prison: Prison<u32> = Prison::new();
1687    /// let key_0 = prison.insert(10)?;
1688    /// let key_1 = prison.insert(20)?;
1689    /// let key_2 = prison.insert(30)?;
1690    /// let key_4_a = prison.insert(40)?;
1691    /// prison.remove(key_4_a)?;
1692    /// let key_4_b = prison.insert(44)?;
1693    /// let key_out_of_bounds = CellKey::from_raw_parts(10, 1);
1694    /// let grd_0_1_2 = prison.guard_many_ref(&[key_0, key_1, key_2])?;
1695    /// assert!(prison.guard_many_mut(&[key_0]).is_err());
1696    /// assert!(prison.guard_many_ref(&[key_out_of_bounds]).is_err());
1697    /// assert!(prison.guard_many_ref(&[key_4_a]).is_err());
1698    /// # Ok(())
1699    /// # }
1700    /// ```
1701    #[must_use = "guarded reference will immediately fall out of scope"]
1702    pub fn guard_many_ref<'a>(
1703        &'a self,
1704        keys: &[CellKey],
1705    ) -> Result<PrisonSliceRef<'a, T>, AccessError> {
1706        let (vals, refs, prison_accesses) = self._add_many_imm_refs(keys)?;
1707        return Ok(PrisonSliceRef {
1708            vals,
1709            refs,
1710            prison_accesses,
1711        });
1712    }
1713
1714    //FN Prison::guard_many_mut_idx()
1715    /// Return a [PrisonSliceMut] that marks all the elements as mutably referenced and wraps
1716    /// them in guarding data that automatically frees their mutable reference counts when it goes out of range.
1717    ///
1718    /// Similar to `guard_many_mut()` but ignores the generation counter
1719    ///
1720    /// [PrisonSliceMut<T>] implements [Deref<Target = \[&mut T\]>](Deref), [DerefMut<Target = \[&mut T\]>](DerefMut), [AsRef<\[&mut T\]>](AsRef), [AsMut<\[&mut T\]>](AsMut),
1721    /// [Borrow<\[&mut T\]>](Borrow), and [BorrowMut<\[&mut T\]>](BorrowMut) to allow transparent access to its underlying slice of values
1722    ///
1723    /// As long as the [PrisonSliceMut] remains in scope, the elements where it's values reside in the
1724    /// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
1725    /// You can manually drop the [PrisonSliceMut] out of scope by passing it as the first parameter
1726    /// to the function [PrisonSliceMut::unguard(p_sli_mut)]
1727    /// ### Example
1728    /// ```rust
1729    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
1730    /// # fn main() -> Result<(), AccessError> {
1731    /// let prison: Prison<u32> = Prison::new();
1732    /// prison.insert(10)?;
1733    /// prison.insert(20)?;
1734    /// prison.insert(30)?;
1735    /// let mut grd_0_1_2 = prison.guard_many_mut_idx(&[0, 1, 2])?;
1736    /// assert_eq!(*grd_0_1_2[0], 10);
1737    /// *grd_0_1_2[0] = 20;
1738    /// PrisonSliceMut::unguard(grd_0_1_2);
1739    /// prison.visit_many_ref_idx(&[0, 1, 2], |vals_0_1_2| {
1740    ///     assert_eq!(*vals_0_1_2[0], 20);
1741    ///     Ok(())
1742    /// });
1743    /// # Ok(())
1744    /// # }
1745    /// ```
1746    /// ## Errors
1747    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1748    /// - [AccessError::ValueStillImmutablyReferenced(idx)] if any element has any number of immutable references
1749    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1750    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted
1751    /// ### Example
1752    /// ```rust
1753    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
1754    /// # fn main() -> Result<(), AccessError> {
1755    /// let prison: Prison<u32> = Prison::new();
1756    /// prison.insert(10)?;
1757    /// prison.insert(20)?;
1758    /// prison.insert(30)?;
1759    /// prison.insert(40)?;
1760    /// prison.remove_idx(3)?;
1761    /// let mut grd_0_1_2 = prison.guard_many_mut_idx(&[0, 1, 2])?;
1762    /// assert!(prison.guard_many_mut_idx(&[0, 1, 2]).is_err());
1763    /// assert!(prison.guard_many_mut_idx(&[5]).is_err());
1764    /// assert!(prison.guard_many_mut_idx(&[3]).is_err());
1765    /// # Ok(())
1766    /// # }
1767    /// ```
1768    #[must_use = "guarded reference will immediately fall out of scope"]
1769    pub fn guard_many_mut_idx<'a>(
1770        &'a self,
1771        indexes: &[usize],
1772    ) -> Result<PrisonSliceMut<'a, T>, AccessError> {
1773        let (vals, refs, prison_accesses) = self._add_many_mut_refs_idx(indexes)?;
1774        return Ok(PrisonSliceMut {
1775            vals,
1776            refs,
1777            prison_accesses,
1778        });
1779    }
1780
1781    //FN Prison::guard_many_ref_idx()
1782    /// Return a [PrisonSliceRef] that marks all the elements as immutably referenced and wraps
1783    /// them in guarding data that automatically decreases their immutable reference counts when it goes out of range.
1784    ///
1785    /// Similar to `guard_many_ref()` but ignores the generation counter
1786    ///
1787    /// [PrisonSliceRef<T>] implements [Deref<Target = \[&T\]>](Deref), [AsRef<\[&T\]>](AsRef),
1788    /// and [Borrow<\[&T\]>](Borrow), to allow transparent access to its underlying slice of values
1789    ///
1790    /// As long as the [PrisonSliceRef] remains in scope, the elements where it's values reside in the
1791    /// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
1792    /// You can manually drop the [PrisonSliceRef] out of scope by passing it as the first parameter
1793    /// to the function [PrisonSliceRef::unguard(p_sli_ref)]
1794    /// ### Example
1795    /// ```rust
1796    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
1797    /// # fn main() -> Result<(), AccessError> {
1798    /// let prison: Prison<u32> = Prison::new();
1799    /// prison.insert(10)?;
1800    /// prison.insert(20)?;
1801    /// prison.insert(30)?;
1802    /// let mut grd_0_1_2 = prison.guard_many_ref_idx(&[0, 1, 2])?;
1803    /// assert_eq!(*grd_0_1_2[0], 10);
1804    /// prison.visit_many_ref_idx(&[0, 1, 2], |vals_0_1_2| {
1805    ///     assert_eq!(*vals_0_1_2[0], 10);
1806    ///     Ok(())
1807    /// });
1808    /// PrisonSliceRef::unguard(grd_0_1_2);
1809    /// # Ok(())
1810    /// # }
1811    /// ```
1812    /// ## Errors
1813    /// - [AccessError::ValueAlreadyMutablyReferenced(idx)] if any element is already mutably referenced
1814    /// - [AccessError::MaximumImmutableReferencesReached(idx)] if you created [usize::MAX] - 2 immutable references to any element
1815    /// - [AccessError::IndexOutOfRange(idx)] if any index is out of range
1816    /// - [AccessError::ValueDeleted(idx, gen)] if any cell is marked as free/deleted
1817    /// ### Example
1818    /// ```rust
1819    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1820    /// # fn main() -> Result<(), AccessError> {
1821    /// let prison: Prison<u32> = Prison::new();
1822    /// prison.insert(10)?;
1823    /// prison.insert(20)?;
1824    /// prison.insert(30)?;
1825    /// prison.insert(40)?;
1826    /// prison.remove_idx(3)?;
1827    /// let grd_0_1_2 = prison.guard_many_ref_idx(&[0, 1, 2])?;
1828    /// assert!(prison.guard_many_mut_idx(&[0]).is_err());
1829    /// assert!(prison.guard_many_ref_idx(&[5]).is_err());
1830    /// assert!(prison.guard_many_ref_idx(&[3]).is_err());
1831    /// # Ok(())
1832    /// # }
1833    /// ```
1834    #[must_use = "guarded reference will immediately fall out of scope"]
1835    pub fn guard_many_ref_idx<'a>(
1836        &'a self,
1837        indexes: &[usize],
1838    ) -> Result<PrisonSliceRef<'a, T>, AccessError> {
1839        let (vals, refs, prison_accesses) = self._add_many_imm_refs_idx(indexes)?;
1840        return Ok(PrisonSliceRef {
1841            vals,
1842            refs,
1843            prison_accesses,
1844        });
1845    }
1846
1847    //FN Prison::guard_slice_mut()
1848    /// Return a [PrisonSliceMut] that marks all the elements as mutably referenced and wraps
1849    /// them in guarding data that automatically frees their mutable reference counts when it goes out of range.
1850    ///
1851    /// Internally this is strictly identical to passing [Prison::guard_many_mut_idx()] a list of all
1852    /// indexes in the slice range, and is subject to all the same restrictions and errors
1853    /// ### Example
1854    /// ```rust
1855    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
1856    /// # fn main() -> Result<(), AccessError> {
1857    /// let u32_prison: Prison<u32> = Prison::new();
1858    /// u32_prison.insert(42)?;
1859    /// u32_prison.insert(43)?;
1860    /// u32_prison.insert(44)?;
1861    /// u32_prison.insert(45)?;
1862    /// u32_prison.insert(46)?;
1863    /// let grd_last_three = u32_prison.guard_slice_mut(2..5)?;
1864    /// assert_eq!(*grd_last_three[0], 44);
1865    /// assert_eq!(*grd_last_three[1], 45);
1866    /// assert_eq!(*grd_last_three[2], 46);
1867    /// # Ok(())
1868    /// # }
1869    /// ```
1870    /// Any standard [Range<usize>](std::ops::Range) notation is allowed as the first paramater,
1871    /// but care must be taken because it is not guaranteed every index within range is a valid
1872    /// value or does not have any other references to it that would violate Rust's memory safety.
1873    /// ### Example
1874    /// ```rust
1875    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::Prison};
1876    /// # fn main() -> Result<(), AccessError> {
1877    /// let u32_prison: Prison<u32> = Prison::new();
1878    /// u32_prison.insert(42)?;
1879    /// u32_prison.insert(43)?;
1880    /// u32_prison.insert(44)?;
1881    /// u32_prison.insert(45)?;
1882    /// u32_prison.insert(46)?;
1883    /// assert!(u32_prison.guard_slice_mut(2..5).is_ok());
1884    /// assert!(u32_prison.guard_slice_mut(2..=4).is_ok());
1885    /// assert!(u32_prison.guard_slice_mut(2..).is_ok());
1886    /// assert!(u32_prison.guard_slice_mut(..3).is_ok());
1887    /// assert!(u32_prison.guard_slice_mut(..=3).is_ok());
1888    /// assert!(u32_prison.guard_slice_mut(..).is_ok());
1889    /// u32_prison.remove_idx(2)?;
1890    /// assert!(u32_prison.guard_slice_mut(..).is_err());
1891    /// # Ok(())
1892    /// # }
1893    /// ```
1894    /// See [Prison::guard_many_mut_idx()] for more info
1895    #[must_use = "guarded reference will immediately fall out of scope"]
1896    pub fn guard_slice_mut<'a, R>(&'a self, range: R) -> Result<PrisonSliceMut<'a, T>, AccessError>
1897    where
1898        R: RangeBounds<usize>,
1899    {
1900        let (start, end) = extract_true_start_end(range, self.vec_len());
1901        let idxs: Vec<usize> = (start..end).into_iter().collect();
1902        return self.guard_many_mut_idx(&idxs);
1903    }
1904
1905    //FN Prison::guard_slice_ref()
1906    /// Return a [PrisonSliceRef] that marks all the elements as immutably referenced and wraps
1907    /// them in guarding data that automatically decreases their immutable reference counts when it goes out of range.
1908    ///
1909    /// Internally this is strictly identical to passing [Prison::guard_many_ref_idx()] a list of all
1910    /// indexes in the slice range, and is subject to all the same restrictions and errors
1911    /// ### Example
1912    /// ```rust
1913    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
1914    /// # fn main() -> Result<(), AccessError> {
1915    /// let u32_prison: Prison<u32> = Prison::new();
1916    /// u32_prison.insert(42)?;
1917    /// u32_prison.insert(43)?;
1918    /// u32_prison.insert(44)?;
1919    /// u32_prison.insert(45)?;
1920    /// u32_prison.insert(46)?;
1921    /// let grd_last_three = u32_prison.guard_slice_ref(2..5)?;
1922    /// let grd_all = u32_prison.guard_slice_ref(..)?;
1923    /// assert_eq!(*grd_all[0], 42);
1924    /// assert_eq!(*grd_all[1], 43);
1925    /// assert_eq!(*grd_last_three[0], 44);
1926    /// assert_eq!(*grd_last_three[1], 45);
1927    /// assert_eq!(*grd_last_three[2], 46);
1928    /// # Ok(())
1929    /// # }
1930    /// ```
1931    /// Any standard [Range<usize>](std::ops::Range) notation is allowed as the first paramater,
1932    /// but care must be taken because it is not guaranteed every index within range is a valid
1933    /// value or does not have any other references to it that would violate Rust's memory safety.
1934    /// ### Example
1935    /// ```rust
1936    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
1937    /// # fn main() -> Result<(), AccessError> {
1938    /// let u32_prison: Prison<u32> = Prison::new();
1939    /// u32_prison.insert(42)?;
1940    /// u32_prison.insert(43)?;
1941    /// u32_prison.insert(44)?;
1942    /// u32_prison.insert(45)?;
1943    /// u32_prison.insert(46)?;
1944    /// assert!(u32_prison.guard_slice_ref(2..5).is_ok());
1945    /// assert!(u32_prison.guard_slice_ref(2..=4).is_ok());
1946    /// assert!(u32_prison.guard_slice_ref(2..).is_ok());
1947    /// assert!(u32_prison.guard_slice_ref(..3).is_ok());
1948    /// assert!(u32_prison.guard_slice_ref(..=3).is_ok());
1949    /// assert!(u32_prison.guard_slice_ref(..).is_ok());
1950    /// u32_prison.remove_idx(2)?;
1951    /// assert!(u32_prison.guard_slice_ref(..).is_err());
1952    /// # Ok(())
1953    /// # }
1954    /// ```
1955    /// See [Prison::guard_many_ref_idx()] for more info
1956    #[must_use = "guarded reference will immediately fall out of scope"]
1957    pub fn guard_slice_ref<'a, R>(&'a self, range: R) -> Result<PrisonSliceRef<'a, T>, AccessError>
1958    where
1959        R: RangeBounds<usize>,
1960    {
1961        let (start, end) = extract_true_start_end(range, self.vec_len());
1962        let idxs: Vec<usize> = (start..end).into_iter().collect();
1963        return self.guard_many_ref_idx(&idxs);
1964    }
1965
1966    //FN Prison::clone_val()
1967    /// Clones the requested value out of the [Prison] into a new variable
1968    ///
1969    /// Only available when elements of type T implement [Clone] (it is assumed that the implementation of `T::clone()` is memory safe).
1970    ///
1971    /// Because cloning does not alter the original, and because the new variable to hold the clone does not have any presumtions about the value, it
1972    /// is safe (in a single-threaded context) to clone out the value even if it is being visited or guarded.
1973    ///
1974    /// This method *will* still return an error if the index or generation of the [CellKey] are invalid
1975    /// ### Example
1976    /// ```rust
1977    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
1978    /// # fn main() -> Result<(), AccessError> {
1979    /// let prison: Prison<String> = Prison::new();
1980    /// let key_0 = prison.insert(String::from("Foo"))?;
1981    /// let key_1 = prison.insert(String::from("Bar"))?;
1982    /// let mut take_foo = String::new();
1983    /// let mut take_bar = String::new();
1984    /// prison.visit_mut(key_0, |val_0| {
1985    ///     take_foo = prison.clone_val(key_0)?;
1986    ///     Ok(())
1987    /// });
1988    /// let grd_1 = prison.guard_mut(key_1)?;
1989    /// take_bar = prison.clone_val(key_1)?;
1990    /// PrisonValueMut::unguard(grd_1);
1991    /// assert_eq!(take_foo, String::from("Foo"));
1992    /// assert_eq!(take_bar, String::from("Bar"));
1993    /// prison.remove(key_1)?;
1994    /// assert!(prison.clone_val(CellKey::from_raw_parts(10, 10)).is_err());
1995    /// assert!(prison.clone_val(key_1).is_err());
1996    /// # Ok(())
1997    /// # }
1998    /// ```
1999    pub fn clone_val(&self, key: CellKey) -> Result<T, AccessError>
2000    where
2001        T: Clone,
2002    {
2003        let internal = internal!(self);
2004        if key.idx >= internal.vec.len() {
2005            return Err(AccessError::IndexOutOfRange(key.idx));
2006        }
2007        match &internal.vec[key.idx] {
2008            cell if cell.is_cell_and_gen_match(key.gen) => {
2009                return Ok(unsafe { cell.val.assume_init_ref().clone() });
2010            }
2011            _ => return Err(AccessError::ValueDeleted(key.idx, key.gen)),
2012        }
2013    }
2014
2015    //FN Prison::clone_val_idx()
2016    /// Clones the requested value out of the [Prison] into a new variable
2017    ///
2018    /// Same as `clone_val()` but ignores the generation counter
2019    ///
2020    /// Only available when elements of type T implement [Clone] (it is assumed that the implementation of `T::clone()` is memory safe).
2021    ///
2022    /// Because cloning does not alter the original, and because the new variable to hold the clone does not have any presumtions about the value, it
2023    /// is safe (in a single-threaded context) to clone out the value even if it is being visited or guarded.
2024    ///
2025    /// This method *will* still return an error if the index is invalid or the value is free/deleted
2026    /// ### Example
2027    /// ```rust
2028    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
2029    /// # fn main() -> Result<(), AccessError> {
2030    /// let prison: Prison<String> = Prison::new();
2031    /// prison.insert(String::from("Foo"))?;
2032    /// prison.insert(String::from("Bar"))?;
2033    /// let mut take_foo = String::new();
2034    /// let mut take_bar = String::new();
2035    /// prison.visit_mut_idx(0, |val_0| {
2036    ///     take_foo = prison.clone_val_idx(0)?;
2037    ///     Ok(())
2038    /// });
2039    /// let grd_1 = prison.guard_mut_idx(1)?;
2040    /// take_bar = prison.clone_val_idx(1)?;
2041    /// PrisonValueMut::unguard(grd_1);
2042    /// assert_eq!(take_foo, String::from("Foo"));
2043    /// assert_eq!(take_bar, String::from("Bar"));
2044    /// prison.remove_idx(1)?;
2045    /// assert!(prison.clone_val_idx(10).is_err());
2046    /// assert!(prison.clone_val_idx(1).is_err());
2047    /// # Ok(())
2048    /// # }
2049    /// ```
2050    pub fn clone_val_idx(&self, idx: usize) -> Result<T, AccessError>
2051    where
2052        T: Clone,
2053    {
2054        let internal = internal!(self);
2055        if idx >= internal.vec.len() {
2056            return Err(AccessError::IndexOutOfRange(idx));
2057        }
2058        match &internal.vec[idx] {
2059            cell if cell.is_cell() => {
2060                return Ok(unsafe { cell.val.assume_init_ref().clone() });
2061            }
2062            _ => return Err(AccessError::ValueDeleted(idx, 0)),
2063        }
2064    }
2065
2066    //FN Prison::clone_many_vals()
2067    /// Clones the requested values out of the [Prison] into a new [Vec<T>]
2068    ///
2069    /// Only available when elements of type T implement [Clone] (it is assumed that the implementation of `T::clone()` is memory safe).
2070    ///
2071    /// Because cloning does not alter the originals, and because the new variables to hold the clones do not have any presumtions about the values, it
2072    /// is safe (in a single-threaded context) to clone out the values even if they are being visited or guarded.
2073    ///
2074    /// This method *will* still return an error if any index or generation of the [CellKey]s are invalid
2075    /// ### Example
2076    /// ```rust
2077    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
2078    /// # fn main() -> Result<(), AccessError> {
2079    /// let prison: Prison<String> = Prison::new();
2080    /// let key_0 = prison.insert(String::from("Foo"))?;
2081    /// let key_1 = prison.insert(String::from("Bar"))?;
2082    /// let mut take_foobar: Vec<String> = Vec::new();
2083    /// prison.visit_mut(key_0, |val_0| {
2084    ///     let grd_1 = prison.guard_mut(key_1)?;
2085    ///     take_foobar = prison.clone_many_vals(&[key_0, key_1])?;
2086    ///     PrisonValueMut::unguard(grd_1);
2087    ///     Ok(())
2088    /// });
2089    /// assert_eq!(take_foobar[0], String::from("Foo"));
2090    /// assert_eq!(take_foobar[1], String::from("Bar"));
2091    /// prison.remove(key_1)?;
2092    /// assert!(prison.clone_many_vals(&[CellKey::from_raw_parts(10, 10)]).is_err());
2093    /// assert!(prison.clone_many_vals(&[key_1]).is_err());
2094    /// # Ok(())
2095    /// # }
2096    /// ```
2097    pub fn clone_many_vals(&self, keys: &[CellKey]) -> Result<Vec<T>, AccessError>
2098    where
2099        T: Clone,
2100    {
2101        let mut vals = Vec::with_capacity(keys.len());
2102        for key in keys {
2103            vals.push(self.clone_val(*key)?);
2104        }
2105        return Ok(vals);
2106    }
2107
2108    //FN Prison::clone_many_vals_idx()
2109    /// Clones the requested values out of the [Prison] into a new [Vec<T>]
2110    ///
2111    /// Same as `clone_many_vals()` but ignores the generation counter
2112    ///
2113    /// Only available when elements of type T implement [Clone] (it is assumed that the implementation of `T::clone()` is memory safe).
2114    ///
2115    /// Because cloning does not alter the originals, and because the new variables to hold the clones do not have any presumtions about the values, it
2116    /// is safe (in a single-threaded context) to clone out the values even if they are being visited or guarded.
2117    ///
2118    /// This method *will* still return an error if any index is out-of-range or free/deleted
2119    /// ### Example
2120    /// ```rust
2121    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
2122    /// # fn main() -> Result<(), AccessError> {
2123    /// let prison: Prison<String> = Prison::new();
2124    /// prison.insert(String::from("Foo"))?;
2125    /// prison.insert(String::from("Bar"))?;
2126    /// let mut take_foobar: Vec<String> = Vec::new();
2127    /// prison.visit_mut_idx(0, |val_0| {
2128    ///     let grd_1 = prison.guard_mut_idx(1)?;
2129    ///     take_foobar = prison.clone_many_vals_idx(&[0, 1])?;
2130    ///     PrisonValueMut::unguard(grd_1);
2131    ///     Ok(())
2132    /// });
2133    /// assert_eq!(take_foobar[0], String::from("Foo"));
2134    /// assert_eq!(take_foobar[1], String::from("Bar"));
2135    /// prison.remove_idx(1)?;
2136    /// assert!(prison.clone_many_vals_idx(&[10]).is_err());
2137    /// assert!(prison.clone_many_vals_idx(&[1]).is_err());
2138    /// # Ok(())
2139    /// # }
2140    /// ```
2141    pub fn clone_many_vals_idx(&self, indexes: &[usize]) -> Result<Vec<T>, AccessError>
2142    where
2143        T: Clone,
2144    {
2145        let mut vals = Vec::with_capacity(indexes.len());
2146        for idx in indexes {
2147            vals.push(self.clone_val_idx(*idx)?);
2148        }
2149        return Ok(vals);
2150    }
2151
2152    //FN: Prison::peek_ref()
2153    /// Get a reference to a value from it's associated [CellKey], ***ignoring reference counting and most other safety measures***
2154    ///
2155    /// Returns [`Ok(&T)`] if the value exists and the generation matches, [Err(AccessError::ValueDeleted(idx, gen))] otherwise
2156    ///
2157    /// This method is provided as a way for libraries depending on this code to perform niche
2158    /// optimized reads of contained values without the overhead of the normal safety checks,
2159    /// or when a mutable reference is active but you can statically confirm that the value will
2160    /// not be mutated from the begining of the returned `&T`'s lifetime to the end of it's lifetime.
2161    ///
2162    /// The returned references are intended to be short-lived and safely contained in a scope where no
2163    /// mutation of the [Prison] as a whole or ANY of its values takes place
2164    /// # Safety
2165    /// When you call this method and as long as the `&T` it returns remains in-scope/alive,
2166    /// you MUST ensure the following:
2167    /// - The value MUST NOT be mutated by ANY source, including active safe reference-counted mutable references
2168    /// - NO operation can be performed that could *potentially* cause the underlying memory address of the [Prison]'s data to relocate
2169    pub unsafe fn peek_ref<'a>(&'a self, key: CellKey) -> Result<&'a T, AccessError> {
2170        match &internal!(self).vec[key.idx] {
2171            cell if cell.is_cell_and_gen_match(key.gen) => {
2172                Ok(unsafe { &cell.val.assume_init_ref() })
2173            }
2174            _ => Err(AccessError::ValueDeleted(key.idx, key.gen)),
2175        }
2176    }
2177
2178    //FN: Prison::peek_ref_idx()
2179    /// Get a reference to a value from it's associated index, ***ignoring reference counting and most other safety measures***
2180    ///
2181    /// Returns [`Ok(&T)`] if the value exists, [Err(AccessError::ValueDeleted(idx, 0))] otherwise
2182    ///
2183    /// This method is provided as a way for libraries depending on this code to perform niche
2184    /// optimized reads of contained values without the overhead of the normal safety checks,
2185    /// or when a mutable reference is active but you can statically confirm that the value will
2186    /// not be mutated from the begining of the returned `&T`s lifetime to the end of it's lifetime.
2187    ///
2188    /// The returned references are intended to be short-lived and safely contained in a scope where no
2189    /// mutation of the [Prison] as a whole or ANY of its values takes place
2190    /// # Safety
2191    /// When you call this method and as long as the `&T` it returns remains in-scope/alive,
2192    /// you MUST ensure the following:
2193    /// - The value MUST NOT be mutated by ANY source, including active safe reference-counted mutable references
2194    /// - NO operation can be performed that could *potentially* cause the underlying memory address of the [Prison]'s data to relocate
2195    pub unsafe fn peek_ref_idx<'a>(&'a self, idx: usize) -> Result<&'a T, AccessError> {
2196        match &internal!(self).vec[idx] {
2197            cell if cell.is_cell() => Ok(unsafe { &cell.val.assume_init_ref() }),
2198            _ => Err(AccessError::ValueDeleted(idx, 0)),
2199        }
2200    }
2201
2202    //------ Prison Private ------
2203    //FN Prison::_add_mut_ref()
2204    #[doc(hidden)]
2205    fn _add_mut_ref(
2206        &self,
2207        idx: usize,
2208        gen: usize,
2209        use_gen: bool,
2210    ) -> Result<(&mut PrisonCell<T>, &mut usize), AccessError> {
2211        let internal = internal!(self);
2212        if idx >= internal.vec.len() {
2213            return Err(AccessError::IndexOutOfRange(idx));
2214        }
2215        match &mut internal.vec[idx] {
2216            cell if cell.is_cell_and_gen_match_opt(gen, use_gen) => {
2217                if cell.refs_or_next == Refs::MUT {
2218                    return Err(AccessError::ValueAlreadyMutablyReferenced(idx));
2219                }
2220                if cell.refs_or_next > 0 {
2221                    return Err(AccessError::ValueStillImmutablyReferenced(idx));
2222                }
2223                cell.refs_or_next = Refs::MUT;
2224                internal.access_count += 1;
2225                return Ok((cell, &mut internal.access_count));
2226            }
2227            _ => return Err(AccessError::ValueDeleted(idx, gen)),
2228        }
2229    }
2230
2231    //FN Prison::_add_imm_ref()
2232    #[doc(hidden)]
2233    fn _add_imm_ref(
2234        &self,
2235        idx: usize,
2236        gen: usize,
2237        use_gen: bool,
2238    ) -> Result<(&mut PrisonCell<T>, &mut usize), AccessError> {
2239        let internal = internal!(self);
2240        if idx >= internal.vec.len() {
2241            return Err(AccessError::IndexOutOfRange(idx));
2242        }
2243        match &mut internal.vec[idx] {
2244            cell if cell.is_cell_and_gen_match_opt(gen, use_gen) => {
2245                if cell.refs_or_next == Refs::MUT {
2246                    return Err(AccessError::ValueAlreadyMutablyReferenced(idx));
2247                }
2248                if cell.refs_or_next == Refs::MAX_IMMUT {
2249                    return Err(AccessError::MaximumImmutableReferencesReached(idx));
2250                }
2251                if cell.refs_or_next == 0 {
2252                    internal.access_count += 1;
2253                }
2254                cell.refs_or_next += 1;
2255                return Ok((cell, &mut internal.access_count));
2256            }
2257            _ => return Err(AccessError::ValueDeleted(idx, gen)),
2258        }
2259    }
2260
2261    //FN Prison::_add_many_mut_refs()
2262    #[doc(hidden)]
2263    fn _add_many_mut_refs(
2264        &self,
2265        cell_keys: &[CellKey],
2266    ) -> Result<(Vec<&mut T>, Vec<&mut usize>, &mut usize), AccessError> {
2267        let internal = internal!(self);
2268        let mut vals = Vec::new();
2269        let mut refs = Vec::new();
2270        let mut ref_all_result = Ok(());
2271        for key in cell_keys {
2272            let ref_result = self._add_mut_ref(key.idx, key.gen, true);
2273            match ref_result {
2274                Ok((cell, _)) => {
2275                    vals.push(unsafe { cell.val.assume_init_mut() });
2276                    refs.push(&mut cell.refs_or_next);
2277                }
2278                Err(e) => {
2279                    ref_all_result = Err(e);
2280                    break;
2281                }
2282            }
2283        }
2284        match ref_all_result {
2285            Ok(_) => {
2286                return Ok((vals, refs, &mut internal.access_count));
2287            }
2288            Err(acc_err) => {
2289                _remove_many_mut_refs(&mut refs, &mut internal.access_count);
2290                return Err(acc_err);
2291            }
2292        }
2293    }
2294
2295    //FN Prison::_add_many_mut_refs_idx()
2296    #[doc(hidden)]
2297    fn _add_many_mut_refs_idx(
2298        &self,
2299        idxs: &[usize],
2300    ) -> Result<(Vec<&mut T>, Vec<&mut usize>, &mut usize), AccessError> {
2301        let internal = internal!(self);
2302        let mut vals = Vec::new();
2303        let mut refs = Vec::new();
2304        let mut ref_all_result = Ok(());
2305        for idx in idxs {
2306            let ref_result = self._add_mut_ref(*idx, 0, false);
2307            match ref_result {
2308                Ok((cell, _)) => {
2309                    vals.push(unsafe { cell.val.assume_init_mut() });
2310                    refs.push(&mut cell.refs_or_next);
2311                }
2312                Err(e) => {
2313                    ref_all_result = Err(e);
2314                    break;
2315                }
2316            }
2317        }
2318        match ref_all_result {
2319            Ok(_) => {
2320                return Ok((vals, refs, &mut internal.access_count));
2321            }
2322            Err(acc_err) => {
2323                _remove_many_mut_refs(&mut refs, &mut internal.access_count);
2324                return Err(acc_err);
2325            }
2326        }
2327    }
2328
2329    //FN Prison::_add_many_imm_refs()
2330    #[doc(hidden)]
2331    fn _add_many_imm_refs(
2332        &self,
2333        cell_keys: &[CellKey],
2334    ) -> Result<(Vec<&T>, Vec<&mut usize>, &mut usize), AccessError> {
2335        let internal = internal!(self);
2336        let mut vals = Vec::new();
2337        let mut refs = Vec::new();
2338        let mut ref_all_result = Ok(());
2339        for key in cell_keys {
2340            let ref_result = self._add_imm_ref(key.idx, key.gen, true);
2341            match ref_result {
2342                Ok((cell, _)) => {
2343                    vals.push(unsafe { cell.val.assume_init_ref() });
2344                    refs.push(&mut cell.refs_or_next);
2345                }
2346                Err(e) => {
2347                    ref_all_result = Err(e);
2348                    break;
2349                }
2350            }
2351        }
2352        match ref_all_result {
2353            Ok(_) => {
2354                return Ok((vals, refs, &mut internal.access_count));
2355            }
2356            Err(acc_err) => {
2357                _remove_many_imm_refs(&mut refs, &mut internal.access_count);
2358                return Err(acc_err);
2359            }
2360        }
2361    }
2362
2363    //FN Prison::_add_many_imm_refs_idx()
2364    #[doc(hidden)]
2365    fn _add_many_imm_refs_idx(
2366        &self,
2367        idxs: &[usize],
2368    ) -> Result<(Vec<&T>, Vec<&mut usize>, &mut usize), AccessError> {
2369        let internal = internal!(self);
2370        let mut vals = Vec::new();
2371        let mut refs = Vec::new();
2372        let mut ref_all_result = Ok(());
2373        for idx in idxs {
2374            let ref_result = self._add_imm_ref(*idx, 0, false);
2375            match ref_result {
2376                Ok((cell, _)) => {
2377                    vals.push(unsafe { cell.val.assume_init_ref() });
2378                    refs.push(&mut cell.refs_or_next);
2379                }
2380                Err(e) => {
2381                    ref_all_result = Err(e);
2382                    break;
2383                }
2384            }
2385        }
2386        match ref_all_result {
2387            Ok(_) => {
2388                return Ok((vals, refs, &mut internal.access_count));
2389            }
2390            Err(acc_err) => {
2391                _remove_many_imm_refs(&mut refs, &mut internal.access_count);
2392                return Err(acc_err);
2393            }
2394        }
2395    }
2396}
2397
2398//FN _remove_mut_ref()
2399#[doc(hidden)]
2400#[inline(always)]
2401fn _remove_mut_ref(refs: &mut usize, accesses: &mut usize) {
2402    *refs = 0;
2403    *accesses -= 1;
2404}
2405
2406//FN _remove_imm_ref()
2407#[doc(hidden)]
2408#[inline(always)]
2409fn _remove_imm_ref(refs: &mut usize, accesses: &mut usize) {
2410    *refs -= 1;
2411    if *refs == 0 {
2412        *accesses -= 1
2413    }
2414}
2415
2416//FN _remove_many_mut_refs()
2417#[doc(hidden)]
2418#[inline(always)]
2419fn _remove_many_mut_refs(refs_list: &mut [&mut usize], accesses: &mut usize) {
2420    for refs in refs_list {
2421        _remove_mut_ref(refs, accesses)
2422    }
2423}
2424
2425//FN _remove_many_imm_refs()
2426#[doc(hidden)]
2427#[inline(always)]
2428fn _remove_many_imm_refs(refs_list: &mut [&mut usize], accesses: &mut usize) {
2429    for refs in refs_list {
2430        _remove_imm_ref(refs, accesses)
2431    }
2432}
2433
2434//IMPL Default for Prison
2435impl<T> Default for Prison<T> {
2436    fn default() -> Self {
2437        Self::new()
2438    }
2439}
2440
2441//STRUCT PrisonInternal
2442#[doc(hidden)]
2443#[derive(Debug)] //COV_IGNORE
2444struct PrisonInternal<T> {
2445    access_count: usize,
2446    generation: usize,
2447    free_count: usize,
2448    next_free: usize,
2449    vec: Vec<PrisonCell<T>>,
2450}
2451
2452//STRUCT PrisonCell
2453#[doc(hidden)]
2454#[derive(Debug)] //COV_IGNORE
2455struct PrisonCell<T> {
2456    refs_or_next: usize,
2457    d_gen_or_prev: usize,
2458    val: MaybeUninit<T>,
2459}
2460
2461//IMPL Drop for PrisonCell
2462impl<T> Drop for PrisonCell<T> {
2463    fn drop(&mut self) {
2464        if self.is_cell() {
2465            unsafe { self.val.assume_init_drop() }
2466        }
2467    }
2468}
2469
2470impl<T> PrisonCell<T> {
2471    #[inline(always)]
2472    fn is_cell_and_gen_match_opt(&self, gen: usize, use_gen: bool) -> bool {
2473        IdxD::is_type_a(self.d_gen_or_prev) && (!use_gen || IdxD::val(self.d_gen_or_prev) == gen)
2474    }
2475    #[inline(always)]
2476    fn is_cell_and_gen_match(&self, gen: usize) -> bool {
2477        IdxD::is_type_a(self.d_gen_or_prev) && IdxD::val(self.d_gen_or_prev) == gen
2478    }
2479    #[inline(always)]
2480    fn is_cell(&self) -> bool {
2481        IdxD::is_type_a(self.d_gen_or_prev)
2482    }
2483    #[inline(always)]
2484    fn is_free(&self) -> bool {
2485        IdxD::is_type_b(self.d_gen_or_prev)
2486    }
2487
2488    fn new_cell(val: T, gen: usize) -> PrisonCell<T> {
2489        PrisonCell {
2490            refs_or_next: 0,
2491            d_gen_or_prev: IdxD::new_type_a(gen),
2492            val: MaybeUninit::new(val),
2493        }
2494    }
2495
2496    fn make_free_unchecked(&mut self, next: usize, prev: usize) -> T {
2497        self.d_gen_or_prev = IdxD::new_type_b(prev);
2498        self.refs_or_next = next;
2499        unsafe { mem_replace(&mut self.val, MaybeUninit::uninit()).assume_init() }
2500    }
2501
2502    fn make_cell_unchecked(&mut self, val: T, gen: usize) {
2503        self.d_gen_or_prev = IdxD::new_type_a(gen);
2504        self.refs_or_next = 0;
2505        self.val = MaybeUninit::new(val);
2506    }
2507
2508    fn overwrite_cell_unchecked(&mut self, val: T, gen: usize) {
2509        self.d_gen_or_prev = IdxD::new_type_a(gen);
2510        self.refs_or_next = 0;
2511        unsafe { self.val.assume_init_drop() };
2512        self.val = MaybeUninit::new(val);
2513    }
2514}
2515
2516//------ Guarded Prison ------
2517//STRUCT PrisonValueMut
2518/// Struct representing a mutable reference to a value that has been allowed to leave the
2519/// [Prison] temporarily, but remains guarded by a wrapper to prevent it from leaking or never unlocking
2520///
2521/// [PrisonValueMut<T>] implements [Deref<Target = T>], [DerefMut<Target = T>], [AsRef<T>], [AsMut<T>],
2522/// [Borrow<T>], and [BorrowMut<T>] to allow transparent access to its underlying value
2523///
2524/// As long as the [PrisonValueMut] remains in scope, the element where it's value resides in the
2525/// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
2526/// You can manually drop the [PrisonValueMut] out of scope by passing it as the first parameter
2527/// to the function [PrisonValueMut::unguard(p_val_mut)]
2528///
2529/// You can obtain a [PrisonValueMut] by calling `guard_mut()` or `guard_mut_idx()` on a [Prison]
2530/// ### Example
2531/// ```rust
2532/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
2533/// # fn main() -> Result<(), AccessError> {
2534/// let prison: Prison<u32> = Prison::new();
2535/// let key_0 = prison.insert(10)?;
2536/// let mut grd_0 = prison.guard_mut(key_0)?;
2537/// assert_eq!(*grd_0, 10);
2538/// *grd_0 = 20;
2539/// PrisonValueMut::unguard(grd_0);
2540/// prison.visit_ref(key_0, |val_0| {
2541///     assert_eq!(*val_0, 20);
2542///     Ok(())
2543/// });
2544/// # Ok(())
2545/// # }
2546/// ```
2547pub struct PrisonValueMut<'a, T> {
2548    cell: &'a mut PrisonCell<T>,
2549    prison_accesses: &'a mut usize,
2550}
2551
2552impl<'a, T> PrisonValueMut<'a, T> {
2553    //FN PrisonValueMut::unguard()
2554    /// Manually end a [PrisonValueMut] value's temporary guarded absence from the [Prison]
2555    ///
2556    /// This method simply takes ownership of the [PrisonValueMut] and immediately lets it go out of scope,
2557    /// causing it's `drop()` method to be called and clearing its mutable reference in the [Prison]
2558    /// ### Example
2559    /// ```rust
2560    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueMut}};
2561    /// # fn main() -> Result<(), AccessError> {
2562    /// let prison: Prison<u32> = Prison::new();
2563    /// prison.insert(10)?;
2564    /// let grd_0 = prison.guard_mut_idx(0)?;
2565    /// // index 0 CANNOT be accessed here because it is being guarded outside the prison
2566    /// assert!(prison.visit_ref_idx(0, |ref_0| Ok(())).is_err());
2567    /// PrisonValueMut::unguard(grd_0);
2568    /// // index 0 CAN be accessed here because it was returned to the prison
2569    /// assert!(prison.visit_ref_idx(0, |ref_0| Ok(())).is_ok());
2570    /// # Ok(())
2571    /// # }
2572    /// ```
2573    pub fn unguard(_prison_val_mut: Self) {}
2574}
2575
2576//IMPL Drop for PrisonValueMut
2577impl<'a, T> Drop for PrisonValueMut<'a, T> {
2578    fn drop(&mut self) {
2579        _remove_mut_ref(&mut self.cell.refs_or_next, self.prison_accesses)
2580    }
2581}
2582
2583//IMPL Deref for PrisonValueMut
2584impl<'a, T> Deref for PrisonValueMut<'a, T> {
2585    type Target = T;
2586
2587    #[inline(always)]
2588    fn deref(&self) -> &Self::Target {
2589        unsafe { self.cell.val.assume_init_ref() }
2590    }
2591}
2592
2593//IMPL DerefMut for PrisonValueMut
2594impl<'a, T> DerefMut for PrisonValueMut<'a, T> {
2595    #[inline(always)]
2596    fn deref_mut(&mut self) -> &mut Self::Target {
2597        unsafe { self.cell.val.assume_init_mut() }
2598    }
2599}
2600
2601//IMPL AsRef for PrisonValueMut
2602impl<'a, T> AsRef<T> for PrisonValueMut<'a, T> {
2603    #[inline(always)]
2604    fn as_ref(&self) -> &T {
2605        unsafe { self.cell.val.assume_init_ref() }
2606    }
2607}
2608
2609//IMPL AsMut for PrisonValueMut
2610impl<'a, T> AsMut<T> for PrisonValueMut<'a, T> {
2611    #[inline(always)]
2612    fn as_mut(&mut self) -> &mut T {
2613        unsafe { self.cell.val.assume_init_mut() }
2614    }
2615}
2616
2617//IMPL Borrow for PrisonValueMut
2618impl<'a, T> Borrow<T> for PrisonValueMut<'a, T> {
2619    #[inline(always)]
2620    fn borrow(&self) -> &T {
2621        unsafe { self.cell.val.assume_init_ref() }
2622    }
2623}
2624
2625//IMPL BorrowMut for PrisonValueMut
2626impl<'a, T> BorrowMut<T> for PrisonValueMut<'a, T> {
2627    #[inline(always)]
2628    fn borrow_mut(&mut self) -> &mut T {
2629        unsafe { self.cell.val.assume_init_mut() }
2630    }
2631}
2632
2633//STRUCT PrisonValueRef
2634/// Struct representing an immutable reference to a value that has been allowed to leave the
2635/// [Prison] temporarily, but remains guarded by a wrapper to prevent it from leaking or never unlocking
2636///
2637/// [PrisonValueRef<T>] implements [Deref<Target = T>], [AsRef<T>], and [Borrow<T>]
2638/// to allow transparent access to its underlying value
2639///
2640/// As long as the [PrisonValueRef] remains in scope, the element where it's value resides in the
2641/// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
2642/// You can manually drop the [PrisonValueRef] out of scope by passing it as the first parameter
2643/// to the function [PrisonValueRef::unguard(p_val_ref)]
2644///
2645/// You can obtain a [PrisonValueRef] by calling `guard_ref()` or `guard_ref_idx()` on a [Prison]
2646/// ### Example
2647/// ```rust
2648/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
2649/// # fn main() -> Result<(), AccessError> {
2650/// let prison: Prison<u32> = Prison::new();
2651/// let key_0 = prison.insert(10)?;
2652/// let mut grd_0 = prison.guard_ref(key_0)?;
2653/// assert_eq!(*grd_0, 10);
2654/// prison.visit_ref(key_0, |val_0| {
2655///     assert_eq!(*val_0, 10);
2656///     Ok(())
2657/// });
2658/// PrisonValueRef::unguard(grd_0);
2659/// # Ok(())
2660/// # }
2661/// ```
2662pub struct PrisonValueRef<'a, T> {
2663    cell: &'a mut PrisonCell<T>,
2664    prison_accesses: &'a mut usize,
2665}
2666
2667impl<'a, T> PrisonValueRef<'a, T> {
2668    //FN PrisonValueRef::unguard()
2669    /// Manually end a [PrisonValueRef] value's temporary guarded absence from the [Prison]
2670    ///
2671    /// This method simply takes ownership of the [PrisonValueRef] and immediately lets it go out of scope,
2672    /// causing it's `drop()` method to be called and decreasing its immutable reference count in the [Prison]
2673    /// ### Example
2674    /// ```rust
2675    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonValueRef}};
2676    /// # fn main() -> Result<(), AccessError> {
2677    /// let prison: Prison<u32> = Prison::new();
2678    /// prison.insert(10)?;
2679    /// let grd_0 = prison.guard_ref_idx(0)?;
2680    /// // index 0 CANNOT be accessed here because it is being guarded outside the prison
2681    /// assert!(prison.visit_mut_idx(0, |ref_0| Ok(())).is_err());
2682    /// PrisonValueRef::unguard(grd_0);
2683    /// // index 0 CAN be accessed here because it was returned to the prison
2684    /// assert!(prison.visit_mut_idx(0, |ref_0| Ok(())).is_ok());
2685    /// # Ok(())
2686    /// # }
2687    /// ```
2688    pub fn unguard(_prison_val_ref: Self) {}
2689}
2690
2691//IMPL Drop for PrisonValueRef
2692impl<'a, T> Drop for PrisonValueRef<'a, T> {
2693    fn drop(&mut self) {
2694        _remove_imm_ref(&mut self.cell.refs_or_next, self.prison_accesses)
2695    }
2696}
2697
2698//IMPL Deref for PrisonValueRef
2699impl<'a, T> Deref for PrisonValueRef<'a, T> {
2700    type Target = T;
2701
2702    #[inline(always)]
2703    fn deref(&self) -> &Self::Target {
2704        unsafe { self.cell.val.assume_init_ref() }
2705    }
2706}
2707
2708//IMPL AsRef for PrisonValueRef
2709impl<'a, T> AsRef<T> for PrisonValueRef<'a, T> {
2710    #[inline(always)]
2711    fn as_ref(&self) -> &T {
2712        unsafe { self.cell.val.assume_init_ref() }
2713    }
2714}
2715
2716//IMPL Borrow for PrisonValueRef
2717impl<'a, T> Borrow<T> for PrisonValueRef<'a, T> {
2718    #[inline(always)]
2719    fn borrow(&self) -> &T {
2720        unsafe { self.cell.val.assume_init_ref() }
2721    }
2722}
2723
2724//STRUCT PrisonSliceMut
2725/// Struct representing a slice of mutable references to values that have been allowed to leave the
2726/// [Prison] temporarily, but remain guarded by a wrapper to prevent them from leaking or never unlocking
2727///
2728/// [PrisonSliceMut<T>] implements [Deref<Target = \[&mut T\]>](Deref), [DerefMut<Target = \[&mut T\]>](DerefMut), [AsRef<\[&mut T\]>](AsRef), [AsMut<\[&mut T\]>](AsMut),
2729/// [Borrow<\[&mut T\]>](Borrow), and [BorrowMut<\[&mut T\]>](BorrowMut) to allow transparent access to its underlying slice of values
2730///
2731/// As long as the [PrisonSliceMut] remains in scope, the elements where it's values reside in the
2732/// [Prison] will remain marked as mutably referenced and unable to be referenced a second time.
2733/// You can manually drop the [PrisonSliceMut] out of scope by passing it as the first parameter
2734/// to the function [PrisonSliceMut::unguard(p_sli_mut)]
2735///
2736/// You can obtain a [PrisonSliceMut] by calling `guard_many_mut()` or `guard_many_mut_idx()` on a [Prison]
2737/// ### Example
2738/// ```rust
2739/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
2740/// # fn main() -> Result<(), AccessError> {
2741/// let prison: Prison<u32> = Prison::new();
2742/// let key_0 = prison.insert(10)?;
2743/// let key_1 = prison.insert(20)?;
2744/// let key_2 = prison.insert(30)?;
2745/// let mut grd_0_1_2 = prison.guard_many_mut(&[key_0, key_1, key_2])?;
2746/// assert_eq!(*grd_0_1_2[1], 20);
2747/// *grd_0_1_2[1] = 42;
2748/// PrisonSliceMut::unguard(grd_0_1_2);
2749/// prison.visit_ref(key_1, |val_1| {
2750///     assert_eq!(*val_1, 42);
2751///     Ok(())
2752/// });
2753/// # Ok(())
2754/// # }
2755/// ```
2756pub struct PrisonSliceMut<'a, T> {
2757    prison_accesses: &'a mut usize,
2758    refs: Vec<&'a mut usize>,
2759    vals: Vec<&'a mut T>,
2760}
2761
2762impl<'a, T> PrisonSliceMut<'a, T> {
2763    //FN PrisonSliceMut::unguard()
2764    /// Manually end a [PrisonSliceMut] value's temporary guarded absence from the [Prison]
2765    ///
2766    /// This method simply takes ownership of the [PrisonSliceMut] and immediately lets it go out of scope,
2767    /// causing it's `drop()` method to be called and decreasing its immutable reference count in the [Prison]
2768    /// ### Example
2769    /// ```rust
2770    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceMut}};
2771    /// # fn main() -> Result<(), AccessError> {
2772    /// let prison: Prison<u32> = Prison::new();
2773    /// prison.insert(10)?;
2774    /// prison.insert(20)?;
2775    /// let grd_all = prison.guard_many_mut_idx(&[0, 1])?;
2776    /// assert!(prison.visit_many_mut_idx(&[0, 1], |ref_all| Ok(())).is_err());
2777    /// PrisonSliceMut::unguard(grd_all);
2778    /// assert!(prison.visit_many_mut_idx(&[0, 1], |ref_all| Ok(())).is_ok());
2779    /// # Ok(())
2780    /// # }
2781    /// ```
2782    pub fn unguard(_prison_sli_mut: Self) {}
2783}
2784
2785//IMPL Drop for PrisonSliceMut
2786impl<'a, T> Drop for PrisonSliceMut<'a, T> {
2787    fn drop(&mut self) {
2788        _remove_many_mut_refs(&mut self.refs, self.prison_accesses)
2789    }
2790}
2791
2792//IMPL Deref for PrisonSliceMut
2793impl<'a, T> Deref for PrisonSliceMut<'a, T> {
2794    type Target = [&'a mut T];
2795
2796    #[inline(always)]
2797    fn deref(&self) -> &Self::Target {
2798        self.vals.as_slice()
2799    }
2800}
2801
2802//IMPL DerefMut for PrisonSliceMut
2803impl<'a, T> DerefMut for PrisonSliceMut<'a, T> {
2804    #[inline(always)]
2805    fn deref_mut(&mut self) -> &mut Self::Target {
2806        self.vals.as_mut_slice()
2807    }
2808}
2809
2810//IMPL AsRef for PrisonSliceMut
2811impl<'a, T> AsRef<[&'a mut T]> for PrisonSliceMut<'a, T> {
2812    #[inline(always)]
2813    fn as_ref(&self) -> &[&'a mut T] {
2814        self.vals.as_slice()
2815    }
2816}
2817
2818//IMPL AsMut for PrisonSliceMut
2819impl<'a, T> AsMut<[&'a mut T]> for PrisonSliceMut<'a, T> {
2820    #[inline(always)]
2821    fn as_mut(&mut self) -> &mut [&'a mut T] {
2822        self.vals.as_mut_slice()
2823    }
2824}
2825
2826//IMPL Borrow for PrisonSliceMut
2827impl<'a, T> Borrow<[&'a mut T]> for PrisonSliceMut<'a, T> {
2828    #[inline(always)]
2829    fn borrow(&self) -> &[&'a mut T] {
2830        self.vals.as_slice()
2831    }
2832}
2833
2834//IMPL BorrowMut for PrisonSliceMut
2835impl<'a, T> BorrowMut<[&'a mut T]> for PrisonSliceMut<'a, T> {
2836    #[inline(always)]
2837    fn borrow_mut(&mut self) -> &mut [&'a mut T] {
2838        self.vals.as_mut_slice()
2839    }
2840}
2841
2842//STRUCT PrisonSliceRef
2843/// Struct representing a slice of immutable references to values that have been allowed to leave the
2844/// [Prison] temporarily, but remain guarded by a wrapper to prevent them from leaking or never unlocking
2845///
2846/// [PrisonSliceRef<T>] implements [Deref<Target = \[&T\]>](Deref), [AsRef<\[&T\]>](AsRef),
2847/// and [Borrow<\[&T\]>](Borrow) to allow transparent access to its underlying slice of values
2848///
2849/// As long as the [PrisonSliceRef] remains in scope, the elements where it's values reside in the
2850/// [Prison] will remain marked as immutably referenced and unable to be mutably referenced.
2851/// You can manually drop the [PrisonSliceRef] out of scope by passing it as the first parameter
2852/// to the function [PrisonSliceRef::unguard(p_sli_ref)]
2853///
2854/// You can obtain a [PrisonSliceRef] by calling `guard_many_ref()` or `guard_many_ref_idx()` on a [Prison]
2855/// ### Example
2856/// ```rust
2857/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
2858/// # fn main() -> Result<(), AccessError> {
2859/// let prison: Prison<u32> = Prison::new();
2860/// let key_0 = prison.insert(10)?;
2861/// let key_1 = prison.insert(20)?;
2862/// let key_2 = prison.insert(30)?;
2863/// let mut grd_0_1_2 = prison.guard_many_ref(&[key_0, key_1, key_2])?;
2864/// assert_eq!(*grd_0_1_2[1], 20);
2865/// prison.visit_ref(key_1, |val_1| {
2866///     assert_eq!(*val_1, 20);
2867///     Ok(())
2868/// });
2869/// PrisonSliceRef::unguard(grd_0_1_2);
2870/// # Ok(())
2871/// # }
2872/// ```
2873pub struct PrisonSliceRef<'a, T> {
2874    prison_accesses: &'a mut usize,
2875    refs: Vec<&'a mut usize>,
2876    vals: Vec<&'a T>,
2877}
2878
2879impl<'a, T> PrisonSliceRef<'a, T> {
2880    //FN PrisonSliceRef::unguard()
2881    /// Manually end a [PrisonSliceRef] value's temporary guarded absence from the [Prison]
2882    ///
2883    /// This method simply takes ownership of the [PrisonSliceRef] and immediately lets it go out of scope,
2884    /// causing it's `drop()` method to be called and decreasing its immutable reference count in the [Prison]
2885    /// ### Example
2886    /// ```rust
2887    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{Prison, PrisonSliceRef}};
2888    /// # fn main() -> Result<(), AccessError> {
2889    /// let prison: Prison<u32> = Prison::new();
2890    /// prison.insert(10)?;
2891    /// prison.insert(20)?;
2892    /// let grd_all = prison.guard_many_ref_idx(&[0, 1])?;
2893    /// assert!(prison.visit_many_mut_idx(&[0, 1], |ref_all| Ok(())).is_err());
2894    /// PrisonSliceRef::unguard(grd_all);
2895    /// assert!(prison.visit_many_mut_idx(&[0, 1], |ref_all| Ok(())).is_ok());
2896    /// # Ok(())
2897    /// # }
2898    /// ```
2899    pub fn unguard(_prison_sli_ref: Self) {}
2900}
2901
2902//IMPL Drop for PrisonSliceRef
2903impl<'a, T> Drop for PrisonSliceRef<'a, T> {
2904    fn drop(&mut self) {
2905        _remove_many_imm_refs(&mut self.refs, self.prison_accesses)
2906    }
2907}
2908
2909//IMPL Deref for PrisonSliceRef
2910impl<'a, T> Deref for PrisonSliceRef<'a, T> {
2911    type Target = [&'a T];
2912
2913    #[inline(always)]
2914    fn deref(&self) -> &Self::Target {
2915        self.vals.as_slice()
2916    }
2917}
2918
2919//IMPL AsRef for PrisonSliceRef
2920impl<'a, T> AsRef<[&'a T]> for PrisonSliceRef<'a, T> {
2921    #[inline(always)]
2922    fn as_ref(&self) -> &[&'a T] {
2923        self.vals.as_slice()
2924    }
2925}
2926
2927//IMPL Borrow for PrisonSliceRef
2928impl<'a, T> Borrow<[&'a T]> for PrisonSliceRef<'a, T> {
2929    #[inline(always)]
2930    fn borrow(&self) -> &[&'a T] {
2931        self.vals.as_slice()
2932    }
2933}
2934
2935//====== JailCell ======
2936//STRUCT JailCell
2937/// Represents a single standalone value that allows interior mutability while upholding memory safety
2938/// with a reference counting [usize]
2939///
2940/// This is a very simple implementation of the principles found in [Prison]
2941///
2942/// It has a single [UnsafeCell] to allow interior mutability. The [UnsafeCell] holds
2943/// one single [usize] to track mutable and immutable references, and the value itself
2944/// of type `T`
2945///
2946/// It has `visit_ref()`, `visit_mut()`, `guard_ref()`, and `guard_mut()` methods, just like [Prison],
2947/// but with drastically simpler requirements for safety checking.
2948/// ### Example
2949/// ```rust
2950/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueRef}};
2951/// # fn main() -> Result<(), AccessError> {
2952/// let string_jail: JailCell<String> = JailCell::new(String::from("'Bad-Guy' Bert"));
2953/// string_jail.visit_mut(|criminal| {
2954///     let bigger_bad = String::from("Dr. Lego-Step");
2955///     println!("Breaking News: {} to be set free to make room for {}", *criminal, bigger_bad);
2956///     *criminal = bigger_bad;
2957///     Ok(())
2958/// })?;
2959/// let guarded_criminal = string_jail.guard_ref()?;
2960/// println!("{} will now be paraded around town for public shaming", *guarded_criminal);
2961/// assert_eq!(*guarded_criminal, String::from("Dr. Lego-Step"));
2962/// JailValueRef::unguard(guarded_criminal);
2963/// # Ok(())
2964/// # }
2965/// ```
2966pub struct JailCell<T> {
2967    internal: UnsafeCell<JailCellMutable<T>>,
2968}
2969
2970impl<T> JailCell<T> {
2971    //FN JailCell::new()
2972    /// Creates a new [JailCell] with the supplied value of type `T`
2973    ///
2974    /// After creation, mutable or immutable references to it's value can only be obtained
2975    /// through its `visit_*()` or `guard_*()` methods
2976    pub fn new(value: T) -> JailCell<T> {
2977        return JailCell {
2978            internal: UnsafeCell::new(JailCellMutable {
2979                refs: 0,
2980                val: value,
2981            }),
2982        };
2983    }
2984
2985    //FN JailCell::visit_mut()
2986    /// Obtain a mutable reference to the [JailCell]'s internal value that gets passed to
2987    /// a closure you provide.
2988    /// ### Example
2989    /// ```rust
2990    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell}};
2991    /// # fn main() -> Result<(), AccessError> {
2992    /// let string_jail: JailCell<String> = JailCell::new(String::from("'Bad-Guy' Bert"));
2993    /// string_jail.visit_mut(|criminal| {
2994    ///     let bigger_bad = String::from("Dr. Lego-Step");
2995    ///     println!("Breaking News: {} to be set free to make room for {}", *criminal, bigger_bad);
2996    ///     *criminal = bigger_bad;
2997    ///     Ok(())
2998    /// })?;
2999    /// # Ok(())
3000    /// # }
3001    /// ```
3002    /// ## Errors
3003    /// - [AccessError::ValueAlreadyMutablyReferenced(0)] if value is already mutably referenced
3004    /// - [AccessError::ValueStillImmutablyReferenced(0)] if value has any number of immutable references
3005    ///  ### Example
3006    /// ```rust
3007    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell}};
3008    /// # fn main() -> Result<(), AccessError> {
3009    /// let jail: JailCell<u32> = JailCell::new(42);
3010    /// jail.visit_mut(|val| {
3011    ///     assert!(jail.visit_mut(|val| Ok(())).is_err());
3012    ///     Ok(())
3013    /// })?;
3014    /// jail.visit_ref(|val| {
3015    ///     assert!(jail.visit_mut(|val| Ok(())).is_err());
3016    ///     Ok(())
3017    /// })?;
3018    /// # Ok(())
3019    /// # }
3020    /// ```
3021    pub fn visit_mut<F>(&self, mut operation: F) -> Result<(), AccessError>
3022    where
3023        F: FnMut(&mut T) -> Result<(), AccessError>,
3024    {
3025        let internal = internal!(self);
3026        internal.add_ref_internal(true)?;
3027        let result = operation(&mut internal.val);
3028        internal.remove_ref_internal();
3029        return result;
3030    }
3031
3032    //FN JailCell::visit_ref()
3033    /// Obtain an immutable reference to the [JailCell]'s internal value that gets passed to
3034    /// a closure you provide.
3035    /// ### Example
3036    /// ```rust
3037    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell}};
3038    /// # fn main() -> Result<(), AccessError> {
3039    /// let string_jail: JailCell<String> = JailCell::new(String::from("'Bad-Guy' Bert"));
3040    /// string_jail.visit_ref(|criminal| {
3041    ///     println!("Breaking News: {} was just captured!", *criminal);
3042    ///     Ok(())
3043    /// })?;
3044    /// # Ok(())
3045    /// # }
3046    /// ```
3047    /// ## Errors
3048    /// - [AccessError::ValueAlreadyMutablyReferenced(0)] if value is already mutably referenced
3049    /// - [AccessError::MaximumImmutableReferencesReached(0)] if value has usize::MAX - 2 immutable references already
3050    ///  ### Example
3051    /// ```rust
3052    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell}};
3053    /// # fn main() -> Result<(), AccessError> {
3054    /// let jail: JailCell<u32> = JailCell::new(42);
3055    /// jail.visit_mut(|val| {
3056    ///     assert!(jail.visit_ref(|val| Ok(())).is_err());
3057    ///     Ok(())
3058    /// })?;
3059    /// # Ok(())
3060    /// # }
3061    /// ```
3062    pub fn visit_ref<F>(&self, mut operation: F) -> Result<(), AccessError>
3063    where
3064        F: FnMut(&T) -> Result<(), AccessError>,
3065    {
3066        let internal = internal!(self);
3067        internal.add_ref_internal(false)?;
3068        let result = operation(&internal.val);
3069        internal.remove_ref_internal();
3070        return result;
3071    }
3072
3073    //FN JailCell::guard_mut()
3074    /// Obtain an [JailValueMut] that marks the [JailCell] mutably referenced as long as it remains
3075    /// in scope and automatically unlocks it when it falls out of scope
3076    ///
3077    /// [JailValueMut<T>] implements [Deref<Target = T>], [DerefMut<Target = T>], [AsRef<T>], [AsMut<T>],
3078    /// [Borrow<T>], and [BorrowMut<T>] to allow transparent access to its underlying value
3079    ///
3080    /// You may manually drop the [JailValueMut] out of scope by passing it to the function
3081    /// [JailValueMut::unguard(_jail_val_mut)]
3082    /// ### Example
3083    /// ```rust
3084    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueMut}};
3085    /// # fn main() -> Result<(), AccessError> {
3086    /// let string_jail: JailCell<String> = JailCell::new(String::from("'Bad-Guy' Bert"));
3087    /// let mut grd_criminal = string_jail.guard_mut()?;
3088    /// let bigger_bad = String::from("Dr. Lego-Step");
3089    /// println!("Breaking News: {} to be set free to make room for {}", *grd_criminal, bigger_bad);
3090    /// *grd_criminal = bigger_bad;
3091    /// JailValueMut::unguard(grd_criminal);
3092    /// # Ok(())
3093    /// # }
3094    /// ```
3095    /// ## Errors
3096    /// - [AccessError::ValueAlreadyMutablyReferenced(0)] if value is already mutably referenced
3097    /// - [AccessError::ValueStillImmutablyReferenced(0)] if value has any number of immutable references
3098    ///  ### Example
3099    /// ```rust
3100    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueRef, JailValueMut}};
3101    /// # fn main() -> Result<(), AccessError> {
3102    /// let jail: JailCell<u32> = JailCell::new(42);
3103    /// let guard_ref = jail.guard_ref()?;
3104    /// assert!(jail.guard_mut().is_err());
3105    /// JailValueRef::unguard(guard_ref);
3106    /// let guard_mut = jail.guard_mut()?;
3107    /// assert!(jail.guard_mut().is_err());
3108    /// JailValueMut::unguard(guard_mut);
3109    /// # Ok(())
3110    /// # }
3111    /// ```
3112    #[must_use = "guarded reference will immediately fall out of scope"]
3113    pub fn guard_mut<'a>(&'a self) -> Result<JailValueMut<'a, T>, AccessError> {
3114        let internal = internal!(self);
3115        internal.add_ref_internal(true)?;
3116        return Ok(JailValueMut {
3117            ref_internal: internal,
3118        });
3119    }
3120
3121    //FN JailCell::guard_ref()
3122    /// Obtain an [JailValueRef] that marks the [JailCell] mutably referenced as long as it remains
3123    /// in scope and automatically unlocks it when it falls out of scope
3124    ///
3125    /// [JailValueRef<T>] implements [Deref<Target = T>], [AsRef<T>], and [Borrow<T>]
3126    /// to allow transparent access to its underlying value
3127    ///
3128    /// You may manually drop the [JailValueRef] out of scope by passing it to the function
3129    /// [JailValueRef::unguard(_jail_val_ref)]
3130    /// ### Example
3131    /// ```rust
3132    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueRef}};
3133    /// # fn main() -> Result<(), AccessError> {
3134    /// let string_jail: JailCell<String> = JailCell::new(String::from("'Bad-Guy' Bert"));
3135    /// let grd_criminal = string_jail.guard_ref()?;
3136    /// println!("Breaking News: {} has been captured!", *grd_criminal);
3137    /// JailValueRef::unguard(grd_criminal);
3138    /// # Ok(())
3139    /// # }
3140    /// ```
3141    /// ## Errors
3142    /// - [AccessError::ValueAlreadyMutablyReferenced(0)] if value is already mutably referenced
3143    /// - [AccessError::MaximumImmutableReferencesReached(0)] if value has usize::MAX - 2 immutable references already
3144    /// ### Example
3145    /// ```rust
3146    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueMut}};
3147    /// # fn main() -> Result<(), AccessError> {
3148    /// let jail: JailCell<u32> = JailCell::new(42);
3149    /// let guard_mut = jail.guard_mut()?;
3150    /// assert!(jail.guard_ref().is_err());
3151    /// JailValueMut::unguard(guard_mut);
3152    /// # Ok(())
3153    /// # }
3154    /// ```
3155    #[must_use = "guarded reference will immediately fall out of scope"]
3156    pub fn guard_ref<'a>(&'a self) -> Result<JailValueRef<'a, T>, AccessError> {
3157        let internal = internal!(self);
3158        internal.add_ref_internal(false)?;
3159        return Ok(JailValueRef {
3160            ref_internal: internal,
3161        });
3162    }
3163    //FN JailCell::clone_val()
3164    /// Clones the requested value out of the [JailCell] into a new variable
3165    ///
3166    /// Only available when type T implements [Clone] (it is assumed that the implementation of `T::clone()` is memory safe).
3167    ///
3168    /// Because cloning does not alter the original, and because the new variable to hold the clone does not have any presumtions about the value, it
3169    /// is safe (in a single-threaded context) to clone out the value even if it is being visited or guarded.
3170    /// ### Example
3171    /// ```rust
3172    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueMut}};
3173    /// # fn main() -> Result<(), AccessError> {
3174    /// let jail: JailCell<String> = JailCell::new(String::from("Dolly"));
3175    /// let guard_mut = jail.guard_mut()?;
3176    /// let dolly_2 = jail.clone_val();
3177    /// JailValueMut::unguard(guard_mut);
3178    /// assert_eq!(dolly_2, String::from("Dolly"));
3179    /// # Ok(())
3180    /// # }
3181    /// ```
3182    pub fn clone_val(&self) -> T
3183    where
3184        T: Clone,
3185    {
3186        internal!(self).val.clone()
3187    }
3188
3189    //FN: JailCell::peek_ref()
3190    /// Get a reference to the value while ***ignoring reference counting and most other safety measures***
3191    ///
3192    /// This method is provided as a way for libraries depending on this code to perform niche
3193    /// optimized reads of contained values without the overhead of the normal safety checks,
3194    /// or when a mutable reference is active but you can statically confirm that the value will
3195    /// not be mutated from the begining of the returned `&T`'s lifetime to the end of it's lifetime.
3196    ///
3197    /// The returned reference is intended to be short-lived and safely contained in a scope where no
3198    /// mutation of the value takes place
3199    /// # Safety
3200    /// When you call this method and as long as the `&T` it returns remains in-scope/alive,
3201    /// you MUST ensure the following:
3202    /// - The value MUST NOT be mutated by ANY source, including active safe reference-counted mutable references
3203    /// - NO operation can be performed that could *potentially* cause the underlying memory address of the [JailCell]'s data to relocate
3204    pub unsafe fn peek_ref<'a>(&'a self) -> &'a T {
3205        &internal!(self).val
3206    }
3207}
3208
3209//IMPL Default for JailCell
3210impl<T> Default for JailCell<T>
3211where
3212    T: Default,
3213{
3214    fn default() -> Self {
3215        Self::new(T::default())
3216    }
3217}
3218
3219//STRUCT JailCellMutable
3220#[doc(hidden)]
3221struct JailCellMutable<T> {
3222    refs: usize,
3223    val: T,
3224}
3225
3226impl<T> JailCellMutable<T> {
3227    //FN JailCellMutable::add_ref_internal()
3228    fn add_ref_internal(&mut self, mutable: bool) -> Result<(), AccessError> {
3229        if self.refs == Refs::MUT {
3230            return Err(AccessError::ValueAlreadyMutablyReferenced(0));
3231        }
3232        if mutable && self.refs > 0 {
3233            return Err(AccessError::ValueStillImmutablyReferenced(0));
3234        }
3235        if self.refs == Refs::MAX_IMMUT {
3236            return Err(AccessError::MaximumImmutableReferencesReached(0));
3237        }
3238        if mutable {
3239            self.refs = Refs::MUT;
3240        } else {
3241            self.refs += 1;
3242        }
3243        return Ok(());
3244    }
3245
3246    //FN JailCellMutable::remove_ref_internal()
3247    fn remove_ref_internal(&mut self) {
3248        if self.refs == Refs::MUT {
3249            self.refs = 0;
3250        } else if self.refs > 0 {
3251            self.refs -= 1;
3252        }
3253    }
3254}
3255
3256//------ Guarded JailCell ------
3257//STRUCT JailValueMut
3258/// A guarded wrapper around a mutable reference to the value contained in a [JailCell]
3259///
3260/// [JailValueMut<T>] implements [Deref<Target = T>], [DerefMut<Target = T>], [AsRef<T>], [AsMut<T>],
3261/// [Borrow<T>], and [BorrowMut<T>] to allow transparent access to its underlying value
3262///
3263/// As long as the [JailValueMut] remains in scope, the value in [JailCell] will
3264/// remain marked as mutably referenced and unable to be referenced a second time.
3265/// You can manually drop the [JailValueMut] out of scope by passing it as the first parameter
3266/// to the function [JailValueMut::unguard(jail_val_mut)]
3267///
3268/// You can obtain a [JailValueMut] by calling `guard_mut()` on a [JailCell]
3269/// ### Example
3270/// ```rust
3271/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueMut}};
3272/// # fn main() -> Result<(), AccessError> {
3273/// let jail: JailCell<u32> = JailCell::new(42);
3274/// let mut grd_mut = jail.guard_mut()?;
3275/// assert_eq!(*grd_mut, 42);
3276/// *grd_mut = 69;
3277/// JailValueMut::unguard(grd_mut);
3278/// jail.visit_ref(|val| {
3279///     assert_eq!(*val, 69);
3280///     Ok(())
3281/// });
3282/// # Ok(())
3283/// # }
3284/// ```
3285pub struct JailValueMut<'a, T> {
3286    ref_internal: &'a mut JailCellMutable<T>,
3287}
3288
3289impl<'a, T> JailValueMut<'a, T> {
3290    //FN JailValueMut::unguard()
3291    /// Manually end a [JailValueMut] value's temporary guarded absence from the [JailCell]
3292    ///
3293    /// This method simply takes ownership of the [JailValueMut] and immediately lets it go out of scope,
3294    /// causing it's `drop()` method to be called and clearing its mutable reference in the [JailCell]
3295    /// ### Example
3296    /// ```rust
3297    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueMut}};
3298    /// # fn main() -> Result<(), AccessError> {
3299    /// let jail: JailCell<u32> = JailCell::new(42);
3300    /// let grd_mut = jail.guard_mut()?;
3301    /// // val CANNOT be referenced again because the mutable reference is still in scope
3302    /// assert!(jail.visit_ref(|val| Ok(())).is_err());
3303    /// JailValueMut::unguard(grd_mut);
3304    /// // val CAN be referenced again because the mutable reference was dropped
3305    /// assert!(jail.visit_ref(|val| Ok(())).is_ok());
3306    /// # Ok(())
3307    /// # }
3308    /// ```
3309    pub fn unguard(_guarded_jail_value: JailValueMut<'a, T>) {}
3310}
3311
3312//IMPL Drop for JailValueMut
3313impl<'a, T> Drop for JailValueMut<'a, T> {
3314    fn drop(&mut self) {
3315        self.ref_internal.remove_ref_internal();
3316    }
3317}
3318
3319//IMPL Deref for JailValueMut
3320impl<'a, T> Deref for JailValueMut<'a, T> {
3321    type Target = T;
3322
3323    #[inline(always)]
3324    fn deref(&self) -> &Self::Target {
3325        &self.ref_internal.val
3326    }
3327}
3328
3329//IMPL DerefMut for JailValueMut
3330impl<'a, T> DerefMut for JailValueMut<'a, T> {
3331    #[inline(always)]
3332    fn deref_mut(&mut self) -> &mut Self::Target {
3333        &mut self.ref_internal.val
3334    }
3335}
3336
3337//IMPL AsRef for JailValueMut
3338impl<'a, T> AsRef<T> for JailValueMut<'a, T> {
3339    #[inline(always)]
3340    fn as_ref(&self) -> &T {
3341        &self.ref_internal.val
3342    }
3343}
3344
3345//IMPL AsMut for JailValueMut
3346impl<'a, T> AsMut<T> for JailValueMut<'a, T> {
3347    #[inline(always)]
3348    fn as_mut(&mut self) -> &mut T {
3349        &mut self.ref_internal.val
3350    }
3351}
3352
3353//IMPL Borrow for JailValueMut
3354impl<'a, T> Borrow<T> for JailValueMut<'a, T> {
3355    #[inline(always)]
3356    fn borrow(&self) -> &T {
3357        &self.ref_internal.val
3358    }
3359}
3360
3361//IMPL BorrowMut for JailValueMut
3362impl<'a, T> BorrowMut<T> for JailValueMut<'a, T> {
3363    #[inline(always)]
3364    fn borrow_mut(&mut self) -> &mut T {
3365        &mut self.ref_internal.val
3366    }
3367}
3368
3369//STRUCT JailValueRef
3370/// A guarded wrapper around an immutable reference to the value contained in a [JailCell]
3371///
3372/// [JailValueRef<T>] implements [Deref<Target = T>], [AsRef<T>], and [Borrow<T>]
3373/// to allow transparent access to its underlying value
3374///
3375/// As long as the [JailValueRef] remains in scope, the value in [JailCell] will
3376/// remain marked as immutably referenced and unable to be mutably referenced.
3377/// You can manually drop the [JailValueRef] out of scope by passing it as the first parameter
3378/// to the function [JailValueRef::unguard(jail_val_ref)]
3379///
3380/// You can obtain a [JailValueRef] by calling `guard_ref()` on a [JailCell]
3381/// ### Example
3382/// ```rust
3383/// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueRef}};
3384/// # fn main() -> Result<(), AccessError> {
3385/// let jail: JailCell<u32> = JailCell::new(42);
3386/// let mut grd_ref = jail.guard_ref()?;
3387/// assert_eq!(*grd_ref, 42);
3388/// jail.visit_ref(|val| {
3389///     assert_eq!(*val, 42);
3390///     Ok(())
3391/// });
3392/// JailValueRef::unguard(grd_ref);
3393/// # Ok(())
3394/// # }
3395/// ```
3396pub struct JailValueRef<'a, T> {
3397    ref_internal: &'a mut JailCellMutable<T>,
3398}
3399
3400impl<'a, T> JailValueRef<'a, T> {
3401    //FN JailValueRef::unguard()
3402    /// Manually end a [JailValueRef] value's temporary guarded absence from the [JailCell]
3403    ///
3404    /// This method simply takes ownership of the [JailValueRef] and immediately lets it go out of scope,
3405    /// causing it's `drop()` method to be called and decreasing its immutable reference count in the [JailCell]
3406    /// ### Example
3407    /// ```rust
3408    /// # use grit_data_prison::{AccessError, CellKey, single_threaded::{JailCell, JailValueRef}};
3409    /// # fn main() -> Result<(), AccessError> {
3410    /// let jail: JailCell<u32> = JailCell::new(42);
3411    /// let grd_ref = jail.guard_ref()?;
3412    /// // val CANNOT be mutably referenced because the immutable reference is still in scope
3413    /// assert!(jail.visit_mut(|val| Ok(())).is_err());
3414    /// JailValueRef::unguard(grd_ref);
3415    /// // val CAN be mutably referenced because the immutable reference was dropped
3416    /// assert!(jail.visit_mut(|val| Ok(())).is_ok());
3417    /// # Ok(())
3418    /// # }
3419    /// ```
3420    pub fn unguard(_guarded_jail_value: Self) {}
3421}
3422
3423//IMPL Drop for JailValueRef
3424impl<'a, T> Drop for JailValueRef<'a, T> {
3425    fn drop(&mut self) {
3426        self.ref_internal.remove_ref_internal();
3427    }
3428}
3429
3430//IMPL Deref for JailValueRef
3431impl<'a, T> Deref for JailValueRef<'a, T> {
3432    type Target = T;
3433
3434    #[inline(always)]
3435    fn deref(&self) -> &Self::Target {
3436        &self.ref_internal.val
3437    }
3438}
3439
3440//IMPL AsRef for JailValueRef
3441impl<'a, T> AsRef<T> for JailValueRef<'a, T> {
3442    #[inline(always)]
3443    fn as_ref(&self) -> &T {
3444        &self.ref_internal.val
3445    }
3446}
3447
3448//IMPL Borrow for JailValueRef
3449impl<'a, T> Borrow<T> for JailValueRef<'a, T> {
3450    #[inline(always)]
3451    fn borrow(&self) -> &T {
3452        &self.ref_internal.val
3453    }
3454}
3455