Squashed 'wrap/' changes from 07330d100..d9ae5ce03
d9ae5ce03 Merge pull request #118 from borglab/feature/matlab-multi-files 9adddf7dd update the main script for matlab wrapping 0b0398d46 remove debug statements since they aren't needed for now df064a364 support for parsing mutiple interface files for Matlab wrapping 1929e197c add test for parsing multiple interface files bac442056 Merge pull request #117 from borglab/fix/matlab-refactor 331f4a8ce update tests to remove redundant code 5426e3af4 generate all content from within the wrap function f78612bf9 make directory check common b7acd7a1f fixed import and test setup 88007b153 Merge pull request #116 from borglab/feature/matlab-refactor a074896e6 utils -> mixins 414557e00 structure 187100439 update gitignore adbc55aea don't use class attributes in matlab wrapper f45ba5b2d broke down some large functions into smaller ones 7756f0548 add mixin for checks and call method to wrap global functions a318e2a67 Merge pull request #115 from borglab/feature/multiple-modules b02b74c3d convert matlab_wrapper to a submodule be8641e83 improved function naming in tests 02ddbfbb0 update tests and docs dfbded2c7 small fixes e9ec5af07 update docs d124e2cfb wrap multiple files 7c7342f86 update cmake to take in new changes for multiple modules 54850f724 Merge pull request #114 from borglab/fix/remove-py35 71ee98321 add mypy annotations ccaea6294 remove support for python 3.5 git-subtree-dir: wrap git-subtree-split: d9ae5ce036c4315db3c28b12db9c73eae246f314release/4.3a0
parent
56bede07cd
commit
4c410fcd0e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,4 +8,4 @@ __pycache__/
|
|||
# Files related to code coverage stats
|
||||
**/.coverage
|
||||
|
||||
gtwrap/matlab_wrapper.tpl
|
||||
gtwrap/matlab_wrapper/matlab_wrapper.tpl
|
||||
|
|
|
@ -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.
|
||||
|
|
8
DOCS.md
8
DOCS.md
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,15 +13,14 @@ gtwrap_get_python_version(${WRAP_PYTHON_VERSION})
|
|||
message(STATUS "Setting Python version for wrapper")
|
||||
set(PYBIND11_PYTHON_VERSION ${WRAP_PYTHON_VERSION})
|
||||
|
||||
# User-friendly Pybind11 wrapping and installing function.
|
||||
# Builds a Pybind11 module from the provided interface_header.
|
||||
# For example, for the interface header gtsam.h, this will
|
||||
# build the wrap module 'gtsam_py.cc'.
|
||||
# User-friendly Pybind11 wrapping and installing function. Builds a Pybind11
|
||||
# module from the provided interface_headers. For example, for the interface
|
||||
# header gtsam.h, this will build the wrap module 'gtsam_py.cc'.
|
||||
#
|
||||
# Arguments:
|
||||
# ~~~
|
||||
# target: The Make target
|
||||
# interface_header: The relative path to the wrapper interface definition file.
|
||||
# interface_headers: List of paths to the wrapper interface definition files. The top level interface file should be first.
|
||||
# generated_cpp: The name of the cpp file which is generated from the tpl file.
|
||||
# module_name: The name of the Python module to use.
|
||||
# top_namespace: The C++ namespace under which the code to be wrapped exists.
|
||||
|
@ -31,16 +30,17 @@ set(PYBIND11_PYTHON_VERSION ${WRAP_PYTHON_VERSION})
|
|||
# libs: Libraries to link with.
|
||||
# dependencies: Dependencies which need to be built before the wrapper.
|
||||
# use_boost (optional): Flag indicating whether to include Boost.
|
||||
function(pybind_wrap
|
||||
target
|
||||
interface_header
|
||||
generated_cpp
|
||||
module_name
|
||||
top_namespace
|
||||
ignore_classes
|
||||
module_template
|
||||
libs
|
||||
dependencies)
|
||||
function(
|
||||
pybind_wrap
|
||||
target
|
||||
interface_headers
|
||||
generated_cpp
|
||||
module_name
|
||||
top_namespace
|
||||
ignore_classes
|
||||
module_template
|
||||
libs
|
||||
dependencies)
|
||||
set(ExtraMacroArgs ${ARGN})
|
||||
list(GET ExtraMacroArgs 0 USE_BOOST)
|
||||
if(USE_BOOST)
|
||||
|
@ -49,57 +49,62 @@ function(pybind_wrap
|
|||
set(_WRAP_BOOST_ARG "")
|
||||
endif(USE_BOOST)
|
||||
|
||||
if (UNIX)
|
||||
if(UNIX)
|
||||
set(GTWRAP_PATH_SEPARATOR ":")
|
||||
else()
|
||||
set(GTWRAP_PATH_SEPARATOR ";")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${generated_cpp}
|
||||
COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${GTWRAP_PACKAGE_DIR}${GTWRAP_PATH_SEPARATOR}$ENV{PYTHONPATH}"
|
||||
${PYTHON_EXECUTABLE}
|
||||
${PYBIND_WRAP_SCRIPT}
|
||||
--src
|
||||
${interface_header}
|
||||
--out
|
||||
${generated_cpp}
|
||||
--module_name
|
||||
${module_name}
|
||||
--top_module_namespaces
|
||||
"${top_namespace}"
|
||||
--ignore
|
||||
${ignore_classes}
|
||||
--template
|
||||
${module_template}
|
||||
${_WRAP_BOOST_ARG}
|
||||
DEPENDS ${interface_header} ${module_template}
|
||||
VERBATIM)
|
||||
add_custom_target(pybind_wrap_${module_name} ALL DEPENDS ${generated_cpp})
|
||||
# Convert .i file names to .cpp file names.
|
||||
foreach(filepath ${interface_headers})
|
||||
get_filename_component(interface ${filepath} NAME)
|
||||
string(REPLACE ".i" ".cpp" cpp_file ${interface})
|
||||
list(APPEND cpp_files ${cpp_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${cpp_files}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
"PYTHONPATH=${GTWRAP_PACKAGE_DIR}${GTWRAP_PATH_SEPARATOR}$ENV{PYTHONPATH}"
|
||||
${PYTHON_EXECUTABLE} ${PYBIND_WRAP_SCRIPT} --src "${interface_headers}"
|
||||
--out "${generated_cpp}" --module_name ${module_name}
|
||||
--top_module_namespaces "${top_namespace}" --ignore ${ignore_classes}
|
||||
--template ${module_template} ${_WRAP_BOOST_ARG}
|
||||
DEPENDS "${interface_headers}" ${module_template}
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(pybind_wrap_${module_name} ALL DEPENDS ${cpp_files})
|
||||
|
||||
# Late dependency injection, to make sure this gets called whenever the
|
||||
# interface header or the wrap library are updated.
|
||||
# ~~~
|
||||
# See: https://stackoverflow.com/questions/40032593/cmake-does-not-rebuild-dependent-after-prerequisite-changes
|
||||
# ~~~
|
||||
add_custom_command(OUTPUT ${generated_cpp}
|
||||
DEPENDS ${interface_header}
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/interface_parser.py
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/pybind_wrapper.py
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/template_instantiator.py
|
||||
APPEND)
|
||||
add_custom_command(
|
||||
OUTPUT ${cpp_files}
|
||||
DEPENDS ${interface_headers}
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/interface_parser.py
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/pybind_wrapper.py
|
||||
# @GTWRAP_SOURCE_DIR@/gtwrap/template_instantiator.py
|
||||
APPEND)
|
||||
|
||||
pybind11_add_module(${target} ${generated_cpp})
|
||||
pybind11_add_module(${target} "${cpp_files}")
|
||||
|
||||
if(APPLE)
|
||||
# `type_info` objects will become "weak private external" if the templated class is initialized implicitly even if we explicitly
|
||||
# export them with `WRAP_EXPORT`. If that happens, the `type_info` for the same templated class will diverge between shared
|
||||
# libraries, causing `dynamic_cast` to fail. This is mitigated by telling Clang to mimic the MSVC behavior.
|
||||
# See https://developer.apple.com/library/archive/technotes/tn2185/_index.html#//apple_ref/doc/uid/DTS10004200-CH1-SUBSECTION2
|
||||
# `type_info` objects will become "weak private external" if the templated
|
||||
# class is initialized implicitly even if we explicitly export them with
|
||||
# `WRAP_EXPORT`. If that happens, the `type_info` for the same templated
|
||||
# class will diverge between shared libraries, causing `dynamic_cast` to
|
||||
# fail. This is mitigated by telling Clang to mimic the MSVC behavior. See
|
||||
# https://developer.apple.com/library/archive/technotes/tn2185/_index.html#//apple_ref/doc/uid/DTS10004200-CH1-SUBSECTION2
|
||||
# https://github.com/CppMicroServices/CppMicroServices/pull/82/files
|
||||
# https://www.russellmcc.com/posts/2013-08-03-rtti.html
|
||||
target_compile_options(${target} PRIVATE "-fvisibility-ms-compat")
|
||||
endif()
|
||||
|
||||
add_dependencies(${target} pybind_wrap_${module_name})
|
||||
|
||||
if(NOT "${libs}" STREQUAL "")
|
||||
target_link_libraries(${target} PRIVATE "${libs}")
|
||||
endif()
|
||||
|
@ -121,10 +126,7 @@ endfunction()
|
|||
# dest_directory: The destination directory to install to.
|
||||
# patterns: list of file patterns to install
|
||||
# ~~~
|
||||
function(install_python_scripts
|
||||
source_directory
|
||||
dest_directory
|
||||
patterns)
|
||||
function(install_python_scripts source_directory dest_directory patterns)
|
||||
set(patterns_args "")
|
||||
set(exclude_patterns "")
|
||||
|
||||
|
@ -144,17 +146,19 @@ function(install_python_scripts
|
|||
# there is one
|
||||
get_filename_component(location "${dest_directory}" PATH)
|
||||
get_filename_component(name "${dest_directory}" NAME)
|
||||
install(DIRECTORY "${source_directory}"
|
||||
DESTINATION "${location}/${name}${build_type_tag}"
|
||||
CONFIGURATIONS "${build_type}"
|
||||
FILES_MATCHING ${patterns_args}
|
||||
PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
install(
|
||||
DIRECTORY "${source_directory}"
|
||||
DESTINATION "${location}/${name}${build_type_tag}"
|
||||
CONFIGURATIONS "${build_type}"
|
||||
FILES_MATCHING ${patterns_args}
|
||||
PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
endforeach()
|
||||
else()
|
||||
install(DIRECTORY "${source_directory}"
|
||||
DESTINATION "${dest_directory}"
|
||||
FILES_MATCHING ${patterns_args}
|
||||
PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
install(
|
||||
DIRECTORY "${source_directory}"
|
||||
DESTINATION "${dest_directory}"
|
||||
FILES_MATCHING ${patterns_args}
|
||||
PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
@ -172,13 +176,14 @@ function(install_python_files source_files dest_directory)
|
|||
foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${build_type}" build_type_upper)
|
||||
set(build_type_tag "")
|
||||
# Split up filename to strip trailing '/' in WRAP_PY_INSTALL_PATH if
|
||||
# there is one
|
||||
# Split up filename to strip trailing '/' in WRAP_PY_INSTALL_PATH if there
|
||||
# is one
|
||||
get_filename_component(location "${dest_directory}" PATH)
|
||||
get_filename_component(name "${dest_directory}" NAME)
|
||||
install(FILES "${source_files}"
|
||||
DESTINATION "${location}/${name}${build_type_tag}"
|
||||
CONFIGURATIONS "${build_type}")
|
||||
install(
|
||||
FILES "${source_files}"
|
||||
DESTINATION "${location}/${name}${build_type_tag}"
|
||||
CONFIGURATIONS "${build_type}")
|
||||
endforeach()
|
||||
else()
|
||||
install(FILES "${source_files}" DESTINATION "${dest_directory}")
|
||||
|
@ -194,18 +199,19 @@ function(create_symlinks source_folder dest_folder)
|
|||
return()
|
||||
endif()
|
||||
|
||||
file(GLOB files
|
||||
LIST_DIRECTORIES true
|
||||
RELATIVE "${source_folder}"
|
||||
"${source_folder}/*")
|
||||
file(
|
||||
GLOB files
|
||||
LIST_DIRECTORIES true
|
||||
RELATIVE "${source_folder}"
|
||||
"${source_folder}/*")
|
||||
foreach(path_file ${files})
|
||||
get_filename_component(folder ${path_file} PATH)
|
||||
get_filename_component(ext ${path_file} EXT)
|
||||
set(ignored_ext ".tpl" ".h")
|
||||
list (FIND ignored_ext "${ext}" _index)
|
||||
if (${_index} GREATER -1)
|
||||
list(FIND ignored_ext "${ext}" _index)
|
||||
if(${_index} GREATER -1)
|
||||
continue()
|
||||
endif ()
|
||||
endif()
|
||||
# Create REAL folder
|
||||
file(MAKE_DIRECTORY "${dest_folder}")
|
||||
|
||||
|
@ -224,9 +230,10 @@ function(create_symlinks source_folder dest_folder)
|
|||
endif()
|
||||
# cmake-format: on
|
||||
|
||||
execute_process(COMMAND ${command}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE output)
|
||||
execute_process(
|
||||
COMMAND ${command}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE output)
|
||||
|
||||
if(NOT ${result} EQUAL 0)
|
||||
message(
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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=''):
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
"""Package to wrap C++ code to Matlab via MEX."""
|
||||
|
||||
from .wrapper import MatlabWrapper
|
|
@ -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):]
|
|
@ -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=' ')
|
File diff suppressed because it is too large
Load Diff
|
@ -13,6 +13,7 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae
|
|||
# pylint: disable=too-many-arguments, too-many-instance-attributes, no-self-use, no-else-return, too-many-arguments, unused-format-string-argument, line-too-long
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import gtwrap.interface_parser as parser
|
||||
import gtwrap.template_instantiator as instantiator
|
||||
|
@ -32,7 +33,7 @@ class PybindWrapper:
|
|||
self.top_module_namespaces = top_module_namespaces
|
||||
self.use_boost = use_boost
|
||||
self.ignore_classes = ignore_classes
|
||||
self._serializing_classes = list()
|
||||
self._serializing_classes = []
|
||||
self.module_template = module_template
|
||||
self.python_keywords = [
|
||||
'lambda', 'False', 'def', 'if', 'raise', 'None', 'del', 'import',
|
||||
|
@ -160,7 +161,7 @@ class PybindWrapper:
|
|||
'self->print',
|
||||
'py::scoped_ostream_redirect output; self->print')
|
||||
|
||||
# Make __repr__() call print() internally
|
||||
# Make __repr__() call .print() internally
|
||||
ret += '''{prefix}.def("__repr__",
|
||||
[](const {cpp_class}& self{opt_comma}{args_signature_with_names}){{
|
||||
gtsam::RedirectCout redirect;
|
||||
|
@ -557,8 +558,15 @@ class PybindWrapper:
|
|||
)
|
||||
return wrapped, includes
|
||||
|
||||
def wrap(self, content):
|
||||
"""Wrap the code in the interface file."""
|
||||
def wrap_file(self, content, module_name=None, submodules=None):
|
||||
"""
|
||||
Wrap the code in the interface file.
|
||||
|
||||
Args:
|
||||
content: The contents of the interface file.
|
||||
module_name: The name of the module.
|
||||
submodules: List of other interface file names that should be linked to.
|
||||
"""
|
||||
# Parse the contents of the interface file
|
||||
module = parser.Module.parseString(content)
|
||||
# Instantiate all templates
|
||||
|
@ -574,23 +582,74 @@ class PybindWrapper:
|
|||
if ',' in cpp_class:
|
||||
new_name = re.sub("[,:<> ]", "", cpp_class)
|
||||
boost_class_export += "typedef {cpp_class} {new_name};\n".format( # noqa
|
||||
cpp_class=cpp_class,
|
||||
new_name=new_name,
|
||||
)
|
||||
cpp_class=cpp_class, new_name=new_name)
|
||||
|
||||
boost_class_export += "BOOST_CLASS_EXPORT({new_name})\n".format(
|
||||
new_name=new_name, )
|
||||
|
||||
# Reset the serializing classes list
|
||||
self._serializing_classes = []
|
||||
|
||||
holder_type = "PYBIND11_DECLARE_HOLDER_TYPE(TYPE_PLACEHOLDER_DONOTUSE, " \
|
||||
"{shared_ptr_type}::shared_ptr<TYPE_PLACEHOLDER_DONOTUSE>);"
|
||||
include_boost = "#include <boost/shared_ptr.hpp>" if self.use_boost else ""
|
||||
|
||||
submodules_init = []
|
||||
|
||||
if submodules is not None:
|
||||
module_def = "PYBIND11_MODULE({0}, m_)".format(module_name)
|
||||
|
||||
for idx, submodule in enumerate(submodules):
|
||||
submodules[idx] = "void {0}(py::module_ &);".format(submodule)
|
||||
submodules_init.append("{0}(m_);".format(submodule))
|
||||
|
||||
else:
|
||||
module_def = "void {0}(py::module_ &m_)".format(module_name)
|
||||
submodules = []
|
||||
|
||||
return self.module_template.format(
|
||||
include_boost=include_boost,
|
||||
module_name=self.module_name,
|
||||
module_def=module_def,
|
||||
module_name=module_name,
|
||||
includes=includes,
|
||||
holder_type=holder_type.format(
|
||||
shared_ptr_type=('boost' if self.use_boost else 'std'))
|
||||
if self.use_boost else "",
|
||||
wrapped_namespace=wrapped_namespace,
|
||||
boost_class_export=boost_class_export,
|
||||
submodules="\n".join(submodules),
|
||||
submodules_init="\n".join(submodules_init),
|
||||
)
|
||||
|
||||
def wrap(self, sources, main_output):
|
||||
"""
|
||||
Wrap all the source interface files.
|
||||
|
||||
Args:
|
||||
sources: List of all interface files.
|
||||
main_output: The name for the main module.
|
||||
"""
|
||||
main_module = sources[0]
|
||||
submodules = []
|
||||
for source in sources[1:]:
|
||||
filename = Path(source).name
|
||||
module_name = Path(source).stem
|
||||
# Read in the complete interface (.i) file
|
||||
with open(source, "r") as f:
|
||||
content = f.read()
|
||||
submodules.append(module_name)
|
||||
cc_content = self.wrap_file(content, module_name=module_name)
|
||||
|
||||
# Generate the C++ code which Pybind11 will use.
|
||||
with open(filename.replace(".i", ".cpp"), "w") as f:
|
||||
f.write(cc_content)
|
||||
|
||||
with open(main_module, "r") as f:
|
||||
content = f.read()
|
||||
cc_content = self.wrap_file(content,
|
||||
module_name=self.module_name,
|
||||
submodules=submodules)
|
||||
|
||||
# Generate the C++ code which Pybind11 will use.
|
||||
with open(main_output, "w") as f:
|
||||
f.write(cc_content)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -67,10 +67,6 @@ def main():
|
|||
if top_module_namespaces[0]:
|
||||
top_module_namespaces = [''] + top_module_namespaces
|
||||
|
||||
# Read in the complete interface (.i) file
|
||||
with open(args.src, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
with open(args.template, "r") as f:
|
||||
template_content = f.read()
|
||||
|
||||
|
@ -83,11 +79,8 @@ def main():
|
|||
)
|
||||
|
||||
# Wrap the code and get back the cpp/cc code.
|
||||
cc_content = wrapper.wrap(content)
|
||||
|
||||
# Generate the C++ code which Pybind11 will use.
|
||||
with open(args.out, "w") as f:
|
||||
f.write(cc_content)
|
||||
sources = args.src.split(';')
|
||||
wrapper.wrap(sources, args.out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <pybind11/iostream.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include "gtsam/base/serialization.h"
|
||||
#include "gtsam/nonlinear/utilities.h" // for RedirectCout.
|
||||
#include "gtsam/base/utilities.h" // for RedirectCout.
|
||||
|
||||
{includes}
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
@ -22,9 +22,13 @@ using namespace std;
|
|||
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_MODULE({module_name}, m_) {{
|
||||
{submodules}
|
||||
|
||||
{module_def} {{
|
||||
m_.doc() = "pybind11 wrapper of {module_name}";
|
||||
|
||||
{submodules_init}
|
||||
|
||||
{wrapped_namespace}
|
||||
|
||||
#include "python/specializations.h"
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// First file to test for multi-file support.
|
||||
|
||||
namespace gtsam {
|
||||
class Class1 {
|
||||
Class1();
|
||||
};
|
||||
|
||||
class Class2 {
|
||||
Class2();
|
||||
};
|
||||
} // namespace gtsam
|
|
@ -0,0 +1,7 @@
|
|||
// Second file to test for multi-file support.
|
||||
|
||||
namespace gtsam {
|
||||
class ClassA {
|
||||
ClassA();
|
||||
};
|
||||
} // namespace gtsam
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue