#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Range {
begin: u32,
end: u32,
key_pos: u32,
}
impl Range {
#[inline]
pub fn new() -> Self {
Range {
begin: 0,
end: 0,
key_pos: 0,
}
}
#[inline]
pub fn set_begin(&mut self, begin: usize) {
assert!(begin <= u32::MAX as usize, "begin exceeds u32::MAX");
self.begin = begin as u32;
}
#[inline]
pub fn set_end(&mut self, end: usize) {
assert!(end <= u32::MAX as usize, "end exceeds u32::MAX");
self.end = end as u32;
}
#[inline]
pub fn set_key_pos(&mut self, key_pos: usize) {
assert!(key_pos <= u32::MAX as usize, "key_pos exceeds u32::MAX");
self.key_pos = key_pos as u32;
}
#[inline]
pub fn begin(&self) -> usize {
self.begin as usize
}
#[inline]
pub fn end(&self) -> usize {
self.end as usize
}
#[inline]
pub fn key_pos(&self) -> usize {
self.key_pos as usize
}
}
#[inline]
pub fn make_range(begin: usize, end: usize, key_pos: usize) -> Range {
let mut range = Range::new();
range.set_begin(begin);
range.set_end(end);
range.set_key_pos(key_pos);
range
}
#[derive(Debug, Clone, Copy, Default)]
pub struct WeightedRange {
range: Range,
weight: f32,
}
impl WeightedRange {
#[inline]
pub fn new() -> Self {
WeightedRange {
range: Range::new(),
weight: 0.0,
}
}
#[inline]
pub fn set_range(&mut self, range: Range) {
self.range = range;
}
#[inline]
pub fn set_begin(&mut self, begin: usize) {
self.range.set_begin(begin);
}
#[inline]
pub fn set_end(&mut self, end: usize) {
self.range.set_end(end);
}
#[inline]
pub fn set_key_pos(&mut self, key_pos: usize) {
self.range.set_key_pos(key_pos);
}
#[inline]
pub fn set_weight(&mut self, weight: f32) {
self.weight = weight;
}
#[inline]
pub fn range(&self) -> &Range {
&self.range
}
#[inline]
pub fn begin(&self) -> usize {
self.range.begin()
}
#[inline]
pub fn end(&self) -> usize {
self.range.end()
}
#[inline]
pub fn key_pos(&self) -> usize {
self.range.key_pos()
}
#[inline]
pub fn weight(&self) -> f32 {
self.weight
}
}
impl PartialEq for WeightedRange {
fn eq(&self, other: &Self) -> bool {
self.weight == other.weight
}
}
impl Eq for WeightedRange {}
impl PartialOrd for WeightedRange {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for WeightedRange {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.weight
.partial_cmp(&other.weight)
.unwrap_or(std::cmp::Ordering::Less)
}
}
#[inline]
pub fn make_weighted_range(begin: usize, end: usize, key_pos: usize, weight: f32) -> WeightedRange {
let mut range = WeightedRange::new();
range.set_begin(begin);
range.set_end(end);
range.set_key_pos(key_pos);
range.set_weight(weight);
range
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_range_new() {
let range = Range::new();
assert_eq!(range.begin(), 0);
assert_eq!(range.end(), 0);
assert_eq!(range.key_pos(), 0);
}
#[test]
fn test_range_setters() {
let mut range = Range::new();
range.set_begin(10);
range.set_end(20);
range.set_key_pos(5);
assert_eq!(range.begin(), 10);
assert_eq!(range.end(), 20);
assert_eq!(range.key_pos(), 5);
}
#[test]
fn test_make_range() {
let range = make_range(100, 200, 50);
assert_eq!(range.begin(), 100);
assert_eq!(range.end(), 200);
assert_eq!(range.key_pos(), 50);
}
#[test]
fn test_range_max_values() {
let mut range = Range::new();
range.set_begin(u32::MAX as usize);
range.set_end(u32::MAX as usize);
range.set_key_pos(u32::MAX as usize);
assert_eq!(range.begin(), u32::MAX as usize);
assert_eq!(range.end(), u32::MAX as usize);
assert_eq!(range.key_pos(), u32::MAX as usize);
}
#[test]
fn test_weighted_range_new() {
let wrange = WeightedRange::new();
assert_eq!(wrange.begin(), 0);
assert_eq!(wrange.end(), 0);
assert_eq!(wrange.key_pos(), 0);
assert_eq!(wrange.weight(), 0.0);
}
#[test]
fn test_weighted_range_setters() {
let mut wrange = WeightedRange::new();
wrange.set_begin(10);
wrange.set_end(20);
wrange.set_key_pos(5);
wrange.set_weight(3.15);
assert_eq!(wrange.begin(), 10);
assert_eq!(wrange.end(), 20);
assert_eq!(wrange.key_pos(), 5);
assert_eq!(wrange.weight(), 3.15);
}
#[test]
fn test_weighted_range_set_range() {
let range = make_range(100, 200, 50);
let mut wrange = WeightedRange::new();
wrange.set_range(range);
wrange.set_weight(2.5);
assert_eq!(wrange.begin(), 100);
assert_eq!(wrange.end(), 200);
assert_eq!(wrange.key_pos(), 50);
assert_eq!(wrange.weight(), 2.5);
}
#[test]
fn test_make_weighted_range() {
let wrange = make_weighted_range(100, 200, 50, 1.5);
assert_eq!(wrange.begin(), 100);
assert_eq!(wrange.end(), 200);
assert_eq!(wrange.key_pos(), 50);
assert_eq!(wrange.weight(), 1.5);
}
#[test]
fn test_weighted_range_ordering() {
let wrange1 = make_weighted_range(0, 10, 0, 1.0);
let wrange2 = make_weighted_range(10, 20, 0, 2.0);
let wrange3 = make_weighted_range(20, 30, 0, 1.5);
assert!(wrange1 < wrange2);
assert!(wrange2 > wrange1);
assert!(wrange1 < wrange3);
assert!(wrange3 < wrange2);
}
#[test]
fn test_weighted_range_equality() {
let wrange1 = make_weighted_range(0, 10, 0, 1.0);
let wrange2 = make_weighted_range(10, 20, 0, 1.0);
let wrange3 = make_weighted_range(0, 10, 0, 2.0);
assert_eq!(wrange1, wrange2);
assert_ne!(wrange1, wrange3);
}
#[test]
fn test_weighted_range_sorting() {
let mut ranges = [
make_weighted_range(0, 10, 0, 3.0),
make_weighted_range(10, 20, 0, 1.0),
make_weighted_range(20, 30, 0, 2.0),
];
ranges.sort();
assert_eq!(ranges[0].weight(), 1.0);
assert_eq!(ranges[1].weight(), 2.0);
assert_eq!(ranges[2].weight(), 3.0);
}
#[test]
fn test_range_default() {
let range = Range::default();
assert_eq!(range.begin(), 0);
assert_eq!(range.end(), 0);
assert_eq!(range.key_pos(), 0);
}
#[test]
fn test_weighted_range_default() {
let wrange = WeightedRange::default();
assert_eq!(wrange.begin(), 0);
assert_eq!(wrange.weight(), 0.0);
}
#[test]
fn test_range_clone() {
let range1 = make_range(10, 20, 5);
let range2 = range1;
assert_eq!(range1, range2);
}
#[test]
fn test_weighted_range_clone() {
let wrange1 = make_weighted_range(10, 20, 5, 1.5);
let wrange2 = wrange1;
assert_eq!(wrange1.weight(), wrange2.weight());
assert_eq!(wrange1.begin(), wrange2.begin());
}
}