[][src]Macro qip::wrap_fn

macro_rules! wrap_fn {
    (@names () <- $name:ident) => { ... };
    (@names ($($body:tt)*) <- $name:ident) => { ... };
    (@names ($($body:tt)*) <- $name:ident, $($tail:tt)*) => { ... };
    (@invoke($func:expr, $builder:expr) ($($body:tt)*) <- $name:ident) => { ... };
    (@invoke($func:expr, $builder:expr) ($($body:tt)*) <- $name:ident, $($tail:tt)*) => { ... };
    (@unwrap_regs($func:expr, $rs:ident) $name:ident) => { ... };
    (@unwrap_regs($func:expr, $rs:ident) $name:ident, $($tail:tt)*) => { ... };
    (@wrap_regs($rs:ident) $name:ident) => { ... };
    (@wrap_regs($rs:ident) $name:ident, $($tail:tt)*) => { ... };
    (@result_body($builder:expr, $func:expr, $rs:ident) $($tail:tt)*) => { ... };
    (@raw_body($builder:expr, $func:expr, $rs:ident) $($tail:tt)*) => { ... };
    (pub $newfunc:ident, ($func:expr), $($tail:tt)*) => { ... };
    (pub $newfunc:ident, $func:expr, $($tail:tt)*) => { ... };
    ($newfunc:ident, ($func:expr), $($tail:tt)*) => { ... };
    ($newfunc:ident, $func:expr, $($tail:tt)*) => { ... };
}

Allows the wrapping of a function with signature: Fn(&mut dyn UnitaryBuilder, Register, Register, ...) -> (Register, ...) or Fn(&mut dyn UnitaryBuilder, Register, Register, ...) -> Result<(Register, ...), CircuitError> to make a new function with signature: Fn(&mut dyn UnitaryBuilder, Vec<Register>) -> Result<Vec<Register>, CircuitError> and is therefore compatible with program!.

Example

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

fn gamma(b: &mut dyn UnitaryBuilder, ra: Register, rb: Register) -> (Register, Register) {
    let (ra, rb) = b.cnot(ra, rb);
    (ra, rb)
}

wrap_fn!(wrapped_gamma, gamma, ra, rb);

// Gamma |ra>|rb[2]>
// Gamma |ra[0]>|rb>
let (ra, rb) = program!(&mut b, ra, rb;
    wrapped_gamma ra, rb[2];
    wrapped_gamma ra[0], rb;
)?;
let r = b.merge(vec![ra, rb])?;

Example with Result

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

fn gamma(b: &mut dyn UnitaryBuilder, ra: Register, rb: Register) -> Result<(Register, Register), CircuitError> {
    let (ra, rb) = b.cnot(ra, rb);
    Ok((ra, rb))
}

wrap_fn!(wrapped_gamma, (gamma), ra, rb);

// Gamma |ra>|rb[2]>
// Gamma |ra[0]>|rb>
let (ra, rb) = program!(&mut b, ra, rb;
    wrapped_gamma ra, rb[2];
    wrapped_gamma ra[0], rb;
)?;
let r = b.merge(vec![ra, rb])?;

Example with UnitaryBuilder function

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

wrap_fn!(cnot, UnitaryBuilder::cnot, ra, rb);

// cnot |ra>|rb[2]>
// cnot |ra[0]>|rb>
let (ra, rb) = program!(&mut b, ra, rb;
    cnot ra, rb[2];
    cnot ra[0], rb;
)?;
let r = b.merge(vec![ra, rb])?;