Skip to content

Commit

Permalink
Use R_altrep_inherits() (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
yutannihilation committed May 2, 2024
1 parent e8201f2 commit 9dcdfc4
Show file tree
Hide file tree
Showing 4 changed files with 672 additions and 10 deletions.
1 change: 1 addition & 0 deletions savvy-ffi/src/altrep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern "C" {

pub fn ALTREP(x: SEXP) -> c_int;
pub fn ALTREP_CLASS(x: SEXP) -> SEXP;
pub fn R_altrep_inherits(x: SEXP, arg1: R_altrep_class_t) -> Rboolean;
pub fn R_new_altrep(aclass: R_altrep_class_t, data1: SEXP, data2: SEXP) -> SEXP;
pub fn R_altrep_data1(x: SEXP) -> SEXP;
pub fn R_altrep_data2(x: SEXP) -> SEXP;
Expand Down
18 changes: 8 additions & 10 deletions src/altrep/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ use std::{collections::HashMap, sync::Mutex};

use once_cell::sync::OnceCell;
use savvy_ffi::{
altrep::{
R_altrep_class_t, R_altrep_data1, R_new_altrep, ALTREP, ALTREP_CLASS, MARK_NOT_MUTABLE,
},
R_NilValue, SEXP,
altrep::{R_altrep_class_t, R_altrep_data1, R_altrep_inherits, R_new_altrep, MARK_NOT_MUTABLE},
R_NilValue, Rboolean_TRUE, SEXP,
};

use crate::{protect::local_protect, IntoExtPtrSexp};
Expand Down Expand Up @@ -103,10 +101,6 @@ pub(crate) fn extract_from_altrep<T>(x: SEXP) -> crate::Result<T> {
/// the class name.
#[inline]
pub(crate) fn assert_altrep_class(x: SEXP, class_name: &'static str) -> crate::error::Result<()> {
if unsafe { ALTREP(x) != 1 } {
return Err("Not an ALTREP".into());
}

let catalogue_mutex = ALTREP_CLASS_CATALOGUE.get().ok_or(crate::Error::new(
"ALTREP_CLASS_CATALOGUE is not initialized",
))?;
Expand All @@ -117,9 +111,13 @@ pub(crate) fn assert_altrep_class(x: SEXP, class_name: &'static str) -> crate::e
.get(class_name)
.ok_or(crate::Error::new("Failed to get the ALTREP class"))?;

if class.ptr == unsafe { ALTREP_CLASS(x) } {
if unsafe { R_altrep_inherits(x, *class) == Rboolean_TRUE } {
Ok(())
} else {
Err("Different ALTREP class".into())
Err(format!(
"Not an object of the specified ALTREP class ({})",
class_name
)
.into())
}
}
Loading

0 comments on commit 9dcdfc4

Please sign in to comment.