Skip to content

Commit

Permalink
better traits for convenience constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Durfee committed Aug 13, 2020
1 parent 6ca6179 commit 11c81d7
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 62 deletions.
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
[package]
name = "segment-map"
version = "0.1.0"
version = "0.1.1"
authors = ["Robert Durfee <rbd@mit.edu>"]
description = "A self-balancing binary search tree for mapping discrete, disjoint segments to values."
license-file = "LICENSE"
repository = "https://github.com/RobertDurfee/SegmentMap"
license = "MIT"
repository = "https://github.com/RobertDurfee/SegmentMap/tree/v0.1.1"
readme = "README.md"
keywords = ["segment-map", "interval-map", "segment", "interval", "map"]
categories = ["data-structures"]
edition = "2018"

[dependencies]
num = "0.3"
79 changes: 79 additions & 0 deletions src/bounded.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::{
usize,
u8,
u16,
u32,
u64,
u128,
isize,
i8,
i16,
i32,
i64,
i128
};

pub trait Bounded {
fn min() -> Self;
fn max() -> Self;
}

impl Bounded for usize {
fn min() -> usize { usize::MIN }
fn max() -> usize { usize::MAX }
}

impl Bounded for u8 {
fn min() -> u8 { u8::MIN }
fn max() -> u8 { u8::MAX }
}

impl Bounded for u16 {
fn min() -> u16 { u16::MIN }
fn max() -> u16 { u16::MAX }
}

impl Bounded for u32 {
fn min() -> u32 { u32::MIN }
fn max() -> u32 { u32::MAX }
}

impl Bounded for u64 {
fn min() -> u64 { u64::MIN }
fn max() -> u64 { u64::MAX }
}

impl Bounded for u128 {
fn min() -> u128 { u128::MIN }
fn max() -> u128 { u128::MAX }
}

impl Bounded for isize {
fn min() -> isize { isize::MIN }
fn max() -> isize { isize::MAX }
}

impl Bounded for i8 {
fn min() -> i8 { i8::MIN }
fn max() -> i8 { i8::MAX }
}

impl Bounded for i16 {
fn min() -> i16 { i16::MIN }
fn max() -> i16 { i16::MAX }
}

impl Bounded for i32 {
fn min() -> i32 { i32::MIN }
fn max() -> i32 { i32::MAX }
}

impl Bounded for i64 {
fn min() -> i64 { i64::MIN }
fn max() -> i64 { i64::MAX }
}

impl Bounded for i128 {
fn min() -> i128 { i128::MIN }
fn max() -> i128 { i128::MAX }
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
mod segment;
mod segment_map_node;
mod segment_map;
mod bounded;
mod next;

pub use crate::segment_map::SegmentMap;
pub use crate::segment::Segment;
pub use crate::bounded::Bounded;
pub use crate::next::Next;
51 changes: 51 additions & 0 deletions src/next.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pub trait Next: Clone + PartialOrd {
fn next(&self) -> Self;
}

impl Next for usize {
fn next(&self) -> usize { self.checked_add(1).expect("integer overflow") }
}

impl Next for u8 {
fn next(&self) -> u8 { self.checked_add(1).expect("integer overflow") }
}

impl Next for u16 {
fn next(&self) -> u16 { self.checked_add(1).expect("integer overflow") }
}

impl Next for u32 {
fn next(&self) -> u32 { self.checked_add(1).expect("integer overflow") }
}

impl Next for u64 {
fn next(&self) -> u64 { self.checked_add(1).expect("integer overflow") }
}

impl Next for u128 {
fn next(&self) -> u128 { self.checked_add(1).expect("integer overflow") }
}

impl Next for isize {
fn next(&self) -> isize { self.checked_add(1).expect("integer overflow") }
}

impl Next for i8 {
fn next(&self) -> i8 { self.checked_add(1).expect("integer overflow") }
}

impl Next for i16 {
fn next(&self) -> i16 { self.checked_add(1).expect("integer overflow") }
}

impl Next for i32 {
fn next(&self) -> i32 { self.checked_add(1).expect("integer overflow") }
}

impl Next for i64 {
fn next(&self) -> i64 { self.checked_add(1).expect("integer overflow") }
}

impl Next for i128 {
fn next(&self) -> i128 { self.checked_add(1).expect("integer overflow") }
}
76 changes: 42 additions & 34 deletions src/segment.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::ops::Add;
use num::{
use crate::{
Bounded,
Zero,
One,
Next,
};

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
Expand All @@ -11,11 +9,18 @@ pub struct Segment<K> {
upper: K,
}

impl<K: PartialOrd> Segment<K> {
impl<K> Segment<K>
where
K: PartialOrd
{
pub fn new(lower: K, upper: K) -> Segment<K> {
Segment { lower, upper }
}

pub fn closed_open(lower: K, upper: K) -> Segment<K> {
Segment { lower, upper }
}

pub fn contains(&self, value: &K) -> bool {
(&self.lower <= value) && (value < &self.upper)
}
Expand All @@ -41,7 +46,10 @@ impl<K: PartialOrd> Segment<K> {
}
}

impl<K: Clone + PartialOrd> Segment<K> {
impl<K> Segment<K>
where
K: Clone + PartialOrd
{
pub fn intersection(&self, other: &Segment<K>) -> Option<Segment<K>> {
if self.is_connected(other) {
Some(Segment {
Expand All @@ -59,63 +67,63 @@ impl<K: Clone + PartialOrd> Segment<K> {
}
}

impl<K: PartialOrd + Zero> Segment<K> {
impl<K> Segment<K>
where
K: PartialOrd + Default
{
pub fn empty() -> Segment<K> {
Segment { lower: K::zero(), upper: K::zero() }
Segment { lower: K::default(), upper: K::default() }
}
}

impl<K: Add<Output = K> + Clone + One + PartialOrd> Segment<K> {
impl<K> Segment<K>
where
K: PartialOrd + Next
{
pub fn singleton(value: K) -> Segment<K> {
Segment { lower: value.clone(), upper: value + K::one() }
Segment { lower: value.clone(), upper: value.next() }
}
}

impl<K: Add<Output = K> + One + PartialOrd> Segment<K> {
pub fn open(lower: K, upper: K) -> Segment<K> {
Segment { lower: lower + K::one(), upper }
Segment { lower: lower.next(), upper }
}

pub fn closed(lower: K, upper: K) -> Segment<K> {
Segment { lower, upper: upper + K::one() }
Segment { lower, upper: upper.next() }
}

pub fn open_closed(lower: K, upper: K) -> Segment<K> {
Segment { lower: lower + K::one(), upper: upper + K::one() }
Segment { lower: lower.next(), upper: upper.next() }
}
}

impl<K: PartialOrd> Segment<K> {
pub fn closed_open(lower: K, upper: K) -> Segment<K> {
Segment { lower, upper }
impl<K> Segment<K>
where
K: Bounded + PartialOrd + Next
{
pub fn at_most(value: K) -> Segment<K> {
Segment { lower: K::min(), upper: value.next() }
}
}

impl<K: Add<Output = K> + Bounded + One + PartialOrd> Segment<K> {
pub fn at_most(value: K) -> Segment<K> {
Segment { lower: K::min_value(), upper: value + K::one() }
pub fn greater_than(value: K) -> Segment<K> {
Segment { lower: value.next(), upper: K::max() }
}
}

impl<K: Bounded + PartialOrd> Segment<K> {
impl<K> Segment<K>
where
K: Bounded + PartialOrd
{
pub fn at_least(value: K) -> Segment<K> {
Segment { lower: value, upper: K::max_value() }
Segment { lower: value, upper: K::max() }
}

pub fn less_than(value: K) -> Segment<K> {
Segment { lower: K::min_value(), upper: value }
}
}

impl<K: Add<Output = K> + Bounded + One + PartialOrd> Segment<K> {
pub fn greater_than(value: K) -> Segment<K> {
Segment { lower: value + K::one(), upper: K::max_value() }
Segment { lower: K::min(), upper: value }
}
}

impl<K: Bounded + PartialOrd> Segment<K> {
pub fn all() -> Segment<K> {
Segment { lower: K::min_value(), upper: K::max_value() }
Segment { lower: K::min(), upper: K::max() }
}
}

Expand Down
22 changes: 18 additions & 4 deletions src/segment_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ pub struct SegmentMap<K, V> {
root: Option<SegmentMapNode<K, V>>,
}

impl<K: PartialOrd, V> SegmentMap<K, V> {
impl<K, V> SegmentMap<K, V>
where
K: PartialOrd
{
pub fn new() -> SegmentMap<K, V> {
SegmentMap { root: None }
}
Expand Down Expand Up @@ -72,7 +75,11 @@ impl<K: PartialOrd, V> SegmentMap<K, V> {
}
}

impl<K: Clone + PartialOrd, V: Clone> SegmentMap<K, V> {
impl<K, V> SegmentMap<K, V>
where
K: Clone + PartialOrd,
V: Clone,
{
pub fn remove(&mut self, segment: &Segment<K>) {
if let Some(root) = self.root.take() {
self.root = root.remove(segment);
Expand Down Expand Up @@ -178,8 +185,15 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
}
}

impl<K: Clone + PartialOrd, V: Clone> Extend<(Segment<K>, V)> for SegmentMap<K, V> {
fn extend<I: IntoIterator<Item = (Segment<K>, V)>>(&mut self, iter: I) {
impl<K, V> Extend<(Segment<K>, V)> for SegmentMap<K, V>
where
K: Clone + PartialOrd,
V: Clone,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (Segment<K>, V)>
{
for (segment, value) in iter {
self.insert(segment, value);
}
Expand Down
Loading

0 comments on commit 11c81d7

Please # to comment.