#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, vec::Vec};
#[cfg(feature = "std")]
use std::{boxed::Box, vec::Vec};
use melinoe::{collections::BrandedVec, MelinoeCell};
use super::cell::{ConstPinnedCell, ConstPinnedSlice, PinnedCell, PinnedSlice};
use crate::NumaNodeId;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct ConstNodeTag<const NODE_ID: u32>;
pub trait CellContainer<'brand, T> {
fn as_cell(&self) -> &MelinoeCell<'brand, T>;
}
impl<'brand, T> CellContainer<'brand, T> for MelinoeCell<'brand, T> {
#[inline]
fn as_cell(&self) -> &MelinoeCell<'brand, T> {
self
}
}
impl<'brand, T> CellContainer<'brand, T> for &MelinoeCell<'brand, T> {
#[inline]
fn as_cell(&self) -> &MelinoeCell<'brand, T> {
self
}
}
pub trait CellSlice<'brand, T> {
fn as_cells(&self) -> &[MelinoeCell<'brand, T>];
}
impl<'brand, T> CellSlice<'brand, T> for Box<[MelinoeCell<'brand, T>]> {
#[inline]
fn as_cells(&self) -> &[MelinoeCell<'brand, T>] {
self
}
}
impl<'brand, T> CellSlice<'brand, T> for &[MelinoeCell<'brand, T>] {
#[inline]
fn as_cells(&self) -> &[MelinoeCell<'brand, T>] {
self
}
}
pub struct PinnedStorage<Tag, Storage> {
tag: Tag,
storage: Storage,
}
impl<Storage> PinnedStorage<NumaNodeId, Storage> {
#[must_use]
#[inline]
pub const fn node_id(&self) -> NumaNodeId {
self.tag
}
}
impl<T> PinnedStorage<NumaNodeId, MelinoeCell<'_, T>> {
#[must_use]
pub const fn new(node_id: NumaNodeId, value: T) -> Self {
Self {
tag: node_id,
storage: MelinoeCell::new(value),
}
}
}
impl<const NODE_ID: u32, T> PinnedStorage<ConstNodeTag<NODE_ID>, MelinoeCell<'_, T>> {
#[must_use]
pub const fn new(value: T) -> Self {
Self {
tag: ConstNodeTag,
storage: MelinoeCell::new(value),
}
}
}
impl<'a, 'brand, T> PinnedStorage<NumaNodeId, &'a MelinoeCell<'brand, T>> {
#[must_use]
#[inline]
pub fn from_unique(node_id: NumaNodeId, cell: &'a mut MelinoeCell<'brand, T>) -> Self {
Self {
tag: node_id,
storage: cell,
}
}
}
impl<'a, 'brand, const NODE_ID: u32, T>
PinnedStorage<ConstNodeTag<NODE_ID>, &'a MelinoeCell<'brand, T>>
{
#[must_use]
#[inline]
pub fn from_unique(cell: &'a mut MelinoeCell<'brand, T>) -> Self {
Self {
tag: ConstNodeTag,
storage: cell,
}
}
}
impl<'brand, T> PinnedStorage<NumaNodeId, Box<[MelinoeCell<'brand, T>]>> {
#[must_use]
pub fn new(node_id: NumaNodeId, values: Vec<T>) -> Self {
Self {
tag: node_id,
storage: BrandedVec::from_iter(values).into_boxed_cells(),
}
}
#[must_use]
pub fn from_fn<F>(node_id: NumaNodeId, len: usize, generate: F) -> Self
where
F: FnMut(usize) -> T,
{
Self {
tag: node_id,
storage: BrandedVec::from_fn(len, generate).into_boxed_cells(),
}
}
#[must_use]
pub const fn from_cells(node_id: NumaNodeId, cells: Box<[MelinoeCell<'brand, T>]>) -> Self {
Self {
tag: node_id,
storage: cells,
}
}
}
impl<'brand, const NODE_ID: u32, T>
PinnedStorage<ConstNodeTag<NODE_ID>, Box<[MelinoeCell<'brand, T>]>>
{
#[must_use]
pub fn new(values: Vec<T>) -> Self {
Self {
tag: ConstNodeTag,
storage: BrandedVec::from_iter(values).into_boxed_cells(),
}
}
#[must_use]
pub fn from_fn<F>(len: usize, generate: F) -> Self
where
F: FnMut(usize) -> T,
{
Self {
tag: ConstNodeTag,
storage: BrandedVec::from_fn(len, generate).into_boxed_cells(),
}
}
#[must_use]
pub const fn from_cells(cells: Box<[MelinoeCell<'brand, T>]>) -> Self {
Self {
tag: ConstNodeTag,
storage: cells,
}
}
}
impl<'a, 'brand, T> PinnedStorage<NumaNodeId, &'a [MelinoeCell<'brand, T>]> {
#[must_use]
#[inline]
pub fn from_unique(node_id: NumaNodeId, cells: &'a mut [MelinoeCell<'brand, T>]) -> Self {
Self {
tag: node_id,
storage: cells,
}
}
}
impl<'a, 'brand, const NODE_ID: u32, T>
PinnedStorage<ConstNodeTag<NODE_ID>, &'a [MelinoeCell<'brand, T>]>
{
#[must_use]
#[inline]
pub fn from_unique(cells: &'a mut [MelinoeCell<'brand, T>]) -> Self {
Self {
tag: ConstNodeTag,
storage: cells,
}
}
}
impl<'brand, Tag: Copy, T> PinnedStorage<Tag, MelinoeCell<'brand, T>> {
#[must_use]
#[inline]
pub const fn as_pinned_ref(&self) -> PinnedStorage<Tag, &MelinoeCell<'brand, T>> {
PinnedStorage {
tag: self.tag,
storage: &self.storage,
}
}
}
impl<'brand, Tag, T> PinnedStorage<Tag, Box<[MelinoeCell<'brand, T>]>> {
#[must_use]
#[inline]
pub fn cells(&self) -> &[MelinoeCell<'brand, T>] {
&self.storage
}
}
impl<'brand, Tag: Copy, T> PinnedStorage<Tag, Box<[MelinoeCell<'brand, T>]>> {
#[must_use]
#[inline]
pub const fn as_pinned_ref(&self) -> PinnedStorage<Tag, &[MelinoeCell<'brand, T>]> {
PinnedStorage {
tag: self.tag,
storage: &self.storage,
}
}
}
#[cfg(feature = "std")]
impl<'brand, Tag, T> PinnedStorage<Tag, Box<[MelinoeCell<'brand, T>]>> {
pub(crate) fn cells_mut(&mut self) -> &mut [MelinoeCell<'brand, T>] {
&mut self.storage
}
}
unsafe impl<'brand, T, Storage: CellContainer<'brand, T>> PinnedCell<'brand, T>
for PinnedStorage<NumaNodeId, Storage>
{
#[inline]
fn node_id(&self) -> NumaNodeId {
self.tag
}
#[inline]
fn cell(&self) -> &MelinoeCell<'brand, T> {
self.storage.as_cell()
}
}
unsafe impl<'brand, const NODE_ID: u32, T, Storage: CellContainer<'brand, T>>
ConstPinnedCell<'brand, NODE_ID, T> for PinnedStorage<ConstNodeTag<NODE_ID>, Storage>
{
#[inline]
fn cell(&self) -> &MelinoeCell<'brand, T> {
self.storage.as_cell()
}
}
unsafe impl<'brand, T, Storage: CellSlice<'brand, T>> PinnedSlice<'brand, T>
for PinnedStorage<NumaNodeId, Storage>
{
#[inline]
fn node_id(&self) -> NumaNodeId {
self.tag
}
#[inline]
fn cells(&self) -> &[MelinoeCell<'brand, T>] {
self.storage.as_cells()
}
}
unsafe impl<'brand, const NODE_ID: u32, T, Storage: CellSlice<'brand, T>>
ConstPinnedSlice<'brand, NODE_ID, T> for PinnedStorage<ConstNodeTag<NODE_ID>, Storage>
{
#[inline]
fn cells(&self) -> &[MelinoeCell<'brand, T>] {
self.storage.as_cells()
}
}