You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
8.0 KiB
315 lines
8.0 KiB
//! Single-index references.
|
|
use super::*;
|
|
|
|
/// A non-mutable reference to an item in `Populator<'a, T>`, inserted or not.
|
|
#[derive(Debug)] // PartialEq, PartialOrd ///XXX: TODO: Should this be Clone (and maybe even Copy)? Check OwnedRef below...
|
|
pub struct Ref<'re, 'a, T: 'a>
|
|
{
|
|
pub(crate) pop: &'re Populator<'a, T>,
|
|
pub(crate) idx: usize,
|
|
//TODO: Maybe add inserted bool, or state representing if this Ref has made a change to the populator. The value will be loaded on creation of the Ref, and will be used as a cached version of `completes[idx].load()`
|
|
//TODO: OR: Hold a reference to the actual AtomicBool at `idx` itself?
|
|
pub(crate) inserted: &'re AtomicBool
|
|
}
|
|
|
|
/// A mutable reference to an item in `Populator<'a, T>`, inserted or not.
|
|
#[derive(Debug, Clone)] // PartialEq, PartialOrd //XXX: TODO: Should this actually be `Clone`? Ref isn't, because its supposed to be a single reference. But since this is arc'd?
|
|
pub struct OwnedRef<'a, T: 'a> // PartialEq, PartialOrd
|
|
{
|
|
pub(super) pop: Arc<Populator<'a, T>>,
|
|
pub(super) idx: usize,
|
|
}
|
|
|
|
/// An exclusive reference to an item in `Populator<'a, T>`, inserted or not.
|
|
#[derive(Debug)]
|
|
pub struct RefEx<'re, 'a, T: 'a>
|
|
{
|
|
pub(super) pop: &'re mut Populator<'a, T>,
|
|
pub(super) idx: usize,
|
|
}
|
|
|
|
impl<'a, T: 'a> PartialEq for OwnedRef<'a, T>
|
|
{
|
|
#[inline]
|
|
fn eq(&self, other: &Self) -> bool
|
|
{
|
|
address_eq(self.pop.as_ref(), other.pop.as_ref()) && self.idx == other.idx
|
|
}
|
|
}
|
|
|
|
impl<'a, T: 'a> PartialOrd for OwnedRef<'a, T>
|
|
{
|
|
#[inline]
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
if address_eq(self.pop.as_ref(), other.pop.as_ref()) {
|
|
self.idx.partial_cmp(&other.idx)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> PartialEq for Ref<'re, 'a, T>
|
|
{
|
|
#[inline]
|
|
fn eq(&self, other: &Self) -> bool
|
|
{
|
|
address_eq(self.pop, other.pop) && self.idx == other.idx
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> PartialOrd for Ref<'re, 'a, T>
|
|
{
|
|
#[inline]
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
if address_eq(self.pop, other.pop) {
|
|
self.idx.partial_cmp(&other.idx)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> Ref<'re, 'a, T>
|
|
{
|
|
/// Get a reference to the parent populator
|
|
#[inline]
|
|
pub fn parent(&self) -> &Populator<'a, T>
|
|
{
|
|
&self.pop
|
|
}
|
|
/// The index that this `Ref` refers to.
|
|
#[inline]
|
|
pub fn slot(&self) -> usize
|
|
{
|
|
self.idx
|
|
}
|
|
/// Checks if the references item currently exists.
|
|
#[inline]
|
|
pub fn exists(&self) -> bool
|
|
{
|
|
self.inserted.load(atomic::Ordering::SeqCst)
|
|
}
|
|
/// Try to insert `value` at the referred slot.
|
|
///
|
|
/// If the slot already has a value, then `Err(value)` is returned, otherwise, `value` is inserted into the table and the number of items now populated is returned.
|
|
#[inline]
|
|
pub fn try_insert(&self, value: T) -> Result<usize, T>
|
|
{
|
|
self.pop.try_insert(self.idx, value)
|
|
}
|
|
/// Insert `value` at the referred slot.
|
|
///
|
|
/// # Panics
|
|
/// If the slot has a value.
|
|
#[inline]
|
|
pub fn insert(&self, value: T) -> usize
|
|
{
|
|
self.pop.insert(self.idx, value)
|
|
}
|
|
|
|
/// Consume into the inner populator reference and slot index
|
|
#[inline]
|
|
pub fn into_parts(self) -> (&'re Populator<'a, T>, usize)
|
|
{
|
|
(self.pop, self.idx)
|
|
}
|
|
|
|
/// Consume into the inner populator reference
|
|
#[inline]
|
|
pub fn into_inner(self) -> &'re Populator<'a, T>
|
|
{
|
|
self.pop
|
|
}
|
|
}
|
|
|
|
impl<'a, T:'a> OwnedRef<'a, T>
|
|
{
|
|
/// Get a reference to the parent `Arc`.
|
|
#[inline]
|
|
pub fn parent(&self) -> &Arc<Populator<'a, T>>
|
|
{
|
|
&self.pop
|
|
}
|
|
/// The index that this `Ref` refers to.
|
|
#[inline]
|
|
pub fn slot(&self) -> usize
|
|
{
|
|
self.idx
|
|
}
|
|
/// Checks if the references item currently exists.
|
|
#[inline]
|
|
pub fn exists(&self) -> bool
|
|
{
|
|
self.pop.exists(self.idx)
|
|
}
|
|
/// Try to insert `value` at the referred slot.
|
|
///
|
|
/// If the slot already has a value, then `Err(value)` is returned, otherwise, `value` is inserted into the table and the number of items now populated is returned.
|
|
#[inline]
|
|
pub fn try_insert(&self, value: T) -> Result<usize, T>
|
|
{
|
|
self.pop.try_insert(self.idx, value)
|
|
}
|
|
/// Insert `value` at the referred slot.
|
|
///
|
|
/// # Panics
|
|
/// If the slot has a value.
|
|
#[inline]
|
|
pub fn insert(&self, value: T) -> usize
|
|
{
|
|
self.pop.insert(self.idx, value)
|
|
}
|
|
|
|
/// Consume into the inner populator and slot index
|
|
#[inline]
|
|
pub fn into_parts(self) -> (Arc<Populator<'a, T>>, usize)
|
|
{
|
|
(self.pop, self.idx)
|
|
}
|
|
|
|
/// Consume into the inner populator
|
|
#[inline]
|
|
pub fn into_inner(self) -> Arc<Populator<'a, T>>
|
|
{
|
|
self.pop
|
|
}
|
|
}
|
|
|
|
//RefEx: Exclusive reference, holds &'re mut Populator<'a, T>
|
|
impl<'re, 'a, T: 'a> RefEx<'re, 'a ,T>
|
|
{
|
|
/// Get a reference to the parent
|
|
#[inline]
|
|
pub fn parent(&self) -> &Populator<'a, T>
|
|
{
|
|
&self.pop
|
|
}
|
|
/// Get a mutable reference to the parent
|
|
#[inline]
|
|
pub fn parent_mut(&mut self) -> &mut Populator<'a, T>
|
|
{
|
|
self.pop
|
|
}
|
|
/// The index that this `RefEx` refers to.
|
|
#[inline]
|
|
pub fn slot(&self) -> usize
|
|
{
|
|
self.idx
|
|
}
|
|
/// Checks if the references item currently exists.
|
|
#[inline]
|
|
pub fn exists(&mut self) -> bool
|
|
{
|
|
self.pop.exists_exclusive(self.idx)
|
|
}
|
|
/// Try to insert `value` at the referred slot.
|
|
///
|
|
/// If the slot already has a value, then `Err(value)` is returned, otherwise, `value` is inserted into the table and a reference to the new element is returned
|
|
#[inline]
|
|
pub fn try_insert(&mut self, value: T) -> Result<&T, T>
|
|
{
|
|
self.pop.try_insert_exclusive(self.idx, value).map(|x| &*x)
|
|
}
|
|
/// Try to insert `value` at the referred slot.
|
|
///
|
|
/// If the slot already has a value, then `Err(value)` is returned, otherwise, `value` is inserted into the table and a mutable reference to the new element is returned.
|
|
#[inline]
|
|
pub fn try_insert_mut(&mut self, value: T) -> Result<&mut T, T>
|
|
{
|
|
self.pop.try_insert_exclusive(self.idx, value)
|
|
}
|
|
/// Insert `value` at the referred slot and returns a reference to the inserted element.
|
|
///
|
|
/// # Panics
|
|
/// If the slot has a value.
|
|
#[inline]
|
|
pub fn insert(&mut self, value: T) -> &T
|
|
{
|
|
&*self.pop.insert_exclusive(self.idx, value)
|
|
}
|
|
/// Insert `value` at the referred slot and returns a reference to the inserted element.
|
|
///
|
|
/// # Panics
|
|
/// If the slot has a value.
|
|
#[inline]
|
|
pub fn insert_mut(&mut self, value: T) -> &mut T
|
|
{
|
|
self.pop.insert_exclusive(self.idx, value)
|
|
}
|
|
|
|
/// Consume into the inner populator and slot index
|
|
#[inline]
|
|
pub fn into_parts(self) -> (&'re mut Populator<'a, T>, usize)
|
|
{
|
|
(self.pop, self.idx)
|
|
}
|
|
|
|
/// Consume into the inner populator
|
|
#[inline]
|
|
pub fn into_inner(self) -> &'re mut Populator<'a, T>
|
|
{
|
|
self.pop
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> From<(&'re Populator<'a, T>, usize)> for Ref<'re, 'a, T>
|
|
{
|
|
#[inline]
|
|
fn from((pop, idx): (&'re Populator<'a, T>, usize)) -> Self
|
|
{
|
|
Self {
|
|
pop,
|
|
idx,
|
|
inserted: &pop.populates[idx]
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> From<Ref<'re, 'a, T>> for (&'re Populator<'a, T>, usize)
|
|
{
|
|
#[inline]
|
|
fn from(from: Ref<'re, 'a, T>) -> Self
|
|
{
|
|
(from.pop, from.idx)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: 'a> From<(Arc<Populator<'a, T>>, usize)> for OwnedRef<'a, T>
|
|
{
|
|
#[inline]
|
|
fn from((pop, idx): (Arc<Populator<'a, T>>, usize)) -> Self
|
|
{
|
|
Self { pop, idx }
|
|
}
|
|
}
|
|
|
|
|
|
impl<'a, T: 'a> From<OwnedRef<'a, T>> for (Arc<Populator<'a, T>>, usize)
|
|
{
|
|
#[inline]
|
|
fn from(from: OwnedRef<'a, T>) -> Self
|
|
{
|
|
(from.pop, from.idx)
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> From<RefEx<'re, 'a, T>> for (&'re mut Populator<'a, T>, usize)
|
|
{
|
|
#[inline]
|
|
fn from(from: RefEx<'re, 'a, T>) -> Self {
|
|
(from.pop, from.idx)
|
|
}
|
|
}
|
|
|
|
impl<'re, 'a, T: 'a> From<(&'re mut Populator<'a, T>, usize)> for RefEx<'re, 'a, T>
|
|
{
|
|
#[inline]
|
|
fn from((pop, idx): (&'re mut Populator<'a, T>, usize)) -> Self
|
|
{
|
|
Self { pop, idx }
|
|
}
|
|
}
|