use std::marker::PhantomData;
use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Clone)]
pub struct Plain;
#[derive(Clone)]
pub struct Map;
pub struct Keyed<T> {
pub witness: PhantomData<T>,
}
impl<T> Clone for Keyed<T> {
fn clone(&self) -> Self {
Keyed {
witness: PhantomData,
}
}
}
pub struct Key<T> {
pub witness: PhantomData<T>,
pub index: usize,
}
impl<T> Clone for Key<T> {
fn clone(&self) -> Self {
Key {
witness: PhantomData,
index: self.index,
}
}
}
pub struct KeyGenerator<T> {
counter: AtomicUsize,
witness: PhantomData<T>,
}
impl<T> KeyGenerator<T> {
pub fn new() -> KeyGenerator<T> {
KeyGenerator {
counter: AtomicUsize::new(0),
witness: PhantomData,
}
}
}
impl KeyGenerator<Plain> {
pub fn next(&self) -> Key<Plain> {
Key {
index: self.counter.fetch_add(1, Ordering::Relaxed),
witness: PhantomData,
}
}
}
impl KeyGenerator<Map> {
pub fn next<T>(&self) -> Key<Keyed<T>> {
Key {
index: self.counter.fetch_add(1, Ordering::Relaxed),
witness: PhantomData,
}
}
}