quantrs2_core/
qubit.rs

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