Merging 'master' into 'wrap'

release/4.3a0
Varun Agrawal 2021-07-11 08:10:35 -07:00
commit 7b9928d933
37 changed files with 1262 additions and 1534 deletions

View File

@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9]
steps:
- name: Checkout

View File

@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9]
steps:
- name: Checkout

2
wrap/.gitignore vendored
View File

@ -8,4 +8,4 @@ __pycache__/
# Files related to code coverage stats
**/.coverage
gtwrap/matlab_wrapper.tpl
gtwrap/matlab_wrapper/matlab_wrapper.tpl

View File

@ -58,7 +58,7 @@ if(NOT DEFINED GTWRAP_INCLUDE_NAME)
endif()
configure_file(${PROJECT_SOURCE_DIR}/templates/matlab_wrapper.tpl.in
${PROJECT_SOURCE_DIR}/gtwrap/matlab_wrapper.tpl)
${PROJECT_SOURCE_DIR}/gtwrap/matlab_wrapper/matlab_wrapper.tpl)
# Install the gtwrap python package as a directory so it can be found by CMake
# for wrapping.

View File

@ -192,12 +192,14 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
- **DO NOT** re-define an overriden function already declared in the external (forward-declared) base class. This will cause an ambiguity problem in the Pybind header file.
- Splitting wrapper over multiple files
- The Pybind11 wrapper supports splitting the wrapping code over multiple files.
- To be able to use classes from another module, simply import the C++ header file in that wrapper file.
- Unfortunately, this means that aliases can no longer be used.
- Similarly, there can be multiple `preamble.h` and `specializations.h` files. Each of these should match the module file name.
### TODO
- Default values for arguments.
- WORKAROUND: make multiple versions of the same function for different configurations of default arguments.
- Handle `gtsam::Rot3M` conversions to quaternions.
- Parse return of const ref arguments.
- Parse `std::string` variants and convert directly to special string.
- Add enum support.
- Add generalized serialization support via `boost.serialization` with hooks to MATLAB save/load.

View File

@ -29,8 +29,10 @@ Using `wrap` in your project is straightforward from here. In your `CMakeLists.t
```cmake
find_package(gtwrap)
set(interface_files ${PROJECT_SOURCE_DIR}/cpp/${PROJECT_NAME}.h)
pybind_wrap(${PROJECT_NAME}_py # target
${PROJECT_SOURCE_DIR}/cpp/${PROJECT_NAME}.h # interface header file
"${interface_files}" # list of interface header files
"${PROJECT_NAME}.cpp" # the generated cpp
"${PROJECT_NAME}" # module_name
"${PROJECT_MODULE_NAME}" # top namespace in the cpp file e.g. gtsam

View File

@ -12,7 +12,7 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
import sys
import pyparsing
import pyparsing # type: ignore
from .classes import *
from .declaration import *

View File

@ -12,7 +12,7 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
from typing import Iterable, List, Union
from pyparsing import Literal, Optional, ZeroOrMore
from pyparsing import Literal, Optional, ZeroOrMore # type: ignore
from .enum import Enum
from .function import ArgumentList, ReturnType
@ -233,7 +233,7 @@ class Class:
self.static_methods = []
self.properties = []
self.operators = []
self.enums = []
self.enums: List[Enum] = []
for m in members:
if isinstance(m, Constructor):
self.ctors.append(m)
@ -274,7 +274,7 @@ class Class:
def __init__(
self,
template: Template,
template: Union[Template, None],
is_virtual: str,
name: str,
parent_class: list,
@ -292,16 +292,16 @@ class Class:
if parent_class:
# If it is in an iterable, extract the parent class.
if isinstance(parent_class, Iterable):
parent_class = parent_class[0]
parent_class = parent_class[0] # type: ignore
# If the base class is a TemplatedType,
# we want the instantiated Typename
if isinstance(parent_class, TemplatedType):
parent_class = parent_class.typename
parent_class = parent_class.typename # type: ignore
self.parent_class = parent_class
else:
self.parent_class = ''
self.parent_class = '' # type: ignore
self.ctors = ctors
self.methods = methods

View File

@ -10,7 +10,7 @@ Classes and rules for declarations such as includes and forward declarations.
Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
"""
from pyparsing import CharsNotIn, Optional
from pyparsing import CharsNotIn, Optional # type: ignore
from .tokens import (CLASS, COLON, INCLUDE, LOPBRACK, ROPBRACK, SEMI_COLON,
VIRTUAL)

View File

@ -10,7 +10,7 @@ Parser class and rules for parsing C++ enums.
Author: Varun Agrawal
"""
from pyparsing import delimitedList
from pyparsing import delimitedList # type: ignore
from .tokens import ENUM, IDENT, LBRACE, RBRACE, SEMI_COLON
from .type import Typename

View File

@ -10,9 +10,9 @@ Parser classes and rules for parsing C++ functions.
Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
"""
from typing import Iterable, List, Union
from typing import Any, Iterable, List, Union
from pyparsing import Optional, ParseResults, delimitedList
from pyparsing import Optional, ParseResults, delimitedList # type: ignore
from .template import Template
from .tokens import (COMMA, DEFAULT_ARG, EQUAL, IDENT, LOPBRACK, LPAREN, PAIR,
@ -42,12 +42,12 @@ class Argument:
name: str,
default: ParseResults = None):
if isinstance(ctype, Iterable):
self.ctype = ctype[0]
self.ctype = ctype[0] # type: ignore
else:
self.ctype = ctype
self.name = name
self.default = default
self.parent = None # type: Union[ArgumentList, None]
self.parent: Union[ArgumentList, None] = None
def __repr__(self) -> str:
return self.to_cpp()
@ -70,7 +70,7 @@ class ArgumentList:
arg.parent = self
# The parent object which contains the argument list
# E.g. Method, StaticMethod, Template, Constructor, GlobalFunction
self.parent = None
self.parent: Any = None
@staticmethod
def from_parse_result(parse_result: ParseResults):
@ -123,7 +123,7 @@ class ReturnType:
self.type2 = type2
# The parent object which contains the return type
# E.g. Method, StaticMethod, Template, Constructor, GlobalFunction
self.parent = None
self.parent: Any = None
def is_void(self) -> bool:
"""

View File

@ -12,7 +12,8 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
# pylint: disable=unnecessary-lambda, unused-import, expression-not-assigned, no-else-return, protected-access, too-few-public-methods, too-many-arguments
from pyparsing import ParseResults, ZeroOrMore, cppStyleComment, stringEnd
from pyparsing import (ParseResults, ZeroOrMore, # type: ignore
cppStyleComment, stringEnd)
from .classes import Class
from .declaration import ForwardDeclaration, Include

View File

@ -14,7 +14,7 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
from typing import List, Union
from pyparsing import Forward, ParseResults, ZeroOrMore
from pyparsing import Forward, ParseResults, ZeroOrMore # type: ignore
from .classes import Class, collect_namespaces
from .declaration import ForwardDeclaration, Include
@ -93,7 +93,7 @@ class Namespace:
return Namespace(t.name, content)
def find_class_or_function(
self, typename: Typename) -> Union[Class, GlobalFunction]:
self, typename: Typename) -> Union[Class, GlobalFunction, ForwardDeclaration]:
"""
Find the Class or GlobalFunction object given its typename.
We have to traverse the tree of namespaces.
@ -115,7 +115,7 @@ class Namespace:
return res[0]
def top_level(self) -> "Namespace":
"""Return the top leve namespace."""
"""Return the top level namespace."""
if self.name == '' or self.parent == '':
return self
else:

View File

@ -12,11 +12,11 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
from typing import List
from pyparsing import Optional, ParseResults, delimitedList
from pyparsing import Optional, ParseResults, delimitedList # type: ignore
from .tokens import (EQUAL, IDENT, LBRACE, LOPBRACK, RBRACE, ROPBRACK,
SEMI_COLON, TEMPLATE, TYPEDEF)
from .type import Typename, TemplatedType
from .type import TemplatedType, Typename
class Template:

View File

@ -10,9 +10,9 @@ All the token definitions.
Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
"""
from pyparsing import (Keyword, Literal, OneOrMore, Or, QuotedString, Suppress,
Word, alphanums, alphas, nestedExpr, nums,
originalTextFor, printables)
from pyparsing import (Keyword, Literal, OneOrMore, Or, # type: ignore
QuotedString, Suppress, Word, alphanums, alphas,
nestedExpr, nums, originalTextFor, printables)
# rule for identifiers (e.g. variable names)
IDENT = Word(alphas + '_', alphanums + '_') ^ Word(nums)

View File

@ -14,7 +14,8 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
from typing import Iterable, List, Union
from pyparsing import Forward, Optional, Or, ParseResults, delimitedList
from pyparsing import (Forward, Optional, Or, ParseResults, # type: ignore
delimitedList)
from .tokens import (BASIS_TYPES, CONST, IDENT, LOPBRACK, RAW_POINTER, REF,
ROPBRACK, SHARED_POINTER)
@ -48,7 +49,7 @@ class Typename:
def __init__(self,
t: ParseResults,
instantiations: Union[tuple, list, str, ParseResults] = ()):
instantiations: Iterable[ParseResults] = ()):
self.name = t[-1] # the name is the last element in this list
self.namespaces = t[:-1]

View File

@ -10,7 +10,9 @@ Parser classes and rules for parsing C++ variables.
Author: Varun Agrawal, Gerry Chen
"""
from pyparsing import Optional, ParseResults
from typing import List
from pyparsing import Optional, ParseResults # type: ignore
from .tokens import DEFAULT_ARG, EQUAL, IDENT, SEMI_COLON
from .type import TemplatedType, Type
@ -40,7 +42,7 @@ class Variable:
t.default[0] if isinstance(t.default, ParseResults) else None))
def __init__(self,
ctype: Type,
ctype: List[Type],
name: str,
default: ParseResults = None,
parent=''):

View File

@ -0,0 +1,3 @@
"""Package to wrap C++ code to Matlab via MEX."""
from .wrapper import MatlabWrapper

View File

@ -0,0 +1,222 @@
"""Mixins for reducing the amount of boilerplate in the main wrapper class."""
import gtwrap.interface_parser as parser
import gtwrap.template_instantiator as instantiator
class CheckMixin:
"""Mixin to provide various checks."""
# Data types that are primitive types
not_ptr_type = ['int', 'double', 'bool', 'char', 'unsigned char', 'size_t']
# Ignore the namespace for these datatypes
ignore_namespace = ['Matrix', 'Vector', 'Point2', 'Point3']
# Methods that should be ignored
ignore_methods = ['pickle']
# Methods that should not be wrapped directly
whitelist = ['serializable', 'serialize']
# Datatypes that do not need to be checked in methods
not_check_type: list = []
def _has_serialization(self, cls):
for m in cls.methods:
if m.name in self.whitelist:
return True
return False
def is_shared_ptr(self, arg_type):
"""
Determine if the `interface_parser.Type` should be treated as a
shared pointer in the wrapper.
"""
return arg_type.is_shared_ptr or (
arg_type.typename.name not in self.not_ptr_type
and arg_type.typename.name not in self.ignore_namespace
and arg_type.typename.name != 'string')
def is_ptr(self, arg_type):
"""
Determine if the `interface_parser.Type` should be treated as a
raw pointer in the wrapper.
"""
return arg_type.is_ptr or (
arg_type.typename.name not in self.not_ptr_type
and arg_type.typename.name not in self.ignore_namespace
and arg_type.typename.name != 'string')
def is_ref(self, arg_type):
"""
Determine if the `interface_parser.Type` should be treated as a
reference in the wrapper.
"""
return arg_type.typename.name not in self.ignore_namespace and \
arg_type.typename.name not in self.not_ptr_type and \
arg_type.is_ref
class FormatMixin:
"""Mixin to provide formatting utilities."""
def _clean_class_name(self, instantiated_class):
"""Reformatted the C++ class name to fit Matlab defined naming
standards
"""
if len(instantiated_class.ctors) != 0:
return instantiated_class.ctors[0].name
return instantiated_class.name
def _format_type_name(self,
type_name,
separator='::',
include_namespace=True,
constructor=False,
method=False):
"""
Args:
type_name: an interface_parser.Typename to reformat
separator: the statement to add between namespaces and typename
include_namespace: whether to include namespaces when reformatting
constructor: if the typename will be in a constructor
method: if the typename will be in a method
Raises:
constructor and method cannot both be true
"""
if constructor and method:
raise ValueError(
'Constructor and method parameters cannot both be True')
formatted_type_name = ''
name = type_name.name
if include_namespace:
for namespace in type_name.namespaces:
if name not in self.ignore_namespace and namespace != '':
formatted_type_name += namespace + separator
if constructor:
formatted_type_name += self.data_type.get(name) or name
elif method:
formatted_type_name += self.data_type_param.get(name) or name
else:
formatted_type_name += name
if separator == "::": # C++
templates = []
for idx in range(len(type_name.instantiations)):
template = '{}'.format(
self._format_type_name(type_name.instantiations[idx],
include_namespace=include_namespace,
constructor=constructor,
method=method))
templates.append(template)
if len(templates) > 0: # If there are no templates
formatted_type_name += '<{}>'.format(','.join(templates))
else:
for idx in range(len(type_name.instantiations)):
formatted_type_name += '{}'.format(
self._format_type_name(type_name.instantiations[idx],
separator=separator,
include_namespace=False,
constructor=constructor,
method=method))
return formatted_type_name
def _format_return_type(self,
return_type,
include_namespace=False,
separator="::"):
"""Format return_type.
Args:
return_type: an interface_parser.ReturnType to reformat
include_namespace: whether to include namespaces when reformatting
"""
return_wrap = ''
if self._return_count(return_type) == 1:
return_wrap = self._format_type_name(
return_type.type1.typename,
separator=separator,
include_namespace=include_namespace)
else:
return_wrap = 'pair< {type1}, {type2} >'.format(
type1=self._format_type_name(
return_type.type1.typename,
separator=separator,
include_namespace=include_namespace),
type2=self._format_type_name(
return_type.type2.typename,
separator=separator,
include_namespace=include_namespace))
return return_wrap
def _format_class_name(self, instantiated_class, separator=''):
"""Format a template_instantiator.InstantiatedClass name."""
if instantiated_class.parent == '':
parent_full_ns = ['']
else:
parent_full_ns = instantiated_class.parent.full_namespaces()
# class_name = instantiated_class.parent.name
#
# if class_name != '':
# class_name += separator
#
# class_name += instantiated_class.name
parentname = "".join([separator + x
for x in parent_full_ns]) + separator
class_name = parentname[2 * len(separator):]
class_name += instantiated_class.name
return class_name
def _format_static_method(self, static_method, separator=''):
"""Example:
gtsamPoint3.staticFunction
"""
method = ''
if isinstance(static_method, parser.StaticMethod):
method += "".join([separator + x for x in static_method.parent.namespaces()]) + \
separator + static_method.parent.name + separator
return method[2 * len(separator):]
def _format_instance_method(self, instance_method, separator=''):
"""Example:
gtsamPoint3.staticFunction
"""
method = ''
if isinstance(instance_method, instantiator.InstantiatedMethod):
method_list = [
separator + x
for x in instance_method.parent.parent.full_namespaces()
]
method += "".join(method_list) + separator
method += instance_method.parent.name + separator
method += instance_method.original.name
method += "<" + instance_method.instantiations.to_cpp() + ">"
return method[2 * len(separator):]
def _format_global_method(self, static_method, separator=''):
"""Example:
gtsamPoint3.staticFunction
"""
method = ''
if isinstance(static_method, parser.GlobalFunction):
method += "".join([separator + x for x in static_method.parent.full_namespaces()]) + \
separator
return method[2 * len(separator):]

View File

@ -0,0 +1,166 @@
import textwrap
class WrapperTemplate:
"""Class to encapsulate string templates for use in wrapper generation"""
boost_headers = textwrap.dedent("""
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
""")
typdef_collectors = textwrap.dedent('''\
typedef std::set<boost::shared_ptr<{class_name_sep}>*> Collector_{class_name};
static Collector_{class_name} collector_{class_name};
''')
delete_obj = textwrap.indent(textwrap.dedent('''\
{{ for(Collector_{class_name}::iterator iter = collector_{class_name}.begin();
iter != collector_{class_name}.end(); ) {{
delete *iter;
collector_{class_name}.erase(iter++);
anyDeleted = true;
}} }}
'''),
prefix=' ')
delete_all_objects = textwrap.dedent('''
void _deleteAllObjects()
{{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);\n
bool anyDeleted = false;
{delete_objs}
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\\n"
"calling destructors, call \'clear all\' again if you plan to now recompile a wrap\\n"
"module, so that your recompiled module is used instead of the old one." << endl;
std::cout.rdbuf(outbuf);
}}
''')
rtti_register = textwrap.dedent('''\
void _{module_name}_RTTIRegister() {{
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_{module_name}_rttiRegistry_created");
if(!alreadyCreated) {{
std::map<std::string, std::string> types;
{rtti_classes}
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {{
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0) {{
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {{
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {{
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}}
mxDestroyArray(newAlreadyCreated);
}}
}}
''')
collector_function_upcast_from_void = textwrap.dedent('''\
void {class_name}_upcastFromVoid_{id}(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<{cpp_name}> Shared;
boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
Shared *self = new Shared(boost::static_pointer_cast<{cpp_name}>(*asVoid));
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
}}\n
''')
class_serialize_method = textwrap.dedent('''\
function varargout = string_serialize(this, varargin)
% STRING_SERIALIZE usage: string_serialize() : returns string
% Doxygen can be found at https://gtsam.org/doxygen/
if length(varargin) == 0
varargout{{1}} = {wrapper}({wrapper_id}, this, varargin{{:}});
else
error('Arguments do not match any overload of function {class_name}.string_serialize');
end
end\n
function sobj = saveobj(obj)
% SAVEOBJ Saves the object to a matlab-readable format
sobj = obj.string_serialize();
end
''')
collector_function_serialize = textwrap.indent(textwrap.dedent("""\
typedef boost::shared_ptr<{full_name}> Shared;
checkArguments("string_serialize",nargout,nargin-1,0);
Shared obj = unwrap_shared_ptr<{full_name}>(in[0], "ptr_{namespace}{class_name}");
ostringstream out_archive_stream;
boost::archive::text_oarchive out_archive(out_archive_stream);
out_archive << *obj;
out[0] = wrap< string >(out_archive_stream.str());
"""),
prefix=' ')
collector_function_deserialize = textwrap.indent(textwrap.dedent("""\
typedef boost::shared_ptr<{full_name}> Shared;
checkArguments("{namespace}{class_name}.string_deserialize",nargout,nargin,1);
string serialized = unwrap< string >(in[0]);
istringstream in_archive_stream(serialized);
boost::archive::text_iarchive in_archive(in_archive_stream);
Shared output(new {full_name}());
in_archive >> *output;
out[0] = wrap_shared_ptr(output,"{namespace}.{class_name}", false);
"""),
prefix=' ')
mex_function = textwrap.dedent('''
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);\n
_{module_name}_RTTIRegister();\n
int id = unwrap<int>(in[0]);\n
try {{
switch(id) {{
{cases} }}
}} catch(const std::exception& e) {{
mexErrMsgTxt(("Exception from gtsam:\\n" + std::string(e.what()) + "\\n").c_str());
}}\n
std::cout.rdbuf(outbuf);
}}
''')
collector_function_shared_return = textwrap.indent(textwrap.dedent('''\
{{
boost::shared_ptr<{name}> shared({shared_obj});
out[{id}] = wrap_shared_ptr(shared,"{name}");
}}{new_line}'''),
prefix=' ')
matlab_deserialize = textwrap.indent(textwrap.dedent("""\
function varargout = string_deserialize(varargin)
% STRING_DESERIALIZE usage: string_deserialize() : returns {class_name}
% Doxygen can be found at https://gtsam.org/doxygen/
if length(varargin) == 1
varargout{{1}} = {wrapper}({id}, varargin{{:}});
else
error('Arguments do not match any overload of function {class_name}.string_deserialize');
end
end\n
function obj = loadobj(sobj)
% LOADOBJ Saves the object to a matlab-readable format
obj = {class_name}.string_deserialize(sobj);
end
"""),
prefix=' ')

View File

@ -4,7 +4,7 @@
import itertools
from copy import deepcopy
from typing import List
from typing import Iterable, List
import gtwrap.interface_parser as parser
@ -29,12 +29,13 @@ def instantiate_type(ctype: parser.Type,
ctype = deepcopy(ctype)
# Check if the return type has template parameters
if len(ctype.typename.instantiations) > 0:
if ctype.typename.instantiations:
for idx, instantiation in enumerate(ctype.typename.instantiations):
if instantiation.name in template_typenames:
template_idx = template_typenames.index(instantiation.name)
ctype.typename.instantiations[idx] = instantiations[
template_idx]
ctype.typename.instantiations[
idx] = instantiations[ # type: ignore
template_idx]
return ctype
@ -212,7 +213,9 @@ class InstantiatedMethod(parser.Method):
void func(X x, Y y);
}
"""
def __init__(self, original, instantiations: List[parser.Typename] = ''):
def __init__(self,
original,
instantiations: Iterable[parser.Typename] = ()):
self.original = original
self.instantiations = instantiations
self.template = ''
@ -278,7 +281,7 @@ class InstantiatedClass(parser.Class):
self.original = original
self.instantiations = instantiations
self.template = ''
self.template = None
self.is_virtual = original.is_virtual
self.parent_class = original.parent_class
self.parent = original.parent
@ -318,7 +321,7 @@ class InstantiatedClass(parser.Class):
self.methods = []
for method in instantiated_methods:
if not method.template:
self.methods.append(InstantiatedMethod(method, ''))
self.methods.append(InstantiatedMethod(method, ()))
else:
instantiations = []
# Get all combinations of template parameters
@ -342,9 +345,9 @@ class InstantiatedClass(parser.Class):
)
def __repr__(self):
return "{virtual} class {name} [{cpp_class}]: {parent_class}\n"\
"{ctors}\n{static_methods}\n{methods}".format(
virtual="virtual" if self.is_virtual else '',
return "{virtual}Class {cpp_class} : {parent_class}\n"\
"{ctors}\n{static_methods}\n{methods}\n{operators}".format(
virtual="virtual " if self.is_virtual else '',
name=self.name,
cpp_class=self.to_cpp(),
parent_class=self.parent,

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3
"""
Helper script to wrap C++ to Matlab.
This script is installed via CMake to the user's binary directory
@ -7,19 +6,24 @@ and invoked during the wrapping by CMake.
"""
import argparse
import os
import sys
from gtwrap.matlab_wrapper import MatlabWrapper, generate_content
from gtwrap.matlab_wrapper import MatlabWrapper
if __name__ == "__main__":
arg_parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
arg_parser.add_argument("--src", type=str, required=True,
arg_parser.add_argument("--src",
type=str,
required=True,
help="Input interface .h file.")
arg_parser.add_argument("--module_name", type=str, required=True,
arg_parser.add_argument("--module_name",
type=str,
required=True,
help="Name of the C++ class being wrapped.")
arg_parser.add_argument("--out", type=str, required=True,
arg_parser.add_argument("--out",
type=str,
required=True,
help="Name of the output folder.")
arg_parser.add_argument(
"--top_module_namespaces",
@ -33,28 +37,22 @@ if __name__ == "__main__":
"`<module_name>.Class` of the corresponding C++ `ns1::ns2::ns3::Class`"
", and `from <module_name> import ns4` gives you access to a Python "
"`ns4.Class` of the C++ `ns1::ns2::ns3::ns4::Class`. ")
arg_parser.add_argument("--ignore",
nargs='*',
type=str,
help="A space-separated list of classes to ignore. "
"Class names must include their full namespaces.")
arg_parser.add_argument(
"--ignore",
nargs='*',
type=str,
help="A space-separated list of classes to ignore. "
"Class names must include their full namespaces.")
args = arg_parser.parse_args()
top_module_namespaces = args.top_module_namespaces.split("::")
if top_module_namespaces[0]:
top_module_namespaces = [''] + top_module_namespaces
with open(args.src, 'r') as f:
content = f.read()
if not os.path.exists(args.src):
os.mkdir(args.src)
print("Ignoring classes: {}".format(args.ignore), file=sys.stderr)
print("[MatlabWrapper] Ignoring classes: {}".format(args.ignore), file=sys.stderr)
wrapper = MatlabWrapper(module_name=args.module_name,
top_module_namespace=top_module_namespaces,
ignore_classes=args.ignore)
cc_content = wrapper.wrap(content)
generate_content(cc_content, args.out)
sources = args.src.split(';')
cc_content = wrapper.wrap(sources, path=args.out)

View File

@ -0,0 +1,36 @@
%class Class1, see Doxygen page for details
%at https://gtsam.org/doxygen/
%
%-------Constructors-------
%Class1()
%
classdef Class1 < handle
properties
ptr_gtsamClass1 = 0
end
methods
function obj = Class1(varargin)
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
my_ptr = varargin{2};
multiple_files_wrapper(0, my_ptr);
elseif nargin == 0
my_ptr = multiple_files_wrapper(1);
else
error('Arguments do not match any overload of gtsam.Class1 constructor');
end
obj.ptr_gtsamClass1 = my_ptr;
end
function delete(obj)
multiple_files_wrapper(2, obj.ptr_gtsamClass1);
end
function display(obj), obj.print(''); end
%DISPLAY Calls print on the object
function disp(obj), obj.display; end
%DISP Calls print on the object
end
methods(Static = true)
end
end

View File

@ -0,0 +1,36 @@
%class Class2, see Doxygen page for details
%at https://gtsam.org/doxygen/
%
%-------Constructors-------
%Class2()
%
classdef Class2 < handle
properties
ptr_gtsamClass2 = 0
end
methods
function obj = Class2(varargin)
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
my_ptr = varargin{2};
multiple_files_wrapper(3, my_ptr);
elseif nargin == 0
my_ptr = multiple_files_wrapper(4);
else
error('Arguments do not match any overload of gtsam.Class2 constructor');
end
obj.ptr_gtsamClass2 = my_ptr;
end
function delete(obj)
multiple_files_wrapper(5, obj.ptr_gtsamClass2);
end
function display(obj), obj.print(''); end
%DISPLAY Calls print on the object
function disp(obj), obj.display; end
%DISP Calls print on the object
end
methods(Static = true)
end
end

View File

@ -0,0 +1,36 @@
%class ClassA, see Doxygen page for details
%at https://gtsam.org/doxygen/
%
%-------Constructors-------
%ClassA()
%
classdef ClassA < handle
properties
ptr_gtsamClassA = 0
end
methods
function obj = ClassA(varargin)
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
my_ptr = varargin{2};
multiple_files_wrapper(6, my_ptr);
elseif nargin == 0
my_ptr = multiple_files_wrapper(7);
else
error('Arguments do not match any overload of gtsam.ClassA constructor');
end
obj.ptr_gtsamClassA = my_ptr;
end
function delete(obj)
multiple_files_wrapper(8, obj.ptr_gtsamClassA);
end
function display(obj), obj.print(''); end
%DISPLAY Calls print on the object
function disp(obj), obj.display; end
%DISP Calls print on the object
end
methods(Static = true)
end
end

View File

@ -7,7 +7,6 @@
#include <folder/path/to/Test.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
@ -16,7 +15,6 @@ typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
@ -38,6 +36,7 @@ static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
void _deleteAllObjects()
{
mstream mout;
@ -104,6 +103,7 @@ void _deleteAllObjects()
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -117,24 +117,29 @@ void _class_RTTIRegister() {
if(!alreadyCreated) {
std::map<std::string, std::string> types;
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}

View File

@ -5,38 +5,11 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <folder/path/to/Test.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
typedef MyVector<12> MyVector12;
typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
static Collector_FunDouble collector_FunDouble;
typedef std::set<boost::shared_ptr<Test>*> Collector_Test;
static Collector_Test collector_Test;
typedef std::set<boost::shared_ptr<PrimitiveRefDouble>*> Collector_PrimitiveRefDouble;
static Collector_PrimitiveRefDouble collector_PrimitiveRefDouble;
typedef std::set<boost::shared_ptr<MyVector3>*> Collector_MyVector3;
static Collector_MyVector3 collector_MyVector3;
typedef std::set<boost::shared_ptr<MyVector12>*> Collector_MyVector12;
static Collector_MyVector12 collector_MyVector12;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntDouble>*> Collector_MultipleTemplatesIntDouble;
static Collector_MultipleTemplatesIntDouble collector_MultipleTemplatesIntDouble;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntFloat>*> Collector_MultipleTemplatesIntFloat;
static Collector_MultipleTemplatesIntFloat collector_MultipleTemplatesIntFloat;
typedef std::set<boost::shared_ptr<ForwardKinematics>*> Collector_ForwardKinematics;
static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
void _deleteAllObjects()
{
@ -44,66 +17,7 @@ void _deleteAllObjects()
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_FunRange::iterator iter = collector_FunRange.begin();
iter != collector_FunRange.end(); ) {
delete *iter;
collector_FunRange.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_FunDouble::iterator iter = collector_FunDouble.begin();
iter != collector_FunDouble.end(); ) {
delete *iter;
collector_FunDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_Test::iterator iter = collector_Test.begin();
iter != collector_Test.end(); ) {
delete *iter;
collector_Test.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_PrimitiveRefDouble::iterator iter = collector_PrimitiveRefDouble.begin();
iter != collector_PrimitiveRefDouble.end(); ) {
delete *iter;
collector_PrimitiveRefDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector3::iterator iter = collector_MyVector3.begin();
iter != collector_MyVector3.end(); ) {
delete *iter;
collector_MyVector3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector12::iterator iter = collector_MyVector12.begin();
iter != collector_MyVector12.end(); ) {
delete *iter;
collector_MyVector12.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntDouble::iterator iter = collector_MultipleTemplatesIntDouble.begin();
iter != collector_MultipleTemplatesIntDouble.end(); ) {
delete *iter;
collector_MultipleTemplatesIntDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntFloat::iterator iter = collector_MultipleTemplatesIntFloat.begin();
iter != collector_MultipleTemplatesIntFloat.end(); ) {
delete *iter;
collector_MultipleTemplatesIntFloat.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematics::iterator iter = collector_ForwardKinematics.begin();
iter != collector_ForwardKinematics.end(); ) {
delete *iter;
collector_ForwardKinematics.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyFactorPosePoint2::iterator iter = collector_MyFactorPosePoint2.begin();
iter != collector_MyFactorPosePoint2.end(); ) {
delete *iter;
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -117,24 +31,29 @@ void _functions_RTTIRegister() {
if(!alreadyCreated) {
std::map<std::string, std::string> types;
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}

View File

@ -5,112 +5,25 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <folder/path/to/Test.h>
#include <gtsam/geometry/Point2.h>
#include <gtsam/geometry/Point3.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
typedef MyVector<12> MyVector12;
typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
BOOST_CLASS_EXPORT_GUID(gtsam::Point2, "gtsamPoint2");
BOOST_CLASS_EXPORT_GUID(gtsam::Point3, "gtsamPoint3");
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
static Collector_FunDouble collector_FunDouble;
typedef std::set<boost::shared_ptr<Test>*> Collector_Test;
static Collector_Test collector_Test;
typedef std::set<boost::shared_ptr<PrimitiveRefDouble>*> Collector_PrimitiveRefDouble;
static Collector_PrimitiveRefDouble collector_PrimitiveRefDouble;
typedef std::set<boost::shared_ptr<MyVector3>*> Collector_MyVector3;
static Collector_MyVector3 collector_MyVector3;
typedef std::set<boost::shared_ptr<MyVector12>*> Collector_MyVector12;
static Collector_MyVector12 collector_MyVector12;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntDouble>*> Collector_MultipleTemplatesIntDouble;
static Collector_MultipleTemplatesIntDouble collector_MultipleTemplatesIntDouble;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntFloat>*> Collector_MultipleTemplatesIntFloat;
static Collector_MultipleTemplatesIntFloat collector_MultipleTemplatesIntFloat;
typedef std::set<boost::shared_ptr<ForwardKinematics>*> Collector_ForwardKinematics;
static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<gtsam::Point2>*> Collector_gtsamPoint2;
static Collector_gtsamPoint2 collector_gtsamPoint2;
typedef std::set<boost::shared_ptr<gtsam::Point3>*> Collector_gtsamPoint3;
static Collector_gtsamPoint3 collector_gtsamPoint3;
void _deleteAllObjects()
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_FunRange::iterator iter = collector_FunRange.begin();
iter != collector_FunRange.end(); ) {
delete *iter;
collector_FunRange.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_FunDouble::iterator iter = collector_FunDouble.begin();
iter != collector_FunDouble.end(); ) {
delete *iter;
collector_FunDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_Test::iterator iter = collector_Test.begin();
iter != collector_Test.end(); ) {
delete *iter;
collector_Test.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_PrimitiveRefDouble::iterator iter = collector_PrimitiveRefDouble.begin();
iter != collector_PrimitiveRefDouble.end(); ) {
delete *iter;
collector_PrimitiveRefDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector3::iterator iter = collector_MyVector3.begin();
iter != collector_MyVector3.end(); ) {
delete *iter;
collector_MyVector3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector12::iterator iter = collector_MyVector12.begin();
iter != collector_MyVector12.end(); ) {
delete *iter;
collector_MyVector12.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntDouble::iterator iter = collector_MultipleTemplatesIntDouble.begin();
iter != collector_MultipleTemplatesIntDouble.end(); ) {
delete *iter;
collector_MultipleTemplatesIntDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntFloat::iterator iter = collector_MultipleTemplatesIntFloat.begin();
iter != collector_MultipleTemplatesIntFloat.end(); ) {
delete *iter;
collector_MultipleTemplatesIntFloat.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematics::iterator iter = collector_ForwardKinematics.begin();
iter != collector_ForwardKinematics.end(); ) {
delete *iter;
collector_ForwardKinematics.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyFactorPosePoint2::iterator iter = collector_MyFactorPosePoint2.begin();
iter != collector_MyFactorPosePoint2.end(); ) {
delete *iter;
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint2::iterator iter = collector_gtsamPoint2.begin();
iter != collector_gtsamPoint2.end(); ) {
delete *iter;
@ -123,6 +36,7 @@ void _deleteAllObjects()
collector_gtsamPoint3.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -136,24 +50,29 @@ void _geometry_RTTIRegister() {
if(!alreadyCreated) {
std::map<std::string, std::string> types;
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}

View File

@ -5,47 +5,11 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <folder/path/to/Test.h>
#include <gtsam/geometry/Point2.h>
#include <gtsam/geometry/Point3.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
typedef MyVector<12> MyVector12;
typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
typedef MyTemplate<gtsam::Point2> MyTemplatePoint2;
typedef MyTemplate<gtsam::Matrix> MyTemplateMatrix;
BOOST_CLASS_EXPORT_GUID(gtsam::Point2, "gtsamPoint2");
BOOST_CLASS_EXPORT_GUID(gtsam::Point3, "gtsamPoint3");
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
static Collector_FunDouble collector_FunDouble;
typedef std::set<boost::shared_ptr<Test>*> Collector_Test;
static Collector_Test collector_Test;
typedef std::set<boost::shared_ptr<PrimitiveRefDouble>*> Collector_PrimitiveRefDouble;
static Collector_PrimitiveRefDouble collector_PrimitiveRefDouble;
typedef std::set<boost::shared_ptr<MyVector3>*> Collector_MyVector3;
static Collector_MyVector3 collector_MyVector3;
typedef std::set<boost::shared_ptr<MyVector12>*> Collector_MyVector12;
static Collector_MyVector12 collector_MyVector12;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntDouble>*> Collector_MultipleTemplatesIntDouble;
static Collector_MultipleTemplatesIntDouble collector_MultipleTemplatesIntDouble;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntFloat>*> Collector_MultipleTemplatesIntFloat;
static Collector_MultipleTemplatesIntFloat collector_MultipleTemplatesIntFloat;
typedef std::set<boost::shared_ptr<ForwardKinematics>*> Collector_ForwardKinematics;
static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<gtsam::Point2>*> Collector_gtsamPoint2;
static Collector_gtsamPoint2 collector_gtsamPoint2;
typedef std::set<boost::shared_ptr<gtsam::Point3>*> Collector_gtsamPoint3;
static Collector_gtsamPoint3 collector_gtsamPoint3;
typedef std::set<boost::shared_ptr<MyBase>*> Collector_MyBase;
static Collector_MyBase collector_MyBase;
typedef std::set<boost::shared_ptr<MyTemplatePoint2>*> Collector_MyTemplatePoint2;
@ -55,84 +19,13 @@ static Collector_MyTemplateMatrix collector_MyTemplateMatrix;
typedef std::set<boost::shared_ptr<ForwardKinematicsFactor>*> Collector_ForwardKinematicsFactor;
static Collector_ForwardKinematicsFactor collector_ForwardKinematicsFactor;
void _deleteAllObjects()
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_FunRange::iterator iter = collector_FunRange.begin();
iter != collector_FunRange.end(); ) {
delete *iter;
collector_FunRange.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_FunDouble::iterator iter = collector_FunDouble.begin();
iter != collector_FunDouble.end(); ) {
delete *iter;
collector_FunDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_Test::iterator iter = collector_Test.begin();
iter != collector_Test.end(); ) {
delete *iter;
collector_Test.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_PrimitiveRefDouble::iterator iter = collector_PrimitiveRefDouble.begin();
iter != collector_PrimitiveRefDouble.end(); ) {
delete *iter;
collector_PrimitiveRefDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector3::iterator iter = collector_MyVector3.begin();
iter != collector_MyVector3.end(); ) {
delete *iter;
collector_MyVector3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector12::iterator iter = collector_MyVector12.begin();
iter != collector_MyVector12.end(); ) {
delete *iter;
collector_MyVector12.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntDouble::iterator iter = collector_MultipleTemplatesIntDouble.begin();
iter != collector_MultipleTemplatesIntDouble.end(); ) {
delete *iter;
collector_MultipleTemplatesIntDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntFloat::iterator iter = collector_MultipleTemplatesIntFloat.begin();
iter != collector_MultipleTemplatesIntFloat.end(); ) {
delete *iter;
collector_MultipleTemplatesIntFloat.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematics::iterator iter = collector_ForwardKinematics.begin();
iter != collector_ForwardKinematics.end(); ) {
delete *iter;
collector_ForwardKinematics.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyFactorPosePoint2::iterator iter = collector_MyFactorPosePoint2.begin();
iter != collector_MyFactorPosePoint2.end(); ) {
delete *iter;
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint2::iterator iter = collector_gtsamPoint2.begin();
iter != collector_gtsamPoint2.end(); ) {
delete *iter;
collector_gtsamPoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint3::iterator iter = collector_gtsamPoint3.begin();
iter != collector_gtsamPoint3.end(); ) {
delete *iter;
collector_gtsamPoint3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyBase::iterator iter = collector_MyBase.begin();
iter != collector_MyBase.end(); ) {
delete *iter;
@ -157,6 +50,7 @@ void _deleteAllObjects()
collector_ForwardKinematicsFactor.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -169,42 +63,38 @@ void _inheritance_RTTIRegister() {
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_inheritance_rttiRegistry_created");
if(!alreadyCreated) {
std::map<std::string, std::string> types;
types.insert(std::make_pair(typeid(MyBase).name(), "MyBase"));
types.insert(std::make_pair(typeid(MyTemplatePoint2).name(), "MyTemplatePoint2"));
types.insert(std::make_pair(typeid(MyTemplateMatrix).name(), "MyTemplateMatrix"));
types.insert(std::make_pair(typeid(ForwardKinematicsFactor).name(), "ForwardKinematicsFactor"));
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}
void gtsamPoint2_collectorInsertAndMakeBase_0(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Point2> Shared;
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
collector_gtsamPoint2.insert(self);
}
void MyBase_collectorInsertAndMakeBase_0(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -214,6 +104,15 @@ void MyBase_collectorInsertAndMakeBase_0(int nargout, mxArray *out[], int nargin
collector_MyBase.insert(self);
}
void MyBase_upcastFromVoid_1(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<MyBase> Shared;
boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
Shared *self = new Shared(boost::static_pointer_cast<MyBase>(*asVoid));
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
}
void MyBase_deconstructor_2(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<MyBase> Shared;
@ -227,19 +126,6 @@ void MyBase_deconstructor_2(int nargout, mxArray *out[], int nargin, const mxArr
}
}
void gtsamPoint2_deconstructor_3(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<gtsam::Point2> Shared;
checkArguments("delete_gtsamPoint2",nargout,nargin,1);
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
Collector_gtsamPoint2::iterator item;
item = collector_gtsamPoint2.find(self);
if(item != collector_gtsamPoint2.end()) {
delete self;
collector_gtsamPoint2.erase(item);
}
}
void MyTemplatePoint2_collectorInsertAndMakeBase_3(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -253,6 +139,15 @@ void MyTemplatePoint2_collectorInsertAndMakeBase_3(int nargout, mxArray *out[],
*reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self);
}
void MyTemplatePoint2_upcastFromVoid_4(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<MyTemplate<gtsam::Point2>> Shared;
boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
Shared *self = new Shared(boost::static_pointer_cast<MyTemplate<gtsam::Point2>>(*asVoid));
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
}
void MyTemplatePoint2_constructor_5(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -399,20 +294,6 @@ void MyTemplatePoint2_Level_18(int nargout, mxArray *out[], int nargin, const mx
out[0] = wrap_shared_ptr(boost::make_shared<MyTemplate<Point2>>(MyTemplate<gtsam::Point2>::Level(K)),"MyTemplatePoint2", false);
}
void gtsamPoint3_constructor_19(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Point3> Shared;
double x = unwrap< double >(in[0]);
double y = unwrap< double >(in[1]);
double z = unwrap< double >(in[2]);
Shared *self = new Shared(new gtsam::Point3(x,y,z));
collector_gtsamPoint3.insert(self);
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
}
void MyTemplateMatrix_collectorInsertAndMakeBase_19(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -426,6 +307,15 @@ void MyTemplateMatrix_collectorInsertAndMakeBase_19(int nargout, mxArray *out[],
*reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self);
}
void MyTemplateMatrix_upcastFromVoid_20(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<MyTemplate<gtsam::Matrix>> Shared;
boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
Shared *self = new Shared(boost::static_pointer_cast<MyTemplate<gtsam::Matrix>>(*asVoid));
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
}
void MyTemplateMatrix_constructor_21(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -572,14 +462,6 @@ void MyTemplateMatrix_Level_34(int nargout, mxArray *out[], int nargin, const mx
out[0] = wrap_shared_ptr(boost::make_shared<MyTemplate<Matrix>>(MyTemplate<gtsam::Matrix>::Level(K)),"MyTemplateMatrix", false);
}
void Test_return_vector2_35(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_vector2",nargout,nargin-1,1);
auto obj = unwrap_shared_ptr<Test>(in[0], "ptr_Test");
Vector value = unwrap< Vector >(in[1]);
out[0] = wrap< Vector >(obj->return_vector2(value));
}
void ForwardKinematicsFactor_collectorInsertAndMakeBase_35(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
@ -593,6 +475,15 @@ void ForwardKinematicsFactor_collectorInsertAndMakeBase_35(int nargout, mxArray
*reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self);
}
void ForwardKinematicsFactor_upcastFromVoid_36(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<ForwardKinematicsFactor> Shared;
boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0]));
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
Shared *self = new Shared(boost::static_pointer_cast<ForwardKinematicsFactor>(*asVoid));
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
}
void ForwardKinematicsFactor_deconstructor_37(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<ForwardKinematicsFactor> Shared;
@ -619,19 +510,19 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
try {
switch(id) {
case 0:
gtsamPoint2_collectorInsertAndMakeBase_0(nargout, out, nargin-1, in+1);
MyBase_collectorInsertAndMakeBase_0(nargout, out, nargin-1, in+1);
break;
case 1:
MyBase_collectorInsertAndMakeBase_0(nargout, out, nargin-1, in+1);
MyBase_upcastFromVoid_1(nargout, out, nargin-1, in+1);
break;
case 2:
MyBase_deconstructor_2(nargout, out, nargin-1, in+1);
break;
case 3:
gtsamPoint2_deconstructor_3(nargout, out, nargin-1, in+1);
MyTemplatePoint2_collectorInsertAndMakeBase_3(nargout, out, nargin-1, in+1);
break;
case 4:
MyTemplatePoint2_collectorInsertAndMakeBase_3(nargout, out, nargin-1, in+1);
MyTemplatePoint2_upcastFromVoid_4(nargout, out, nargin-1, in+1);
break;
case 5:
MyTemplatePoint2_constructor_5(nargout, out, nargin-1, in+1);
@ -676,10 +567,10 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
MyTemplatePoint2_Level_18(nargout, out, nargin-1, in+1);
break;
case 19:
gtsamPoint3_constructor_19(nargout, out, nargin-1, in+1);
MyTemplateMatrix_collectorInsertAndMakeBase_19(nargout, out, nargin-1, in+1);
break;
case 20:
MyTemplateMatrix_collectorInsertAndMakeBase_19(nargout, out, nargin-1, in+1);
MyTemplateMatrix_upcastFromVoid_20(nargout, out, nargin-1, in+1);
break;
case 21:
MyTemplateMatrix_constructor_21(nargout, out, nargin-1, in+1);
@ -724,10 +615,10 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
MyTemplateMatrix_Level_34(nargout, out, nargin-1, in+1);
break;
case 35:
Test_return_vector2_35(nargout, out, nargin-1, in+1);
ForwardKinematicsFactor_collectorInsertAndMakeBase_35(nargout, out, nargin-1, in+1);
break;
case 36:
ForwardKinematicsFactor_collectorInsertAndMakeBase_35(nargout, out, nargin-1, in+1);
ForwardKinematicsFactor_upcastFromVoid_36(nargout, out, nargin-1, in+1);
break;
case 37:
ForwardKinematicsFactor_deconstructor_37(nargout, out, nargin-1, in+1);

View File

@ -0,0 +1,229 @@
#include <gtwrap/matlab.h>
#include <map>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
typedef std::set<boost::shared_ptr<gtsam::Class1>*> Collector_gtsamClass1;
static Collector_gtsamClass1 collector_gtsamClass1;
typedef std::set<boost::shared_ptr<gtsam::Class2>*> Collector_gtsamClass2;
static Collector_gtsamClass2 collector_gtsamClass2;
typedef std::set<boost::shared_ptr<gtsam::ClassA>*> Collector_gtsamClassA;
static Collector_gtsamClassA collector_gtsamClassA;
void _deleteAllObjects()
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_gtsamClass1::iterator iter = collector_gtsamClass1.begin();
iter != collector_gtsamClass1.end(); ) {
delete *iter;
collector_gtsamClass1.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamClass2::iterator iter = collector_gtsamClass2.begin();
iter != collector_gtsamClass2.end(); ) {
delete *iter;
collector_gtsamClass2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamClassA::iterator iter = collector_gtsamClassA.begin();
iter != collector_gtsamClassA.end(); ) {
delete *iter;
collector_gtsamClassA.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
"calling destructors, call 'clear all' again if you plan to now recompile a wrap\n"
"module, so that your recompiled module is used instead of the old one." << endl;
std::cout.rdbuf(outbuf);
}
void _multiple_files_RTTIRegister() {
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_multiple_files_rttiRegistry_created");
if(!alreadyCreated) {
std::map<std::string, std::string> types;
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
registry = mxCreateStructMatrix(1, 1, 0, NULL);
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}
void gtsamClass1_collectorInsertAndMakeBase_0(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Class1> Shared;
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
collector_gtsamClass1.insert(self);
}
void gtsamClass1_constructor_1(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Class1> Shared;
Shared *self = new Shared(new gtsam::Class1());
collector_gtsamClass1.insert(self);
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
}
void gtsamClass1_deconstructor_2(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<gtsam::Class1> Shared;
checkArguments("delete_gtsamClass1",nargout,nargin,1);
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
Collector_gtsamClass1::iterator item;
item = collector_gtsamClass1.find(self);
if(item != collector_gtsamClass1.end()) {
delete self;
collector_gtsamClass1.erase(item);
}
}
void gtsamClass2_collectorInsertAndMakeBase_3(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Class2> Shared;
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
collector_gtsamClass2.insert(self);
}
void gtsamClass2_constructor_4(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::Class2> Shared;
Shared *self = new Shared(new gtsam::Class2());
collector_gtsamClass2.insert(self);
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
}
void gtsamClass2_deconstructor_5(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<gtsam::Class2> Shared;
checkArguments("delete_gtsamClass2",nargout,nargin,1);
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
Collector_gtsamClass2::iterator item;
item = collector_gtsamClass2.find(self);
if(item != collector_gtsamClass2.end()) {
delete self;
collector_gtsamClass2.erase(item);
}
}
void gtsamClassA_collectorInsertAndMakeBase_6(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::ClassA> Shared;
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
collector_gtsamClassA.insert(self);
}
void gtsamClassA_constructor_7(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mexAtExit(&_deleteAllObjects);
typedef boost::shared_ptr<gtsam::ClassA> Shared;
Shared *self = new Shared(new gtsam::ClassA());
collector_gtsamClassA.insert(self);
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
}
void gtsamClassA_deconstructor_8(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
typedef boost::shared_ptr<gtsam::ClassA> Shared;
checkArguments("delete_gtsamClassA",nargout,nargin,1);
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
Collector_gtsamClassA::iterator item;
item = collector_gtsamClassA.find(self);
if(item != collector_gtsamClassA.end()) {
delete self;
collector_gtsamClassA.erase(item);
}
}
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
_multiple_files_RTTIRegister();
int id = unwrap<int>(in[0]);
try {
switch(id) {
case 0:
gtsamClass1_collectorInsertAndMakeBase_0(nargout, out, nargin-1, in+1);
break;
case 1:
gtsamClass1_constructor_1(nargout, out, nargin-1, in+1);
break;
case 2:
gtsamClass1_deconstructor_2(nargout, out, nargin-1, in+1);
break;
case 3:
gtsamClass2_collectorInsertAndMakeBase_3(nargout, out, nargin-1, in+1);
break;
case 4:
gtsamClass2_constructor_4(nargout, out, nargin-1, in+1);
break;
case 5:
gtsamClass2_deconstructor_5(nargout, out, nargin-1, in+1);
break;
case 6:
gtsamClassA_collectorInsertAndMakeBase_6(nargout, out, nargin-1, in+1);
break;
case 7:
gtsamClassA_constructor_7(nargout, out, nargin-1, in+1);
break;
case 8:
gtsamClassA_deconstructor_8(nargout, out, nargin-1, in+1);
break;
}
} catch(const std::exception& e) {
mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str());
}
std::cout.rdbuf(outbuf);
}

View File

@ -5,9 +5,6 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <folder/path/to/Test.h>
#include <gtsam/geometry/Point2.h>
#include <gtsam/geometry/Point3.h>
#include <gtsam/nonlinear/Values.h>
#include <path/to/ns1.h>
#include <path/to/ns1/ClassB.h>
@ -15,51 +12,8 @@
#include <path/to/ns2/ClassA.h>
#include <path/to/ns3.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
typedef MyVector<12> MyVector12;
typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
typedef MyTemplate<gtsam::Point2> MyTemplatePoint2;
typedef MyTemplate<gtsam::Matrix> MyTemplateMatrix;
BOOST_CLASS_EXPORT_GUID(gtsam::Point2, "gtsamPoint2");
BOOST_CLASS_EXPORT_GUID(gtsam::Point3, "gtsamPoint3");
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
static Collector_FunDouble collector_FunDouble;
typedef std::set<boost::shared_ptr<Test>*> Collector_Test;
static Collector_Test collector_Test;
typedef std::set<boost::shared_ptr<PrimitiveRefDouble>*> Collector_PrimitiveRefDouble;
static Collector_PrimitiveRefDouble collector_PrimitiveRefDouble;
typedef std::set<boost::shared_ptr<MyVector3>*> Collector_MyVector3;
static Collector_MyVector3 collector_MyVector3;
typedef std::set<boost::shared_ptr<MyVector12>*> Collector_MyVector12;
static Collector_MyVector12 collector_MyVector12;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntDouble>*> Collector_MultipleTemplatesIntDouble;
static Collector_MultipleTemplatesIntDouble collector_MultipleTemplatesIntDouble;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntFloat>*> Collector_MultipleTemplatesIntFloat;
static Collector_MultipleTemplatesIntFloat collector_MultipleTemplatesIntFloat;
typedef std::set<boost::shared_ptr<ForwardKinematics>*> Collector_ForwardKinematics;
static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<gtsam::Point2>*> Collector_gtsamPoint2;
static Collector_gtsamPoint2 collector_gtsamPoint2;
typedef std::set<boost::shared_ptr<gtsam::Point3>*> Collector_gtsamPoint3;
static Collector_gtsamPoint3 collector_gtsamPoint3;
typedef std::set<boost::shared_ptr<MyBase>*> Collector_MyBase;
static Collector_MyBase collector_MyBase;
typedef std::set<boost::shared_ptr<MyTemplatePoint2>*> Collector_MyTemplatePoint2;
static Collector_MyTemplatePoint2 collector_MyTemplatePoint2;
typedef std::set<boost::shared_ptr<MyTemplateMatrix>*> Collector_MyTemplateMatrix;
static Collector_MyTemplateMatrix collector_MyTemplateMatrix;
typedef std::set<boost::shared_ptr<ForwardKinematicsFactor>*> Collector_ForwardKinematicsFactor;
static Collector_ForwardKinematicsFactor collector_ForwardKinematicsFactor;
typedef std::set<boost::shared_ptr<ns1::ClassA>*> Collector_ns1ClassA;
static Collector_ns1ClassA collector_ns1ClassA;
typedef std::set<boost::shared_ptr<ns1::ClassB>*> Collector_ns1ClassB;
@ -75,108 +29,13 @@ static Collector_ClassD collector_ClassD;
typedef std::set<boost::shared_ptr<gtsam::Values>*> Collector_gtsamValues;
static Collector_gtsamValues collector_gtsamValues;
void _deleteAllObjects()
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_FunRange::iterator iter = collector_FunRange.begin();
iter != collector_FunRange.end(); ) {
delete *iter;
collector_FunRange.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_FunDouble::iterator iter = collector_FunDouble.begin();
iter != collector_FunDouble.end(); ) {
delete *iter;
collector_FunDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_Test::iterator iter = collector_Test.begin();
iter != collector_Test.end(); ) {
delete *iter;
collector_Test.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_PrimitiveRefDouble::iterator iter = collector_PrimitiveRefDouble.begin();
iter != collector_PrimitiveRefDouble.end(); ) {
delete *iter;
collector_PrimitiveRefDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector3::iterator iter = collector_MyVector3.begin();
iter != collector_MyVector3.end(); ) {
delete *iter;
collector_MyVector3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector12::iterator iter = collector_MyVector12.begin();
iter != collector_MyVector12.end(); ) {
delete *iter;
collector_MyVector12.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntDouble::iterator iter = collector_MultipleTemplatesIntDouble.begin();
iter != collector_MultipleTemplatesIntDouble.end(); ) {
delete *iter;
collector_MultipleTemplatesIntDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntFloat::iterator iter = collector_MultipleTemplatesIntFloat.begin();
iter != collector_MultipleTemplatesIntFloat.end(); ) {
delete *iter;
collector_MultipleTemplatesIntFloat.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematics::iterator iter = collector_ForwardKinematics.begin();
iter != collector_ForwardKinematics.end(); ) {
delete *iter;
collector_ForwardKinematics.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyFactorPosePoint2::iterator iter = collector_MyFactorPosePoint2.begin();
iter != collector_MyFactorPosePoint2.end(); ) {
delete *iter;
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint2::iterator iter = collector_gtsamPoint2.begin();
iter != collector_gtsamPoint2.end(); ) {
delete *iter;
collector_gtsamPoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint3::iterator iter = collector_gtsamPoint3.begin();
iter != collector_gtsamPoint3.end(); ) {
delete *iter;
collector_gtsamPoint3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyBase::iterator iter = collector_MyBase.begin();
iter != collector_MyBase.end(); ) {
delete *iter;
collector_MyBase.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyTemplatePoint2::iterator iter = collector_MyTemplatePoint2.begin();
iter != collector_MyTemplatePoint2.end(); ) {
delete *iter;
collector_MyTemplatePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyTemplateMatrix::iterator iter = collector_MyTemplateMatrix.begin();
iter != collector_MyTemplateMatrix.end(); ) {
delete *iter;
collector_MyTemplateMatrix.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematicsFactor::iterator iter = collector_ForwardKinematicsFactor.begin();
iter != collector_ForwardKinematicsFactor.end(); ) {
delete *iter;
collector_ForwardKinematicsFactor.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns1ClassA::iterator iter = collector_ns1ClassA.begin();
iter != collector_ns1ClassA.end(); ) {
delete *iter;
@ -219,6 +78,7 @@ void _deleteAllObjects()
collector_gtsamValues.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -231,10 +91,8 @@ void _namespaces_RTTIRegister() {
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_namespaces_rttiRegistry_created");
if(!alreadyCreated) {
std::map<std::string, std::string> types;
types.insert(std::make_pair(typeid(MyBase).name(), "MyBase"));
types.insert(std::make_pair(typeid(MyTemplatePoint2).name(), "MyTemplatePoint2"));
types.insert(std::make_pair(typeid(MyTemplateMatrix).name(), "MyTemplateMatrix"));
types.insert(std::make_pair(typeid(ForwardKinematicsFactor).name(), "ForwardKinematicsFactor"));
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
@ -242,18 +100,21 @@ void _namespaces_RTTIRegister() {
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}

View File

@ -5,78 +5,11 @@
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <folder/path/to/Test.h>
#include <gtsam/geometry/Cal3Bundler.h>
#include <gtsam/geometry/Point2.h>
#include <gtsam/geometry/Point3.h>
#include <gtsam/nonlinear/Values.h>
#include <path/to/ns1.h>
#include <path/to/ns1/ClassB.h>
#include <path/to/ns2.h>
#include <path/to/ns2/ClassA.h>
#include <path/to/ns3.h>
typedef Fun<double> FunDouble;
typedef PrimitiveRef<double> PrimitiveRefDouble;
typedef MyVector<3> MyVector3;
typedef MyVector<12> MyVector12;
typedef MultipleTemplates<int, double> MultipleTemplatesIntDouble;
typedef MultipleTemplates<int, float> MultipleTemplatesIntFloat;
typedef MyFactor<gtsam::Pose2, gtsam::Matrix> MyFactorPosePoint2;
typedef MyTemplate<gtsam::Point2> MyTemplatePoint2;
typedef MyTemplate<gtsam::Matrix> MyTemplateMatrix;
typedef gtsam::PinholeCamera<gtsam::Cal3Bundler> PinholeCameraCal3Bundler;
typedef gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3> GeneralSFMFactorCal3Bundler;
BOOST_CLASS_EXPORT_GUID(gtsam::Point2, "gtsamPoint2");
BOOST_CLASS_EXPORT_GUID(gtsam::Point3, "gtsamPoint3");
typedef std::set<boost::shared_ptr<FunRange>*> Collector_FunRange;
static Collector_FunRange collector_FunRange;
typedef std::set<boost::shared_ptr<FunDouble>*> Collector_FunDouble;
static Collector_FunDouble collector_FunDouble;
typedef std::set<boost::shared_ptr<Test>*> Collector_Test;
static Collector_Test collector_Test;
typedef std::set<boost::shared_ptr<PrimitiveRefDouble>*> Collector_PrimitiveRefDouble;
static Collector_PrimitiveRefDouble collector_PrimitiveRefDouble;
typedef std::set<boost::shared_ptr<MyVector3>*> Collector_MyVector3;
static Collector_MyVector3 collector_MyVector3;
typedef std::set<boost::shared_ptr<MyVector12>*> Collector_MyVector12;
static Collector_MyVector12 collector_MyVector12;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntDouble>*> Collector_MultipleTemplatesIntDouble;
static Collector_MultipleTemplatesIntDouble collector_MultipleTemplatesIntDouble;
typedef std::set<boost::shared_ptr<MultipleTemplatesIntFloat>*> Collector_MultipleTemplatesIntFloat;
static Collector_MultipleTemplatesIntFloat collector_MultipleTemplatesIntFloat;
typedef std::set<boost::shared_ptr<ForwardKinematics>*> Collector_ForwardKinematics;
static Collector_ForwardKinematics collector_ForwardKinematics;
typedef std::set<boost::shared_ptr<MyFactorPosePoint2>*> Collector_MyFactorPosePoint2;
static Collector_MyFactorPosePoint2 collector_MyFactorPosePoint2;
typedef std::set<boost::shared_ptr<gtsam::Point2>*> Collector_gtsamPoint2;
static Collector_gtsamPoint2 collector_gtsamPoint2;
typedef std::set<boost::shared_ptr<gtsam::Point3>*> Collector_gtsamPoint3;
static Collector_gtsamPoint3 collector_gtsamPoint3;
typedef std::set<boost::shared_ptr<MyBase>*> Collector_MyBase;
static Collector_MyBase collector_MyBase;
typedef std::set<boost::shared_ptr<MyTemplatePoint2>*> Collector_MyTemplatePoint2;
static Collector_MyTemplatePoint2 collector_MyTemplatePoint2;
typedef std::set<boost::shared_ptr<MyTemplateMatrix>*> Collector_MyTemplateMatrix;
static Collector_MyTemplateMatrix collector_MyTemplateMatrix;
typedef std::set<boost::shared_ptr<ForwardKinematicsFactor>*> Collector_ForwardKinematicsFactor;
static Collector_ForwardKinematicsFactor collector_ForwardKinematicsFactor;
typedef std::set<boost::shared_ptr<ns1::ClassA>*> Collector_ns1ClassA;
static Collector_ns1ClassA collector_ns1ClassA;
typedef std::set<boost::shared_ptr<ns1::ClassB>*> Collector_ns1ClassB;
static Collector_ns1ClassB collector_ns1ClassB;
typedef std::set<boost::shared_ptr<ns2::ClassA>*> Collector_ns2ClassA;
static Collector_ns2ClassA collector_ns2ClassA;
typedef std::set<boost::shared_ptr<ns2::ns3::ClassB>*> Collector_ns2ns3ClassB;
static Collector_ns2ns3ClassB collector_ns2ns3ClassB;
typedef std::set<boost::shared_ptr<ns2::ClassC>*> Collector_ns2ClassC;
static Collector_ns2ClassC collector_ns2ClassC;
typedef std::set<boost::shared_ptr<ClassD>*> Collector_ClassD;
static Collector_ClassD collector_ClassD;
typedef std::set<boost::shared_ptr<gtsam::Values>*> Collector_gtsamValues;
static Collector_gtsamValues collector_gtsamValues;
typedef std::set<boost::shared_ptr<gtsam::NonlinearFactorGraph>*> Collector_gtsamNonlinearFactorGraph;
static Collector_gtsamNonlinearFactorGraph collector_gtsamNonlinearFactorGraph;
typedef std::set<boost::shared_ptr<gtsam::SfmTrack>*> Collector_gtsamSfmTrack;
@ -86,150 +19,13 @@ static Collector_gtsamPinholeCameraCal3Bundler collector_gtsamPinholeCameraCal3B
typedef std::set<boost::shared_ptr<GeneralSFMFactorCal3Bundler>*> Collector_gtsamGeneralSFMFactorCal3Bundler;
static Collector_gtsamGeneralSFMFactorCal3Bundler collector_gtsamGeneralSFMFactorCal3Bundler;
void _deleteAllObjects()
{
mstream mout;
std::streambuf *outbuf = std::cout.rdbuf(&mout);
bool anyDeleted = false;
{ for(Collector_FunRange::iterator iter = collector_FunRange.begin();
iter != collector_FunRange.end(); ) {
delete *iter;
collector_FunRange.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_FunDouble::iterator iter = collector_FunDouble.begin();
iter != collector_FunDouble.end(); ) {
delete *iter;
collector_FunDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_Test::iterator iter = collector_Test.begin();
iter != collector_Test.end(); ) {
delete *iter;
collector_Test.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_PrimitiveRefDouble::iterator iter = collector_PrimitiveRefDouble.begin();
iter != collector_PrimitiveRefDouble.end(); ) {
delete *iter;
collector_PrimitiveRefDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector3::iterator iter = collector_MyVector3.begin();
iter != collector_MyVector3.end(); ) {
delete *iter;
collector_MyVector3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyVector12::iterator iter = collector_MyVector12.begin();
iter != collector_MyVector12.end(); ) {
delete *iter;
collector_MyVector12.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntDouble::iterator iter = collector_MultipleTemplatesIntDouble.begin();
iter != collector_MultipleTemplatesIntDouble.end(); ) {
delete *iter;
collector_MultipleTemplatesIntDouble.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MultipleTemplatesIntFloat::iterator iter = collector_MultipleTemplatesIntFloat.begin();
iter != collector_MultipleTemplatesIntFloat.end(); ) {
delete *iter;
collector_MultipleTemplatesIntFloat.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematics::iterator iter = collector_ForwardKinematics.begin();
iter != collector_ForwardKinematics.end(); ) {
delete *iter;
collector_ForwardKinematics.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyFactorPosePoint2::iterator iter = collector_MyFactorPosePoint2.begin();
iter != collector_MyFactorPosePoint2.end(); ) {
delete *iter;
collector_MyFactorPosePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint2::iterator iter = collector_gtsamPoint2.begin();
iter != collector_gtsamPoint2.end(); ) {
delete *iter;
collector_gtsamPoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamPoint3::iterator iter = collector_gtsamPoint3.begin();
iter != collector_gtsamPoint3.end(); ) {
delete *iter;
collector_gtsamPoint3.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyBase::iterator iter = collector_MyBase.begin();
iter != collector_MyBase.end(); ) {
delete *iter;
collector_MyBase.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyTemplatePoint2::iterator iter = collector_MyTemplatePoint2.begin();
iter != collector_MyTemplatePoint2.end(); ) {
delete *iter;
collector_MyTemplatePoint2.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_MyTemplateMatrix::iterator iter = collector_MyTemplateMatrix.begin();
iter != collector_MyTemplateMatrix.end(); ) {
delete *iter;
collector_MyTemplateMatrix.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ForwardKinematicsFactor::iterator iter = collector_ForwardKinematicsFactor.begin();
iter != collector_ForwardKinematicsFactor.end(); ) {
delete *iter;
collector_ForwardKinematicsFactor.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns1ClassA::iterator iter = collector_ns1ClassA.begin();
iter != collector_ns1ClassA.end(); ) {
delete *iter;
collector_ns1ClassA.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns1ClassB::iterator iter = collector_ns1ClassB.begin();
iter != collector_ns1ClassB.end(); ) {
delete *iter;
collector_ns1ClassB.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns2ClassA::iterator iter = collector_ns2ClassA.begin();
iter != collector_ns2ClassA.end(); ) {
delete *iter;
collector_ns2ClassA.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns2ns3ClassB::iterator iter = collector_ns2ns3ClassB.begin();
iter != collector_ns2ns3ClassB.end(); ) {
delete *iter;
collector_ns2ns3ClassB.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ns2ClassC::iterator iter = collector_ns2ClassC.begin();
iter != collector_ns2ClassC.end(); ) {
delete *iter;
collector_ns2ClassC.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_ClassD::iterator iter = collector_ClassD.begin();
iter != collector_ClassD.end(); ) {
delete *iter;
collector_ClassD.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamValues::iterator iter = collector_gtsamValues.begin();
iter != collector_gtsamValues.end(); ) {
delete *iter;
collector_gtsamValues.erase(iter++);
anyDeleted = true;
} }
{ for(Collector_gtsamNonlinearFactorGraph::iterator iter = collector_gtsamNonlinearFactorGraph.begin();
iter != collector_gtsamNonlinearFactorGraph.end(); ) {
delete *iter;
@ -254,6 +50,7 @@ void _deleteAllObjects()
collector_gtsamGeneralSFMFactorCal3Bundler.erase(iter++);
anyDeleted = true;
} }
if(anyDeleted)
cout <<
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
@ -266,10 +63,8 @@ void _special_cases_RTTIRegister() {
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_special_cases_rttiRegistry_created");
if(!alreadyCreated) {
std::map<std::string, std::string> types;
types.insert(std::make_pair(typeid(MyBase).name(), "MyBase"));
types.insert(std::make_pair(typeid(MyTemplatePoint2).name(), "MyTemplatePoint2"));
types.insert(std::make_pair(typeid(MyTemplateMatrix).name(), "MyTemplateMatrix"));
types.insert(std::make_pair(typeid(ForwardKinematicsFactor).name(), "ForwardKinematicsFactor"));
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
if(!registry)
@ -277,18 +72,21 @@ void _special_cases_RTTIRegister() {
typedef std::pair<std::string, std::string> StringPair;
for(const StringPair& rtti_matlab: types) {
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
if(fieldId < 0)
if(fieldId < 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
}
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0)
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(registry);
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0)
if(mexPutVariable("global", "gtsam_geometry_rttiRegistry_created", newAlreadyCreated) != 0) {
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
}
mxDestroyArray(newAlreadyCreated);
}
}

11
wrap/tests/fixtures/part1.i vendored Normal file
View File

@ -0,0 +1,11 @@
// First file to test for multi-file support.
namespace gtsam {
class Class1 {
Class1();
};
class Class2 {
Class2();
};
} // namespace gtsam

7
wrap/tests/fixtures/part2.i vendored Normal file
View File

@ -0,0 +1,7 @@
// Second file to test for multi-file support.
namespace gtsam {
class ClassA {
ClassA();
};
} // namespace gtsam

View File

@ -22,73 +22,31 @@ class TestWrap(unittest.TestCase):
"""
Test the Matlab wrapper
"""
TEST_DIR = osp.dirname(osp.realpath(__file__))
INTERFACE_DIR = osp.join(TEST_DIR, "fixtures")
MATLAB_TEST_DIR = osp.join(TEST_DIR, "expected", "matlab")
MATLAB_ACTUAL_DIR = osp.join(TEST_DIR, "actual", "matlab")
def setUp(self) -> None:
super().setUp()
# Create the `actual/matlab` directory
os.makedirs(MATLAB_ACTUAL_DIR, exist_ok=True)
# Set up all the directories
self.TEST_DIR = osp.dirname(osp.realpath(__file__))
self.INTERFACE_DIR = osp.join(self.TEST_DIR, "fixtures")
self.MATLAB_TEST_DIR = osp.join(self.TEST_DIR, "expected", "matlab")
self.MATLAB_ACTUAL_DIR = osp.join(self.TEST_DIR, "actual", "matlab")
# set the log level to INFO by default
logger.remove() # remove the default sink
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
def generate_content(self, cc_content, path=MATLAB_ACTUAL_DIR):
"""Generate files and folders from matlab wrapper content.
# Generate the matlab.h file if it does not exist
template_file = osp.join(self.TEST_DIR, "..", "gtwrap",
"matlab_wrapper", "matlab_wrapper.tpl")
if not osp.exists(template_file):
with open(template_file, 'w') as tpl:
tpl.write("#include <gtwrap/matlab.h>\n#include <map>\n")
Keyword arguments:
cc_content -- the content to generate formatted as
(file_name, file_content) or
(folder_name, [(file_name, file_content)])
path -- the path to the files parent folder within the main folder
"""
for c in cc_content:
if isinstance(c, list):
if len(c) == 0:
continue
logger.debug("c object: {}".format(c[0][0]))
path_to_folder = osp.join(path, c[0][0])
# Create the `actual/matlab` directory
os.makedirs(self.MATLAB_ACTUAL_DIR, exist_ok=True)
if not osp.isdir(path_to_folder):
try:
os.makedirs(path_to_folder, exist_ok=True)
except OSError:
pass
for sub_content in c:
logger.debug("sub object: {}".format(sub_content[1][0][0]))
self.generate_content(sub_content[1], path_to_folder)
elif isinstance(c[1], list):
path_to_folder = osp.join(path, c[0])
logger.debug(
"[generate_content_global]: {}".format(path_to_folder))
if not osp.isdir(path_to_folder):
try:
os.makedirs(path_to_folder, exist_ok=True)
except OSError:
pass
for sub_content in c[1]:
path_to_file = osp.join(path_to_folder, sub_content[0])
logger.debug(
"[generate_global_method]: {}".format(path_to_file))
with open(path_to_file, 'w') as f:
f.write(sub_content[1])
else:
path_to_file = osp.join(path, c[0])
logger.debug("[generate_content]: {}".format(path_to_file))
if not osp.isdir(path_to_file):
try:
os.mkdir(path)
except OSError:
pass
with open(path_to_file, 'w') as f:
f.write(c[1])
# set the log level to INFO by default
logger.remove() # remove the default sink
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
def compare_and_diff(self, file):
"""
@ -109,11 +67,7 @@ class TestWrap(unittest.TestCase):
python3 wrap/matlab_wrapper.py --src wrap/tests/geometry.h
--module_name geometry --out wrap/tests/actual-matlab
"""
with open(osp.join(self.INTERFACE_DIR, 'geometry.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'geometry.i')
# Create MATLAB wrapper instance
wrapper = MatlabWrapper(
@ -122,24 +76,18 @@ class TestWrap(unittest.TestCase):
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
self.assertTrue(osp.isdir(osp.join(self.MATLAB_ACTUAL_DIR, '+gtsam')))
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = ['+gtsam/Point2.m', '+gtsam/Point3.m', 'geometry_wrapper.cpp']
self.assertTrue(osp.isdir(osp.join(self.MATLAB_ACTUAL_DIR, '+gtsam')))
for file in files:
self.compare_and_diff(file)
def test_functions(self):
"""Test interface file with function info."""
with open(osp.join(self.INTERFACE_DIR, 'functions.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'functions.i')
wrapper = MatlabWrapper(
module_name='functions',
@ -147,9 +95,7 @@ class TestWrap(unittest.TestCase):
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = [
'functions_wrapper.cpp', 'aGlobalFunction.m', 'load2D.m',
@ -163,11 +109,7 @@ class TestWrap(unittest.TestCase):
def test_class(self):
"""Test interface file with only class info."""
with open(osp.join(self.INTERFACE_DIR, 'class.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'class.i')
wrapper = MatlabWrapper(
module_name='class',
@ -175,9 +117,7 @@ class TestWrap(unittest.TestCase):
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = [
'class_wrapper.cpp', 'FunDouble.m', 'FunRange.m',
@ -191,21 +131,14 @@ class TestWrap(unittest.TestCase):
def test_inheritance(self):
"""Test interface file with class inheritance definitions."""
with open(osp.join(self.INTERFACE_DIR, 'inheritance.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'inheritance.i')
wrapper = MatlabWrapper(
module_name='inheritance',
top_module_namespace=['gtsam'],
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = [
'inheritance_wrapper.cpp', 'MyBase.m', 'MyTemplateMatrix.m',
@ -219,11 +152,7 @@ class TestWrap(unittest.TestCase):
"""
Test interface file with full namespace definition.
"""
with open(osp.join(self.INTERFACE_DIR, 'namespaces.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'namespaces.i')
wrapper = MatlabWrapper(
module_name='namespaces',
@ -231,9 +160,7 @@ class TestWrap(unittest.TestCase):
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = [
'namespaces_wrapper.cpp', '+ns1/aGlobalFunction.m',
@ -249,21 +176,14 @@ class TestWrap(unittest.TestCase):
"""
Tests for some unique, non-trivial features.
"""
with open(osp.join(self.INTERFACE_DIR, 'special_cases.i'), 'r') as f:
content = f.read()
if not osp.exists(self.MATLAB_ACTUAL_DIR):
os.mkdir(self.MATLAB_ACTUAL_DIR)
file = osp.join(self.INTERFACE_DIR, 'special_cases.i')
wrapper = MatlabWrapper(
module_name='special_cases',
top_module_namespace=['gtsam'],
ignore_classes=[''],
)
cc_content = wrapper.wrap(content)
self.generate_content(cc_content)
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
files = [
'special_cases_wrapper.cpp',
@ -274,6 +194,31 @@ class TestWrap(unittest.TestCase):
for file in files:
self.compare_and_diff(file)
def test_multiple_files(self):
"""
Test for when multiple interface files are specified.
"""
file1 = osp.join(self.INTERFACE_DIR, 'part1.i')
file2 = osp.join(self.INTERFACE_DIR, 'part2.i')
wrapper = MatlabWrapper(
module_name='multiple_files',
top_module_namespace=['gtsam'],
ignore_classes=[''],
)
wrapper.wrap([file1, file2], path=self.MATLAB_ACTUAL_DIR)
files = [
'multiple_files_wrapper.cpp',
'+gtsam/Class1.m',
'+gtsam/Class2.m',
'+gtsam/ClassA.m',
]
for file in files:
self.compare_and_diff(file)
if __name__ == '__main__':
unittest.main()

View File

@ -31,9 +31,9 @@ class TestWrap(unittest.TestCase):
# Create the `actual/python` directory
os.makedirs(PYTHON_ACTUAL_DIR, exist_ok=True)
def wrap_content(self, content, module_name, output_dir):
def wrap_content(self, sources, module_name, output_dir):
"""
Common function to wrap content.
Common function to wrap content in `sources`.
"""
with open(osp.join(self.TEST_DIR,
"pybind_wrapper.tpl")) as template_file:
@ -46,15 +46,12 @@ class TestWrap(unittest.TestCase):
ignore_classes=[''],
module_template=module_template)
cc_content = wrapper.wrap(content)
output = osp.join(self.TEST_DIR, output_dir, module_name + ".cpp")
if not osp.exists(osp.join(self.TEST_DIR, output_dir)):
os.mkdir(osp.join(self.TEST_DIR, output_dir))
with open(output, 'w') as f:
f.write(cc_content)
wrapper.wrap(sources, output)
return output
@ -76,39 +73,32 @@ class TestWrap(unittest.TestCase):
python3 ../pybind_wrapper.py --src geometry.h --module_name
geometry_py --out output/geometry_py.cc
"""
with open(osp.join(self.INTERFACE_DIR, 'geometry.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'geometry_py',
source = osp.join(self.INTERFACE_DIR, 'geometry.i')
output = self.wrap_content([source], 'geometry_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('geometry_pybind.cpp', output)
def test_functions(self):
"""Test interface file with function info."""
with open(osp.join(self.INTERFACE_DIR, 'functions.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'functions_py',
source = osp.join(self.INTERFACE_DIR, 'functions.i')
output = self.wrap_content([source], 'functions_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('functions_pybind.cpp', output)
def test_class(self):
"""Test interface file with only class info."""
with open(osp.join(self.INTERFACE_DIR, 'class.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'class_py', self.PYTHON_ACTUAL_DIR)
source = osp.join(self.INTERFACE_DIR, 'class.i')
output = self.wrap_content([source], 'class_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('class_pybind.cpp', output)
def test_inheritance(self):
"""Test interface file with class inheritance definitions."""
with open(osp.join(self.INTERFACE_DIR, 'inheritance.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'inheritance_py',
source = osp.join(self.INTERFACE_DIR, 'inheritance.i')
output = self.wrap_content([source], 'inheritance_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('inheritance_pybind.cpp', output)
@ -119,10 +109,8 @@ class TestWrap(unittest.TestCase):
python3 ../pybind_wrapper.py --src namespaces.i --module_name
namespaces_py --out output/namespaces_py.cpp
"""
with open(osp.join(self.INTERFACE_DIR, 'namespaces.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'namespaces_py',
source = osp.join(self.INTERFACE_DIR, 'namespaces.i')
output = self.wrap_content([source], 'namespaces_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('namespaces_pybind.cpp', output)
@ -131,10 +119,8 @@ class TestWrap(unittest.TestCase):
"""
Tests for operator overloading.
"""
with open(osp.join(self.INTERFACE_DIR, 'operator.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'operator_py',
source = osp.join(self.INTERFACE_DIR, 'operator.i')
output = self.wrap_content([source], 'operator_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('operator_pybind.cpp', output)
@ -143,10 +129,8 @@ class TestWrap(unittest.TestCase):
"""
Tests for some unique, non-trivial features.
"""
with open(osp.join(self.INTERFACE_DIR, 'special_cases.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'special_cases_py',
source = osp.join(self.INTERFACE_DIR, 'special_cases.i')
output = self.wrap_content([source], 'special_cases_py',
self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('special_cases_pybind.cpp', output)
@ -155,10 +139,8 @@ class TestWrap(unittest.TestCase):
"""
Test if enum generation is correct.
"""
with open(osp.join(self.INTERFACE_DIR, 'enum.i'), 'r') as f:
content = f.read()
output = self.wrap_content(content, 'enum_py', self.PYTHON_ACTUAL_DIR)
source = osp.join(self.INTERFACE_DIR, 'enum.i')
output = self.wrap_content([source], 'enum_py', self.PYTHON_ACTUAL_DIR)
self.compare_and_diff('enum_pybind.cpp', output)