Skip to content

remove table lifetime annotations #373

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/forward_simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use rand::rngs::StdRng;
use rand::Rng;
use rand::SeedableRng;
use rand_distr::{Exp, Uniform};
use tskit::TableAccess;
use tskit::TskitTypeAccess;

#[derive(clap::Parser)]
Expand Down
2 changes: 1 addition & 1 deletion src/_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ macro_rules! build_owned_tables {
}

impl std::ops::Deref for $name {
type Target = $deref<'static>;
type Target = $deref;

fn deref(&self) -> &Self::Target {
// SAFETY: that T* and &T have same layout,
Expand Down
75 changes: 50 additions & 25 deletions src/edge_table.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ptr::NonNull;

use crate::bindings as ll_bindings;
use crate::metadata;
use crate::Position;
Expand Down Expand Up @@ -28,7 +30,7 @@ impl PartialEq for EdgeTableRow {
}

fn make_edge_table_row(table: &EdgeTable, pos: tsk_id_t) -> Option<EdgeTableRow> {
let table_ref = table.table_;
let table_ref = table.as_ref();
Some(EdgeTableRow {
id: pos.into(),
left: table.left(pos)?,
Expand All @@ -39,8 +41,8 @@ fn make_edge_table_row(table: &EdgeTable, pos: tsk_id_t) -> Option<EdgeTableRow>
})
}

pub(crate) type EdgeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a EdgeTable<'a>>;
pub(crate) type EdgeTableIterator<'a> = crate::table_iterator::TableIterator<EdgeTable<'a>>;
pub(crate) type EdgeTableRefIterator<'a> = crate::table_iterator::TableIterator<&'a EdgeTable>;
pub(crate) type EdgeTableIterator = crate::table_iterator::TableIterator<EdgeTable>;

impl<'a> Iterator for EdgeTableRefIterator<'a> {
type Item = EdgeTableRow;
Expand All @@ -52,7 +54,7 @@ impl<'a> Iterator for EdgeTableRefIterator<'a> {
}
}

impl<'a> Iterator for EdgeTableIterator<'a> {
impl Iterator for EdgeTableIterator {
type Item = EdgeTableRow;

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -64,22 +66,32 @@ impl<'a> Iterator for EdgeTableIterator<'a> {

/// An immutable view of an edge table.
///
/// These are not created directly.
/// Instead, use [`TableAccess::edges`](crate::TableAccess::edges)
/// to get a reference to an existing edge table;
/// These are not created directly but are accessed
/// by types implementing [`std::ops::Deref`] to
/// [`crate::table_views::TableViews`]
#[repr(transparent)]
pub struct EdgeTable<'a> {
table_: &'a ll_bindings::tsk_edge_table_t,
pub struct EdgeTable {
pub(crate) table_: NonNull<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 {
EdgeTable { table_: edges }
impl EdgeTable {
pub(crate) fn new_from_table(
edges: *mut ll_bindings::tsk_edge_table_t,
) -> Result<Self, TskitError> {
let n = NonNull::new(edges).ok_or_else(|| {
TskitError::LibraryError("null pointer to tsk_edge_table_t".to_string())
})?;
Ok(EdgeTable { table_: n })
}

pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_edge_table_t {
// SAFETY: NonNull
unsafe { self.table_.as_ref() }
}

/// 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_ref().num_rows.into()
}

/// Return the ``parent`` value from row ``row`` of the table.
Expand All @@ -88,12 +100,12 @@ impl<'a> EdgeTable<'a> {
///
/// * `Some(parent)` if `u` is valid.
/// * `None` otherwise.
pub fn parent<E: Into<EdgeId> + Copy>(&'a self, row: E) -> Option<NodeId> {
pub fn parent<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<NodeId> {
unsafe_tsk_column_access!(
row.into().0,
0,
self.num_rows(),
self.table_,
self.as_ref(),
parent,
NodeId
)
Expand All @@ -105,8 +117,15 @@ impl<'a> EdgeTable<'a> {
///
/// * `Some(child)` if `u` is valid.
/// * `None` otherwise.
pub fn child<E: Into<EdgeId> + Copy>(&'a self, row: E) -> Option<NodeId> {
unsafe_tsk_column_access!(row.into().0, 0, self.num_rows(), self.table_, child, NodeId)
pub fn child<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<NodeId> {
unsafe_tsk_column_access!(
row.into().0,
0,
self.num_rows(),
self.as_ref(),
child,
NodeId
)
}

/// Return the ``left`` value from row ``row`` of the table.
Expand All @@ -115,12 +134,12 @@ impl<'a> EdgeTable<'a> {
///
/// * `Some(position)` if `u` is valid.
/// * `None` otherwise.
pub fn left<E: Into<EdgeId> + Copy>(&'a self, row: E) -> Option<Position> {
pub fn left<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<Position> {
unsafe_tsk_column_access!(
row.into().0,
0,
self.num_rows(),
self.table_,
self.as_ref(),
left,
Position
)
Expand All @@ -132,8 +151,14 @@ impl<'a> EdgeTable<'a> {
///
/// * `Some(position)` if `u` is valid.
/// * `None` otherwise.
pub fn right<E: Into<EdgeId> + Copy>(&'a self, row: E) -> Option<Position> {
unsafe_tsk_column_access_and_map_into!(row.into().0, 0, self.num_rows(), self.table_, right)
pub fn right<E: Into<EdgeId> + Copy>(&self, row: E) -> Option<Position> {
unsafe_tsk_column_access_and_map_into!(
row.into().0,
0,
self.num_rows(),
self.as_ref(),
right
)
}

/// Retrieve decoded metadata for a `row`.
Expand All @@ -153,10 +178,10 @@ impl<'a> EdgeTable<'a> {
/// The big-picture semantics are the same for all table types.
/// See [`crate::IndividualTable::metadata`] for examples.
pub fn metadata<T: metadata::EdgeMetadata>(
&'a self,
&self,
row: EdgeId,
) -> Option<Result<T, TskitError>> {
let table_ref = self.table_;
let table_ref = self.as_ref();
let buffer = metadata_to_vector!(self, table_ref, row.0)?;
Some(decode_metadata_row!(T, buffer).map_err(|e| e.into()))
}
Expand All @@ -165,7 +190,7 @@ impl<'a> EdgeTable<'a> {
/// The value of the iterator is [`EdgeTableRow`].
///
pub fn iter(&self) -> impl Iterator<Item = EdgeTableRow> + '_ {
crate::table_iterator::make_table_iterator::<&EdgeTable<'a>>(self)
crate::table_iterator::make_table_iterator::<&EdgeTable>(self)
}

/// Return row `r` of the table.
Expand Down
69 changes: 42 additions & 27 deletions src/individual_table.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ptr::NonNull;

use crate::bindings as ll_bindings;
use crate::metadata;
use crate::IndividualFlags;
Expand Down Expand Up @@ -45,15 +47,15 @@ impl PartialEq for IndividualTableRow {

/// An immutable view of a individual table.
///
/// 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,
/// These are not created directly but are accessed
/// by types implementing [`std::ops::Deref`] to
/// [`crate::table_views::TableViews`]
pub struct IndividualTable {
table_: NonNull<ll_bindings::tsk_individual_table_t>,
}

fn make_individual_table_row(table: &IndividualTable, pos: tsk_id_t) -> Option<IndividualTableRow> {
let table_ref = table.table_;
let table_ref = table.as_ref();
Some(IndividualTableRow {
id: pos.into(),
flags: table.flags(pos)?,
Expand All @@ -64,9 +66,8 @@ fn make_individual_table_row(table: &IndividualTable, pos: tsk_id_t) -> Option<I
}

pub(crate) type IndividualTableRefIterator<'a> =
crate::table_iterator::TableIterator<&'a IndividualTable<'a>>;
pub(crate) type IndividualTableIterator<'a> =
crate::table_iterator::TableIterator<IndividualTable<'a>>;
crate::table_iterator::TableIterator<&'a IndividualTable>;
pub(crate) type IndividualTableIterator = crate::table_iterator::TableIterator<IndividualTable>;

impl<'a> Iterator for IndividualTableRefIterator<'a> {
type Item = IndividualTableRow;
Expand All @@ -78,7 +79,7 @@ impl<'a> Iterator for IndividualTableRefIterator<'a> {
}
}

impl<'a> Iterator for IndividualTableIterator<'a> {
impl Iterator for IndividualTableIterator {
type Item = IndividualTableRow;

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -88,16 +89,24 @@ 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 {
IndividualTable {
table_: individuals,
}
impl IndividualTable {
pub(crate) fn new_from_table(
individuals: *mut ll_bindings::tsk_individual_table_t,
) -> Result<Self, TskitError> {
let n = NonNull::new(individuals).ok_or_else(|| {
TskitError::LibraryError("null pointer to tsk_individual_table_t".to_string())
})?;
Ok(IndividualTable { table_: n })
}

pub(crate) fn as_ref(&self) -> &ll_bindings::tsk_individual_table_t {
// SAFETY: NonNull
unsafe { self.table_.as_ref() }
}

/// 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_ref().num_rows.into()
}

/// Return the flags for a given row.
Expand All @@ -107,7 +116,13 @@ impl<'a> IndividualTable<'a> {
/// * `Some(flags)` if `row` is valid.
/// * `None` otherwise.
pub fn flags<I: Into<IndividualId> + Copy>(&self, row: I) -> Option<IndividualFlags> {
unsafe_tsk_column_access_and_map_into!(row.into().0, 0, self.num_rows(), self.table_, flags)
unsafe_tsk_column_access_and_map_into!(
row.into().0,
0,
self.num_rows(),
self.as_ref(),
flags
)
}

/// Return the locations for a given row.
Expand All @@ -121,7 +136,7 @@ impl<'a> IndividualTable<'a> {
row.into().0,
0,
self.num_rows(),
self.table_,
self.as_ref(),
location,
location_offset,
location_length,
Expand All @@ -140,7 +155,7 @@ impl<'a> IndividualTable<'a> {
row.into().0,
0,
self.num_rows(),
self.table_,
self.as_ref(),
parents,
parents_offset,
parents_length,
Expand Down Expand Up @@ -179,7 +194,7 @@ impl<'a> IndividualTable<'a> {
///
/// ```
/// # #[cfg(feature = "derive")] {
/// # use tskit::TableAccess;
/// #
/// # let mut tables = tskit::TableCollection::new(100.).unwrap();
/// # #[derive(serde::Serialize, serde::Deserialize, tskit::metadata::IndividualMetadata)]
/// # #[serializer("serde_json")]
Expand All @@ -202,7 +217,7 @@ impl<'a> IndividualTable<'a> {
///
/// ```
/// # #[cfg(feature = "derive")] {
/// # use tskit::TableAccess;
/// #
/// # let mut tables = tskit::TableCollection::new(100.).unwrap();
/// # #[derive(serde::Serialize, serde::Deserialize, tskit::metadata::IndividualMetadata)]
/// # #[serializer("serde_json")]
Expand Down Expand Up @@ -248,7 +263,7 @@ impl<'a> IndividualTable<'a> {
# struct MutationMetadata {
# x: i32,
# }
# use tskit::TableAccess;
#
# let mut tables = tskit::TableCollection::new(10.).unwrap();
match tables.individuals().metadata::<MutationMetadata>(0.into())
{
Expand Down Expand Up @@ -280,7 +295,7 @@ match tables.individuals().metadata::<MutationMetadata>(0.into())
///
/// ```
/// # #[cfg(feature = "derive")] {
/// # use tskit::TableAccess;
/// #
/// # #[derive(serde::Serialize, serde::Deserialize, tskit::metadata::IndividualMetadata)]
/// # #[serializer("serde_json")]
/// # struct IndividualMetadata {
Expand Down Expand Up @@ -319,10 +334,10 @@ match tables.individuals().metadata::<MutationMetadata>(0.into())
/// types](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types) to enforce at *compile time* that exactly one type (`struct/enum`, etc.) is a valid
/// metadata type for a table.
pub fn metadata<T: metadata::IndividualMetadata>(
&'a self,
&self,
row: IndividualId,
) -> Option<Result<T, TskitError>> {
let table_ref = self.table_;
let table_ref = self.as_ref();
let buffer = metadata_to_vector!(self, table_ref, row.0)?;
Some(decode_metadata_row!(T, buffer).map_err(|e| e.into()))
}
Expand All @@ -331,7 +346,7 @@ match tables.individuals().metadata::<MutationMetadata>(0.into())
/// The value of the iterator is [`IndividualTableRow`].
///
pub fn iter(&self) -> impl Iterator<Item = IndividualTableRow> + '_ {
crate::table_iterator::make_table_iterator::<&IndividualTable<'a>>(self)
crate::table_iterator::make_table_iterator::<&IndividualTable>(self)
}

/// Return row `r` of the table.
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ pub mod prelude;
mod site_table;
mod table_collection;
mod table_iterator;
pub mod table_views;
mod traits;
mod tree_interface;
mod trees;
Expand Down Expand Up @@ -438,8 +439,6 @@ pub use site_table::{OwnedSiteTable, SiteTable, SiteTableRow};
pub use table_collection::TableCollection;
pub use traits::IndividualLocation;
pub use traits::IndividualParents;
pub use traits::NodeListGenerator;
pub use traits::TableAccess;
pub use traits::TskitTypeAccess;
pub use tree_interface::{NodeTraversalOrder, TreeInterface};
pub use trees::{Tree, TreeSequence};
Expand Down
6 changes: 3 additions & 3 deletions src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//! ```
//! # #[cfg(feature = "derive")] {
//! use tskit::handle_metadata_return;
//! use tskit::TableAccess;
//!
//!
//! #[derive(serde::Serialize, serde::Deserialize, tskit::metadata::MutationMetadata)]
//! #[serializer("serde_json")]
Expand Down Expand Up @@ -75,7 +75,7 @@
//!
//! ```
//! # #[cfg(feature = "derive")] {
//! use tskit::TableAccess;
//!
//! #[derive(serde::Serialize, serde::Deserialize, PartialEq, PartialOrd)]
//! struct GeneticValue(f64);
//!
Expand All @@ -101,7 +101,7 @@
//! For fun, we'll use the Python [`pickle`](https://docs.rs/crate/serde-pickle/) format.
//!
//! ```
//! use tskit::TableAccess;
//!
//!
//! #[derive(serde::Serialize, serde::Deserialize)]
//! struct Metadata {
Expand Down
Loading