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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use serde::{Deserialize, Serialize};
use std::fmt;
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct QubitRef(u64);
impl fmt::Display for QubitRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl Into<String> for QubitRef {
fn into(self) -> String {
format!("{}", self.0)
}
}
impl QubitRef {
pub fn from_foreign(qubit: u64) -> Option<QubitRef> {
if qubit == 0 {
None
} else {
Some(QubitRef(qubit as u64))
}
}
pub fn to_foreign(self) -> u64 {
assert_ne!(self.0, 0);
self.0 as u64
}
pub fn option_to_foreign(qubit: Option<QubitRef>) -> u64 {
if let Some(x) = qubit {
x.0 as u64
} else {
0
}
}
}
pub struct QubitRefGenerator {
counter: std::ops::RangeFrom<u64>,
}
impl Default for QubitRefGenerator {
fn default() -> Self {
Self::new()
}
}
impl QubitRefGenerator {
pub fn new() -> QubitRefGenerator {
QubitRefGenerator { counter: (1..) }
}
pub fn allocate(&mut self, num_qubits: usize) -> Vec<QubitRef> {
(&mut self.counter).take(num_qubits).map(QubitRef).collect()
}
pub fn free(&mut self, _qubits: impl IntoIterator<Item = QubitRef>) {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn construct_generator() {
let mut q1 = QubitRefGenerator::default();
let mut q2 = QubitRefGenerator::new();
assert_eq!(q1.allocate(2), q2.allocate(2));
}
#[test]
fn alloc_free() {
let mut q = QubitRefGenerator::default();
let qrefs = q.allocate(1);
assert_eq!(qrefs.len(), 1);
q.free(vec![QubitRef::from_foreign(4).unwrap()]);
let qrefs = q.allocate(1);
assert_eq!(qrefs[0], QubitRef::from_foreign(2).unwrap());
}
#[test]
fn convert_qrefs() {
let mut q = QubitRefGenerator::new();
let qr = QubitRef::from_foreign(0);
assert_eq!(qr, None);
let qr = QubitRef::from_foreign(1).unwrap();
assert_eq!(qr, (q.allocate(1))[0]);
assert_eq!(42, QubitRef::from_foreign(42).unwrap().to_foreign());
assert_eq!(0, QubitRef::option_to_foreign(None));
assert_eq!(
42,
QubitRef::option_to_foreign(Some(QubitRef::from_foreign(42).unwrap()))
);
}
#[test]
#[should_panic]
fn convert_zero() {
let _ = QubitRef(0).to_foreign();
}
#[test]
fn display_qref() {
let qubits = QubitRefGenerator::default().allocate(1);
assert_eq!(qubits[0].to_string(), "1");
let s: String = qubits[0].into();
assert_eq!(s, "1".to_string());
}
}