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
142
143
144
145
146
147
148
149
//! Qubit identifier types for type-safe quantum circuit construction.
//!
//! Provides [`QubitId`], a zero-cost transparent wrapper around a `u32` that
//! uniquely identifies a qubit within a circuit or register.
use serde::{Deserialize, Serialize};
/// A transparent wrapper around a qubit identifier.
///
/// This provides type safety for qubit references while
/// maintaining zero-cost abstraction.
///
/// # Examples
///
/// ```rust
/// use quantrs2_core::qubit::QubitId;
///
/// let q0 = QubitId::new(0);
/// let q1 = QubitId::new(1);
/// assert_eq!(q0.id(), 0);
/// assert!(q0 < q1);
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[repr(transparent)]
pub struct QubitId(pub u32);
impl QubitId {
/// Create a new qubit identifier.
///
/// # Examples
///
/// ```rust
/// use quantrs2_core::qubit::QubitId;
/// let q = QubitId::new(3);
/// assert_eq!(q.id(), 3);
/// ```
#[inline]
pub const fn new(id: u32) -> Self {
Self(id)
}
/// Get the raw identifier value.
#[inline]
pub const fn id(&self) -> u32 {
self.0
}
}
impl From<u32> for QubitId {
#[inline]
fn from(id: u32) -> Self {
Self(id)
}
}
impl From<QubitId> for u32 {
#[inline]
fn from(qubit: QubitId) -> Self {
qubit.0
}
}
impl From<usize> for QubitId {
#[inline]
fn from(id: usize) -> Self {
Self(id as u32)
}
}
impl From<QubitId> for usize {
#[inline]
fn from(qubit: QubitId) -> Self {
qubit.0 as Self
}
}
impl From<i32> for QubitId {
#[inline]
fn from(id: i32) -> Self {
Self(id as u32)
}
}
/// A collection of qubits for multi-qubit operations
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct QubitSet {
qubits: Vec<QubitId>,
}
impl QubitSet {
/// Create a new empty qubit set
pub const fn new() -> Self {
Self { qubits: Vec::new() }
}
/// Create a qubit set with a specific capacity
pub fn with_capacity(capacity: usize) -> Self {
Self {
qubits: Vec::with_capacity(capacity),
}
}
/// Add a qubit to the set
pub fn add(&mut self, qubit: impl Into<QubitId>) {
self.qubits.push(qubit.into());
}
/// Get all qubits in the set
pub fn qubits(&self) -> &[QubitId] {
&self.qubits
}
/// Get the number of qubits in the set
pub fn len(&self) -> usize {
self.qubits.len()
}
/// Check if the set is empty
pub fn is_empty(&self) -> bool {
self.qubits.is_empty()
}
}
impl Default for QubitSet {
fn default() -> Self {
Self::new()
}
}
impl From<Vec<QubitId>> for QubitSet {
fn from(qubits: Vec<QubitId>) -> Self {
Self { qubits }
}
}
impl<const N: usize> From<[QubitId; N]> for QubitSet {
fn from(qubits: [QubitId; N]) -> Self {
Self {
qubits: qubits.to_vec(),
}
}
}
impl<const N: usize> From<[u32; N]> for QubitSet {
fn from(ids: [u32; N]) -> Self {
let qubits = ids.iter().map(|&id| QubitId::new(id)).collect();
Self { qubits }
}
}