Support switch range cases for floating-point values.
This commit is contained in:
@@ -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]
|
||||
|
Reference in New Issue
Block a user