diff --git a/src/edge_table.rs b/src/edge_table.rs index bd044730b..21d91ffae 100644 --- a/src/edge_table.rs +++ b/src/edge_table.rs @@ -31,7 +31,7 @@ fn make_edge_table_row(table: &EdgeTable, pos: tsk_id_t) -> Option // set up the iterator let p = crate::SizeType::try_from(pos).unwrap(); if p < table.num_rows() { - let table_ref = table.table_; + let table_ref = &unsafe { *table.table_ }; let rv = EdgeTableRow { id: pos.into(), left: table.left(pos).unwrap(), @@ -46,8 +46,8 @@ fn make_edge_table_row(table: &EdgeTable, pos: tsk_id_t) -> Option } } -pub(crate) type EdgeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a EdgeTable<'a>>; -pub(crate) type EdgeTableIterator<'a> = crate::table_iterator::TableIterator>; +pub(crate) type EdgeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a EdgeTable>; +pub(crate) type EdgeTableIterator<'a> = crate::table_iterator::TableIterator; impl<'a> Iterator for EdgeTableRefIterator<'a> { type Item = EdgeTableRow; @@ -74,18 +74,34 @@ impl<'a> Iterator for EdgeTableIterator<'a> { /// These are not created directly. /// Instead, use [`TableAccess::edges`](crate::TableAccess::edges) /// to get a reference to an existing edge table; -pub struct EdgeTable<'a> { - table_: &'a ll_bindings::tsk_edge_table_t, +pub struct EdgeTable { + table_: *const ll_bindings::tsk_edge_table_t, } -impl<'a> EdgeTable<'a> { - pub(crate) fn new_from_table(edges: &'a ll_bindings::tsk_edge_table_t) -> Self { +impl EdgeTable { + pub(crate) fn as_ll_ref(&self) -> &ll_bindings::tsk_edge_table_t { + // SAFETY: cannot be constructed with null pointer + unsafe { &(*self.table_) } + } + + pub(crate) fn new_from_table(edges: &ll_bindings::tsk_edge_table_t) -> Self { EdgeTable { table_: edges } } + pub(crate) fn new_null() -> Self { + Self { + table_: std::ptr::null(), + } + } + + pub(crate) fn set_ptr(&mut self, ptr: *const ll_bindings::tsk_edge_table_t) { + assert!(!ptr.is_null()); + self.table_ = ptr; + } + /// Return the number of rows - pub fn num_rows(&'a self) -> crate::SizeType { - self.table_.num_rows.into() + pub fn num_rows(&self) -> crate::SizeType { + self.as_ll_ref().num_rows.into() } /// Return the ``parent`` value from row ``row`` of the table. @@ -94,8 +110,14 @@ impl<'a> EdgeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn parent + Copy>(&'a self, row: E) -> Result { - unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.parent, NodeId) + pub fn parent + Copy>(&self, row: E) -> Result { + unsafe_tsk_column_access!( + row.into().0, + 0, + self.num_rows(), + self.as_ll_ref().parent, + NodeId + ) } /// Return the ``child`` value from row ``row`` of the table. @@ -104,8 +126,14 @@ impl<'a> EdgeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn child + Copy>(&'a self, row: E) -> Result { - unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.child, NodeId) + pub fn child + Copy>(&self, row: E) -> Result { + unsafe_tsk_column_access!( + row.into().0, + 0, + self.num_rows(), + self.as_ll_ref().child, + NodeId + ) } /// Return the ``left`` value from row ``row`` of the table. @@ -114,8 +142,8 @@ impl<'a> EdgeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn left + Copy>(&'a self, row: E) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.left) { + pub fn left + Copy>(&self, row: E) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().left) { Ok(p) => Ok(p.into()), Err(e) => Err(e), } @@ -127,18 +155,18 @@ impl<'a> EdgeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn right + Copy>(&'a self, row: E) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.right) { + pub fn right + Copy>(&self, row: E) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().right) { Ok(p) => Ok(p.into()), Err(e) => Err(e), } } pub fn metadata( - &'a self, + &self, row: EdgeId, ) -> Result, TskitError> { - let table_ref = self.table_; + let table_ref = &unsafe { *self.table_ }; let buffer = metadata_to_vector!(table_ref, row.0)?; decode_metadata_row!(T, buffer) } @@ -147,7 +175,7 @@ impl<'a> EdgeTable<'a> { /// The value of the iterator is [`EdgeTableRow`]. /// pub fn iter(&self) -> impl Iterator + '_ { - crate::table_iterator::make_table_iterator::<&EdgeTable<'a>>(self) + crate::table_iterator::make_table_iterator::<&EdgeTable>(self) } /// Return row `r` of the table. diff --git a/src/individual_table.rs b/src/individual_table.rs index 96b7106b9..c1e4617a6 100644 --- a/src/individual_table.rs +++ b/src/individual_table.rs @@ -46,8 +46,8 @@ impl PartialEq for IndividualTableRow { /// These are not created directly. /// Instead, use [`TableAccess::individuals`](crate::TableAccess::individuals) /// to get a reference to an existing node table; -pub struct IndividualTable<'a> { - table_: &'a ll_bindings::tsk_individual_table_t, +pub struct IndividualTable { + table_: *const ll_bindings::tsk_individual_table_t, } fn make_individual_table_row(table: &IndividualTable, pos: tsk_id_t) -> Option { @@ -56,7 +56,7 @@ fn make_individual_table_row(table: &IndividualTable, pos: tsk_id_t) -> Option Option = - crate::table_iterator::TableIterator<&'a IndividualTable<'a>>; -pub(crate) type IndividualTableIterator<'a> = - crate::table_iterator::TableIterator>; + crate::table_iterator::TableIterator<&'a IndividualTable>; +pub(crate) type IndividualTableIterator<'a> = crate::table_iterator::TableIterator; impl<'a> Iterator for IndividualTableRefIterator<'a> { type Item = IndividualTableRow; @@ -95,16 +94,31 @@ impl<'a> Iterator for IndividualTableIterator<'a> { } } -impl<'a> IndividualTable<'a> { - pub(crate) fn new_from_table(individuals: &'a ll_bindings::tsk_individual_table_t) -> Self { +impl IndividualTable { + pub(crate) fn as_ll_ref(&self) -> &ll_bindings::tsk_individual_table_t { + unsafe { &(*self.table_) } + } + + pub(crate) fn new_from_table(individuals: &ll_bindings::tsk_individual_table_t) -> Self { IndividualTable { table_: individuals, } } + pub(crate) fn new_null() -> Self { + Self { + table_: std::ptr::null(), + } + } + + pub(crate) fn set_ptr(&mut self, ptr: *const ll_bindings::tsk_individual_table_t) { + assert!(!ptr.is_null()); + self.table_ = ptr; + } + /// Return the number of rows - pub fn num_rows(&'a self) -> crate::SizeType { - self.table_.num_rows.into() + pub fn num_rows(&self) -> crate::SizeType { + self.as_ll_ref().num_rows.into() } /// Return the flags for a given row. @@ -116,7 +130,7 @@ impl<'a> IndividualTable<'a> { &self, row: I, ) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.flags) { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().flags) { Ok(f) => Ok(IndividualFlags::from(f)), Err(e) => Err(e), } @@ -135,9 +149,9 @@ impl<'a> IndividualTable<'a> { row.into().0, 0, self.num_rows(), - self.table_.location, - self.table_.location_offset, - self.table_.location_length, + self.as_ll_ref().location, + self.as_ll_ref().location_offset, + self.as_ll_ref().location_length, Location ) } @@ -155,9 +169,9 @@ impl<'a> IndividualTable<'a> { row.into().0, 0, self.num_rows(), - self.table_.parents, - self.table_.parents_offset, - self.table_.parents_length, + self.as_ll_ref().parents, + self.as_ll_ref().parents_offset, + self.as_ll_ref().parents_length, IndividualId ) } @@ -243,10 +257,10 @@ impl<'a> IndividualTable<'a> { /// # } /// ``` pub fn metadata( - &'a self, + &self, row: IndividualId, ) -> Result, TskitError> { - let table_ref = self.table_; + let table_ref = &unsafe { *self.table_ }; let buffer = metadata_to_vector!(table_ref, row.0)?; decode_metadata_row!(T, buffer) } @@ -255,7 +269,7 @@ impl<'a> IndividualTable<'a> { /// The value of the iterator is [`IndividualTableRow`]. /// pub fn iter(&self) -> impl Iterator + '_ { - crate::table_iterator::make_table_iterator::<&IndividualTable<'a>>(self) + crate::table_iterator::make_table_iterator::<&IndividualTable>(self) } /// Return row `r` of the table. diff --git a/src/migration_table.rs b/src/migration_table.rs index 7468d5ae5..da84b76ba 100644 --- a/src/migration_table.rs +++ b/src/migration_table.rs @@ -37,7 +37,7 @@ fn make_migration_table_row(table: &MigrationTable, pos: tsk_id_t) -> Option Option = - crate::table_iterator::TableIterator<&'a MigrationTable<'a>>; -pub(crate) type MigrationTableIterator<'a> = - crate::table_iterator::TableIterator>; + crate::table_iterator::TableIterator<&'a MigrationTable>; +pub(crate) type MigrationTableIterator<'a> = crate::table_iterator::TableIterator; impl<'a> Iterator for MigrationTableRefIterator<'a> { type Item = MigrationTableRow; @@ -83,18 +82,32 @@ impl<'a> Iterator for MigrationTableIterator<'a> { /// These are not created directly. /// Instead, use [`TableAccess::migrations`](crate::TableAccess::migrations) /// to get a reference to an existing node table; -pub struct MigrationTable<'a> { - table_: &'a ll_bindings::tsk_migration_table_t, +pub struct MigrationTable { + table_: *const ll_bindings::tsk_migration_table_t, } -impl<'a> MigrationTable<'a> { - pub(crate) fn new_from_table(migrations: &'a ll_bindings::tsk_migration_table_t) -> Self { +impl MigrationTable { + pub(crate) fn as_ll_ref(&self) -> &ll_bindings::tsk_migration_table_t { + unsafe { &(*self.table_) } + } + pub(crate) fn new_from_table(migrations: &ll_bindings::tsk_migration_table_t) -> Self { MigrationTable { table_: migrations } } + pub(crate) fn new_null() -> Self { + Self { + table_: std::ptr::null(), + } + } + + pub(crate) fn set_ptr(&mut self, ptr: *const ll_bindings::tsk_migration_table_t) { + assert!(!ptr.is_null()); + self.table_ = ptr; + } + /// Return the number of rows - pub fn num_rows(&'a self) -> SizeType { - self.table_.num_rows.into() + pub fn num_rows(&self) -> SizeType { + self.as_ll_ref().num_rows.into() } /// Return the left coordinate for a given row. @@ -102,8 +115,8 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn left + Copy>(&'a self, row: M) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.left) { + pub fn left + Copy>(&self, row: M) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().left) { Ok(p) => Ok(p.into()), Err(e) => Err(e), } @@ -114,8 +127,8 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn right + Copy>(&'a self, row: M) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.right) { + pub fn right + Copy>(&self, row: M) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().right) { Ok(p) => Ok(p.into()), Err(e) => Err(e), } @@ -126,8 +139,14 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn node + Copy>(&'a self, row: M) -> Result { - unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.node, NodeId) + pub fn node + Copy>(&self, row: M) -> Result { + unsafe_tsk_column_access!( + row.into().0, + 0, + self.num_rows(), + self.as_ll_ref().node, + NodeId + ) } /// Return the source population for a given row. @@ -135,15 +154,12 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn source + Copy>( - &'a self, - row: M, - ) -> Result { + pub fn source + Copy>(&self, row: M) -> Result { unsafe_tsk_column_access!( row.into().0, 0, self.num_rows(), - self.table_.source, + self.as_ll_ref().source, PopulationId ) } @@ -153,12 +169,12 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn dest + Copy>(&'a self, row: M) -> Result { + pub fn dest + Copy>(&self, row: M) -> Result { unsafe_tsk_column_access!( row.into().0, 0, self.num_rows(), - self.table_.dest, + self.as_ll_ref().dest, PopulationId ) } @@ -168,8 +184,8 @@ impl<'a> MigrationTable<'a> { /// # Errors /// /// * [`TskitError::IndexError`] if `row` is out of range. - pub fn time + Copy>(&'a self, row: M) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.time) { + pub fn time + Copy>(&self, row: M) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().time) { Ok(t) => Ok(t.into()), Err(e) => Err(e), } @@ -181,10 +197,10 @@ impl<'a> MigrationTable<'a> { /// /// * [`TskitError::IndexError`] if `row` is out of range. pub fn metadata( - &'a self, + &self, row: MigrationId, ) -> Result, TskitError> { - let table_ref = self.table_; + let table_ref = &unsafe { *self.table_ }; let buffer = metadata_to_vector!(table_ref, row.0)?; decode_metadata_row!(T, buffer) } @@ -192,7 +208,7 @@ impl<'a> MigrationTable<'a> { /// Return an iterator over rows of the table. /// The value of the iterator is [`MigrationTableRow`]. pub fn iter(&self) -> impl Iterator + '_ { - crate::table_iterator::make_table_iterator::<&MigrationTable<'a>>(self) + crate::table_iterator::make_table_iterator::<&MigrationTable>(self) } /// Return row `r` of the table. diff --git a/src/mutation_table.rs b/src/mutation_table.rs index 04995e543..091559b51 100644 --- a/src/mutation_table.rs +++ b/src/mutation_table.rs @@ -34,7 +34,7 @@ fn make_mutation_table_row(table: &MutationTable, pos: tsk_id_t) -> Option Option = - crate::table_iterator::TableIterator<&'a MutationTable<'a>>; -pub(crate) type MutationTableIterator<'a> = crate::table_iterator::TableIterator>; + crate::table_iterator::TableIterator<&'a MutationTable>; +pub(crate) type MutationTableIterator<'a> = crate::table_iterator::TableIterator; impl<'a> Iterator for MutationTableRefIterator<'a> { type Item = MutationTableRow; @@ -78,18 +78,34 @@ impl<'a> Iterator for MutationTableIterator<'a> { /// These are not created directly. /// Instead, use [`TableAccess::mutations`](crate::TableAccess::mutations) /// to get a reference to an existing mutation table; -pub struct MutationTable<'a> { - table_: &'a ll_bindings::tsk_mutation_table_t, +pub struct MutationTable { + table_: *const ll_bindings::tsk_mutation_table_t, } -impl<'a> MutationTable<'a> { - pub(crate) fn new_from_table(mutations: &'a ll_bindings::tsk_mutation_table_t) -> Self { +impl MutationTable { + fn as_ll_ref(&self) -> &ll_bindings::tsk_mutation_table_t { + // SAFETY: cannot be constructed with null pointer + unsafe { &(*self.table_) } + } + + pub(crate) fn new_from_table(mutations: &ll_bindings::tsk_mutation_table_t) -> Self { MutationTable { table_: mutations } } + pub(crate) fn new_null() -> Self { + Self { + table_: std::ptr::null(), + } + } + + pub(crate) fn set_ptr(&mut self, ptr: *const ll_bindings::tsk_mutation_table_t) { + assert!(!ptr.is_null()); + self.table_ = ptr; + } + /// Return the number of rows. - pub fn num_rows(&'a self) -> SizeType { - self.table_.num_rows.into() + pub fn num_rows(&self) -> SizeType { + self.as_ll_ref().num_rows.into() } /// Return the ``site`` value from row ``row`` of the table. @@ -98,8 +114,14 @@ impl<'a> MutationTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn site + Copy>(&'a self, row: M) -> Result { - unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.site, SiteId) + pub fn site + Copy>(&self, row: M) -> Result { + unsafe_tsk_column_access!( + row.into().0, + 0, + self.num_rows(), + self.as_ll_ref().site, + SiteId + ) } /// Return the ``node`` value from row ``row`` of the table. @@ -108,8 +130,14 @@ impl<'a> MutationTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn node + Copy>(&'a self, row: M) -> Result { - unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.node, NodeId) + pub fn node + Copy>(&self, row: M) -> Result { + unsafe_tsk_column_access!( + row.into().0, + 0, + self.num_rows(), + self.as_ll_ref().node, + NodeId + ) } /// Return the ``parent`` value from row ``row`` of the table. @@ -118,12 +146,12 @@ impl<'a> MutationTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn parent + Copy>(&'a self, row: M) -> Result { + pub fn parent + Copy>(&self, row: M) -> Result { unsafe_tsk_column_access!( row.into().0, 0, self.num_rows(), - self.table_.parent, + self.as_ll_ref().parent, MutationId ) } @@ -134,8 +162,8 @@ impl<'a> MutationTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn time + Copy>(&'a self, row: M) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.time) { + pub fn time + Copy>(&self, row: M) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().time) { Ok(t) => Ok(t.into()), Err(e) => Err(e), } @@ -152,23 +180,23 @@ impl<'a> MutationTable<'a> { /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. pub fn derived_state>( - &'a self, + &self, row: M, ) -> Result>, TskitError> { metadata::char_column_to_vector( - self.table_.derived_state, - self.table_.derived_state_offset, + self.as_ll_ref().derived_state, + self.as_ll_ref().derived_state_offset, row.into().0, - self.table_.num_rows, - self.table_.derived_state_length, + self.as_ll_ref().num_rows, + self.as_ll_ref().derived_state_length, ) } pub fn metadata( - &'a self, + &self, row: MutationId, ) -> Result, TskitError> { - let table_ref = self.table_; + let table_ref = &unsafe { *self.table_ }; let buffer = metadata_to_vector!(table_ref, row.0)?; decode_metadata_row!(T, buffer) } @@ -176,7 +204,7 @@ impl<'a> MutationTable<'a> { /// Return an iterator over rows of the table. /// The value of the iterator is [`MutationTableRow`]. pub fn iter(&self) -> impl Iterator + '_ { - crate::table_iterator::make_table_iterator::<&MutationTable<'a>>(self) + crate::table_iterator::make_table_iterator::<&MutationTable>(self) } /// Return row `r` of the table. diff --git a/src/node_table.rs b/src/node_table.rs index 35b73c6aa..af8e07016 100644 --- a/src/node_table.rs +++ b/src/node_table.rs @@ -33,7 +33,7 @@ fn make_node_table_row(table: &NodeTable, pos: tsk_id_t) -> Option // set up the iterator let p = crate::SizeType::try_from(pos).unwrap(); if p < table.num_rows() { - let table_ref = table.table_; + let table_ref = &unsafe { *table.table_ }; Some(NodeTableRow { id: pos.into(), time: table.time(pos).unwrap(), @@ -47,8 +47,8 @@ fn make_node_table_row(table: &NodeTable, pos: tsk_id_t) -> Option } } -pub(crate) type NodeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a NodeTable<'a>>; -pub(crate) type NodeTableIterator<'a> = crate::table_iterator::TableIterator>; +pub(crate) type NodeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a NodeTable>; +pub(crate) type NodeTableIterator<'a> = crate::table_iterator::TableIterator; impl<'a> Iterator for NodeTableRefIterator<'a> { type Item = NodeTableRow; @@ -75,18 +75,34 @@ impl<'a> Iterator for NodeTableIterator<'a> { /// These are not created directly. /// Instead, use [`TableAccess::nodes`](crate::TableAccess::nodes) /// to get a reference to an existing node table; -pub struct NodeTable<'a> { - table_: &'a ll_bindings::tsk_node_table_t, +pub struct NodeTable { + table_: *const ll_bindings::tsk_node_table_t, } -impl<'a> NodeTable<'a> { - pub(crate) fn new_from_table(nodes: &'a ll_bindings::tsk_node_table_t) -> Self { +impl NodeTable { + fn as_ll_ref(&self) -> &ll_bindings::tsk_node_table_t { + // SAFETY: cannot be constructed with null pointer + unsafe { &(*self.table_) } + } + + pub(crate) fn new_from_table(nodes: &ll_bindings::tsk_node_table_t) -> Self { NodeTable { table_: nodes } } + pub(crate) fn new_null() -> Self { + Self { + table_: std::ptr::null(), + } + } + + pub(crate) fn set_ptr(&mut self, ptr: *const ll_bindings::tsk_node_table_t) { + assert!(!ptr.is_null()); + self.table_ = ptr; + } + /// Return the number of rows - pub fn num_rows(&'a self) -> SizeType { - self.table_.num_rows.into() + pub fn num_rows(&self) -> SizeType { + self.as_ll_ref().num_rows.into() } /// Return the ``time`` value from row ``row`` of the table. @@ -95,8 +111,8 @@ impl<'a> NodeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn time + Copy>(&'a self, row: N) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.time) { + pub fn time + Copy>(&self, row: N) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().time) { Ok(t) => Ok(t.into()), Err(e) => Err(e), } @@ -108,48 +124,25 @@ impl<'a> NodeTable<'a> { /// /// Will return [``IndexError``](crate::TskitError::IndexError) /// if ``row`` is out of range. - pub fn flags + Copy>(&'a self, row: N) -> Result { - match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_.flags) { + pub fn flags + Copy>(&self, row: N) -> Result { + match unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.as_ll_ref().flags) { Ok(f) => Ok(NodeFlags::from(f)), Err(e) => Err(e), } } - /// Mutable access to node flags. - pub fn flags_array_mut(&mut self) -> &mut [NodeFlags] { - unsafe { - std::slice::from_raw_parts_mut( - self.table_.flags.cast::(), - usize::try_from(self.table_.num_rows).unwrap(), - ) - } - } - - /// Mutable access to node times. - pub fn time_array_mut(&mut self) -> &mut [Time] { - unsafe { - std::slice::from_raw_parts_mut( - self.table_.time.cast::