diff --git a/Cargo.toml b/Cargo.toml index 54e0d5f3c..6206ed086 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ serde = {version = "1.0.118", features = ["derive"], optional = true} serde_json = {version = "1.0.67", optional = true} bincode = {version = "1.3.1", optional = true} tskit-derive = {version = "0.2.0", path = "tskit-derive", optional = true} +mbox = "0.6.0" [dev-dependencies] clap = "~2.34.0" diff --git a/src/_macros.rs b/src/_macros.rs index dee48a471..f663e7fd0 100644 --- a/src/_macros.rs +++ b/src/_macros.rs @@ -132,10 +132,6 @@ macro_rules! drop_for_tskit_type { fn drop(&mut self) { let rv = unsafe { $drop(&mut *self.inner) }; panic_on_tskit_error!(rv); - unsafe { - libc::free(self.inner as *mut libc::c_void); - } - self.inner = std::ptr::null_mut(); } } }; @@ -145,11 +141,11 @@ macro_rules! tskit_type_access { ($name: ident, $ll_name: ty) => { impl $crate::TskitTypeAccess<$ll_name> for $name { fn as_ptr(&self) -> *const $ll_name { - self.inner + &*self.inner } fn as_mut_ptr(&mut self) -> *mut $ll_name { - self.inner + &mut *self.inner } } }; @@ -159,12 +155,15 @@ macro_rules! build_tskit_type { ($name: ident, $ll_name: ty, $drop: ident) => { impl $crate::ffi::WrapTskitType<$ll_name> for $name { fn wrap() -> Self { + use mbox::MBox; let temp = unsafe { libc::malloc(std::mem::size_of::<$ll_name>()) as *mut $ll_name }; - if temp.is_null() { - panic!("out of memory"); - } - $name { inner: temp } + let nonnull = match std::ptr::NonNull::<$ll_name>::new(temp) { + Some(x) => x, + None => panic!("out of memory"), + }; + let mbox = unsafe { MBox::from_non_null_raw(nonnull) }; + $name { inner: mbox } } } drop_for_tskit_type!($name, $drop); diff --git a/src/ffi.rs b/src/ffi.rs index e2a9b3634..f0fb1272e 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -23,9 +23,10 @@ mod tests { use crate::bindings as ll_bindings; use crate::TskitTypeAccess; use ll_bindings::tsk_table_collection_free; + use mbox::MBox; pub struct TableCollectionMock { - inner: *mut ll_bindings::tsk_table_collection_t, + inner: MBox, } build_tskit_type!( @@ -41,15 +42,13 @@ mod tests { let rv = unsafe { ll_bindings::tsk_table_collection_init(s.as_mut_ptr(), 0) }; assert_eq!(rv, 0); - unsafe { - (*s.inner).sequence_length = len; - } + (*s.inner).sequence_length = len; s } fn sequence_length(&self) -> f64 { - unsafe { (*self.inner).sequence_length } + (*self.inner).sequence_length } } diff --git a/src/table_collection.rs b/src/table_collection.rs index 20ee919c9..7110a90bf 100644 --- a/src/table_collection.rs +++ b/src/table_collection.rs @@ -26,6 +26,7 @@ use crate::TskitTypeAccess; use crate::{tsk_flags_t, tsk_id_t, tsk_size_t}; use crate::{EdgeId, IndividualId, MigrationId, MutationId, NodeId, PopulationId, SiteId}; use ll_bindings::tsk_table_collection_free; +use mbox::MBox; /// A table collection. /// @@ -117,7 +118,7 @@ use ll_bindings::tsk_table_collection_free; /// those needed for current goals in ongoing projects. /// 2. Strengthen some of the error handling. pub struct TableCollection { - pub(crate) inner: *mut ll_bindings::tsk_table_collection_t, + pub(crate) inner: MBox, } build_tskit_type!( @@ -137,12 +138,12 @@ impl TableCollection { }); } let mut tables = Self::wrap(); - let rv = unsafe { ll_bindings::tsk_table_collection_init(tables.inner, 0) }; + let rv = unsafe { ll_bindings::tsk_table_collection_init(tables.as_mut_ptr(), 0) }; if rv < 0 { return Err(crate::error::TskitError::ErrorCode { code: rv }); } unsafe { - (*tables.inner).sequence_length = sequence_length.0; + (*tables.as_mut_ptr()).sequence_length = sequence_length.0; } Ok(tables) } @@ -155,12 +156,12 @@ impl TableCollection { Err(e) => return Err(e), } - let tables = tables.unwrap(); + let mut tables = tables.unwrap(); let c_str = std::ffi::CString::new(filename).unwrap(); let rv = unsafe { ll_bindings::tsk_table_collection_load( - tables.inner, + tables.as_mut_ptr(), c_str.as_ptr(), ll_bindings::TSK_NO_INIT, ) @@ -171,7 +172,7 @@ impl TableCollection { /// Length of the sequence/"genome". pub fn sequence_length(&self) -> Position { - unsafe { (*self.inner).sequence_length }.into() + unsafe { (*self.as_ptr()).sequence_length }.into() } /// Add a row to the edge table @@ -184,7 +185,7 @@ impl TableCollection { ) -> Result { let rv = unsafe { ll_bindings::tsk_edge_table_add_row( - &mut (*self.inner).edges, + &mut (*self.as_mut_ptr()).edges, left.into().0, right.into().0, parent.into().0, @@ -215,7 +216,7 @@ impl TableCollection { let md = EncodedMetadata::new(metadata)?; let rv = unsafe { ll_bindings::tsk_edge_table_add_row( - &mut (*self.inner).edges, + &mut (*self.as_mut_ptr()).edges, left.into().0, right.into().0, parent.into().0, @@ -237,7 +238,7 @@ impl TableCollection { ) -> Result { let rv = unsafe { ll_bindings::tsk_individual_table_add_row( - &mut (*self.inner).individuals, + &mut (*self.as_mut_ptr()).individuals, flags, location.as_ptr() as *const f64, location.len() as tsk_size_t, @@ -265,7 +266,7 @@ impl TableCollection { let md = EncodedMetadata::new(metadata)?; let rv = unsafe { ll_bindings::tsk_individual_table_add_row( - &mut (*self.inner).individuals, + &mut (*self.as_mut_ptr()).individuals, flags, location.as_ptr() as *const f64, location.len() as tsk_size_t, @@ -300,7 +301,7 @@ impl TableCollection { ) -> Result { let rv = unsafe { ll_bindings::tsk_migration_table_add_row( - &mut (*self.inner).migrations, + &mut (*self.as_mut_ptr()).migrations, span.0.into().0, span.1.into().0, node.into().0, @@ -339,7 +340,7 @@ impl TableCollection { let md = EncodedMetadata::new(metadata)?; let rv = unsafe { ll_bindings::tsk_migration_table_add_row( - &mut (*self.inner).migrations, + &mut (*self.as_mut_ptr()).migrations, span.0.into().0, span.1.into().0, node.into().0, @@ -363,7 +364,7 @@ impl TableCollection { ) -> Result { let rv = unsafe { ll_bindings::tsk_node_table_add_row( - &mut (*self.inner).nodes, + &mut (*self.as_mut_ptr()).nodes, flags, time.into().0, population.into().0, @@ -393,7 +394,7 @@ impl TableCollection { let md = EncodedMetadata::new(metadata)?; let rv = unsafe { ll_bindings::tsk_node_table_add_row( - &mut (*self.inner).nodes, + &mut (*self.as_mut_ptr()).nodes, flags, time.into().0, population.into().0, @@ -416,7 +417,7 @@ impl TableCollection { let rv = unsafe { ll_bindings::tsk_site_table_add_row( - &mut (*self.inner).sites, + &mut (*self.as_mut_ptr()).sites, position.into().0, astate.0, astate.1, @@ -440,7 +441,7 @@ impl TableCollection { let rv = unsafe { ll_bindings::tsk_site_table_add_row( - &mut (*self.inner).sites, + &mut (*self.as_mut_ptr()).sites, position.into().0, astate.0, astate.1, @@ -464,7 +465,7 @@ impl TableCollection { let dstate = process_state_input!(derived_state); let rv = unsafe { ll_bindings::tsk_mutation_table_add_row( - &mut (*self.inner).mutations, + &mut (*self.as_mut_ptr()).mutations, site.into().0, node.into().0, parent.into().0, @@ -499,7 +500,7 @@ impl TableCollection { let rv = unsafe { ll_bindings::tsk_mutation_table_add_row( - &mut (*self.inner).mutations, + &mut (*self.as_mut_ptr()).mutations, site.into().0, node.into().0, parent.into().0, @@ -517,7 +518,7 @@ impl TableCollection { pub fn add_population(&mut self) -> Result { let rv = unsafe { ll_bindings::tsk_population_table_add_row( - &mut (*self.inner).populations, + &mut (*self.as_mut_ptr()).populations, std::ptr::null(), 0, ) @@ -534,7 +535,7 @@ impl TableCollection { let md = EncodedMetadata::new(metadata)?; let rv = unsafe { ll_bindings::tsk_population_table_add_row( - &mut (*self.inner).populations, + &mut (*self.as_mut_ptr()).populations, md.as_ptr(), md.len().into(), ) @@ -552,7 +553,7 @@ impl TableCollection { /// that is currently unused. A future release may break `API` /// here if the `C` library is updated to use flags. pub fn build_index(&mut self) -> TskReturnValue { - let rv = unsafe { ll_bindings::tsk_table_collection_build_index(self.inner, 0) }; + let rv = unsafe { ll_bindings::tsk_table_collection_build_index(self.as_mut_ptr(), 0) }; handle_tsk_return_value!(rv) } @@ -568,8 +569,8 @@ impl TableCollection { if self.is_indexed() { Some(unsafe { std::slice::from_raw_parts( - (*self.inner).indexes.edge_insertion_order as *const EdgeId, - (*self.inner).indexes.num_edges as usize, + (*self.as_ptr()).indexes.edge_insertion_order as *const EdgeId, + (*self.as_ptr()).indexes.num_edges as usize, ) }) } else { @@ -584,8 +585,8 @@ impl TableCollection { if self.is_indexed() { Some(unsafe { std::slice::from_raw_parts( - (*self.inner).indexes.edge_removal_order as *const EdgeId, - (*self.inner).indexes.num_edges as usize, + (*self.as_ptr()).indexes.edge_removal_order as *const EdgeId, + (*self.as_ptr()).indexes.num_edges as usize, ) }) } else { @@ -598,7 +599,11 @@ impl TableCollection { /// be used to affect where sorting starts from for each table. pub fn sort(&mut self, start: &Bookmark, options: TableSortOptions) -> TskReturnValue { let rv = unsafe { - ll_bindings::tsk_table_collection_sort(self.inner, &start.offsets, options.bits()) + ll_bindings::tsk_table_collection_sort( + self.as_mut_ptr(), + &start.offsets, + options.bits(), + ) }; handle_tsk_return_value!(rv) @@ -616,11 +621,7 @@ impl TableCollection { pub fn dump(&self, filename: &str, options: TableOutputOptions) -> TskReturnValue { let c_str = std::ffi::CString::new(filename).unwrap(); let rv = unsafe { - ll_bindings::tsk_table_collection_dump( - self.inner as *mut ll_bindings::tsk_table_collection_t, - c_str.as_ptr(), - options.bits(), - ) + ll_bindings::tsk_table_collection_dump(self.as_ptr(), c_str.as_ptr(), options.bits()) }; handle_tsk_return_value!(rv) @@ -631,7 +632,8 @@ impl TableCollection { /// Memory will be released when the object goes out /// of scope. pub fn clear(&mut self, options: TableClearOptions) -> TskReturnValue { - let rv = unsafe { ll_bindings::tsk_table_collection_clear(self.inner, options.bits()) }; + let rv = + unsafe { ll_bindings::tsk_table_collection_clear(self.as_mut_ptr(), options.bits()) }; handle_tsk_return_value!(rv) } @@ -640,7 +642,7 @@ impl TableCollection { /// Not public b/c not very safe. #[allow(dead_code)] fn free(&mut self) -> TskReturnValue { - let rv = unsafe { ll_bindings::tsk_table_collection_free(self.inner) }; + let rv = unsafe { ll_bindings::tsk_table_collection_free(self.as_mut_ptr()) }; handle_tsk_return_value!(rv) } @@ -648,14 +650,17 @@ impl TableCollection { /// Return ``true`` if ``self`` contains the same /// data as ``other``, and ``false`` otherwise. pub fn equals(&self, other: &TableCollection, options: TableEqualityOptions) -> bool { - unsafe { ll_bindings::tsk_table_collection_equals(self.inner, other.inner, options.bits()) } + unsafe { + ll_bindings::tsk_table_collection_equals(self.as_ptr(), other.as_ptr(), options.bits()) + } } /// Return a "deep" copy of the tables. pub fn deepcopy(&self) -> Result { - let copy = TableCollection::new(1.)?; + let mut copy = TableCollection::new(1.)?; - let rv = unsafe { ll_bindings::tsk_table_collection_copy(self.inner, copy.inner, 0) }; + let rv = + unsafe { ll_bindings::tsk_table_collection_copy(self.as_ptr(), copy.as_mut_ptr(), 0) }; handle_tsk_return_value!(rv, copy) } @@ -695,7 +700,7 @@ impl TableCollection { } let rv = unsafe { ll_bindings::tsk_table_collection_simplify( - self.inner, + self.as_mut_ptr(), samples.as_ptr() as *const tsk_id_t, samples.len() as tsk_size_t, options.bits(), @@ -759,39 +764,40 @@ impl TableCollection { /// tables.check_integrity(tskit::TableIntegrityCheckFlags::default()).unwrap(); /// ``` pub fn check_integrity(&self, flags: TableIntegrityCheckFlags) -> TskReturnValue { - let rv = - unsafe { ll_bindings::tsk_table_collection_check_integrity(self.inner, flags.bits()) }; + let rv = unsafe { + ll_bindings::tsk_table_collection_check_integrity(self.as_ptr(), flags.bits()) + }; handle_tsk_return_value!(rv) } } impl TableAccess for TableCollection { fn edges(&self) -> EdgeTable { - EdgeTable::new_from_table(unsafe { &(*self.inner).edges }) + EdgeTable::new_from_table(&(*self.inner).edges) } fn individuals(&self) -> IndividualTable { - IndividualTable::new_from_table(unsafe { &(*self.inner).individuals }) + IndividualTable::new_from_table(&(*self.inner).individuals) } fn migrations(&self) -> MigrationTable { - MigrationTable::new_from_table(unsafe { &(*self.inner).migrations }) + MigrationTable::new_from_table(&(*self.inner).migrations) } fn nodes(&self) -> NodeTable { - NodeTable::new_from_table(unsafe { &(*self.inner).nodes }) + NodeTable::new_from_table(&(*self.inner).nodes) } fn sites(&self) -> SiteTable { - SiteTable::new_from_table(unsafe { &(*self.inner).sites }) + SiteTable::new_from_table(&(*self.inner).sites) } fn mutations(&self) -> MutationTable { - MutationTable::new_from_table(unsafe { &(*self.inner).mutations }) + MutationTable::new_from_table(&(*self.inner).mutations) } fn populations(&self) -> PopulationTable { - PopulationTable::new_from_table(unsafe { &(*self.inner).populations }) + PopulationTable::new_from_table(&(*self.inner).populations) } } @@ -814,7 +820,7 @@ impl crate::provenance::Provenance for TableCollection { } fn provenances(&self) -> crate::provenance::ProvenanceTable { - crate::provenance::ProvenanceTable::new_from_table(unsafe { &(*self.inner).provenances }) + crate::provenance::ProvenanceTable::new_from_table(&(*self.inner).provenances) } } diff --git a/src/trees.rs b/src/trees.rs index 07985fb13..b55f98099 100644 --- a/src/trees.rs +++ b/src/trees.rs @@ -21,12 +21,13 @@ use crate::TskReturnValue; use crate::TskitTypeAccess; use crate::{tsk_id_t, tsk_size_t, TableCollection}; use ll_bindings::{tsk_tree_free, tsk_treeseq_free}; +use mbox::MBox; /// A Tree. /// /// Wrapper around `tsk_tree_t`. pub struct Tree { - pub(crate) inner: *mut ll_bindings::tsk_tree_t, + pub(crate) inner: MBox, current_tree: i32, advanced: bool, num_nodes: tsk_size_t, @@ -51,8 +52,9 @@ impl Tree { if temp.is_null() { panic!("out of memory"); } + let mbox = unsafe { MBox::from_raw(temp as *mut ll_bindings::tsk_tree_t) }; Self { - inner: temp, + inner: mbox, current_tree: 0, advanced: false, num_nodes, @@ -61,8 +63,9 @@ impl Tree { } fn new(ts: &TreeSequence, flags: TreeFlags) -> Result { - let tree = Self::wrap(unsafe { (*(*ts.inner).tables).nodes.num_rows }, flags); - let mut rv = unsafe { ll_bindings::tsk_tree_init(tree.inner, ts.inner, flags.bits()) }; + let mut tree = Self::wrap(unsafe { (*(*ts.as_ptr()).tables).nodes.num_rows }, flags); + let mut rv = + unsafe { ll_bindings::tsk_tree_init(tree.as_mut_ptr(), ts.as_ptr(), flags.bits()) }; if rv < 0 { return Err(TskitError::ErrorCode { code: rv }); } @@ -70,9 +73,9 @@ impl Tree { if !flags.contains(TreeFlags::NO_SAMPLE_COUNTS) { rv = unsafe { ll_bindings::tsk_tree_set_tracked_samples( - tree.inner, + tree.as_mut_ptr(), ts.num_samples().into(), - (*tree.inner).samples, + (*tree.as_ptr()).samples, ) }; } @@ -345,12 +348,10 @@ impl Tree { /// Return the `[left, right)` coordinates of the tree. pub fn interval(&self) -> (Position, Position) { - unsafe { - ( - (*self.inner).interval.left.into(), - (*self.inner).interval.right.into(), - ) - } + ( + (*self.inner).interval.left.into(), + (*self.inner).interval.right.into(), + ) } /// Return the length of the genome for which this @@ -552,7 +553,7 @@ impl Tree { pub fn num_tracked_samples(&self, u: NodeId) -> Result { let mut n = u64::MAX; let np: *mut u64 = &mut n; - let code = unsafe { ll_bindings::tsk_tree_get_num_tracked_samples(self.inner, u.0, np) }; + let code = unsafe { ll_bindings::tsk_tree_get_num_tracked_samples(self.as_ptr(), u.0, np) }; handle_tsk_return_value!(code, n) } @@ -571,8 +572,9 @@ impl Tree { pub fn kc_distance(&self, other: &Tree, lambda: f64) -> Result { let mut kc = f64::NAN; let kcp: *mut f64 = &mut kc; - let code = - unsafe { ll_bindings::tsk_tree_kc_distance(self.inner, other.inner, lambda, kcp) }; + let code = unsafe { + ll_bindings::tsk_tree_kc_distance(self.as_ptr(), other.as_ptr(), lambda, kcp) + }; handle_tsk_return_value!(code, kc) } } @@ -581,9 +583,9 @@ impl streaming_iterator::StreamingIterator for Tree { type Item = Tree; fn advance(&mut self) { let rv = if self.current_tree == 0 { - unsafe { ll_bindings::tsk_tree_first(self.inner) } + unsafe { ll_bindings::tsk_tree_first(self.as_mut_ptr()) } } else { - unsafe { ll_bindings::tsk_tree_next(self.inner) } + unsafe { ll_bindings::tsk_tree_next(self.as_mut_ptr()) } }; if rv == 0 { self.advanced = false; @@ -607,9 +609,9 @@ impl streaming_iterator::StreamingIterator for Tree { impl streaming_iterator::DoubleEndedStreamingIterator for Tree { fn advance_back(&mut self) { let rv = if self.current_tree == 0 { - unsafe { ll_bindings::tsk_tree_last(self.inner) } + unsafe { ll_bindings::tsk_tree_last(self.as_mut_ptr()) } } else { - unsafe { ll_bindings::tsk_tree_prev(self.inner) } + unsafe { ll_bindings::tsk_tree_prev(self.as_mut_ptr()) } }; if rv == 0 { self.advanced = false; @@ -708,12 +710,12 @@ impl<'a> PostorderNodeIterator<'a> { let mut nodes = vec![ NodeId::NULL; // NOTE: this fn does not return error codes - unsafe { ll_bindings::tsk_tree_get_size_bound(tree.inner) } as usize + unsafe { ll_bindings::tsk_tree_get_size_bound(tree.as_ptr()) } as usize ]; let rv = unsafe { ll_bindings::tsk_tree_postorder( - tree.inner, + tree.as_ptr(), NodeId::NULL.into(), // start from virtual root nodes.as_mut_ptr() as *mut tsk_id_t, ptr as *mut tsk_size_t, @@ -761,7 +763,7 @@ impl<'a> RootIterator<'a> { fn new(tree: &'a Tree) -> Self { RootIterator { current_root: None, - next_root: unsafe { ll_bindings::tsk_tree_get_left_root(tree.inner).into() }, + next_root: unsafe { ll_bindings::tsk_tree_get_left_root(tree.as_ptr()).into() }, tree, } } @@ -942,7 +944,7 @@ iterator_for_nodeiterator!(SamplesIterator<'_>); /// let treeseq = tables.tree_sequence(tskit::TreeSequenceFlags::default()).unwrap(); /// ``` pub struct TreeSequence { - pub(crate) inner: *mut ll_bindings::tsk_treeseq_t, + pub(crate) inner: MBox, } build_tskit_type!(TreeSequence, ll_bindings::tsk_treeseq_t, tsk_treeseq_free); @@ -985,9 +987,11 @@ impl TreeSequence { /// tskit::TreeSequenceFlags::default()).unwrap(); /// ``` pub fn new(tables: TableCollection, flags: TreeSequenceFlags) -> Result { - let t = tables; - let treeseq = Self::wrap(); - let rv = unsafe { ll_bindings::tsk_treeseq_init(treeseq.inner, t.inner, flags.bits()) }; + let mut t = tables; + let mut treeseq = Self::wrap(); + let rv = unsafe { + ll_bindings::tsk_treeseq_init(treeseq.as_mut_ptr(), t.as_mut_ptr(), flags.bits()) + }; handle_tsk_return_value!(rv, treeseq) } @@ -1001,13 +1005,8 @@ impl TreeSequence { /// pub fn dump(&self, filename: &str, options: TableOutputOptions) -> TskReturnValue { let c_str = std::ffi::CString::new(filename).unwrap(); - let rv = unsafe { - ll_bindings::tsk_treeseq_dump( - self.inner as *mut ll_bindings::tsk_treeseq_t, - c_str.as_ptr(), - options.bits(), - ) - }; + let rv = + unsafe { ll_bindings::tsk_treeseq_dump(self.as_ptr(), c_str.as_ptr(), options.bits()) }; handle_tsk_return_value!(rv) } @@ -1026,10 +1025,11 @@ impl TreeSequence { /// /// [`TskitError`] will be raised if the underlying C library returns an error code. pub fn dump_tables(&self) -> Result { - let copy = TableCollection::new(1.)?; + let mut copy = TableCollection::new(1.)?; - let rv = - unsafe { ll_bindings::tsk_table_collection_copy((*self.inner).tables, copy.inner, 0) }; + let rv = unsafe { + ll_bindings::tsk_table_collection_copy((*self.as_ptr()).tables, copy.as_mut_ptr(), 0) + }; handle_tsk_return_value!(rv, copy) } @@ -1086,11 +1086,11 @@ impl TreeSequence { note = "Please use TreeSequence::sample_nodes instead" )] pub fn samples_to_vec(&self) -> Vec { - let num_samples = unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.inner) }; + let num_samples = unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.as_ptr()) }; let mut rv = vec![]; for i in 0..num_samples { - let u = NodeId::from(unsafe { *(*self.inner).samples.offset(i as isize) }); + let u = NodeId::from(unsafe { *(*self.as_ptr()).samples.offset(i as isize) }); rv.push(u); } rv @@ -1098,13 +1098,13 @@ impl TreeSequence { /// Get the list of sample nodes as a slice. pub fn sample_nodes(&self) -> &[NodeId] { - let num_samples = unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.inner) }; + let num_samples = unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.as_ptr()) }; tree_array_slice!(self, samples, num_samples) } /// Get the number of trees. pub fn num_trees(&self) -> SizeType { - unsafe { ll_bindings::tsk_treeseq_get_num_trees(self.inner) }.into() + unsafe { ll_bindings::tsk_treeseq_get_num_trees(self.as_ptr()) }.into() } /// Calculate the average Kendall-Colijn (`K-C`) distance between @@ -1121,14 +1121,15 @@ impl TreeSequence { pub fn kc_distance(&self, other: &TreeSequence, lambda: f64) -> Result { let mut kc: f64 = f64::NAN; let kcp: *mut f64 = &mut kc; - let code = - unsafe { ll_bindings::tsk_treeseq_kc_distance(self.inner, other.inner, lambda, kcp) }; + let code = unsafe { + ll_bindings::tsk_treeseq_kc_distance(self.as_ptr(), other.as_ptr(), lambda, kcp) + }; handle_tsk_return_value!(code, kc) } // FIXME: document pub fn num_samples(&self) -> SizeType { - unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.inner) }.into() + unsafe { ll_bindings::tsk_treeseq_get_num_samples(self.as_ptr()) }.into() } /// Simplify tables and return a new tree sequence. @@ -1152,19 +1153,19 @@ impl TreeSequence { ) -> Result<(Self, Option>), TskitError> { let mut tables = TableCollection::new(unsafe { (*(*self.inner).tables).sequence_length })?; tables.build_index().unwrap(); - let ts = tables.tree_sequence(TreeSequenceFlags::default())?; + let mut ts = tables.tree_sequence(TreeSequenceFlags::default())?; let mut output_node_map: Vec = vec![]; if idmap { output_node_map.resize(usize::from(self.nodes().num_rows()), NodeId::NULL); } let rv = unsafe { ll_bindings::tsk_treeseq_simplify( - self.inner, + self.as_ptr(), // NOTE: casting away const-ness: samples.as_ptr() as *mut tsk_id_t, samples.len() as tsk_size_t, options.bits(), - ts.inner, + ts.as_mut_ptr(), match idmap { true => output_node_map.as_mut_ptr() as *mut tsk_id_t, false => std::ptr::null_mut(),