use crate::traits::{BiIndexable, Graph, IndexGraph, IndexNetwork, Indexable, Network};
use std::fmt;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut};
use std::slice::IterMut;
pub trait NumItems<G> {
fn num_items(g: &G) -> usize;
}
pub trait Indexer<G, I> {
fn index(g: &G, item: I) -> usize;
}
pub struct IndexItemSlice<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b,
{
g: &'a G,
data: &'b [T],
phantom: PhantomData<Idx>,
}
impl<'a, 'b, G, T, Idx> Clone for IndexItemSlice<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b,
{
fn clone(&self) -> Self {
IndexItemSlice {
g: self.g,
data: self.data,
phantom: PhantomData,
}
}
}
impl<'a, 'b, G, T, Idx> Copy for IndexItemSlice<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b,
{
}
pub struct IndexItemSliceMut<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b,
{
g: &'a G,
data: &'b mut [T],
phantom: PhantomData<Idx>,
}
pub struct IndexItemVec<'a, G, T, Idx>
where
G: 'a,
{
g: &'a G,
data: Vec<T>,
phantom: PhantomData<Idx>,
}
impl<'a, G, Idx, T> Clone for IndexItemVec<'a, G, T, Idx>
where
G: 'a,
T: Clone,
{
fn clone(&self) -> Self {
IndexItemVec {
g: self.g,
data: self.data.clone(),
phantom: PhantomData,
}
}
}
impl<'a, G, Idx, T> fmt::Debug for IndexItemVec<'a, G, T, Idx>
where
G: 'a,
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.data.fmt(fmt)
}
}
impl<'a, 'b, G, Idx, T> fmt::Debug for IndexItemSlice<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b + fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.data.fmt(fmt)
}
}
impl<'a, 'b, G, Idx, T> fmt::Debug for IndexItemSliceMut<'a, 'b, G, T, Idx>
where
G: 'a,
T: 'b + fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.data.fmt(fmt)
}
}
impl<'a, 'b, G, Idx, T> Deref for IndexItemSliceMut<'a, 'b, G, T, Idx>
where
G: 'a,
Idx: 'b,
{
type Target = IndexItemSliceMut<'a, 'b, G, Idx, T>;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const Self as *const Self::Target) }
}
}
impl<'a, 'b, G, T, Idx> IndexItemSlice<'a, 'b, G, T, Idx>
where
G: 'a,
Idx: NumItems<G>,
{
pub fn new(g: &'a G, data: &'b [T]) -> IndexItemSlice<'a, 'b, G, T, Idx> {
assert_eq!(
Idx::num_items(g),
data.len(),
"Slice must have size {}",
Idx::num_items(g)
);
IndexItemSlice {
g,
data,
phantom: PhantomData,
}
}
pub fn map<F, R>(&self, f: F) -> IndexItemVec<'a, G, R, Idx>
where
F: Fn(&T) -> R,
{
IndexItemVec {
g: self.g,
data: self.data.iter().map(f).collect(),
phantom: PhantomData,
}
}
}
impl<'a, 'b, G, Idx, T> IndexItemSliceMut<'a, 'b, G, T, Idx>
where
G: 'a,
Idx: NumItems<G>,
{
pub fn new(g: &'a G, data: &'b mut [T]) -> IndexItemSliceMut<'a, 'b, G, T, Idx> {
assert_eq!(
Idx::num_items(g),
data.len(),
"Slice must have size {}",
Idx::num_items(g)
);
IndexItemSliceMut {
g,
data,
phantom: PhantomData,
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
self.data.iter_mut()
}
}
impl<'a, G, Idx, T> IndexItemVec<'a, G, T, Idx>
where
G: 'a,
Idx: NumItems<G>,
{
pub fn from_vec(g: &'a G, values: Vec<T>) -> Self {
assert_eq!(
Idx::num_items(g),
values.len(),
"Vector must have size {}",
Idx::num_items(g)
);
IndexItemVec {
g,
data: values,
phantom: PhantomData,
}
}
pub fn as_slice<'s>(&'s self) -> IndexItemSlice<'a, 's, G, T, Idx>
where
'a: 's,
{
IndexItemSlice {
g: self.g,
data: self.data.as_slice(),
phantom: PhantomData,
}
}
pub fn as_mut_slice<'s>(&'s mut self) -> IndexItemSliceMut<'a, 's, G, T, Idx>
where
'a: 's,
{
IndexItemSliceMut {
g: self.g,
data: self.data.as_mut_slice(),
phantom: PhantomData,
}
}
pub fn reset(&mut self, x: T)
where
T: Clone,
{
let n = self.data.len();
self.data.clear();
self.data.resize(n, x);
}
pub fn map<F, R>(&self, f: F) -> IndexItemVec<'a, G, R, Idx>
where
F: Fn(&T) -> R,
{
IndexItemVec {
g: self.g,
data: self.data.iter().map(f).collect(),
phantom: PhantomData,
}
}
pub fn map_into<F, R>(self, f: F) -> IndexItemVec<'a, G, R, Idx>
where
F: Fn(T) -> R,
{
IndexItemVec {
g: self.g,
data: self.data.into_iter().map(f).collect(),
phantom: PhantomData,
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
self.data.iter_mut()
}
}
impl<'a, 'b, G, T, Idx, I> Index<I> for IndexItemSlice<'a, 'b, G, T, Idx>
where
Idx: Indexer<G, I>,
{
type Output = T;
fn index(&self, u: I) -> &T {
&self.data[Idx::index(self.g, u)]
}
}
impl<'a, 'b, G, T, Idx, I> Index<I> for IndexItemSliceMut<'a, 'b, G, T, Idx>
where
Idx: Indexer<G, I>,
{
type Output = T;
fn index(&self, u: I) -> &T {
&self.data[Idx::index(self.g, u)]
}
}
impl<'a, 'b, G, T, Idx, I> IndexMut<I> for IndexItemSliceMut<'a, 'b, G, T, Idx>
where
Idx: Indexer<G, I>,
{
fn index_mut(&mut self, u: I) -> &mut T {
&mut self.data[Idx::index(self.g, u)]
}
}
impl<'a, G, T, Idx, I> Index<I> for IndexItemVec<'a, G, T, Idx>
where
Idx: Indexer<G, I>,
{
type Output = T;
fn index(&self, u: I) -> &T {
&self.data[Idx::index(self.g, u)]
}
}
impl<'a, G, T, Idx, I> IndexMut<I> for IndexItemVec<'a, G, T, Idx>
where
Idx: Indexer<G, I>,
{
fn index_mut(&mut self, u: I) -> &mut T {
&mut self.data[Idx::index(self.g, u)]
}
}
impl<'a, 'b, G, T, Idx> Deref for IndexItemSlice<'a, 'b, G, T, Idx> {
type Target = [T];
fn deref(&self) -> &[T] {
self.data
}
}
impl<'a, G, Idx, T> Deref for IndexItemVec<'a, G, T, Idx> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.data
}
}
pub struct NodeIndexer;
impl<'a, G> Indexer<G, G::Node> for NodeIndexer
where
G: IndexGraph<'a>,
{
fn index(g: &G, u: G::Node) -> usize {
g.node_id(u)
}
}
impl<'a, G> NumItems<G> for NodeIndexer
where
G: Graph<'a>,
{
fn num_items(g: &G) -> usize {
g.num_nodes()
}
}
pub struct EdgeIndexer;
impl<'a, G> Indexer<G, G::Edge> for EdgeIndexer
where
G: IndexGraph<'a>,
{
fn index(g: &G, u: G::Edge) -> usize {
g.edge_id(u)
}
}
impl<'a, G> NumItems<G> for EdgeIndexer
where
G: Graph<'a>,
{
fn num_items(g: &G) -> usize {
g.num_edges()
}
}
pub struct BiEdgeIndexer;
impl<'a, G> Indexer<G, G::Edge> for BiEdgeIndexer
where
G: IndexNetwork<'a>,
{
fn index(g: &G, u: G::Edge) -> usize {
g.biedge_id(u)
}
}
impl<'a, G> NumItems<G> for BiEdgeIndexer
where
G: Network<'a>,
{
fn num_items(g: &G) -> usize {
g.num_edges() * 2
}
}
pub type IndexNodeSlice<'a, 'b, G, T> = IndexItemSlice<'a, 'b, G, T, NodeIndexer>;
pub type IndexNodeSliceMut<'a, 'b, G, T> = IndexItemSliceMut<'a, 'b, G, T, NodeIndexer>;
pub type IndexNodeVec<'a, G, T> = IndexItemVec<'a, G, T, NodeIndexer>;
pub type IndexEdgeSlice<'a, 'b, G, T> = IndexItemSlice<'a, 'b, G, T, EdgeIndexer>;
pub type IndexEdgeSliceMut<'a, 'b, G, T> = IndexItemSliceMut<'a, 'b, G, T, EdgeIndexer>;
pub type IndexEdgeVec<'a, G, T> = IndexItemVec<'a, G, T, EdgeIndexer>;
pub type IndexBiEdgeSlice<'a, 'b, G, T> = IndexItemSlice<'a, 'b, G, T, BiEdgeIndexer>;
pub type IndexBiEdgeSliceMut<'a, 'b, G, T> = IndexItemSliceMut<'a, 'b, G, T, BiEdgeIndexer>;
pub type IndexBiEdgeVec<'a, G, T> = IndexItemVec<'a, G, T, BiEdgeIndexer>;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ItemVec<T, Idx>(Vec<T>, PhantomData<Idx>);
impl<T, Idx> ItemVec<T, Idx> {
pub fn new(v: Vec<T>) -> ItemVec<T, Idx> {
ItemVec(v, PhantomData)
}
pub fn as_slice(&self) -> &ItemSlice<T, Idx> {
self
}
}
impl<T, Idx> From<Vec<T>> for ItemVec<T, Idx> {
fn from(vec: Vec<T>) -> ItemVec<T, Idx> {
ItemVec::new(vec)
}
}
impl<T, Idx> Deref for ItemVec<T, Idx> {
type Target = ItemSlice<T, Idx>;
fn deref(&self) -> &ItemSlice<T, Idx> {
self.0.as_slice().into()
}
}
impl<T, Idx> DerefMut for ItemVec<T, Idx> {
fn deref_mut(&mut self) -> &mut ItemSlice<T, Idx> {
self.0.as_mut_slice().into()
}
}
pub struct ItemSlice<T, Idx>(PhantomData<Idx>, [T]);
impl<'a, T, Idx> From<&'a [T]> for &'a ItemSlice<T, Idx> {
fn from(v: &'a [T]) -> &'a ItemSlice<T, Idx> {
unsafe { &*(v as *const [T] as *const ItemSlice<T, Idx>) }
}
}
impl<'a, T, Idx> From<&'a mut [T]> for &'a mut ItemSlice<T, Idx> {
fn from(v: &'a mut [T]) -> &'a mut ItemSlice<T, Idx> {
unsafe { &mut *(v as *mut [T] as *mut ItemSlice<T, Idx>) }
}
}
impl<T, Idx> Deref for ItemSlice<T, Idx> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.1
}
}
impl<T, Idx> DerefMut for ItemSlice<T, Idx> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.1
}
}
pub trait NumberedIndexer<I> {
fn index(item: I) -> usize;
}
impl<T, I, Idx> Index<I> for ItemVec<T, Idx>
where
Idx: NumberedIndexer<I>,
{
type Output = T;
fn index(&self, item: I) -> &T {
&self.0[Idx::index(item)]
}
}
impl<T, I, Idx> IndexMut<I> for ItemVec<T, Idx>
where
Idx: NumberedIndexer<I>,
{
fn index_mut(&mut self, item: I) -> &mut T {
&mut self.0[Idx::index(item)]
}
}
impl<'a, T, I, Idx> Index<I> for &'a ItemVec<T, Idx>
where
Idx: NumberedIndexer<I>,
{
type Output = T;
fn index(&self, item: I) -> &T {
&self.0[Idx::index(item)]
}
}
impl<'a, T, I, Idx> Index<I> for &'a mut ItemVec<T, Idx>
where
Idx: NumberedIndexer<I>,
{
type Output = T;
fn index(&self, item: I) -> &T {
&self.0[Idx::index(item)]
}
}
impl<'a, T, I, Idx> IndexMut<I> for &'a mut ItemVec<T, Idx>
where
Idx: NumberedIndexer<I>,
{
fn index_mut(&mut self, item: I) -> &mut T {
&mut self.0[Idx::index(item)]
}
}
impl<'a, T, I, Idx> Index<I> for &'a ItemSlice<T, Idx>
where
Idx: NumberedIndexer<I>,
{
type Output = T;
fn index(&self, item: I) -> &T {
&self.1[Idx::index(item)]
}
}
impl<'a, T, I, Idx> Index<I> for &'a mut ItemSlice<T, Idx>
where
Idx: NumberedIndexer<I>,
{
type Output = T;
fn index(&self, item: I) -> &T {
&self.1[Idx::index(item)]
}
}
impl<'a, T, I, Idx> IndexMut<I> for &'a mut ItemSlice<T, Idx>
where
Idx: NumberedIndexer<I>,
{
fn index_mut(&mut self, item: I) -> &mut T {
&mut self.1[Idx::index(item)]
}
}
impl<N> NumberedIndexer<N> for NodeIndexer
where
N: Indexable,
{
fn index(node: N) -> usize {
node.index()
}
}
impl<E> NumberedIndexer<E> for EdgeIndexer
where
E: Indexable,
{
fn index(edge: E) -> usize {
edge.index()
}
}
impl<E> NumberedIndexer<E> for BiEdgeIndexer
where
E: BiIndexable,
{
fn index(edge: E) -> usize {
edge.biindex()
}
}
pub type NodeVec<T> = ItemVec<T, NodeIndexer>;
pub type EdgeVec<T> = ItemVec<T, EdgeIndexer>;
pub type BiEdgeVec<T> = ItemVec<T, BiEdgeIndexer>;
pub type NodeSlice<T> = ItemSlice<T, NodeIndexer>;
pub type EdgeSlice<T> = ItemSlice<T, EdgeIndexer>;
pub type BiEdgeSlice<T> = ItemSlice<T, BiEdgeIndexer>;
impl<'a, G, T, Idx> From<(&'a G, ItemVec<T, Idx>)> for IndexItemVec<'a, G, T, Idx>
where
G: IndexGraph<'a>,
Idx: NumItems<G>,
{
fn from(other: (&'a G, ItemVec<T, Idx>)) -> Self {
IndexItemVec::from_vec(other.0, (other.1).0)
}
}
#[cfg(test)]
mod tests {
use crate::classes::peterson;
use crate::traits::*;
use crate::LinkedListGraph;
#[test]
fn test_iter() {
let g = peterson::<LinkedListGraph>();
let mut weights = idxedgevec![&g, (0..g.num_edges()).collect()];
for (i, &x) in weights.iter().enumerate() {
assert_eq!(i, x);
}
for x in weights.iter_mut() {
*x = *x + 1;
}
for (i, &x) in weights.iter().enumerate() {
assert_eq!(i + 1, x);
}
}
#[test]
fn test_map() {
let g = peterson::<LinkedListGraph>();
let weights = idxedgevec![&g, (0..g.num_edges()).collect()];
let new_weights = weights.map(|i| i + 1);
for e in g.edges() {
assert_eq!(weights[e] + 1, new_weights[e]);
}
let new_weights = new_weights.map_into(|i| i * 2);
for e in g.edges() {
assert_eq!(2 * (weights[e] + 1), new_weights[e]);
}
}
}