1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
use std::ops::{BitAnd, BitOr, BitXor, Not}; use crate::{util::ContainerSizeGames, Bit, GateLike, RustImpls}; #[cfg(test)] mod tests; impl<Rust> GateLike for RustImpls<Rust> where Rust: GateLike, { fn compute(&mut self, mut input: Vec<Bit>) -> Vec<Bit> { debug_assert_eq!(input.len(), self.num_of_inputs()); unsafe { match self { RustImpls::Dup(ref amount) => { let value = input.get_copied(0); input.change_len(*amount, value) } RustImpls::Not => { input.get_unchecked_mut(0).action_assign(Bit::not); input } RustImpls::Nand => compute_binary_operation(input, |x, y| !(x && y)), RustImpls::And => compute_binary_operation(input, Bit::bitand), RustImpls::Or => compute_binary_operation(input, Bit::bitor), RustImpls::Nor => compute_binary_operation(input, |x, y| !(x || y)), RustImpls::Xor => compute_binary_operation(input, Bit::bitxor), RustImpls::User(component) => component.compute(input), } } } fn num_of_inputs(&self) -> usize { match self { RustImpls::Dup(_) => 1, RustImpls::Not => 1, RustImpls::Nand => 2, RustImpls::And => 2, RustImpls::Or => 2, RustImpls::Nor => 2, RustImpls::Xor => 2, RustImpls::User(component) => component.num_of_inputs(), } } } unsafe fn compute_binary_operation<O>(input: Vec<Bit>, operation: O) -> Vec<Bit> where O: FnOnce(Bit, Bit) -> Bit, { let value = operation(input.get_copied(0), input.get_copied(1)); input.shorten(1, value) } trait ActionAssign: Sized + Copy { fn action_assign<F>(&mut self, action: F) -> &mut Self where F: FnOnce(Self) -> Self, { *self = action(*self); self } } impl<T> ActionAssign for T where T: Sized + Copy {}