-
Notifications
You must be signed in to change notification settings - Fork 5
Allow for standalone tables #262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
After a bit of hacking:
|
It is looking like this requires some significant
|
See comments over in #265 re: a plan of action. |
#265 has a working pattern now. There is no need for a new type abstracting out "do we own the pointer or not". There are, however, several side effects that affect the back end:
Yay, progress. |
Here are some further design options: // START OF PRELUDE
use std::ops::Deref;
use std::ptr::NonNull;
mod ll_bindings {
pub struct tsk_edge_table_t {}
pub struct tsk_table_collection_t {
pub edges: tsk_edge_table_t,
}
}
type MBox<T> = Box<T>;
struct TableCollection {
inner: MBox<ll_bindings::tsk_table_collection_t>,
}
struct EdgeTable<'a> {
table_: &'a ll_bindings::tsk_edge_table_t,
}
trait TableAccess {
fn edges(&self) -> EdgeTable;
}
impl TableAccess for TableCollection {
fn edges(&self) -> EdgeTable {
EdgeTable::new_from_table(&(*self.inner).edges)
}
}
impl<'a> EdgeTable<'a> {
fn new_from_table(edges: &'a ll_bindings::tsk_edge_table_t) -> Self {
EdgeTable { table_: edges }
}
}
// END OF PRELUDE
// Option 1
struct OwnedEdgeTableV1 {
edges: MBox<ll_bindings::tsk_edge_table_t>,
}
impl OwnedEdgeTableV1 {
pub fn borrow(&self) -> EdgeTable<'_> { // returns EdgeTableV2<'a>
EdgeTable::new_from_table(&self.edges)
}
}
// Option 2
struct OwnedEdgeTableV2 {
edges: MBox<ll_bindings::tsk_edge_table_t>,
}
#[repr(transparent)] // needed so the transmute on the newtype is safe
struct EdgeTableV2<'a> {
table_: &'a ll_bindings::tsk_edge_table_t,
}
impl Deref for OwnedEdgeTableV2 {
type Target = EdgeTableV2<'static>;
fn deref(&self) -> &Self::Target { // returns &'a EdgeTableV2<'static>
unsafe { std::mem::transmute(&self.edges) }
}
}
// Option 3
#[repr(transparent)]
struct EdgeTableV3 {
table_: NonNull<ll_bindings::tsk_edge_table_t>,
}
impl EdgeTableV3 {
// this would be just for convenience to hide the unsafe
/* private*/ fn as_ref(&self) -> &ll_bindings::tsk_edge_table_t {
// Safety: only constructed with ref
unsafe { self.table_.as_ref() }
}
pub(crate) fn ref_from_ref<'a>(edges: &'a ll_bindings::tsk_edge_table_t) -> &'a Self {
// Safety: NonNull<T> has the layout of *mut T,
// matching the layout of *const T,
// matching the layout of &T
unsafe { std::mem::transmute(edges) }
}
}
struct OwnedEdgeTableV3 {
edges: MBox<ll_bindings::tsk_edge_table_t>,
}
impl Deref for OwnedEdgeTableV3 {
type Target = EdgeTableV3;
fn deref(&self) -> &Self::Target { // returns &'_ EdgeTableV3
EdgeTableV3::ref_from_ref(&self.edges)
}
}
trait TableAccessV3 {
fn edges(&self) -> &EdgeTableV3;
}
impl TableAccessV3 for TableCollection {
fn edges(&self) -> &EdgeTableV3 { // returns &'_ EdgeTableV3
EdgeTableV3::ref_from_ref(&(*self.inner).edges)
}
} |
thanks @MomoLangenstein ! |
The pattern 2 from @momolangenstein is implemented in #267. |
We currently only define table types as immutable
views of data owned by table collections/tree sequences.
To support standalone tables:
OwningXTable
for row typeX
.impl std::ops::Deref
for each new type.The deref target is
XTable
.add_row
andadd_row_with_metadata
.copy
function.Thanks to @momolangenstein for suggesting the
Deref
pattern.The text was updated successfully, but these errors were encountered: