1use crate::backend::sdsl_c;
2use crate::meta;
3use anyhow::{format_err, Result};
4
5use crate::interface::common::{self, Code, Id};
6
7pub struct IntVector<const WIDTH: u8> {
26 ptr: common::VoidPtr,
27 interface: Interface,
28}
29
30impl<const WIDTH: u8> IntVector<WIDTH> {
31 pub fn new(size: usize, default_value: usize, width: Option<u8>) -> Result<Self> {
37 assert!(
38 (WIDTH == 0 && width.is_some()) || (WIDTH != 0 && width.is_none()),
39 "Width argument must be specified iff WIDTH const generic value is 0."
40 );
41 let width = match width {
42 Some(width) => width,
43 None => WIDTH,
44 };
45
46 let id = Self::id()?;
47 let interface = Interface::new(&id)?;
48 let ptr = (interface.create)(size, default_value, width);
49
50 Ok(Self { ptr, interface })
51 }
52
53 pub fn from_file(path: &std::path::PathBuf) -> Result<Self> {
57 assert!(
58 WIDTH == 0,
59 "Generic const WIDTH must be zero when loading from file."
60 );
61 let int_vector = Self::new(1, 0, Some(64))?;
62
63 let path = path
64 .to_str()
65 .ok_or(format_err!("Failed to convert PathBuf into str."))?;
66 let path = std::ffi::CString::new(path)?;
67
68 (int_vector.interface.io.load_from_file)(int_vector.ptr, path.as_ptr());
69 Ok(int_vector)
70 }
71
72 pub fn get(&self, index: usize) -> usize {
76 (self.interface.get)(self.ptr, index)
77 }
78
79 pub fn set(&mut self, index: usize, value: usize) {
84 (self.interface.set)(self.ptr, index, value)
85 }
86
87 pub fn is_empty(&self) -> bool {
89 (self.interface.is_empty)(self.ptr)
90 }
91
92 pub fn resize(&mut self, size: usize) {
96 (self.interface.resize)(self.ptr, size)
97 }
98
99 pub fn bit_resize(&mut self, size: usize) {
103 (self.interface.bit_resize)(self.ptr, size)
104 }
105
106 pub fn len(&self) -> usize {
108 (self.interface.len)(self.ptr)
109 }
110
111 pub fn max_size(&self) -> usize {
113 (self.interface.max_size)(self.ptr)
114 }
115
116 pub fn bit_size(&self) -> usize {
118 (self.interface.bit_size)(self.ptr)
119 }
120
121 pub fn capacity(&self) -> usize {
126 (self.interface.capacity)(self.ptr)
127 }
128
129 pub fn data(&self) -> common::VoidPtr {
131 (self.interface.data)(self.ptr)
133 }
134
135 pub fn width(&self) -> u8 {
137 (self.interface.width)(self.ptr)
138 }
139
140 pub fn set_width(&mut self, width: usize) -> Result<()> {
147 if WIDTH != 0 {
148 Err(format_err!(
149 "WIDTH is non-zero. Width is therefore immutable."
150 ))
151 } else {
152 Ok((self.interface.set_width)(self.ptr, width))
153 }
154 }
155
156 pub fn iter(&self) -> common::VectorIterator<usize, Self> {
158 common::VectorIterator::new(&self, self.len())
159 }
160}
161
162impl<const WIDTH: u8> common::util::Util for IntVector<WIDTH> {
163 fn util(&self) -> &common::util::Interface {
164 &self.interface.util
165 }
166}
167
168impl<const WIDTH: u8> common::io::IO for IntVector<WIDTH> {
169 fn io(&self) -> &common::io::Interface {
170 &self.interface.io
171 }
172}
173
174impl<const WIDTH: u8> common::Ptr for IntVector<WIDTH> {
175 fn ptr(&self) -> &common::VoidPtr {
176 &self.ptr
177 }
178}
179
180impl<'a, const WIDTH: u8> common::Id for IntVector<WIDTH> {
181 fn id() -> Result<String> {
182 let meta = Box::new(meta::int_vector::IntVectorMeta::new()) as Box<dyn meta::common::Meta>;
183 let parameters_c_code = Self::parameters_c_code()?;
184 let id = sdsl_c::specification::get_id(&meta.c_code(¶meters_c_code)?)?;
185 Ok(id)
186 }
187}
188
189impl<'a, const WIDTH: u8> common::Code for IntVector<WIDTH> {
190 fn c_code() -> Result<String> {
191 let meta = Box::new(meta::int_vector::IntVectorMeta::new()) as Box<dyn meta::common::Meta>;
192 let parameters_c_code = Self::parameters_c_code()?;
193 Ok(meta.c_code(¶meters_c_code)?)
194 }
195
196 fn parameters_c_code() -> Result<Vec<String>> {
197 Ok(vec![WIDTH.to_string()])
198 }
199}
200
201impl<const WIDTH: u8> common::IterGet<usize> for IntVector<WIDTH> {
202 fn iter_get(&self, index: usize) -> usize {
203 (self.interface.get)(self.ptr, index)
204 }
205}
206
207impl<const WIDTH: u8> Drop for IntVector<WIDTH> {
208 fn drop(&mut self) {
209 (self.interface.drop)(self.ptr)
210 }
211}
212
213impl<const WIDTH: u8> Clone for IntVector<WIDTH> {
214 fn clone(&self) -> Self {
215 Self {
216 ptr: (self.interface.clone)(self.ptr),
217 interface: self.interface.clone(),
218 }
219 }
220}
221
222impl<const WIDTH: u8> std::fmt::Debug for IntVector<WIDTH> {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 f.debug_list().entries(self.iter()).finish()
225 }
226}
227
228impl<const WIDTH: u8> IntoIterator for IntVector<WIDTH> {
229 type Item = usize;
230 type IntoIter = common::VectorIntoIterator<usize, IntVector<WIDTH>>;
231
232 fn into_iter(self) -> Self::IntoIter {
233 let len = self.len();
234 common::VectorIntoIterator::new(self, len)
235 }
236}
237
238#[derive(Clone)]
239struct Interface {
240 create: extern "C" fn(usize, usize, u8) -> common::VoidPtr,
241 drop: extern "C" fn(common::VoidPtr),
242 clone: extern "C" fn(common::VoidPtr) -> common::VoidPtr,
243 is_empty: extern "C" fn(common::VoidPtr) -> bool,
244
245 resize: extern "C" fn(common::VoidPtr, usize),
246 bit_resize: extern "C" fn(common::VoidPtr, usize),
247 len: extern "C" fn(common::VoidPtr) -> usize,
248 max_size: extern "C" fn(common::VoidPtr) -> usize,
249 bit_size: extern "C" fn(common::VoidPtr) -> usize,
250 capacity: extern "C" fn(common::VoidPtr) -> usize,
251
252 data: extern "C" fn(common::VoidPtr) -> common::VoidPtr,
253 width: extern "C" fn(common::VoidPtr) -> u8,
254 set_width: extern "C" fn(common::VoidPtr, usize),
255
256 get: extern "C" fn(common::VoidPtr, usize) -> usize,
257 set: extern "C" fn(common::VoidPtr, usize, usize),
258
259 pub io: common::io::Interface,
260 util: common::util::Interface,
261 _lib: std::sync::Arc<sharedlib::Lib>,
262}
263
264impl Interface {
265 pub fn new(id: &str) -> Result<Self> {
266 let lib = sdsl_c::LIB.clone();
267 let builder = sdsl_c::FunctionBuilder::new(Some("int_vector"), id, lib.clone());
268
269 Ok(Self {
270 create: builder.get("create")?,
271 drop: builder.get("destroy")?,
272 clone: builder.get("copy")?,
273 is_empty: builder.get("empty")?,
274
275 resize: builder.get("resize")?,
276 bit_resize: builder.get("bit_resize")?,
277 len: builder.get("size")?,
278 max_size: builder.get("max_size")?,
279 bit_size: builder.get("bit_size")?,
280 capacity: builder.get("capacity")?,
281
282 get: builder.get("get_element")?,
283 set: builder.get("set_element")?,
284
285 data: builder.get("data")?,
286 width: builder.get("width")?,
287 set_width: builder.get("set_width")?,
288
289 io: common::io::Interface::new(&id)?,
290 util: common::util::Interface::new(&id)?,
291 _lib: lib.clone(),
292 })
293 }
294}
295
296#[macro_export(local_inner_macros)]
309macro_rules! int_vector {
310 (@single $($x:tt)*) => (());
311 (@count $($rest:expr),*) => (<[()]>::len(&[$(int_vector!(@single $rest)),*]));
312
313 ($($key:expr,)+) => { int_vector!($($key),+) };
314 ($($key:expr),*) => {
315 {
316 let _size = int_vector!(@count $($key),*);
317 let mut _vec = sdsl::int_vectors::IntVector::<0>::new(_size, 0, Some(64))?;
318 let mut i = 0;
319 $(
320 _vec.set(i, $key);
321 i += 1;
322 )*
323 _vec
324 }
325 };
326}