use std::collections::btree_map::{IntoIter, Iter, IterMut};
use std::collections::BTreeMap;
use core::fmt::{Debug, Display, Formatter, Result};
use core::hash::Hash;
use core::ops::{Index, IndexMut};
use core::str::FromStr;
use super::algorithm::{DictDisplay, DictFromStr};
use super::hash_dict::algo::{contains_slice, count, count_fn, count_item_fn, count_key_fn, count_slice, difference, distinct, distinct_fn, ext, find, find_fn, find_slice, intersect, pop, pop_slice, remove, remove_slice, replace, replace_fn, replace_slice, sym_diff, union, Dict, DictMut, DictRef};
use super::UDSI::{Container, Indexed, IndContainer};
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OrdDict<Key, Value> {
pub cont: BTreeMap<Key, Value>
}
impl<T,U> Container<(T,U)> for OrdDict<T,U> {
fn len(&self) -> usize {
self.cont.len()
}
}
impl<T,U> IndContainer<T,U> for OrdDict<T,U> {
fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a T,&'a U)> where T: 'a, U: 'a {
self.cont.iter()
}
fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a T,&'a mut U)> where T: 'a, U: 'a {
self.cont.iter_mut()
}
}
impl<T: Display, U: Display> DictDisplay<T,U> for OrdDict<T,U> {}
impl<T: Display, U: Display> Display for OrdDict<T,U> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
self.display(f, "OrdDict")
}
}
impl<T: Ord,U> Extend<(T,U)> for OrdDict<T,U> {
fn extend<I: IntoIterator<Item = (T,U)>>(&mut self, iter: I) {
self.cont.append(&mut iter.into_iter().collect());
}
}
impl<T: Ord,U> FromIterator<(T,U)> for OrdDict<T,U> {
fn from_iter<I: IntoIterator<Item = (T,U)>>(iter: I) -> Self {
let mut cont = Self::new();
cont.extend(iter);
cont
}
}
impl<T,U> IntoIterator for OrdDict<T,U> {
type Item = (T,U);
type IntoIter = IntoIter<T,U>;
fn into_iter(self) -> Self::IntoIter {
self.cont.into_iter()
}
}
impl<'a,T,U> IntoIterator for &'a OrdDict<T,U> {
type Item = (&'a T,&'a U);
type IntoIter = Iter<'a,T,U>;
fn into_iter(self) -> Self::IntoIter {
self.cont.iter()
}
}
impl<'a,T,U> IntoIterator for &'a mut OrdDict<T,U> {
type Item = (&'a T,&'a mut U);
type IntoIter = IterMut<'a,T,U>;
fn into_iter(self) -> Self::IntoIter {
self.cont.iter_mut()
}
}
impl<T,U,V: Into<BTreeMap<T,U>>> From<V> for OrdDict<T,U> {
fn from(value: V) -> Self {
use crate::ord_dict;
ord_dict![cont: value.into()]
}
}
impl<T: Ord + FromStr + Default, U: FromStr + Default> DictFromStr<T,U> for OrdDict<T,U> where <T as FromStr>::Err : Display, <U as FromStr>::Err : Display {}
impl<T: Ord + FromStr + Default, U: FromStr + Default> FromStr for OrdDict<T,U> where <T as FromStr>::Err : Display, <U as FromStr>::Err : Display {
type Err = String;
fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
Self::from_string(s, "OrdDict", |cont, t, u| {cont.cont.insert(t,u);})
}
}
#[macro_export]
macro_rules! ord_dict {
[cont: $x:expr] => {
{
use $crate::structs::ord_dict::OrdDict;
OrdDict { cont: ($x)}
}
};
[$($x:tt : $y:tt),*] => {
{
use std::collections::BTreeMap;
use $crate::structs::ord_dict::OrdDict;
let mut inner=BTreeMap::new();
$(
inner.insert($x,$y);
)*
OrdDict { cont: (inner) }
}
};
}
impl<X: Ord + Hash + Clone + core::fmt::Debug, T: Ord + Clone> Indexed<X,T> for OrdDict<X,T> {
fn add(&mut self, elem: (X,T)) -> &mut Self {
self.cont.insert(elem.0, elem.1);
self
}
fn add_slice(&mut self, slice: Vec<(X,T)>) -> &mut Self {
for val in slice { self.cont.insert(val.0, val.1); }
self
}
fn contains(&self, elem: &T) -> bool {
self.cont.iter().any(|x| x.1==elem)
}
fn contains_fn(&self, mut f: impl FnMut(&T) -> bool) -> bool {
self.cont.iter().any(|(_,t)| f(t))
}
fn contains_slice(&self, slice: &[T]) -> bool {
contains_slice(DictRef::OrdMap(&self.cont), slice)
}
fn contains_key(&self, key: &X) -> bool {
self.cont.contains_key(key)
}
fn contains_key_fn(&self, mut f: impl FnMut(&X) -> bool) -> bool {
self.cont.iter().any(|(x,_)| f(x))
}
fn contains_item(&self, item: (&X,&T)) -> bool {
self.contains_key(item.0) && self.cont[item.0]==*item.1
}
fn contains_item_fn(&self, f: impl FnMut((&X,&T)) -> bool) -> bool {
self.cont.iter().any(f)
}
fn count(&self, elem: &T) -> usize {
count(DictRef::OrdMap(&self.cont), elem)
}
fn count_fn(&self, f: impl FnMut(&T) -> bool) -> usize {
count_fn(DictRef::OrdMap(&self.cont), f)
}
fn count_slice(&self, slice: &[T]) -> usize {
count_slice(DictRef::OrdMap(&self.cont), slice)
}
fn count_key(&self, key: &X) -> usize {
usize::from(self.contains_key(key))
}
fn count_key_fn(&self, f: impl FnMut(&X) -> bool) -> usize {
count_key_fn(DictRef::OrdMap(&self.cont), f)
}
fn count_item(&self, item: (&X,&T)) -> usize {
usize::from(self.contains_item(item))
}
fn count_item_fn(&self, f: impl FnMut((&X,&T)) -> bool) -> usize {
count_item_fn(DictRef::OrdMap(&self.cont), f)
}
fn find(&self, elem: &T, maxcount: Option<isize>) -> Vec<&X> {
find(DictRef::OrdMap(&self.cont), elem, maxcount).into_iter().map(|x| unsafe {x.as_ref().unwrap()}).collect()
}
fn find_fn(&self, f: impl FnMut(&T) -> bool, maxcount: Option<isize>) -> Vec<&X> {
find_fn(DictRef::OrdMap(&self.cont), f, maxcount).into_iter().map(|x| unsafe {x.as_ref().unwrap()}).collect()
}
fn find_slice(&self, slice: &[T], maxcount: Option<isize>) -> Vec<&X> {
find_slice(DictRef::OrdMap(&self.cont), slice, maxcount).into_iter().map(|x| unsafe {x.as_ref().unwrap()}).collect()
}
fn pop(&mut self, index: &X) -> T {
pop(DictMut::OrdMap(&mut self.cont), index)
}
fn pop_slice(&mut self, indices: &[X]) -> Vec<T> {
pop_slice(DictMut::OrdMap(&mut self.cont), indices)
}
fn remove(&mut self, index: &X) -> &mut Self {
remove(DictMut::OrdMap(&mut self.cont), index);
self
}
fn remove_slice(&mut self, indices: &[X]) -> &mut Self {
remove_slice(DictMut::OrdMap(&mut self.cont), indices);
self
}
fn replace(&mut self, what: &T, to_what: Option<&T>, max_count: Option<isize>) -> &mut Self {
replace(DictMut::OrdMap(&mut self.cont), what, to_what, max_count);
self
}
fn replace_fn(&mut self, f: impl FnMut(&T)->bool, to_what: Option<&T>, max_count: Option<isize>) -> &mut Self {
replace_fn(DictMut::OrdMap(&mut self.cont), f, to_what, max_count);
self
}
fn replace_slice<const N: usize>(&mut self, slice: &[T;N], to_what: Option<&[T;N]>, max_count: Option<isize>) -> &mut Self {
replace_slice(DictMut::OrdMap(&mut self.cont), slice, to_what, max_count);
self
}
fn distinct(&mut self) -> &mut Self {
distinct(DictMut::OrdMap(&mut self.cont));
self
}
fn distinct_fn<U: Ord>(&mut self, f: impl FnMut(&T) -> U) -> &mut Self {
distinct_fn(DictMut::OrdMap(&mut self.cont), f);
self
}
fn clear(&mut self) -> &mut Self {
self.cont.clear();
self
}
fn union(&mut self, other: Self) -> &mut Self {
union(DictMut::OrdMap(&mut self.cont), Dict::OrdMap(other.cont));
self
}
fn intersect(&mut self, other: &Self) -> &mut Self {
intersect(DictMut::OrdMap(&mut self.cont), DictRef::OrdMap(&other.cont));
self
}
fn difference(&mut self, other: &Self) -> &mut Self {
difference(DictMut::OrdMap(&mut self.cont), DictRef::OrdMap(&other.cont));
self
}
fn sym_diff(&mut self, other: Self) -> &mut Self {
sym_diff(DictMut::OrdMap(&mut self.cont), Dict::OrdMap(other.cont));
self
}
fn maxi(&self) -> (&T, &X) {
let res=ext(DictRef::OrdMap(&self.cont), true);
unsafe {(res.0.as_ref().unwrap(),res.1.as_ref().unwrap())}
}
fn mini(&self) -> (&T, &X) {
let res=ext(DictRef::OrdMap(&self.cont), false);
unsafe {(res.0.as_ref().unwrap(),res.1.as_ref().unwrap())}
}
fn keys<'a>(&'a self) -> impl Iterator<Item = &'a X> where X: 'a {
self.cont.keys()
}
fn values<'a>(&'a self) -> impl Iterator<Item = &'a T> where T: 'a {
self.cont.values()
}
fn into_keys(self) -> impl IntoIterator<Item = X> {
self.cont.into_keys()
}
fn into_values(self) -> impl IntoIterator<Item = T> {
self.cont.into_values()
}
}
impl<T,U> OrdDict<T,U> {
#[must_use]
pub const fn new() -> Self {
Self { cont: (BTreeMap::new()) }
}
}
impl<T: Ord,U> Index<&T> for OrdDict<T,U> {
type Output = U;
fn index(&self, index: &T) -> &Self::Output {
&self.cont[index]
}
}
impl<T: Ord,U> IndexMut<&T> for OrdDict<T,U> {
fn index_mut(&mut self, index: &T) -> &mut Self::Output {
self.cont.get_mut(index).unwrap()
}
}