1#![deny(clippy::all, clippy::pedantic)]
4#![allow(clippy::missing_safety_doc)]
5#![allow(clippy::missing_panics_doc)]
6
7pub mod arrays;
14pub mod bigints;
15pub mod callables;
16pub mod math;
17pub mod output_recording;
18pub mod range_support;
19pub mod strings;
20pub mod tuples;
21
22use std::{
23 ffi::CString,
24 mem::{self, ManuallyDrop},
25 rc::{Rc, Weak},
26};
27
28use output_recording::record_output_str;
29
30unsafe fn update_counts<T>(raw_rc: *const T, update: i32, is_alias: bool) {
32 unsafe {
33 let mut remaining = update;
34 while remaining != 0 {
35 let rc = ManuallyDrop::new(Rc::from_raw(raw_rc));
36 if remaining > 0 {
37 if is_alias {
38 mem::forget(Rc::downgrade(&rc));
40 } else {
41 Rc::increment_strong_count(raw_rc);
42 }
43
44 remaining -= 1;
45 } else {
46 if is_alias {
47 let w = Weak::into_raw(Rc::downgrade(&rc));
49
50 drop(Weak::from_raw(w));
52 drop(Weak::from_raw(w));
53 } else {
54 Rc::decrement_strong_count(raw_rc);
55 }
56
57 remaining += 1;
58 }
59 }
60 }
61}
62
63#[derive(Debug, Copy, Clone)]
64#[repr(i8)]
65pub enum Pauli {
66 I = 0,
67 X = 1,
68 Z = 2,
69 Y = 3,
70}
71
72#[unsafe(no_mangle)]
73pub extern "C" fn __quantum__rt__memory_allocate(size: u64) -> *mut u8 {
74 (vec![
75 0_u8;
76 size.try_into()
77 .expect("Memory size is too large for `usize` type on this platform.")
78 ])
79 .leak()
80 .as_mut_ptr()
81}
82
83#[cfg(feature = "fail-support")]
84#[unsafe(no_mangle)]
85pub unsafe extern "C" fn __quantum__rt__fail(str: *const CString) {
86 unsafe {
87 __quantum__rt__message(str);
88 panic!("{}", (*str).to_str().expect("Unable to convert string"));
89 }
90}
91
92#[cfg(feature = "message-support")]
93#[unsafe(no_mangle)]
94pub unsafe extern "C" fn __quantum__rt__message(str: *const CString) {
95 unsafe {
96 record_output_str(&format!(
97 "INFO\t{}",
98 (*str)
99 .to_str()
100 .expect("Unable to convert input string")
101 .escape_default()
102 ))
103 .expect("Failed to write message output");
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_memory_allocate() {
113 let size = 10;
114 let mem = __quantum__rt__memory_allocate(size as u64);
115 unsafe {
116 for val in Vec::from_raw_parts(mem, size, size) {
117 assert_eq!(val, 0);
118 }
119 }
120 }
121
122 #[ignore = "Test triggers a panic during unwinding"]
123 #[test]
124 #[should_panic(expected = "FAIL")]
125 fn test_fail() {
126 let str = CString::new("FAIL").unwrap();
127 unsafe {
128 __quantum__rt__fail(&raw const str);
129 }
130 }
131
132 #[test]
133 fn test_message() {
134 let str = CString::new("Message").unwrap();
135 unsafe {
136 __quantum__rt__message(&raw const str);
137 }
138 assert_eq!(str.to_str().unwrap(), "Message");
140 }
141}