Skip to content

Commit be92c74

Browse files
committed
refactor: Add macros to implement owned tables.
1 parent 3f3e847 commit be92c74

File tree

3 files changed

+59
-67
lines changed

3 files changed

+59
-67
lines changed

src/_macros.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,49 @@ macro_rules! handle_metadata_return {
533533
};
534534
}
535535

536+
macro_rules! build_owned_tables {
537+
($name: ty, $deref: ident, $llname: ty, $init: ident, $free: ident) => {
538+
impl $name {
539+
fn new() -> Self {
540+
let temp = unsafe { libc::malloc(std::mem::size_of::<$llname>()) as *mut $llname };
541+
let nonnull = match std::ptr::NonNull::<$llname>::new(temp) {
542+
Some(x) => x,
543+
None => panic!("out of memory"),
544+
};
545+
let mut table = unsafe { mbox::MBox::from_non_null_raw(nonnull) };
546+
let rv = unsafe { $init(&mut (*table), 0) };
547+
assert_eq!(rv, 0);
548+
Self { table }
549+
}
550+
}
551+
552+
impl Default for $name {
553+
fn default() -> Self {
554+
Self::new()
555+
}
556+
}
557+
558+
impl std::ops::Deref for $name {
559+
type Target = $deref<'static>;
560+
561+
fn deref(&self) -> &Self::Target {
562+
// SAFETY: that T* and &T have same layout,
563+
// and Target is repr(transparent).
564+
unsafe { std::mem::transmute(&self.table) }
565+
}
566+
}
567+
568+
impl Drop for $name {
569+
fn drop(&mut self) {
570+
let rv = unsafe { $free(&mut (*self.table)) };
571+
if rv != 0 {
572+
panic!("error when calling {}: {}", stringify!(free), rv);
573+
}
574+
}
575+
}
576+
};
577+
}
578+
536579
#[cfg(test)]
537580
mod test {
538581
use crate::error::TskitError;

src/edge_table.rs

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::metadata;
33
use crate::Position;
44
use crate::{tsk_id_t, TskitError};
55
use crate::{EdgeId, NodeId};
6+
use ll_bindings::{tsk_edge_table_free, tsk_edge_table_init};
67

78
/// Row of an [`EdgeTable`]
89
pub struct EdgeTableRow {
@@ -217,21 +218,6 @@ pub struct OwnedEdgeTable {
217218
}
218219

219220
impl OwnedEdgeTable {
220-
fn new() -> Self {
221-
let temp = unsafe {
222-
libc::malloc(std::mem::size_of::<ll_bindings::tsk_edge_table_t>())
223-
as *mut ll_bindings::tsk_edge_table_t
224-
};
225-
let nonnull = match std::ptr::NonNull::<ll_bindings::tsk_edge_table_t>::new(temp) {
226-
Some(x) => x,
227-
None => panic!("out of memory"),
228-
};
229-
let mut table = unsafe { mbox::MBox::from_non_null_raw(nonnull) };
230-
let rv = unsafe { ll_bindings::tsk_edge_table_init(&mut (*table), 0) };
231-
assert_eq!(rv, 0);
232-
Self { table }
233-
}
234-
235221
pub fn add_row(
236222
&mut self,
237223
left: impl Into<Position>,
@@ -279,27 +265,10 @@ impl OwnedEdgeTable {
279265
}
280266
}
281267

282-
impl std::ops::Deref for OwnedEdgeTable {
283-
type Target = EdgeTable<'static>;
284-
285-
fn deref(&self) -> &Self::Target {
286-
// SAFETY: that T* and &T have same layout,
287-
// and Target is repr(transparent).
288-
unsafe { std::mem::transmute(&self.table) }
289-
}
290-
}
291-
292-
impl Default for OwnedEdgeTable {
293-
fn default() -> Self {
294-
Self::new()
295-
}
296-
}
297-
298-
impl Drop for OwnedEdgeTable {
299-
fn drop(&mut self) {
300-
let rv = unsafe { ll_bindings::tsk_edge_table_free(&mut (*self.table)) };
301-
if rv != 0 {
302-
panic!("error when calling tsk_edge_table_free: {}", rv);
303-
}
304-
}
305-
}
268+
build_owned_tables!(
269+
OwnedEdgeTable,
270+
EdgeTable,
271+
ll_bindings::tsk_edge_table_t,
272+
tsk_edge_table_init,
273+
tsk_edge_table_free
274+
);

src/population_table.rs

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::tsk_id_t;
44
use crate::PopulationId;
55
use crate::SizeType;
66
use crate::TskitError;
7+
use ll_bindings::{tsk_population_table_free, tsk_population_table_init};
78

89
/// Row of a [`PopulationTable`]
910
#[derive(Eq)]
@@ -164,19 +165,6 @@ pub struct OwnedPopulationTable {
164165
}
165166

166167
impl OwnedPopulationTable {
167-
fn new() -> Self {
168-
let temp = unsafe {
169-
libc::malloc(std::mem::size_of::<ll_bindings::tsk_population_table_t>())
170-
as *mut ll_bindings::tsk_population_table_t
171-
};
172-
let nonnull = match std::ptr::NonNull::<ll_bindings::tsk_population_table_t>::new(temp) {
173-
Some(x) => x,
174-
None => panic!("out of memory"),
175-
};
176-
let table = unsafe { mbox::MBox::from_non_null_raw(nonnull) };
177-
Self { table }
178-
}
179-
180168
pub fn add_row(&mut self) -> Result<PopulationId, TskitError> {
181169
let rv = unsafe {
182170
ll_bindings::tsk_population_table_add_row(&mut (*self.table), std::ptr::null(), 0)
@@ -202,18 +190,10 @@ impl OwnedPopulationTable {
202190
}
203191
}
204192

205-
impl std::ops::Deref for OwnedPopulationTable {
206-
type Target = PopulationTable<'static>;
207-
208-
fn deref(&self) -> &Self::Target {
209-
// SAFETY: that T* and &T have same layout,
210-
// and Target is repr(transparent).
211-
unsafe { std::mem::transmute(&self.table) }
212-
}
213-
}
214-
215-
impl Default for OwnedPopulationTable {
216-
fn default() -> Self {
217-
Self::new()
218-
}
219-
}
193+
build_owned_tables!(
194+
OwnedPopulationTable,
195+
PopulationTable,
196+
ll_bindings::tsk_population_table_t,
197+
tsk_population_table_init,
198+
tsk_population_table_free
199+
);

0 commit comments

Comments
 (0)