[−][src]Struct fasteval::slab::ParseSlab
ParseSlab
is where parse()
results are stored, located at Slab.ps
.
Unsafe Variable Registration with add_unsafe_var()
(This is documented here because the
add_unsafe_var()
method and its documentation
only appears if fasteval
is built with the unsafe-vars
feature (cargo build --features unsafe-vars
). I want this documentation to appear
regardless of the build mode, so I'm putting it here.)
Here is the function signature of the add_unsafe_var()
method:
pub unsafe fn add_unsafe_var(&mut self, name: String, ptr: &f64)
If you are using Unsafe Variables, you
need to pre-register the unsafe variable names and pointers before
calling parse()
. This is because Unsafe Variables are represented
specially in the parse AST; therefore, parse()
needs to know what
variables are unsafe and which ones are normal so that it can produce the
correct AST.
If you forget to pre-register an unsafe variable before parse()
, the
variable will be treated like a Normal Variable, and you'll probably get an
Undefined
error during evaluation.
Safety
You must guarantee that Unsafe Variable pointers remain valid for the lifetime of the resulting expression. If you continue to use an expression after the memory of an unsafe variable has been reclaimed, you will have undefined behavior.
Examples
Here is an example of correct and incorrect use of unsafe variable pointers:
use fasteval::Evaler; // use this trait so we can call eval(). use fasteval::Compiler; // use this trait so we can call compile(). // Here is an example of INCORRECT registration. DO NOT DO THIS! fn bad_unsafe_var(slab_mut:&mut fasteval::Slab) { let bad : f64 = 0.0; // Saves a pointer to 'bad': unsafe { slab_mut.ps.add_unsafe_var("bad".to_string(), &bad); } // `add_unsafe_var()` only exists if the `unsafe-vars` feature is enabled: `cargo test --features unsafe-vars` // 'bad' goes out-of-scope here, and the pointer we registered is no longer valid! // This will result in undefined behavior. } fn main() -> Result<(), fasteval::Error> { let mut slab = fasteval::Slab::new(); // The Unsafe Variable will use a pointer to read this memory location: // You must make sure that this variable stays in-scope as long as the // expression is in-use. let mut deg : f64 = 0.0; // Unsafe Variables must be registered before 'parse()'. // (Normal Variables only need definitions during the 'eval' phase.) unsafe { slab.ps.add_unsafe_var("deg".to_string(), °); } // `add_unsafe_var()` only exists if the `unsafe-vars` feature is enabled: `cargo test --features unsafe-vars` // bad_unsafe_var(&mut slab); // Don't do it this way. let expr_str = "sin(deg/360 * 2*pi())"; let expr_ref = fasteval::Parser::new().parse(expr_str, &mut slab.ps)?.from(&slab.ps); // The main reason people use Unsafe Variables is to maximize performance. // Compilation also helps performance, so it is usually used together with Unsafe Variables: let compiled = expr_ref.compile(&slab.ps, &mut slab.cs); let mut ns = fasteval::EmptyNamespace; // We only define unsafe variables, not normal variables, // so EmptyNamespace is fine. for d in 0..360 { deg = d as f64; let val = fasteval::eval_compiled!(compiled, &slab, &mut ns); eprintln!("sin({}°) = {}", deg, val); } Ok(()) }
Methods
impl ParseSlab
[src]
pub fn get_expr(&self, expr_i: ExpressionI) -> &Expression
[src]
Returns a reference to the Expression
located at expr_i
within the `ParseSlab.exprs'.
If expr_i
is out-of-bounds, a reference to a default Expression
is returned.
pub fn get_val(&self, val_i: ValueI) -> &Value
[src]
Returns a reference to the Value
located at val_i
within the `ParseSlab.vals'.
If val_i
is out-of-bounds, a reference to a default Value
is returned.
pub fn clear(&mut self)
[src]
Clears all data from ParseSlab.exprs
and ParseSlab.vals
.
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for ParseSlab
impl Send for ParseSlab
impl Sync for ParseSlab
impl Unpin for ParseSlab
impl UnwindSafe for ParseSlab
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,