Add support for function call operator
MODIFY
binding-generator/src/func.rs
binding-generator/src/func.rs
@@ -21,6 +21,7 @@ pub enum OperatorKind {
Mul,
Div,
Deref,
+ Apply,
Equals,
NotEquals,
GreaterThan,
@@ -48,6 +49,7 @@ impl OperatorKind {
OperatorKind::Mul
}
}
+ "()" => OperatorKind::Apply,
"/" => OperatorKind::Div,
"==" => OperatorKind::Equals,
"!=" => OperatorKind::NotEquals,
@@ -67,7 +69,7 @@ impl OperatorKind {
pub fn add_args_to_name(&self) -> bool {
match self {
- OperatorKind::Index | OperatorKind::BitwiseNot => false,
+ OperatorKind::Index | OperatorKind::BitwiseNot | OperatorKind::Apply => false,
OperatorKind::Unsupported
| OperatorKind::Add
| OperatorKind::Sub

MODIFY
binding-generator/src/generator.rs
binding-generator/src/generator.rs
@@ -62,8 +62,7 @@ impl<'m> EphemeralGenerator<'m> {
}
fn add_used_in_smart_ptr(&mut self, func: Entity) {
- for arg in func.get_arguments().into_iter().flatten() {
- if let Some(arg_type) = arg.get_type() {
+ for arg_type in func.get_arguments().iter().flatten().map(Entity::get_type).flatten() {
if arg_type
.get_declaration()
.map_or(false, |ent| ent.cpp_name(CppNameStyle::Reference).starts_with("cv::Ptr"))
@@ -83,7 +82,6 @@ impl<'m> EphemeralGenerator<'m> {
}
}
}
- }
pub fn generate_header(&self) -> String {
static TPL: Lazy<CompiledInterpolation> =
@@ -110,8 +108,25 @@ impl<'m> EphemeralGenerator<'m> {
}
let mut used_in_smart_ptr = self.used_in_smart_ptr.iter().collect::<Vec<_>>();
used_in_smart_ptr.sort_unstable();
+
+ fn all_descendants<'d>(descendants: &'d HashMap<String, HashSet<String>>, class: &str) -> HashSet<&'d String> {
+ descendants
+ .get(class)
+ .map(|d| d.iter().collect::<Vec<_>>())
+ .into_iter()
+ .flatten()
+ .flat_map(|descendant| {
+ let mut out = all_descendants(descendants, descendant);
+ out.insert(descendant);
+ out
+ })
+ .collect()
+ }
+
for used_cppfull in used_in_smart_ptr {
- let mut descendants = self.descendants.get(used_cppfull).into_iter().flatten().collect::<Vec<_>>();
+ let mut descendants = all_descendants(&self.descendants, used_cppfull)
+ .into_iter()
+ .collect::<Vec<_>>();
descendants.sort_unstable();
for desc_cppfull in descendants {
if !self.used_in_smart_ptr.contains(desc_cppfull) {

MODIFY
binding-generator/src/settings.rs
binding-generator/src/settings.rs
@@ -650,6 +650,8 @@ pub static ELEMENT_EXPORT_TWEAK: Lazy<HashMap<&str, fn(&mut ExportConfig)>> = La
"cv::GKinds" => ExportConfig::make_export as _,
"cv::GRunArgs" => ExportConfig::make_export as _,
"cv::GShapes" => ExportConfig::make_export as _,
+ "cv::GTypeInfo" => ExportConfig::make_export as _,
+ "cv::GTypesInfo" => ExportConfig::make_export as _,
"cv::RMat::IAdapter" => ExportConfig::make_export as _,
"cv::detail::ExtractArgsCallback" => ExportConfig::make_export as _,
"cv::detail::ExtractMetaCallback" => ExportConfig::make_export as _,

MODIFY
binding-generator/src/writer/rust_native/func.rs
binding-generator/src/writer/rust_native/func.rs
@@ -367,6 +367,7 @@ impl RustElement for Func<'_, '_> {
OperatorKind::Sub => "sub",
OperatorKind::Mul => "mul",
OperatorKind::Div => "div",
+ OperatorKind::Apply => "apply",
OperatorKind::Deref => {
if self.constness().is_const() {
"try_deref"

MODIFY
binding-generator/src/writer/rust_native/mod.rs
binding-generator/src/writer/rust_native/mod.rs
+use std::collections::BTreeMap;
use std::fmt::Debug;
use std::fs;
use std::fs::{File, OpenOptions};
@@ -37,6 +38,7 @@ mod typedef;
mod vector;
type Entries = Vec<(String, String)>;
+type UniqueEntries = BTreeMap<String, String>;
#[derive(Clone, Debug)]
pub struct RustNativeBindingWriter<'s> {
@@ -54,7 +56,7 @@ pub struct RustNativeBindingWriter<'s> {
consts: Entries,
enums: Entries,
rust_funcs: Entries,
- rust_typedefs: Entries,
+ rust_typedefs: Option<UniqueEntries>,
rust_classes: Entries,
export_funcs: Entries,
export_classes: Entries,
@@ -87,7 +89,7 @@ impl<'s> RustNativeBindingWriter<'s> {
consts: vec![],
enums: vec![],
rust_funcs: vec![],
- rust_typedefs: vec![],
+ rust_typedefs: Some(BTreeMap::new()),
rust_classes: vec![],
export_funcs: vec![],
export_classes: vec![],
@@ -145,10 +147,13 @@ impl GeneratorVisitor for RustNativeBindingWriter<'_> {
fn visit_typedef(&mut self, typedef: Typedef) {
self.emit_debug_log(&typedef);
- self.rust_typedefs.push((
- typedef.cpp_name(CppNameStyle::Reference).into_owned(),
- typedef.gen_rust(self.opencv_version),
- ))
+ let opencv_version = self.opencv_version;
+ self.rust_typedefs.as_mut().map(|typedefs| {
+ let cpp_refname = typedef.cpp_name(CppNameStyle::Reference);
+ if !typedefs.contains_key(cpp_refname.as_ref()) {
+ typedefs.insert(cpp_refname.into_owned(), typedef.gen_rust(opencv_version));
+ }
+ });
}
fn visit_class(&mut self, class: Class) {
@@ -250,7 +255,12 @@ impl Drop for RustNativeBindingWriter<'_> {
let mut rust = join(&mut self.consts);
rust += &join(&mut self.enums);
- rust += &join(&mut self.rust_typedefs);
+ let mut typedefs = self
+ .rust_typedefs
+ .take()
+ .map(|typedefs| typedefs.into_iter().collect())
+ .unwrap_or_default();
+ rust += &join(&mut typedefs);
rust += &join(&mut self.rust_funcs);
rust += &join(&mut self.rust_classes);
let prelude = RUST_PRELUDE.interpolate(&hashmap! {

MODIFY
src/manual/core/ptr.rs
src/manual/core/ptr.rs
@@ -7,6 +7,9 @@ use crate::traits::{Boxed, OpenCVType, OpenCVTypeArg, OpenCVTypeExternContainer}
mod ptr_extern;
mod ptr_f32;
+/// This is similar to Rust `Box`, but handled by the C++. Some OpenCV functions insist on accepting `Ptr` instead of a heap
+/// allocated object so we need to satisfy those.
+///
/// [docs.opencv.org 3.x](https://docs.opencv.org/3.4/d0/de7/structcv_1_1Ptr.html)
/// [docs.opencv.org 4.x](https://en.cppreference.com/w/cpp/memory/shared_ptr)
pub struct Ptr<T: ?Sized>
@@ -21,9 +24,10 @@ impl<T: ?Sized> Ptr<T>
where
Self: PtrExtern,
{
+ /// Create a new `Ptr` from the object
pub fn new(val: T) -> Self
where
- T: for<'a> OpenCVType<'a>,
+ T: for<'a> OpenCVTypeArg<'a>,
Self: PtrExternCtor<T>,
{
let val = val.opencv_into_extern_container_nofail();

MODIFY
src/manual/core/ptr/ptr_extern.rs
src/manual/core/ptr/ptr_extern.rs
@@ -14,7 +14,7 @@ pub trait PtrExtern {
}
#[doc(hidden)]
-pub trait PtrExternCtor<T: for<'a> OpenCVType<'a>> {
+pub trait PtrExternCtor<T: for<'a> OpenCVTypeArg<'a>> {
#[doc(hidden)]
unsafe fn extern_new<'a>(val: extern_container_send!(mut T: 'a)) -> extern_receive!(Self: 'a)
where

Add support for function call operator