Skip to content

Commit

Permalink
Allow creation of Vector<BoxedRef<_>> instances and using them as ToI…
Browse files Browse the repository at this point in the history
…nputArray
  • Loading branch information
twistedfall committed Apr 15, 2024
1 parent d718187 commit 4ececc8
Show file tree
Hide file tree
Showing 23 changed files with 698 additions and 64 deletions.
17 changes: 9 additions & 8 deletions binding-generator/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,6 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
}
}

pub fn is_trait(&self) -> bool {
self.kind().is_boxed()
// self.is_abstract() || self.has_descendants() || settings::FORCE_CLASS_TRAIT.contains(self.cpp_name(CppNameStyle::Reference).as_ref())
}

/// Special case of an empty class with only an anonymous enum inside (e.g. DrawLinesMatchesFlags)
pub fn as_enum(&self) -> Option<Enum<'tu>> {
match self {
Expand Down Expand Up @@ -429,7 +424,7 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
&& !fld_type_kind.is_char_ptr_string(fld_type_ref.type_hint())
{
fld_type_ref.set_type_hint(TypeRefTypeHint::PrimitivePtrAsRaw);
} else if fld_type_kind.as_class().map_or(false, |cls| cls.is_trait()) {
} else if fld_type_kind.as_class().map_or(false, |cls| cls.kind().is_trait()) {
fld_type_ref.set_type_hint(TypeRefTypeHint::TraitClassConcrete);
}
let fld_type_kind = fld_type_ref.kind();
Expand Down Expand Up @@ -718,7 +713,7 @@ impl fmt::Debug for Class<'_, '_> {
if self.is_polymorphic() {
props.push("polymorphic");
}
if self.is_trait() {
if self.kind().is_trait() {
props.push("trait");
}
if self.as_enum().is_some() {
Expand Down Expand Up @@ -800,7 +795,13 @@ impl ClassKind {

pub fn is_boxed(self) -> bool {
match self {
// fixme: Self::System to return true is kind of hack to make sure that system classes are passed by void*, probably better to handle in explicitly in CppPassByVoidPtrRenderLane
Self::Boxed | Self::BoxedForced => true,
Self::Simple | Self::Other | Self::System => false,
}
}

pub fn is_trait(&self) -> bool {
match self {
Self::Boxed | Self::BoxedForced | Self::System => true,
Self::Simple | Self::Other => false,
}
Expand Down
9 changes: 8 additions & 1 deletion binding-generator/src/class/desc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ impl<'tu, 'ge> ClassDesc<'tu, 'ge> {
}
}

pub fn system(cpp_refname: impl Into<Rc<str>>, rust_module: impl Into<Rc<str>>) -> Self {
Self {
kind: ClassKind::System,
..Self::boxed(cpp_refname, rust_module)
}
}

/// `cv::Scalar`
pub fn cv_scalar() -> Class<'tu, 'ge> {
Class::new_desc(Self::simple("cv::Scalar", "core"))
Expand Down Expand Up @@ -104,7 +111,7 @@ impl<'tu, 'ge> ClassDesc<'tu, 'ge> {

/// `cv::String`
pub fn cv_string() -> Class<'tu, 'ge> {
Class::new_desc(Self::boxed("cv::String", "core"))
Class::new_desc(Self::system("cv::String", "core"))
}

/// `cv::MatConstIterator`
Expand Down
6 changes: 1 addition & 5 deletions binding-generator/src/type_ref/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<'tu, 'ge> TypeRefKind<'tu, 'ge> {
match self {
TypeRefKind::Typedef(tdef) => tdef.underlying_type_ref().kind().extern_pass_kind(),
TypeRefKind::Class(inner) if !inner.string_type().is_some() => {
if inner.kind().is_boxed() {
if inner.kind().is_trait() {
ExternPassKind::ByVoidPtr
} else {
ExternPassKind::ByPtr
Expand Down Expand Up @@ -212,10 +212,6 @@ impl<'tu, 'ge> TypeRefKind<'tu, 'ge> {
}
}

pub fn as_simple_class(&self) -> Option<Cow<Class<'tu, 'ge>>> {
self.as_class().filter(|cls| cls.kind().is_simple())
}

pub fn as_vector(&self) -> Option<Cow<Vector<'tu, 'ge>>> {
match self {
TypeRefKind::StdVector(out) => Some(Borrowed(out)),
Expand Down
4 changes: 2 additions & 2 deletions binding-generator/src/writer/rust_native/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ fn gen_rust_class(c: &Class, opencv_version: &str) -> String {
static TRAIT_TPL: Lazy<CompiledInterpolation> = Lazy::new(|| include_str!("tpl/class/trait.tpl.rs").compile_interpolation());

let type_ref = c.type_ref();
let is_trait = c.is_trait();
let class_kind = c.kind();
let is_trait = class_kind.is_trait();
let doc_comment = c.rendered_doc_comment("///", opencv_version);

let mut out = String::new();
Expand Down Expand Up @@ -577,7 +577,7 @@ pub trait ClassExt {
impl ClassExt for Class<'_, '_> {
fn rust_trait_name(&self, style: NameStyle, constness: Constness) -> Cow<str> {
let mut out = self.rust_name(style);
if self.is_trait() {
if self.kind().is_trait() {
if constness.is_const() {
out.to_mut().push_str("TraitConst");
} else {
Expand Down
2 changes: 1 addition & 1 deletion binding-generator/src/writer/rust_native/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ impl RustNativeGeneratedElement for Func<'_, '_> {

let doc_comment = self.rendered_doc_comment("///", _opencv_version);
let visibility = if let Some(cls) = as_instance_method {
if cls.is_trait() {
if cls.kind().is_trait() {
""
} else {
"pub "
Expand Down
2 changes: 1 addition & 1 deletion binding-generator/src/writer/rust_native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl GeneratorVisitor for RustNativeBindingWriter<'_> {

fn visit_class(&mut self, class: Class) {
self.emit_debug_log(&class);
if class.is_trait() {
if class.kind().is_trait() {
self.prelude_traits.push(format!(
"super::{}",
class.rust_trait_name(NameStyle::decl(), Constness::Const).into_owned()
Expand Down
6 changes: 3 additions & 3 deletions binding-generator/src/writer/rust_native/smart_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl RustNativeGeneratedElement for SmartPtr<'_, '_> {
]);

let mut impls = String::new();
if let Some(cls) = pointee_kind.as_class().filter(|cls| cls.is_trait()) {
if let Some(cls) = pointee_kind.as_class().filter(|cls| cls.kind().is_trait()) {
inter_vars.extend([
("base_rust_as_raw_const", cls.rust_as_raw_name(Constness::Const).into()),
("base_rust_as_raw_mut", cls.rust_as_raw_name(Constness::Mut).into()),
Expand Down Expand Up @@ -195,7 +195,7 @@ fn extern_functions<'tu, 'ge>(ptr: &SmartPtr<'tu, 'ge>) -> Vec<Func<'tu, 'ge>> {
pointee_type.with_inherent_constness(Constness::Mut),
));
out.push(FuncDesc::method_delete(smartptr_class.clone()));
if let Some(cls) = pointee_kind.as_class().filter(|cls| cls.is_trait()) {
if let Some(cls) = pointee_kind.as_class().filter(|cls| cls.kind().is_trait()) {
for base in all_bases(&cls) {
out.push(method_cast_to_base(
smartptr_class.clone(),
Expand Down Expand Up @@ -266,7 +266,7 @@ fn method_new<'tu, 'ge>(
) -> Func<'tu, 'ge> {
let pointee_kind = pointee_type.kind();
let val = if pointee_kind.is_copy(pointee_type.type_hint()) {
if pointee_kind.as_simple_class().is_some() {
if pointee_kind.as_class().map_or(false, |cls| cls.kind().is_simple()) {
panic!("Ptr with simple class is not supported");
} else {
format!("new {typ}(val)", typ = pointee_type.cpp_name(CppNameStyle::Reference)).into()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

vector_boxed_ref! { {{inner_rust_full}} }

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

vector_copy_non_bool! { {{inner_rust_full}},
{{extern_data}}, {{extern_data_mut}}, {{extern_from_slice}},
{{extern_clone}},
}


Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ vector_extern! { {{inner_rust_full}},
{{extern_push}}, {{extern_insert}},
}


Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@


impl ToInputArray for {{rust_full}} {
{{input_array_impl}}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

vector_non_copy_or_bool! { {{clone}}{{inner_rust_full}} }


23 changes: 8 additions & 15 deletions binding-generator/src/writer/rust_native/type_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::borrow::Cow::{Borrowed, Owned};
pub use lifetime::{Lifetime, LifetimeIterator};
pub use nullability::NullabilityExt;

use crate::class::ClassKind;
use crate::renderer::TypeRefRenderer;
use crate::type_ref::{
Constness, Dir, ExternDir, FishStyle, InputOutputArrayKind, NameStyle, TypeRef, TypeRefKind, TypeRefTypeHint,
Expand Down Expand Up @@ -101,26 +100,20 @@ impl TypeRefExt for TypeRef<'_, '_> {
};
match tref_kind.canonical().into_owned() {
TypeRefKind::Class(cls) => {
if cls.is_trait() {
let cls_kind = cls.kind();
if cls_kind.is_simple() {
RenderLane::SimpleClass(SimpleClassRenderLane::from_non_canonical_indirection(
tref.into_owned(),
indirection,
))
} else if cls_kind.is_trait() {
RenderLane::TraitClass(TraitClassRenderLane::from_non_canonical_class_indirection(
self.clone(),
cls,
indirection,
))
} else {
let cls_kind = cls.kind();
match cls_kind {
ClassKind::Simple => RenderLane::SimpleClass(SimpleClassRenderLane::from_non_canonical_indirection(
tref.into_owned(),
indirection,
)),
ClassKind::Boxed | ClassKind::BoxedForced | ClassKind::System => {
RenderLane::CppPassByVoidPtr(CppPassByVoidPtrRenderLane::from_non_canonical(tref.into_owned()))
}
ClassKind::Other => {
unreachable!("Any other kind of class shouldn't be generated")
}
}
unreachable!("Any other kind of class shouldn't be generated")
}
}
TypeRefKind::Enum(enm) => RenderLane::Enum(EnumRenderLane::from_non_canonical_enum_indirection(
Expand Down
23 changes: 19 additions & 4 deletions binding-generator/src/writer/rust_native/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@ impl RustNativeGeneratedElement for Vector<'_, '_> {
static EXTERN_TPL: Lazy<CompiledInterpolation> =
Lazy::new(|| include_str!("tpl/vector/rust_extern.tpl.rs").compile_interpolation());

static ADD_COPY_NON_BOOL_TPL: Lazy<CompiledInterpolation> =
static COPY_NON_BOOL_TPL: Lazy<CompiledInterpolation> =
Lazy::new(|| include_str!("tpl/vector/rust_copy_non_bool.tpl.rs").compile_interpolation());

static ADD_NON_COPY_OR_BOOL_TPL: Lazy<CompiledInterpolation> =
static NON_COPY_OR_BOOL_TPL: Lazy<CompiledInterpolation> =
Lazy::new(|| include_str!("tpl/vector/rust_non_copy_or_bool.tpl.rs").compile_interpolation());

static BOXED_REF_TPL: Lazy<CompiledInterpolation> =
Lazy::new(|| include_str!("tpl/vector/rust_boxed_ref.tpl.rs").compile_interpolation());

static INPUT_ARRAY_TPL: Lazy<CompiledInterpolation> =
Lazy::new(|| include_str!("tpl/vector/rust_input_array.tpl.rs").compile_interpolation());

Expand Down Expand Up @@ -148,7 +151,7 @@ impl RustNativeGeneratedElement for Vector<'_, '_> {
("extern_data_mut", extern_data_mut.into()),
("extern_from_slice", extern_from_slice.into()),
]);
impls += &ADD_COPY_NON_BOOL_TPL.interpolate(&inter_vars);
impls += &COPY_NON_BOOL_TPL.interpolate(&inter_vars);
} else {
inter_vars.insert(
"clone",
Expand All @@ -159,7 +162,7 @@ impl RustNativeGeneratedElement for Vector<'_, '_> {
}
.into(),
);
impls += &ADD_NON_COPY_OR_BOOL_TPL.interpolate(&inter_vars);
impls += &NON_COPY_OR_BOOL_TPL.interpolate(&inter_vars);
}
if element_type.is_element_data_type() || element_is_bool {
let input_array = method_input_array(vector_class.clone()).gen_rust(opencv_version);
Expand All @@ -175,6 +178,18 @@ impl RustNativeGeneratedElement for Vector<'_, '_> {
impls += &OUTPUT_ARRAY_TPL.interpolate(&inter_vars);
}
}
if element_kind.as_class().map_or(false, |cls| cls.kind().is_boxed()) {
impls += &BOXED_REF_TPL.interpolate(&inter_vars);
inter_vars.insert(
"inner_rust_full",
format!("BoxedRef<'_, {}>", inter_vars["inner_rust_full"]).into(),
);
impls += &EXTERN_TPL.interpolate(&inter_vars);
if element_type.is_element_data_type() {
inter_vars.insert("rust_full", format!("BoxedRef<'_, {}>", rust_localalias).into());
impls += &INPUT_ARRAY_TPL.interpolate(&inter_vars);
}
}
}
}
inter_vars.insert("impls", impls.into());
Expand Down

0 comments on commit 4ececc8

Please sign in to comment.