lay 0.1.0

Traits for quantum computing
Documentation
use std::convert::{AsRef, AsMut};

use crate::Layer;
use crate::gates::{PauliGate, HGate, SGate, TGate, CXGate};
use crate::operations::{Operation, PauliOperation, HOperation, SOperation, TOperation, CXOperation};

#[derive(Debug)]
pub struct OpsVec<L: Layer + ?Sized> {
    inner: Vec<L::Operation>,
}

impl<L> OpsVec<L> where L: Layer + ?Sized {
    pub fn new() -> Self {
        OpsVec::from_vec(vec![])
    }

    pub fn from_vec(v: Vec<L::Operation>) -> Self {
        OpsVec { inner: v }
    }

    pub fn into_vec(self) -> Vec<L::Operation> {
        self.inner
    }

    pub fn as_slice(&self) -> &[L::Operation] {
        &self.inner
    }

    pub fn as_mut_slice(&mut self) -> &mut [L::Operation] {
        &mut self.inner
    }

    pub fn as_vec(&self) -> &Vec<L::Operation> {
        &self.inner
    }

    pub fn as_mut_vec(&mut self) -> &mut Vec<L::Operation> {
        &mut self.inner
    }

    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn iter(&self) -> impl Iterator<Item=&L::Operation> {
        self.inner.iter()
    }

    pub fn clear(&mut self) {
        self.inner.clear()
    }
}

impl<L: Layer + ?Sized> AsRef<[L::Operation]> for OpsVec<L> {
    fn as_ref(&self) -> &[L::Operation] {
        self.as_slice()
    }
}

impl<L: Layer + ?Sized> AsMut<[L::Operation]> for OpsVec<L> {
    fn as_mut(&mut self) -> &mut [L::Operation] {
        self.as_mut_slice()
    }
}

impl<L> OpsVec<L> where L: Layer + ?Sized, L::Operation: Operation<L> {
    pub fn initialize(&mut self) {
        self.inner.push(L::Operation::initialize());
    }
    pub fn measure(&mut self, q: L::Qubit, s: L::Slot) {
        self.inner.push(L::Operation::measure(q, s));
    }
}

impl<L> OpsVec<L> where L: Layer + PauliGate + ?Sized, L::Operation: PauliOperation<L> {
    pub fn x(&mut self, q: <L as Layer>::Qubit) {
        self.inner.push(L::Operation::x(q));
    }

    pub fn y(&mut self, q: <L as Layer>::Qubit) {
        self.inner.push(L::Operation::y(q));
    }

    pub fn z(&mut self, q: <L as Layer>::Qubit) {
        self.inner.push(L::Operation::z(q));
    }
}

impl<L> OpsVec<L> where L: Layer + HGate + ?Sized, L::Operation: HOperation<L> {
    pub fn h(&mut self, q: <L as Layer>::Qubit) {
        self.inner.push(L::Operation::h(q));
    }
}

impl<L> OpsVec<L> where L: Layer + SGate + ?Sized, L::Operation: SOperation<L> {
    pub fn s(&mut self, q: <L as Layer>::Qubit) where L: SGate {
        self.inner.push(L::Operation::s(q));
    }

    pub fn sdg(&mut self, q: <L as Layer>::Qubit) where L: SGate {
        self.inner.push(L::Operation::sdg(q));
    }
}

impl<L> OpsVec<L> where L: Layer + TGate + ?Sized, L::Operation: TOperation<L> {
    pub fn t(&mut self, q: <L as Layer>::Qubit) where L: TGate {
        self.inner.push(L::Operation::t(q));
    }

    pub fn tdg(&mut self, q: <L as Layer>::Qubit) where L: TGate {
        self.inner.push(L::Operation::tdg(q));
    }
}

impl<L> OpsVec<L> where L: Layer + CXGate + ?Sized, L::Operation: CXOperation<L> {
    pub fn cx(&mut self, c: <L as Layer>::Qubit, t: <L as Layer>::Qubit) where L: CXGate {
        self.inner.push(L::Operation::cx(c, t));
    }
}