use self::internal_float::InternalFloat;
use crate::model::unit::{AsF64, *};
use allocative::Allocative;
use derive_more::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, Sum};
use serde::{Deserialize, Serialize};
use std::{
fmt::Display,
ops::{Deref, DerefMut},
};
#[derive(
Copy,
Clone,
Debug,
Eq,
PartialEq,
PartialOrd,
Ord,
Add,
AddAssign,
Sub,
SubAssign,
Mul,
MulAssign,
Div,
DivAssign,
Sum,
Neg,
Serialize,
Deserialize,
Allocative,
)]
pub struct Cost(InternalFloat);
impl Cost {
pub const ZERO: Cost = Cost(InternalFloat::ZERO);
pub const ONE: Cost = Cost(InternalFloat::ONE);
pub const INFINITY: Cost = Cost(InternalFloat::INFINITY);
pub const MIN_COST: Cost = Cost(InternalFloat::MIN);
pub fn new(value: f64) -> Cost {
Cost(InternalFloat::new(value))
}
pub fn enforce_strictly_positive(cost: Cost) -> Cost {
if cost <= Cost::ZERO {
Cost::MIN_COST
} else {
cost
}
}
pub fn enforce_non_negative(cost: Cost) -> Cost {
if cost < Cost::ZERO {
Cost::ZERO
} else {
cost
}
}
}
impl Default for Cost {
fn default() -> Self {
Cost::ZERO
}
}
impl From<f64> for Cost {
fn from(f: f64) -> Self {
Cost(InternalFloat::new(f))
}
}
impl AsF64 for Cost {
fn as_f64(&self) -> f64 {
self.0 .0
}
}
impl From<Cost> for f64 {
fn from(val: Cost) -> Self {
val.0.into_inner()
}
}
impl Display for Cost {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ReverseCost(std::cmp::Reverse<Cost>);
impl From<Cost> for ReverseCost {
fn from(cost: Cost) -> Self {
ReverseCost(std::cmp::Reverse(cost))
}
}
impl Allocative for ReverseCost {
fn visit<'a, 'b: 'a>(&self, visitor: &'a mut allocative::Visitor<'b>) {
let _visitor = visitor.enter_self_sized::<Self>();
}
}
impl Deref for ReverseCost {
type Target = std::cmp::Reverse<Cost>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for ReverseCost {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}