quantrs2_core/
qubit.rs

1/// A transparent wrapper around a qubit identifier
2///
3/// This provides type safety for qubit references while
4/// maintaining zero-cost abstraction.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[repr(transparent)]
7pub struct QubitId(pub u32);
8
9impl QubitId {
10    /// Create a new qubit identifier
11    #[inline]
12    pub const fn new(id: u32) -> Self {
13        Self(id)
14    }
15
16    /// Get the raw identifier value
17    #[inline]
18    pub const fn id(&self) -> u32 {
19        self.0
20    }
21}
22
23impl From<u32> for QubitId {
24    #[inline]
25    fn from(id: u32) -> Self {
26        Self(id)
27    }
28}
29
30impl From<QubitId> for u32 {
31    #[inline]
32    fn from(qubit: QubitId) -> Self {
33        qubit.0
34    }
35}
36
37impl From<usize> for QubitId {
38    #[inline]
39    fn from(id: usize) -> Self {
40        Self(id as u32)
41    }
42}
43
44impl From<QubitId> for usize {
45    #[inline]
46    fn from(qubit: QubitId) -> Self {
47        qubit.0 as usize
48    }
49}
50
51impl From<i32> for QubitId {
52    #[inline]
53    fn from(id: i32) -> Self {
54        Self(id as u32)
55    }
56}
57
58/// A collection of qubits for multi-qubit operations
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct QubitSet {
61    qubits: Vec<QubitId>,
62}
63
64impl QubitSet {
65    /// Create a new empty qubit set
66    pub fn new() -> Self {
67        Self { qubits: Vec::new() }
68    }
69
70    /// Create a qubit set with a specific capacity
71    pub fn with_capacity(capacity: usize) -> Self {
72        Self {
73            qubits: Vec::with_capacity(capacity),
74        }
75    }
76
77    /// Add a qubit to the set
78    pub fn add(&mut self, qubit: impl Into<QubitId>) {
79        self.qubits.push(qubit.into());
80    }
81
82    /// Get all qubits in the set
83    pub fn qubits(&self) -> &[QubitId] {
84        &self.qubits
85    }
86
87    /// Get the number of qubits in the set
88    pub fn len(&self) -> usize {
89        self.qubits.len()
90    }
91
92    /// Check if the set is empty
93    pub fn is_empty(&self) -> bool {
94        self.qubits.is_empty()
95    }
96}
97
98impl Default for QubitSet {
99    fn default() -> Self {
100        Self::new()
101    }
102}
103
104impl From<Vec<QubitId>> for QubitSet {
105    fn from(qubits: Vec<QubitId>) -> Self {
106        Self { qubits }
107    }
108}
109
110impl<const N: usize> From<[QubitId; N]> for QubitSet {
111    fn from(qubits: [QubitId; N]) -> Self {
112        Self {
113            qubits: qubits.to_vec(),
114        }
115    }
116}
117
118impl<const N: usize> From<[u32; N]> for QubitSet {
119    fn from(ids: [u32; N]) -> Self {
120        let qubits = ids.iter().map(|&id| QubitId::new(id)).collect();
121        Self { qubits }
122    }
123}