commit 3de76e4fca95c089550f297f6b74c85776c3e51a
parent 134aa92d1cbabf909b91cc9155ab4a5741dad3fe
Author: jojo <jojolepromain@gmail.com>
Date: Wed, 27 Sep 2017 14:40:31 -0400
Made all the things generic ;)
Diffstat:
2 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
@@ -4,13 +4,14 @@ use std::f32;
/// A regular function that is only defined between lower and higher.
/// If two functions intersect their higher and lower bounds respectively.
/// The second will take precedence where f(lower).
-pub struct BoundedFunction {
+pub struct BoundedFunction<B,O>
+where B:PartialOrd{
/// The stored function f(x) = ???
- pub func: fn(f32) -> f32,
+ pub func: fn(B) -> O,
/// The lower bound of the function.
- pub lower: f32,
+ pub lower: B,
/// The higher bound of the function.
- pub higher: f32,
+ pub higher: B,
}
/// Define a functions defined by multiple functions parts.
@@ -18,19 +19,21 @@ pub struct BoundedFunction {
/// Uses bounds as [lower,higher],
/// except in the case of a lower bound overlapping a higher bound.
/// In this case, the lower bound always take precedence.
-pub struct PartialFunction {
- funcs: Vec<BoundedFunction>,
+pub struct PartialFunction<B,O>
+where B:PartialOrd{
+ funcs: Vec<BoundedFunction<B,O>>,
}
-impl PartialFunction {
+impl<B,O> PartialFunction<B,O>
+where B:PartialOrd{
/// Creates a new PartialFunctionBuilder
- pub fn new() -> PartialFunctionBuilder {
+ pub fn new() -> PartialFunctionBuilder<B,O> {
PartialFunctionBuilder::new()
}
/// Evaluates the partial function.
/// Returns NAN if no function is defined.
- pub fn eval(&self, x: f32) -> f32 {
+ pub fn eval(&self, x: B) -> Option<O> {
let iter = self.funcs.iter().enumerate();
for (i, bounded) in iter {
let next = self.funcs.get(i + 1);
@@ -39,46 +42,48 @@ impl PartialFunction {
(next.is_some() && next.unwrap().lower != bounded.higher)
{
let f = bounded.func;
- return f(x);
+ return Some(f(x));
}
}
- f32::NAN
+ None
}
}
/// A builder to create an immutable PartialFunction.
-pub struct PartialFunctionBuilder {
- funcs: Vec<BoundedFunction>,
+pub struct PartialFunctionBuilder<B,O>
+where B:PartialOrd{
+ funcs: Vec<BoundedFunction<B,O>>,
}
-impl PartialFunctionBuilder {
+impl<B,O> PartialFunctionBuilder<B,O>
+where B:PartialOrd{
/// Creates a new PartialFunctionBuilder.
pub fn new() -> Self {
PartialFunctionBuilder { funcs: vec![] }
}
/// Adds a bounded function bounded between [lower,higher[ of function func.
- pub fn with(mut self, lower: f32, higher: f32, func: fn(f32) -> f32) -> Self {
+ pub fn with(mut self, lower: B, higher: B, func: fn(B) -> O) -> Self {
+ debug_assert!(self.can_insert(&lower, &higher));
let f = BoundedFunction {
func: func,
lower: lower,
higher: higher,
};
- debug_assert!(self.can_insert(lower, higher));
self.funcs.push(f);
self
}
/// Check if you can safely insert into the function list for the specified bounds.
- pub fn can_insert(&self, lower: f32, higher: f32) -> bool {
+ pub fn can_insert(&self, lower: &B, higher: &B) -> bool {
!self.funcs.iter().any(|b| {
- (lower >= b.lower && lower < b.higher) || (higher > b.lower && higher <= b.higher) ||
- (lower <= b.lower && higher >= b.higher)
+ (lower >= &b.lower && lower < &b.higher) || (higher > &b.lower && higher <= &b.higher) ||
+ (lower <= &b.lower && higher >= &b.higher)
})
}
/// Builds the PartialFunction from the functions added using with.
- pub fn build(mut self) -> PartialFunction {
+ pub fn build(mut self) -> PartialFunction<B,O> {
self.funcs.sort_by(|a, b| {
a.lower
.partial_cmp(&b.lower)
diff --git a/tests/tests.rs b/tests/tests.rs
@@ -7,22 +7,22 @@ mod tests {
#[test]
fn single() {
let p = PartialFunction::new().with(0.0, 1.0, |x| x).build();
- assert_eq!(0.5, p.eval(0.5));
+ assert_eq!(Some(0.5), p.eval(0.5));
}
#[test]
fn single_start() {
let p = PartialFunction::new().with(0.0, 1.0, |x| x).build();
- assert_eq!(0.0, p.eval(0.0));
+ assert_eq!(Some(0.0), p.eval(0.0));
}
#[test]
fn single_ending() {
let p = PartialFunction::new().with(0.0, 1.0, |x| x).build();
- assert_eq!(1.0, p.eval(1.0));
+ assert_eq!(Some(1.0), p.eval(1.0));
}
#[test]
fn single_nan() {
let p = PartialFunction::new().with(0.0, 1.0, |x| x).build();
- assert!(p.eval(999.0).is_nan());
+ assert!(p.eval(999.0).is_none());
}
#[test]
fn dual_start() {
@@ -30,7 +30,7 @@ mod tests {
.with(1.0, 2.0, |x| 5.0)
.with(0.0, 1.0, |x| x)
.build();
- assert_eq!(5.0, p.eval(1.0));
+ assert_eq!(Some(5.0), p.eval(1.0));
}
#[test]
fn dual_end() {
@@ -38,7 +38,7 @@ mod tests {
.with(0.0, 1.0, |x| x)
.with(1.0, 2.0, |x| 5.0)
.build();
- assert_eq!(5.0, p.eval(1.0));
+ assert_eq!(Some(5.0), p.eval(1.0));
}
#[test]
#[should_panic]