use crate::{
graph::{iter, Edge},
IntKeyMap, MapWithCapacity,
};
use core::{
fmt::Debug,
marker::PhantomData,
ops::{Index, IndexMut},
};
#[cfg(feature = "rayon")]
use {
crate::map::ParIterMap,
crate::util::{ParEdgeWeightIter, ParEdgeWeightIterMut},
rayon::iter::ParallelIterator,
};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
pub(super) map: EM,
#[cfg_attr(feature = "serde", serde(skip_serializing, default))]
_marker: PhantomData<(E, NI, EI, EM)>,
}
impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
pub fn contains_key(&self, index: EI) -> bool {
self.map.contains_key(index)
}
pub fn get(&self, index: EI) -> Option<&Edge<E, NI, EI>> {
self.map.get(index)
}
pub fn get_mut(&mut self, index: EI) -> Option<&mut Edge<E, NI, EI>> {
self.map.get_mut(index)
}
pub fn weight(&self, index: EI) -> Option<&E> {
self.map.get(index).map(Edge::weight)
}
pub fn weight_mut(&mut self, index: EI) -> Option<&mut E> {
self.map.get_mut(index).map(Edge::weight_mut)
}
pub fn iter(&self) -> EM::Iter<'_> {
self.map.iter()
}
pub fn iter_mut(&mut self) -> EM::IterMut<'_> {
self.map.iter_mut()
}
pub fn iter_weights(&self) -> iter::EdgeWeights<'_, E, NI, EI, EM> {
iter::EdgeWeights { inner: self.iter() }
}
pub fn iter_weights_mut(&mut self) -> iter::EdgeWeightsMut<'_, E, NI, EI, EM> {
iter::EdgeWeightsMut {
inner: self.iter_mut(),
}
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
}
impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + MapWithCapacity<Edge<E, NI, EI>, Key = EI>,
{
pub(super) fn with_capacity(capacity: usize) -> Self {
Self {
map: EM::with_capacity(capacity),
_marker: PhantomData,
}
}
}
#[cfg(feature = "rayon")]
impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
E: Sync + Send,
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Send + Sync + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + ParIterMap<Edge<E, NI, EI>, Key = EI>,
{
pub fn par_iter(&self) -> EM::ParIter<'_> {
self.map.par_iter()
}
pub fn par_iter_mut(&mut self) -> EM::ParIterMut<'_> {
self.map.par_iter_mut()
}
pub fn par_iter_weights(&self) -> ParEdgeWeightIter<EM::ParIter<'_>, NI, EI, E> {
self.map
.par_iter()
.map(|(index, node)| (index, node.weight()))
}
pub fn par_iter_weights_mut(&mut self) -> ParEdgeWeightIterMut<EM::ParIterMut<'_>, NI, EI, E> {
self.map
.par_iter_mut()
.map(|(index, node)| (index, node.weight_mut()))
}
}
impl<E, NI, EI, EM> Default for Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
fn default() -> Self {
Self {
map: Default::default(),
_marker: PhantomData,
}
}
}
impl<E, NI, EI, EM> Index<EI> for Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
type Output = Edge<E, NI, EI>;
fn index(&self, index: EI) -> &Self::Output {
self.map.get(index).expect("invalid edge index")
}
}
impl<E, NI, EI, EM> IndexMut<EI> for Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
fn index_mut(&mut self, index: EI) -> &mut Self::Output {
self.map.get_mut(index).expect("invalid edge index")
}
}
impl<'a, E, NI, EI, EM> IntoIterator for &'a Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
type Item = (EI, &'a Edge<E, NI, EI>);
type IntoIter = EM::Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter()
}
}
impl<'a, E, NI, EI, EM> IntoIterator for &'a mut Edges<E, NI, EI, EM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
type Item = (EI, &'a mut Edge<E, NI, EI>);
type IntoIter = EM::IterMut<'a>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter_mut()
}
}