[][src]Struct fasteval::slab::ParseSlab

pub struct ParseSlab { /* fields omitted */ }

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(), &deg); }  // `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

impl Debug for ParseSlab[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.