Added OwnedRef: References a single slot from an Arc"d Populator.

Fortune for parapop's current commit: Future blessing − 末吉
master
Avril 2 years ago
parent c7932794f0
commit 9a30ad5665
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -192,9 +192,15 @@ impl<'a, T> Populator<'a, T>
}
}
/// Get a reference to an item at `idx` whether it exists or not.
#[inline]
pub fn get_ref(&self, idx: usize) -> Ref<'_, 'a, T>
#[inline(always)]
fn bounds_okay(&self, idx: usize) -> bool
{
idx < self.populates.len()
}
#[inline(always)]
fn bounds_check(&self, idx: usize)
{
#[inline(never)]
#[cold]
@ -205,12 +211,34 @@ impl<'a, T> Populator<'a, T>
if idx >= self.populates.len() {
_panic_oob(idx, self.populates.len())
}
}
/// Get a reference to an item at `idx` whether it exists or not.
///
/// # Panics
/// If the index is out of bounds
#[inline]
pub fn get_ref(&self, idx: usize) -> Ref<'_, 'a, T>
{
self.bounds_check(idx);
Ref {
pop: self,
idx
}
}
//TODO: get_into(Arc<Self>) -> OwnedRef
/// Consume into a reference to a specific index in the populator, whether it exists or not.
///
/// # Panics
/// If the index is out of bounds
#[inline]
pub fn into_ref(self: std::sync::Arc<Self>, idx: usize) -> OwnedRef<'a, T>
{
OwnedRef {
pop: self,
idx
}
}
//TODO: get_excusive -> RefEx
/// Try to get an exclusive, mutable reference to an item at `idx` if an item exists there.

@ -1,5 +1,6 @@
//! Single-index references.
use super::*;
use std::sync::Arc;
#[derive(Debug)] // PartialEq, PartialOrd
pub struct Ref<'re, 'a, T: 'a>
@ -10,6 +11,34 @@ pub struct Ref<'re, 'a, T: 'a>
//TODO: OR: Hold a reference to the actual AtomicBool at `idx` itself?
}
#[derive(Debug)]
pub struct OwnedRef<'a, T: 'a> // PartialEq, PartialOrd
{
pub(super) pop: Arc<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>
{
@ -63,8 +92,65 @@ impl<'re, 'a, T: 'a> Ref<'re, 'a, T>
{
self.pop.insert(self.idx, value)
}
}
//TODO: OwnedRef: From Arc<Self> receiver of Arc<Populator<'static, T>>
//TODO: RefEx: Exclusive reference, holds &'ref mut Populator<'a, T>
impl<'a, T:'a> OwnedRef<'a, T>
{
/// 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
#[inline]
pub fn into_inner(self) -> Arc<Populator<'a, T>>
{
self.pop
}
}
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)
}
}
//TODO: RefEx: Exclusive reference, holds &'re mut Populator<'a, T>

Loading…
Cancel
Save