charon_lib/ids/
generator.rs

1use index_vec::Idx;
2use std::marker::PhantomData;
3
4#[derive(Debug, Clone, Copy)]
5pub struct Generator<I: Idx> {
6    counter: usize,
7    phantom: PhantomData<I>,
8}
9
10impl<I: Idx> Generator<I> {
11    pub fn new() -> Self {
12        Self::new_with_init_value(I::from_usize(0))
13    }
14
15    pub fn new_with_init_value(index: I) -> Self {
16        Generator {
17            counter: index.index(),
18            phantom: PhantomData,
19        }
20    }
21
22    pub fn fresh_id(&mut self) -> I {
23        let index = I::from_usize(self.counter);
24        // The release version of the code doesn't check for overflows.
25        // As the max usize is very large, overflows are extremely
26        // unlikely. Still, it is extremely important for our code that
27        // no overflows happen on the index counters.
28        self.counter = self.counter.checked_add(1).unwrap();
29        index
30    }
31}
32
33// Manual impl to avoid the `I: Default` bound.
34impl<I: Idx> Default for Generator<I> {
35    fn default() -> Self {
36        Self {
37            counter: Default::default(),
38            phantom: Default::default(),
39        }
40    }
41}