Support switch range cases for floating-point values.

This commit is contained in:
Stephen Chung
2023-02-12 23:20:14 +08:00
parent d0a47d7f66
commit 10089c5cb0
7 changed files with 68 additions and 45 deletions

View File

@@ -4,8 +4,9 @@ use super::{ASTFlags, ASTNode, BinaryExpr, Expr, FnCallExpr, Ident};
use crate::engine::{KEYWORD_EVAL, OP_EQUALS};
use crate::func::StraightHashMap;
use crate::tokenizer::Token;
use crate::types::dynamic::Union;
use crate::types::Span;
use crate::{calc_fn_hash, Position, StaticVec, INT};
use crate::{calc_fn_hash, Dynamic, Position, StaticVec, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
@@ -257,7 +258,7 @@ impl IntoIterator for RangeCase {
type Item = INT;
type IntoIter = Box<dyn Iterator<Item = Self::Item>>;
#[inline(always)]
#[inline]
#[must_use]
fn into_iter(self) -> Self::IntoIter {
match self {
@@ -269,7 +270,7 @@ impl IntoIterator for RangeCase {
impl RangeCase {
/// Returns `true` if the range contains no items.
#[inline(always)]
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
match self {
@@ -278,7 +279,7 @@ impl RangeCase {
}
}
/// Size of the range.
#[inline(always)]
#[inline]
#[must_use]
pub fn len(&self) -> INT {
match self {
@@ -288,15 +289,56 @@ impl RangeCase {
Self::InclusiveInt(r, ..) => *r.end() - *r.start() + 1,
}
}
/// Is the specified number within this range?
#[inline(always)]
/// Is the specified value within this range?
#[inline]
#[must_use]
pub fn contains(&self, n: INT) -> bool {
pub fn contains(&self, value: &Dynamic) -> bool {
match value {
Dynamic(Union::Int(v, ..)) => self.contains_int(*v),
#[cfg(not(feature = "no_float"))]
Dynamic(Union::Float(v, ..)) => self.contains_float(**v),
#[cfg(feature = "decimal")]
Dynamic(Union::Decimal(v, ..)) => self.contains_decimal(**v),
_ => false,
}
}
/// Is the specified number within this range?
#[inline]
#[must_use]
pub fn contains_int(&self, n: INT) -> bool {
match self {
Self::ExclusiveInt(r, ..) => r.contains(&n),
Self::InclusiveInt(r, ..) => r.contains(&n),
}
}
/// Is the specified floating-point number within this range?
#[cfg(not(feature = "no_float"))]
#[inline]
#[must_use]
pub fn contains_float(&self, n: crate::FLOAT) -> bool {
use crate::FLOAT;
match self {
Self::ExclusiveInt(r, ..) => ((r.start as FLOAT)..(r.end as FLOAT)).contains(&n),
Self::InclusiveInt(r, ..) => ((*r.start() as FLOAT)..=(*r.end() as FLOAT)).contains(&n),
}
}
/// Is the specified decimal number within this range?
#[cfg(feature = "decimal")]
#[inline]
#[must_use]
pub fn contains_decimal(&self, n: rust_decimal::Decimal) -> bool {
use rust_decimal::Decimal;
match self {
Self::ExclusiveInt(r, ..) => {
(Into::<Decimal>::into(r.start)..Into::<Decimal>::into(r.end)).contains(&n)
}
Self::InclusiveInt(r, ..) => {
(Into::<Decimal>::into(*r.start())..=Into::<Decimal>::into(*r.end())).contains(&n)
}
}
}
/// Is the specified range inclusive?
#[inline(always)]
#[must_use]