use crate::backend::sdsl_c;
use crate::meta;
use anyhow::{format_err, Result};
use crate::interface::common::{self, Code, Id, Ptr};
pub struct SelectSupportMcl<'a, BitPattern: common::bit_patterns::BitPattern> {
_bp: Option<BitPattern>,
_bit_vector: Option<&'a super::bit_vectors::bit_vector::BitVector>,
ptr: common::VoidPtr,
interface: Interface,
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> SelectSupportMcl<'a, BitPattern> {
pub fn new(bit_vector: &'a super::bit_vectors::bit_vector::BitVector) -> Result<Self> {
let id = Self::id()?;
let interface = Interface::new(&id)?;
let ptr = (interface.create)(*bit_vector.ptr());
Ok(Self {
_bp: None,
_bit_vector: Some(&bit_vector),
ptr,
interface,
})
}
fn default() -> Result<Self> {
let id = Self::id()?;
let interface = Interface::new(&id)?;
let ptr = (interface.create)(std::ptr::null());
Ok(Self {
_bp: None,
_bit_vector: None,
ptr,
interface,
})
}
pub fn from_file(path: &std::path::PathBuf) -> Result<Self> {
let rs = Self::default()?;
let path = path
.to_str()
.ok_or(format_err!("Failed to convert PathBuf into str."))?;
let path = std::ffi::CString::new(path)?;
(rs.interface.io.load_from_file)(rs.ptr, path.as_ptr());
Ok(rs)
}
pub fn select(&self, index: usize) -> usize {
(self.interface.select)(self.ptr, index)
}
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> common::io::IO
for SelectSupportMcl<'a, BitPattern>
{
fn io(&self) -> &common::io::Interface {
&self.interface.io
}
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> common::Ptr
for SelectSupportMcl<'a, BitPattern>
{
fn ptr(&self) -> &common::VoidPtr {
&self.ptr
}
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> common::Id
for SelectSupportMcl<'a, BitPattern>
{
fn id() -> Result<String> {
let meta = Box::new(meta::select_support_mcl::SelectSupportMclMeta::new())
as Box<dyn meta::common::Meta>;
let parameters_c_code = Self::parameters_c_code()?;
let id = sdsl_c::specification::get_id(&meta.c_code(¶meters_c_code)?)?;
Ok(id)
}
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> common::Code
for SelectSupportMcl<'a, BitPattern>
{
fn c_code() -> Result<String> {
let meta = Box::new(meta::select_support_mcl::SelectSupportMclMeta::new())
as Box<dyn meta::common::Meta>;
let parameters_c_code = Self::parameters_c_code()?;
Ok(meta.c_code(¶meters_c_code)?)
}
fn parameters_c_code() -> Result<Vec<String>> {
Ok(vec![BitPattern::c_code()?])
}
}
impl<'a, BitPattern: common::bit_patterns::BitPattern> Drop for SelectSupportMcl<'a, BitPattern> {
fn drop(&mut self) {
(self.interface.drop)(self.ptr)
}
}
#[derive(Clone)]
struct Interface {
create: extern "C" fn(common::VoidPtr) -> common::VoidPtr,
drop: extern "C" fn(common::VoidPtr),
select: extern "C" fn(common::VoidPtr, usize) -> usize,
pub io: common::io::Interface,
_lib: std::sync::Arc<sharedlib::Lib>,
}
impl Interface {
pub fn new(id: &str) -> Result<Self> {
let lib = sdsl_c::LIB.clone();
let builder = sdsl_c::FunctionBuilder::new(Some("select_support_mcl"), id, lib.clone());
Ok(Self {
create: builder.get("create")?,
drop: builder.get("destroy")?,
select: builder.get("select")?,
io: common::io::Interface::new(&id)?,
_lib: lib.clone(),
})
}
}