Merging 'master' into 'wrap'
commit
54e5dc23aa
|
@ -1,52 +0,0 @@
|
|||
name: Python CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.name }} 🐍 ${{ matrix.python_version }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: ${{ matrix.python_version }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Github Actions requires a single row to be added to the build matrix.
|
||||
# See https://help.github.com/en/articles/workflow-syntax-for-github-actions.
|
||||
name: [
|
||||
ubuntu-18.04
|
||||
]
|
||||
|
||||
python_version: [3]
|
||||
include:
|
||||
- name: ubuntu-18.04
|
||||
os: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Install (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
|
||||
sudo apt install cmake build-essential pkg-config libpython-dev python-numpy libboost-all-dev
|
||||
- name: Install (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew install cmake ninja boost
|
||||
- name: Build (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo pip$PYTHON_VERSION install -r requirements.txt
|
||||
cd tests
|
||||
python$PYTHON_VERSION test_pybind_wrapper.py
|
||||
python$PYTHON_VERSION test_matlab_wrapper.py
|
||||
- name: Build (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
pip$PYTHON_VERSION install -r requirements.txt
|
||||
cd tests
|
||||
python$PYTHON_VERSION test_pybind_wrapper.py
|
||||
python$PYTHON_VERSION test_matlab_wrapper.py
|
|
@ -0,0 +1,38 @@
|
|||
name: Wrap CI for Linux
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Tests for 🐍 ${{ matrix.python-version }}
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt install cmake build-essential pkg-config libpython-dev python-numpy libboost-all-dev
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Python Dependencies
|
||||
run: |
|
||||
sudo pip3 install -U pip setuptools
|
||||
sudo pip3 install -r requirements.txt
|
||||
|
||||
- name: Build and Test
|
||||
run: |
|
||||
cd tests
|
||||
# Use Pytest to run all the tests.
|
||||
pytest
|
|
@ -0,0 +1,36 @@
|
|||
name: Wrap CI for macOS
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Tests for 🐍 ${{ matrix.python-version }}
|
||||
runs-on: macos-10.15
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
brew install cmake ninja boost
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Python Dependencies
|
||||
run: |
|
||||
pip3 install -r requirements.txt
|
||||
|
||||
- name: Build and Test
|
||||
run: |
|
||||
cd tests
|
||||
# Use Pytest to run all the tests.
|
||||
pytest
|
|
@ -3,3 +3,6 @@ __pycache__/
|
|||
*build*
|
||||
*dist*
|
||||
*.egg-info
|
||||
|
||||
# Files related to code coverage stats
|
||||
**/.coverage
|
|
@ -31,17 +31,17 @@ include(GNUInstallDirs)
|
|||
|
||||
# Install the gtwrap python package as a directory so it can be found by CMake
|
||||
# for wrapping.
|
||||
install(DIRECTORY gtwrap DESTINATION "${CMAKE_INSTALL_DATADIR}/gtwrap")
|
||||
install(DIRECTORY gtwrap DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap")
|
||||
|
||||
# Install wrapping scripts as binaries to `CMAKE_INSTALL_PREFIX/bin` so they can
|
||||
# be invoked for wrapping. We use DESTINATION (instead of TYPE) so we can
|
||||
# support older CMake versions.
|
||||
install(PROGRAMS scripts/pybind_wrap.py scripts/matlab_wrap.py
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_BINDIR})
|
||||
|
||||
# Install pybind11 directory to `CMAKE_INSTALL_PREFIX/lib/gtwrap/pybind11` This
|
||||
# will allow the gtwrapConfig.cmake file to load it later.
|
||||
install(DIRECTORY pybind11 DESTINATION "${CMAKE_INSTALL_LIBDIR}/gtwrap")
|
||||
install(DIRECTORY pybind11 DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap")
|
||||
|
||||
# Install the matlab.h file to `CMAKE_INSTALL_PREFIX/lib/gtwrap/matlab.h`.
|
||||
install(FILES matlab.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gtwrap")
|
||||
install(FILES matlab.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/gtwrap")
|
||||
|
|
17
wrap/DOCS.md
17
wrap/DOCS.md
|
@ -52,8 +52,8 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
|
|||
- Class variables are read-write so they can be updated directly in Python.
|
||||
|
||||
- Pointer types
|
||||
- To declare a pointer type (including shared pointers), simply add an asterisk (i.e. `*`) to the class name.
|
||||
- E.g. `gtsam::noiseModel::Base*` to define the wrapping for the `Base` noise model shared pointer.
|
||||
- To declare a simple/raw pointer, simply add an `@` to the class name, e.g.`Pose3@`.
|
||||
- To declare a shared pointer (e.g. `gtsam::noiseModel::Base::shared_ptr`), use an asterisk (i.e. `*`). E.g. `gtsam::noiseModel::Base*` to define the wrapping for the `Base` noise model shared pointer.
|
||||
|
||||
- Comments can use either C++ or C style, with multiple lines.
|
||||
|
||||
|
@ -76,9 +76,13 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
|
|||
- Functions specified outside of a class are **global**.
|
||||
- Can be overloaded with different arguments.
|
||||
- Can have multiple functions of the same name in different namespaces.
|
||||
- Functions can be templated and have multiple template arguments, e.g.
|
||||
```cpp
|
||||
template<T, >
|
||||
```
|
||||
|
||||
- Using classes defined in other modules
|
||||
- If you are using a class `OtherClass` not wrapped in an interface file, add `class OtherClass;` as a forward declaration to avoid a dependency error.
|
||||
- If you are using a class `OtherClass` not wrapped in an interface file, add `class OtherClass;` as a forward declaration to avoid a dependency error. `OtherClass` should be in the same project.
|
||||
|
||||
- Virtual inheritance
|
||||
- Specify fully-qualified base classes, i.e. `virtual class Derived : ns::Base {` where `ns` is the namespace.
|
||||
|
@ -140,9 +144,9 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
|
|||
|
||||
- Forward declarations and class definitions for **Pybind**:
|
||||
- Need to specify the base class (both this forward class and base class are declared in an external Pybind header)
|
||||
This is so that Pybind can generate proper inheritance.
|
||||
- This is so that Pybind can generate proper inheritance.
|
||||
|
||||
Example when wrapping a gtsam-based project:
|
||||
- Example for when wrapping a gtsam-based project:
|
||||
|
||||
```cpp
|
||||
// forward declarations
|
||||
|
@ -153,8 +157,7 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
|
|||
virtual class MyFactor : gtsam::NoiseModelFactor {...};
|
||||
```
|
||||
|
||||
- **DO NOT** re-define an overriden function already declared in the external (forward-declared) base class
|
||||
- This will cause an ambiguity problem in Pybind header file.
|
||||
- **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.
|
||||
|
||||
|
||||
### TODO
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
# This config file modifies CMAKE_MODULE_PATH so that the wrap cmake files may
|
||||
# be included This file also allows the use of `find_package(gtwrap)` in CMake.
|
||||
|
||||
set(GTWRAP_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
set(GTWRAP_CMAKE_DIR "${GTWRAP_DIR}")
|
||||
set(GTWRAP_SCRIPT_DIR ${GTWRAP_CMAKE_DIR}/../../../bin)
|
||||
set(GTWRAP_PYTHON_PACKAGE_DIR ${GTWRAP_CMAKE_DIR}/../../../share/gtwrap)
|
||||
else()
|
||||
set(GTWRAP_CMAKE_DIR "${GTWRAP_DIR}")
|
||||
set(GTWRAP_SCRIPT_DIR ${GTWRAP_CMAKE_DIR}/../../../bin)
|
||||
set(GTWRAP_PYTHON_PACKAGE_DIR ${GTWRAP_CMAKE_DIR}/../../../share/gtwrap)
|
||||
endif()
|
||||
|
||||
# Standard includes
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(GTWRAP_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
set(GTWRAP_CMAKE_DIR "${GTWRAP_DIR}")
|
||||
set(GTWRAP_SCRIPT_DIR ${CMAKE_INSTALL_FULL_BINDIR})
|
||||
set(GTWRAP_PYTHON_PACKAGE_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap)
|
||||
else()
|
||||
set(GTWRAP_CMAKE_DIR "${GTWRAP_DIR}")
|
||||
set(GTWRAP_SCRIPT_DIR ${CMAKE_INSTALL_FULL_BINDIR})
|
||||
set(GTWRAP_PYTHON_PACKAGE_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap)
|
||||
endif()
|
||||
|
||||
# Load all the CMake scripts from the standard location
|
||||
include(${GTWRAP_CMAKE_DIR}/PybindWrap.cmake)
|
||||
include(${GTWRAP_CMAKE_DIR}/GtwrapUtils.cmake)
|
||||
|
@ -28,4 +29,4 @@ set(PYBIND_WRAP_SCRIPT "${GTWRAP_SCRIPT_DIR}/pybind_wrap.py")
|
|||
set(MATLAB_WRAP_SCRIPT "${GTWRAP_SCRIPT_DIR}/matlab_wrap.py")
|
||||
|
||||
# Load the pybind11 code from the library installation path
|
||||
add_subdirectory(${GTWRAP_CMAKE_DIR}/../../gtwrap/pybind11 pybind11)
|
||||
add_subdirectory(${CMAKE_INSTALL_FULL_LIBDIR}/gtwrap/pybind11 pybind11)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Doxyfile 1.8.11
|
||||
# Doxyfile 1.9.1
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
|
@ -17,11 +17,11 @@
|
|||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# This tag specifies the encoding used for all characters in the config file
|
||||
# that follow. The default is UTF-8 which is also the encoding used for all text
|
||||
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
|
||||
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
|
||||
# for the list of possible encodings.
|
||||
# This tag specifies the encoding used for all characters in the configuration
|
||||
# file that follow. The default is UTF-8 which is also the encoding used for all
|
||||
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||
# iconv built into libc) for the transcoding. See
|
||||
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
|
@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
|
|||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = "GTSAM"
|
||||
PROJECT_NAME = GTSAM
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
|
@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
|
|||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all generated output in the proper direction.
|
||||
# Possible values are: None, LTR, RTL and Context.
|
||||
# The default value is: None.
|
||||
|
||||
OUTPUT_TEXT_DIRECTION = None
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
|
||||
# descriptions after the members that are listed in the file and class
|
||||
# documentation (similar to Javadoc). Set to NO to disable this.
|
||||
|
@ -179,6 +187,16 @@ SHORT_NAMES = NO
|
|||
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
|
||||
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
|
||||
# such as
|
||||
# /***************
|
||||
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
|
||||
# Javadoc-style will behave just like regular comments and it will not be
|
||||
# interpreted by doxygen.
|
||||
# The default value is: NO.
|
||||
|
||||
JAVADOC_BANNER = NO
|
||||
|
||||
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
||||
# line (until the first dot) of a Qt-style comment as the brief description. If
|
||||
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
|
||||
|
@ -199,6 +217,14 @@ QT_AUTOBRIEF = NO
|
|||
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
|
||||
# By default Python docstrings are displayed as preformatted text and doxygen's
|
||||
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
|
||||
# doxygen's special commands can be used and the contents of the docstring
|
||||
# documentation blocks is shown as doxygen documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
PYTHON_DOCSTRING = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||
# documentation from any documented member that it re-implements.
|
||||
# The default value is: YES.
|
||||
|
@ -226,16 +252,15 @@ TAB_SIZE = 4
|
|||
# will allow you to put the command \sideeffect (or @sideeffect) in the
|
||||
# documentation, which will result in a user-defined paragraph with heading
|
||||
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
||||
# newlines.
|
||||
# newlines (in the resulting output). You can put ^^ in the value part of an
|
||||
# alias to insert a newline as if a physical newline was in the original file.
|
||||
# When you need a literal { or } or , in the value part of an alias you have to
|
||||
# escape them by means of a backslash (\), this can lead to conflicts with the
|
||||
# commands \{ and \} for these it is advised to use the version @{ and @} or use
|
||||
# a double escape (\\{ and \\})
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
|
@ -264,28 +289,40 @@ OPTIMIZE_FOR_FORTRAN = NO
|
|||
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
|
||||
# sources only. Doxygen will then generate output that is more tailored for that
|
||||
# language. For instance, namespaces will be presented as modules, types will be
|
||||
# separated into more groups, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_SLICE = NO
|
||||
|
||||
# Doxygen selects the parser to use depending on the extension of the files it
|
||||
# parses. With this tag you can assign which parser to use for a given
|
||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
|
||||
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
|
||||
# Fortran. In the later case the parser tries to guess whether the code is fixed
|
||||
# or free formatted code, this is the default for Fortran type files), VHDL. For
|
||||
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
|
||||
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
|
||||
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||
# default for Fortran type files). For instance to make doxygen treat .inc files
|
||||
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||
# use: inc=Fortran f=C.
|
||||
#
|
||||
# Note: For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||
# the files are not read by doxygen.
|
||||
# the files are not read by doxygen. When specifying no_extension you should add
|
||||
# * to the FILE_PATTERNS.
|
||||
#
|
||||
# Note see also the list of default file extension mappings.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
|
||||
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
||||
# according to the Markdown format, which allows for more readable
|
||||
# documentation. See http://daringfireball.net/projects/markdown/ for details.
|
||||
# documentation. See https://daringfireball.net/projects/markdown/ for details.
|
||||
# The output of markdown processing is further processed by doxygen, so you can
|
||||
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
||||
# case of backward compatibilities issues.
|
||||
|
@ -293,6 +330,15 @@ EXTENSION_MAPPING =
|
|||
|
||||
MARKDOWN_SUPPORT = YES
|
||||
|
||||
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
|
||||
# to that level are automatically included in the table of contents, even if
|
||||
# they do not have an id attribute.
|
||||
# Note: This feature currently applies only to Markdown headings.
|
||||
# Minimum value: 0, maximum value: 99, default value: 5.
|
||||
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||
|
||||
TOC_INCLUDE_HEADINGS = 5
|
||||
|
||||
# When enabled doxygen tries to link words that correspond to documented
|
||||
# classes, or namespaces to their corresponding documentation. Such a link can
|
||||
# be prevented in individual cases by putting a % sign in front of the word or
|
||||
|
@ -318,7 +364,7 @@ BUILTIN_STL_SUPPORT = NO
|
|||
CPP_CLI_SUPPORT = NO
|
||||
|
||||
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
|
||||
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
|
||||
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
|
||||
# will parse them like normal C++ but will assume all classes use public instead
|
||||
# of private inheritance when no explicit protection keyword is present.
|
||||
# The default value is: NO.
|
||||
|
@ -404,6 +450,19 @@ TYPEDEF_HIDES_STRUCT = NO
|
|||
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
|
||||
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
|
||||
# during processing. When set to 0 doxygen will based this on the number of
|
||||
# cores available in the system. You can set it explicitly to a value larger
|
||||
# than 0 to get more control over the balance between CPU load and processing
|
||||
# speed. At this moment only the input processing can be done using multiple
|
||||
# threads. Since this is still an experimental feature the default is set to 1,
|
||||
# which efficively disables parallel processing. Please report any issues you
|
||||
# encounter. Generating dot graphs in parallel is controlled by the
|
||||
# DOT_NUM_THREADS setting.
|
||||
# Minimum value: 0, maximum value: 32, default value: 1.
|
||||
|
||||
NUM_PROC_THREADS = 1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -416,7 +475,7 @@ LOOKUP_CACHE_SIZE = 0
|
|||
# normally produced when WARNINGS is set to YES.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_ALL =
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
||||
# be included in the documentation.
|
||||
|
@ -424,6 +483,12 @@ EXTRACT_ALL =
|
|||
|
||||
EXTRACT_PRIVATE = NO
|
||||
|
||||
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
|
||||
# methods of a class will be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PRIV_VIRTUAL = NO
|
||||
|
||||
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
||||
# scope will be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
@ -461,6 +526,13 @@ EXTRACT_LOCAL_METHODS = NO
|
|||
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
# If this flag is set to YES, the name of an unnamed parameter in a declaration
|
||||
# will be determined by the corresponding definition. By default unnamed
|
||||
# parameters remain unnamed in the output.
|
||||
# The default value is: YES.
|
||||
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
|
||||
# undocumented members inside documented classes or files. If set to NO these
|
||||
# members will be included in the various overviews, but no documentation
|
||||
|
@ -478,8 +550,8 @@ HIDE_UNDOC_MEMBERS = NO
|
|||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
||||
# (class|struct|union) declarations. If set to NO, these declarations will be
|
||||
# included in the documentation.
|
||||
# declarations. If set to NO, these declarations will be included in the
|
||||
# documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
|
@ -498,11 +570,18 @@ HIDE_IN_BODY_DOCS = NO
|
|||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# and Mac users are advised to set this option to NO.
|
||||
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
|
||||
# able to match the capabilities of the underlying filesystem. In case the
|
||||
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||
# whose names only differ in casing), the option must be set to YES to properly
|
||||
# deal with such files in case they appear in the input. For filesystems that
|
||||
# are not case sensitive the option should be be set to NO to properly deal with
|
||||
# output files written for symbols that only differ in casing, such as for two
|
||||
# classes, one named CLASS and the other named Class, and to also support
|
||||
# references to files without having to specify the exact matching casing. On
|
||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||
# YES.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
@ -689,7 +768,7 @@ LAYOUT_FILE =
|
|||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||
# the reference definitions. This must be a list of .bib files. The .bib
|
||||
# extension is automatically appended if omitted. This requires the bibtex tool
|
||||
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
|
||||
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
|
||||
# For LaTeX the style of the bibliography can be controlled using
|
||||
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||
# search path. See also \cite for info how to create references.
|
||||
|
@ -734,13 +813,17 @@ WARN_IF_DOC_ERROR = YES
|
|||
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
||||
# are documented, but have no documentation for their parameters or return
|
||||
# value. If set to NO, doxygen will only warn about wrong or incomplete
|
||||
# parameter documentation, but not about the absence of documentation.
|
||||
# parameter documentation, but not about the absence of documentation. If
|
||||
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_NO_PARAMDOC = NO
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||
# at the end of the doxygen process doxygen will return with a non-zero status.
|
||||
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
||||
|
@ -776,8 +859,8 @@ INPUT =
|
|||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
|
||||
# possible encodings.
|
||||
# documentation (see:
|
||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
|
@ -790,11 +873,15 @@ INPUT_ENCODING = UTF-8
|
|||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# read by doxygen.
|
||||
#
|
||||
# Note the list of default checked file patterns might differ from the list of
|
||||
# default file extension mappings.
|
||||
#
|
||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
|
||||
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
||||
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
|
||||
# *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS =
|
||||
|
||||
|
@ -949,7 +1036,7 @@ INLINE_SOURCES = NO
|
|||
STRIP_CODE_COMMENTS = YES
|
||||
|
||||
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
||||
# function all documented functions referencing it will be listed.
|
||||
# entity all documented functions referencing it will be listed.
|
||||
# The default value is: NO.
|
||||
|
||||
REFERENCED_BY_RELATION = NO
|
||||
|
@ -981,12 +1068,12 @@ SOURCE_TOOLTIPS = YES
|
|||
# If the USE_HTAGS tag is set to YES then the references to source code will
|
||||
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
|
||||
# source browser. The htags tool is part of GNU's global source tagging system
|
||||
# (see http://www.gnu.org/software/global/global.html). You will need version
|
||||
# (see https://www.gnu.org/software/global/global.html). You will need version
|
||||
# 4.8.6 or higher.
|
||||
#
|
||||
# To use it do the following:
|
||||
# - Install the latest version of global
|
||||
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
|
||||
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
|
||||
# - Make sure the INPUT points to the root of the source tree
|
||||
# - Run doxygen as normal
|
||||
#
|
||||
|
@ -1008,25 +1095,6 @@ USE_HTAGS = NO
|
|||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
|
||||
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
|
||||
# cost of reduced performance. This can be particularly helpful with template
|
||||
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
||||
# information.
|
||||
# Note: The availability of this option depends on whether or not doxygen was
|
||||
# generated with the -Duse-libclang=ON option for CMake.
|
||||
# The default value is: NO.
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||
# line options that you would normally use when invoking the compiler. Note that
|
||||
# the include paths will already be set by doxygen for the files and directories
|
||||
# specified with INPUT and INCLUDE_PATH.
|
||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||
|
||||
CLANG_OPTIONS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1038,13 +1106,6 @@ CLANG_OPTIONS =
|
|||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
|
@ -1145,7 +1206,7 @@ HTML_EXTRA_FILES =
|
|||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||
# will adjust the colors in the style sheet and background images according to
|
||||
# this color. Hue is specified as an angle on a colorwheel, see
|
||||
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
|
||||
# purple, and 360 is red again.
|
||||
# Minimum value: 0, maximum value: 359, default value: 220.
|
||||
|
@ -1181,6 +1242,17 @@ HTML_COLORSTYLE_GAMMA = 80
|
|||
|
||||
HTML_TIMESTAMP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||
# documentation will contain a main index with vertical navigation menus that
|
||||
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||
# consists of multiple levels of tabs that are statically embedded in every HTML
|
||||
# page. Disable this option to support browsers that do not have JavaScript,
|
||||
# like the Qt help browser.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_DYNAMIC_MENUS = YES
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
# page has loaded.
|
||||
|
@ -1204,13 +1276,14 @@ HTML_INDEX_NUM_ENTRIES = 100
|
|||
|
||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
|
||||
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||
# that directory and running make install will install the docset in
|
||||
# environment (see:
|
||||
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
|
||||
# create a documentation set, doxygen will generate a Makefile in the HTML
|
||||
# output directory. Running make will produce the docset in that directory and
|
||||
# running make install will install the docset in
|
||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
|
||||
# for more information.
|
||||
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||
# genXcode/_index.html for more information.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
|
@ -1249,8 +1322,8 @@ DOCSET_PUBLISHER_NAME = Publisher
|
|||
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||
# Windows.
|
||||
# (see:
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
|
||||
#
|
||||
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||
|
@ -1280,7 +1353,7 @@ CHM_FILE =
|
|||
HHC_LOCATION =
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
# (YES) or that it should be included in the main .chm file (NO).
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
|
@ -1325,7 +1398,8 @@ QCH_FILE =
|
|||
|
||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||
# Project output. For more information please see Qt Help Project / Namespace
|
||||
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
|
||||
# (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# The default value is: org.doxygen.Project.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
|
@ -1333,8 +1407,8 @@ QHP_NAMESPACE = org.doxygen.Project
|
|||
|
||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
|
||||
# folders).
|
||||
# Folders (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
|
||||
# The default value is: doc.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
|
@ -1342,30 +1416,30 @@ QHP_VIRTUAL_FOLDER = doc
|
|||
|
||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||
# filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_NAME =
|
||||
|
||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
|
||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
|
||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||
# generated .qhp file.
|
||||
# The QHG_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
|
||||
# run qhelpgenerator on the generated .qhp file.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHG_LOCATION =
|
||||
|
@ -1442,6 +1516,17 @@ TREEVIEW_WIDTH = 250
|
|||
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
|
||||
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||
# Possible values are: png (the default) and svg (looks nicer but requires the
|
||||
# pdf2svg or inkscape tool).
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FORMULA_FORMAT = png
|
||||
|
||||
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||
# the HTML documentation. When you change the font size after a successful
|
||||
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||
|
@ -1451,7 +1536,7 @@ EXT_LINKS_IN_WINDOW = NO
|
|||
|
||||
FORMULA_FONTSIZE = 10
|
||||
|
||||
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
|
||||
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
|
||||
# generated for formulas are transparent PNGs. Transparent PNGs are not
|
||||
# supported properly for IE 6.0, but are supported on all modern browsers.
|
||||
#
|
||||
|
@ -1462,8 +1547,14 @@ FORMULA_FONTSIZE = 10
|
|||
|
||||
FORMULA_TRANSPARENT = YES
|
||||
|
||||
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||
# the section "Including formulas" for details.
|
||||
|
||||
FORMULA_MACROFILE =
|
||||
|
||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||
# http://www.mathjax.org) which uses client side Javascript for the rendering
|
||||
# https://www.mathjax.org) which uses client side JavaScript for the rendering
|
||||
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
||||
# installed or if you want to formulas look prettier in the HTML output. When
|
||||
# enabled you may also need to install MathJax separately and configure the path
|
||||
|
@ -1475,7 +1566,7 @@ USE_MATHJAX = NO
|
|||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
# http://docs.mathjax.org/en/latest/output.html) for more details.
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
|
||||
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||
# compatibility), NativeMML (i.e. MathML) and SVG.
|
||||
# The default value is: HTML-CSS.
|
||||
|
@ -1490,8 +1581,8 @@ MATHJAX_FORMAT = HTML-CSS
|
|||
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
|
||||
# Content Delivery Network so you can quickly see the result without installing
|
||||
# MathJax. However, it is strongly recommended to install a local copy of
|
||||
# MathJax from http://www.mathjax.org before deployment.
|
||||
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||
# MathJax from https://www.mathjax.org before deployment.
|
||||
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
|
@ -1505,7 +1596,8 @@ MATHJAX_EXTENSIONS =
|
|||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
|
||||
# (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
|
||||
# example see the documentation.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
|
@ -1533,7 +1625,7 @@ MATHJAX_CODEFILE =
|
|||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a web server instead of a web client using Javascript. There
|
||||
# implemented using a web server instead of a web client using JavaScript. There
|
||||
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||
|
@ -1552,7 +1644,8 @@ SERVER_BASED_SEARCH = NO
|
|||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: http://xapian.org/).
|
||||
# Xapian (see:
|
||||
# https://xapian.org/).
|
||||
#
|
||||
# See the section "External Indexing and Searching" for details.
|
||||
# The default value is: NO.
|
||||
|
@ -1565,8 +1658,9 @@ EXTERNAL_SEARCH = NO
|
|||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: http://xapian.org/). See the section "External Indexing and
|
||||
# Searching" for details.
|
||||
# Xapian (see:
|
||||
# https://xapian.org/). See the section "External Indexing and Searching" for
|
||||
# details.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
SEARCHENGINE_URL =
|
||||
|
@ -1617,21 +1711,35 @@ LATEX_OUTPUT = latex
|
|||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||
# invoked.
|
||||
#
|
||||
# Note that when enabling USE_PDFLATEX this option is only used for generating
|
||||
# bitmaps for formulas in the HTML output, but not in the Makefile that is
|
||||
# written to the output directory.
|
||||
# The default file is: latex.
|
||||
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
|
||||
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
|
||||
# chosen this is overwritten by pdflatex. For specific output languages the
|
||||
# default can have been set differently, this depends on the implementation of
|
||||
# the output language.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_CMD_NAME = latex
|
||||
|
||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
||||
# index for LaTeX.
|
||||
# Note: This tag is used in the Makefile / make.bat.
|
||||
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
|
||||
# (.tex).
|
||||
# The default file is: makeindex.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
|
||||
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
|
||||
# generate index for LaTeX. In case there is no backslash (\) as first character
|
||||
# it will be automatically added in the LaTeX code.
|
||||
# Note: This tag is used in the generated output file (.tex).
|
||||
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
|
||||
# The default value is: makeindex.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_MAKEINDEX_CMD = makeindex
|
||||
|
||||
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
|
||||
# documents. This may be useful for small projects and may help to save some
|
||||
# trees in general.
|
||||
|
@ -1716,9 +1824,11 @@ LATEX_EXTRA_FILES =
|
|||
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
|
||||
# higher quality PDF documentation.
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
|
||||
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
|
||||
# files. Set this option to YES, to get a higher quality PDF documentation.
|
||||
#
|
||||
# See also section LATEX_CMD_NAME for selecting the engine.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
|
@ -1752,7 +1862,7 @@ LATEX_SOURCE_CODE = NO
|
|||
|
||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||
# bibliography, e.g. plainnat, or ieeetr. See
|
||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
# The default value is: plain.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
|
@ -1766,6 +1876,14 @@ LATEX_BIB_STYLE = plain
|
|||
|
||||
LATEX_TIMESTAMP = NO
|
||||
|
||||
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# path from which the emoji images will be read. If a relative path is entered,
|
||||
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||
# LATEX_OUTPUT directory will be used.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_EMOJI_DIRECTORY =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1805,9 +1923,9 @@ COMPACT_RTF = NO
|
|||
|
||||
RTF_HYPERLINKS = NO
|
||||
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
|
||||
# file, i.e. a series of assignments. You only have to provide replacements,
|
||||
# missing definitions are set to their default value.
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||
# configuration file, i.e. a series of assignments. You only have to provide
|
||||
# replacements, missing definitions are set to their default value.
|
||||
#
|
||||
# See also section "Doxygen usage" for information on how to generate the
|
||||
# default style sheet that doxygen normally uses.
|
||||
|
@ -1816,8 +1934,8 @@ RTF_HYPERLINKS = NO
|
|||
RTF_STYLESHEET_FILE =
|
||||
|
||||
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||
# similar to doxygen's config file. A template extensions file can be generated
|
||||
# using doxygen -e rtf extensionFile.
|
||||
# similar to doxygen's configuration file. A template extensions file can be
|
||||
# generated using doxygen -e rtf extensionFile.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
@ -1903,6 +2021,13 @@ XML_OUTPUT = xml
|
|||
|
||||
XML_PROGRAMLISTING = YES
|
||||
|
||||
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
|
||||
# namespace members in file scope as well, matching the HTML output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_NS_MEMB_FILE_SCOPE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the DOCBOOK output
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -1935,9 +2060,9 @@ DOCBOOK_PROGRAMLISTING = NO
|
|||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
|
||||
# AutoGen Definitions (see http://autogen.sf.net) file that captures the
|
||||
# structure of the code including all documentation. Note that this feature is
|
||||
# still experimental and incomplete at the moment.
|
||||
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
|
||||
# the structure of the code including all documentation. Note that this feature
|
||||
# is still experimental and incomplete at the moment.
|
||||
# The default value is: NO.
|
||||
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
|
@ -2104,12 +2229,6 @@ EXTERNAL_GROUPS = YES
|
|||
|
||||
EXTERNAL_PAGES = YES
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
# The default file (with absolute path) is: /usr/bin/perl.
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -2123,15 +2242,6 @@ PERL_PATH = /usr/bin/perl
|
|||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
|
@ -2150,7 +2260,7 @@ HIDE_UNDOC_RELATIONS = YES
|
|||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||
# Bell Labs. The other options in this section have no effect if this option is
|
||||
# set to NO
|
||||
# The default value is: YES.
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = YES
|
||||
|
||||
|
@ -2229,10 +2339,32 @@ UML_LOOK = NO
|
|||
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||
# 10.
|
||||
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
||||
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
|
||||
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
|
||||
# tag is set to YES, doxygen will add type and arguments for attributes and
|
||||
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
|
||||
# will not generate fields with class member information in the UML graphs. The
|
||||
# class diagrams will look similar to the default class diagrams but using UML
|
||||
# notation for the relationships.
|
||||
# Possible values are: NO, YES and NONE.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
DOT_UML_DETAILS = NO
|
||||
|
||||
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
|
||||
# to display on a single line. If the actual line length exceeds this threshold
|
||||
# significantly it will wrapped across multiple lines. Some heuristics are apply
|
||||
# to avoid ugly line breaks.
|
||||
# Minimum value: 0, maximum value: 1000, default value: 17.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
|
||||
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||
# collaboration graphs will show the relations between templates and their
|
||||
# instances.
|
||||
|
@ -2306,9 +2438,7 @@ DIRECTORY_GRAPH = YES
|
|||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||
# requirement).
|
||||
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
|
||||
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
|
||||
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
|
||||
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
|
||||
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
||||
# png:gdiplus:gdiplus.
|
||||
# The default value is: png.
|
||||
|
@ -2361,6 +2491,11 @@ DIAFILE_DIRS =
|
|||
|
||||
PLANTUML_JAR_PATH =
|
||||
|
||||
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
|
||||
# configuration file for plantuml.
|
||||
|
||||
PLANTUML_CFG_FILE =
|
||||
|
||||
# When using plantuml, the specified paths are searched for files specified by
|
||||
# the !include statement in a plantuml block.
|
||||
|
||||
|
@ -2419,9 +2554,11 @@ DOT_MULTI_TARGETS = NO
|
|||
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
|
||||
# files that are used to generate the various graphs.
|
||||
#
|
||||
# Note: This setting is not only used for dot files but also for msc and
|
||||
# plantuml temporary files.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
|
@ -4,7 +4,7 @@ import xml.etree.ElementTree as ET
|
|||
|
||||
from docs.docs import ClassDoc, Doc, Docs, FreeDoc
|
||||
|
||||
DOXYGEN_CONF = 'conf_doxygen.py'
|
||||
DOXYGEN_CONF = 'doxygen.conf'
|
||||
|
||||
|
||||
class ParseDoxygenXML():
|
||||
|
|
|
@ -4,7 +4,7 @@ from docs.doc_template import ClassDoc, Doc, Docs, FreeDoc
|
|||
import os.path as path
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
DOXYGEN_CONF = 'conf_doxygen.py'
|
||||
DOXYGEN_CONF = 'doxygen.conf'
|
||||
|
||||
|
||||
def parse(input_path, output_path, quiet=False, generate_xml_flag=True):
|
||||
|
|
|
@ -12,11 +12,11 @@ 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
|
||||
|
||||
import sys
|
||||
import typing
|
||||
from typing import Iterable, Union, Tuple, List
|
||||
|
||||
import pyparsing
|
||||
import pyparsing # type: ignore
|
||||
from pyparsing import (CharsNotIn, Forward, Group, Keyword, Literal, OneOrMore,
|
||||
Optional, Or, ParseException, ParserElement, Suppress,
|
||||
Optional, Or, ParseException, ParseResults, ParserElement, Suppress,
|
||||
Word, ZeroOrMore, alphanums, alphas, cppStyleComment,
|
||||
delimitedList, empty, nums, stringEnd)
|
||||
|
||||
|
@ -43,7 +43,8 @@ ParserElement.enablePackrat()
|
|||
# rule for identifiers (e.g. variable names)
|
||||
IDENT = Word(alphas + '_', alphanums + '_') ^ Word(nums)
|
||||
|
||||
POINTER, REF = map(Literal, "*&")
|
||||
RAW_POINTER, SHARED_POINTER, REF = map(Literal, "@*&")
|
||||
|
||||
LPAREN, RPAREN, LBRACE, RBRACE, COLON, SEMI_COLON = map(Suppress, "(){}:;")
|
||||
LOPBRACK, ROPBRACK, COMMA, EQUAL = map(Suppress, "<>,=")
|
||||
CONST, VIRTUAL, CLASS, STATIC, PAIR, TEMPLATE, TYPEDEF, INCLUDE = map(
|
||||
|
@ -71,36 +72,50 @@ BASIS_TYPES = map(
|
|||
"size_t",
|
||||
"double",
|
||||
"float",
|
||||
"string",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class Typename:
|
||||
"""
|
||||
Type's name with full namespaces, used in Type class.
|
||||
Generic type which can be either a basic type or a class type,
|
||||
similar to C++'s `typename` aka a qualified dependent type.
|
||||
Contains type name with full namespace and template arguments.
|
||||
|
||||
E.g.
|
||||
```
|
||||
gtsam::PinholeCamera<gtsam::Cal3S2>
|
||||
```
|
||||
|
||||
will give the name as `PinholeCamera`, namespace as `gtsam`,
|
||||
and template instantiations as `[gtsam::Cal3S2]`.
|
||||
|
||||
Args:
|
||||
namespaces_and_name: A list representing the namespaces of the type
|
||||
with the type being the last element.
|
||||
instantiations: Template parameters to the type.
|
||||
"""
|
||||
|
||||
namespaces_name_rule = delimitedList(IDENT, "::")
|
||||
instantiation_name_rule = delimitedList(IDENT, "::")
|
||||
rule = Forward()
|
||||
|
||||
rule << (
|
||||
namespaces_name_rule("namespaces_name")
|
||||
namespaces_name_rule("namespaces_and_name") #
|
||||
+ Optional(
|
||||
(LOPBRACK + delimitedList(rule, ",")("instantiations") + ROPBRACK)
|
||||
)
|
||||
).setParseAction(lambda t: Typename(t.namespaces_name, t.instantiations))
|
||||
(LOPBRACK + delimitedList(rule, ",")("instantiations") + ROPBRACK))
|
||||
).setParseAction(lambda t: Typename(t.namespaces_and_name, t.instantiations))
|
||||
|
||||
def __init__(self, namespaces_name, instantiations=()):
|
||||
self.namespaces = namespaces_name[:-1]
|
||||
self.name = namespaces_name[-1]
|
||||
def __init__(self,
|
||||
namespaces_and_name: ParseResults,
|
||||
instantiations: Union[tuple, list, str, ParseResults] = ()):
|
||||
self.name = namespaces_and_name[-1] # the name is the last element in this list
|
||||
self.namespaces = namespaces_and_name[:-1]
|
||||
|
||||
if instantiations:
|
||||
if not isinstance(instantiations, typing.Iterable):
|
||||
self.instantiations = instantiations.asList()
|
||||
if isinstance(instantiations, Iterable):
|
||||
self.instantiations = instantiations # type: ignore
|
||||
else:
|
||||
self.instantiations = instantiations
|
||||
self.instantiations = instantiations.asList()
|
||||
else:
|
||||
self.instantiations = []
|
||||
|
||||
|
@ -108,21 +123,21 @@ class Typename:
|
|||
self.namespaces = ["gtsam"]
|
||||
|
||||
@staticmethod
|
||||
def from_parse_result(parse_result):
|
||||
"""Return the typename from the parsed result."""
|
||||
def from_parse_result(parse_result: Union[str, list]):
|
||||
"""Unpack the parsed result to get the Typename instance."""
|
||||
return parse_result[0]
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return self.to_cpp()
|
||||
|
||||
def instantiated_name(self):
|
||||
def instantiated_name(self) -> str:
|
||||
"""Get the instantiated name of the type."""
|
||||
res = self.name
|
||||
for instantiation in self.instantiations:
|
||||
res += instantiation.instantiated_name()
|
||||
return res
|
||||
|
||||
def to_cpp(self):
|
||||
def to_cpp(self) -> str:
|
||||
"""Generate the C++ code for wrapping."""
|
||||
idx = 1 if self.namespaces and not self.namespaces[0] else 0
|
||||
if self.instantiations:
|
||||
|
@ -137,93 +152,111 @@ class Typename:
|
|||
cpp_name,
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
def __eq__(self, other) -> bool:
|
||||
if isinstance(other, Typename):
|
||||
return str(self) == str(other)
|
||||
else:
|
||||
return NotImplemented
|
||||
return False
|
||||
|
||||
def __ne__(self, other):
|
||||
def __ne__(self, other) -> bool:
|
||||
res = self.__eq__(other)
|
||||
if res is NotImplemented:
|
||||
return res
|
||||
return not res
|
||||
|
||||
|
||||
class Type:
|
||||
"""
|
||||
The type value that is parsed, e.g. void, string, size_t.
|
||||
"""
|
||||
class _QualifiedType:
|
||||
"""
|
||||
Type with qualifiers.
|
||||
"""
|
||||
class QualifiedType:
|
||||
"""Type with qualifiers, such as `const`."""
|
||||
|
||||
rule = (
|
||||
Optional(CONST("is_const"))
|
||||
+ Typename.rule("typename")
|
||||
+ Optional(POINTER("is_ptr") | REF("is_ref"))
|
||||
Typename.rule("typename") #
|
||||
+ Optional(SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr") | REF("is_ref"))
|
||||
).setParseAction(
|
||||
lambda t: Type._QualifiedType(
|
||||
Typename.from_parse_result(t.typename),
|
||||
t.is_const,
|
||||
t.is_ptr,
|
||||
t.is_ref,
|
||||
)
|
||||
lambda t: QualifiedType(t)
|
||||
)
|
||||
|
||||
def __init__(self, typename, is_const, is_ptr, is_ref):
|
||||
self.typename = typename
|
||||
self.is_const = is_const
|
||||
self.is_ptr = is_ptr
|
||||
self.is_ref = is_ref
|
||||
def __init__(self, t: ParseResults):
|
||||
self.typename = Typename.from_parse_result(t.typename)
|
||||
self.is_shared_ptr = t.is_shared_ptr
|
||||
self.is_ptr = t.is_ptr
|
||||
self.is_ref = t.is_ref
|
||||
|
||||
class _BasisType:
|
||||
"""
|
||||
Basis types don't have qualifiers and only allow copy-by-value.
|
||||
class BasisType:
|
||||
"""
|
||||
Basis types are the built-in types in C++ such as double, int, char, etc.
|
||||
|
||||
rule = Or(BASIS_TYPES).setParseAction(lambda t: Typename(t))
|
||||
When using templates, the basis type will take on the same form as the template.
|
||||
|
||||
E.g.
|
||||
```
|
||||
template<T = {double}>
|
||||
void func(const T& x);
|
||||
```
|
||||
|
||||
will give
|
||||
|
||||
```
|
||||
m_.def("CoolFunctionDoubleDouble",[](const double& s) {
|
||||
return wrap_example::CoolFunction<double,double>(s);
|
||||
}, py::arg("s"));
|
||||
```
|
||||
"""
|
||||
|
||||
rule = (
|
||||
_BasisType.rule("basis") | _QualifiedType.rule("qualified") # BR
|
||||
Or(BASIS_TYPES)("typename") #
|
||||
+ Optional(SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr") | REF("is_ref")) #
|
||||
).setParseAction(lambda t: BasisType(t))
|
||||
|
||||
def __init__(self, t: ParseResults):
|
||||
self.typename = Typename([t.typename])
|
||||
self.is_ptr = t.is_ptr
|
||||
self.is_shared_ptr = t.is_shared_ptr
|
||||
self.is_ref = t.is_ref
|
||||
|
||||
class Type:
|
||||
"""The type value that is parsed, e.g. void, string, size_t."""
|
||||
rule = (
|
||||
Optional(CONST("is_const")) #
|
||||
+ (BasisType.rule("basis") | QualifiedType.rule("qualified")) # BR
|
||||
).setParseAction(lambda t: Type.from_parse_result(t))
|
||||
|
||||
def __init__(self, typename, is_const, is_ptr, is_ref, is_basis):
|
||||
def __init__(self, typename: Typename, is_const: str, is_shared_ptr: str,
|
||||
is_ptr: str, is_ref: str, is_basis: bool):
|
||||
self.typename = typename
|
||||
self.is_const = is_const
|
||||
self.is_shared_ptr = is_shared_ptr
|
||||
self.is_ptr = is_ptr
|
||||
self.is_ref = is_ref
|
||||
self.is_basis = is_basis
|
||||
|
||||
@staticmethod
|
||||
def from_parse_result(t):
|
||||
def from_parse_result(t: ParseResults):
|
||||
"""Return the resulting Type from parsing the source."""
|
||||
if t.basis:
|
||||
return Type(
|
||||
typename=t.basis,
|
||||
is_const='',
|
||||
is_ptr='',
|
||||
is_ref='',
|
||||
typename=t.basis.typename,
|
||||
is_const=t.is_const,
|
||||
is_shared_ptr=t.basis.is_shared_ptr,
|
||||
is_ptr=t.basis.is_ptr,
|
||||
is_ref=t.basis.is_ref,
|
||||
is_basis=True,
|
||||
)
|
||||
elif t.qualified:
|
||||
return Type(
|
||||
typename=t.qualified.typename,
|
||||
is_const=t.qualified.is_const,
|
||||
is_const=t.is_const,
|
||||
is_shared_ptr=t.qualified.is_shared_ptr,
|
||||
is_ptr=t.qualified.is_ptr,
|
||||
is_ref=t.qualified.is_ref,
|
||||
is_basis=False,
|
||||
)
|
||||
else:
|
||||
raise ValueError("Parse result is not a Type?")
|
||||
raise ValueError("Parse result is not a Type")
|
||||
|
||||
def __repr__(self):
|
||||
return '{} {}{}{}'.format(
|
||||
self.typename, self.is_const, self.is_ptr, self.is_ref
|
||||
)
|
||||
def __repr__(self) -> str:
|
||||
return "{self.typename} " \
|
||||
"{self.is_const}{self.is_shared_ptr}{self.is_ptr}{self.is_ref}".format(
|
||||
self=self)
|
||||
|
||||
def to_cpp(self, use_boost):
|
||||
def to_cpp(self, use_boost: bool) -> str:
|
||||
"""
|
||||
Generate the C++ code for wrapping.
|
||||
|
||||
|
@ -231,26 +264,24 @@ class Type:
|
|||
Treat Matrix and Vector as "const Matrix&" and "const Vector&" resp.
|
||||
"""
|
||||
shared_ptr_ns = "boost" if use_boost else "std"
|
||||
return (
|
||||
"{const} {shared_ptr}{typename}"
|
||||
"{shared_ptr_ropbracket}{ref}".format(
|
||||
const="const"
|
||||
if self.is_const
|
||||
or self.is_ptr
|
||||
or self.typename.name in ["Matrix", "Vector"]
|
||||
else "",
|
||||
typename=self.typename.to_cpp(),
|
||||
shared_ptr="{}::shared_ptr<".format(shared_ptr_ns)
|
||||
if self.is_ptr
|
||||
else "",
|
||||
shared_ptr_ropbracket=">" if self.is_ptr else "",
|
||||
ref="&"
|
||||
if self.is_ref
|
||||
or self.is_ptr
|
||||
or self.typename.name in ["Matrix", "Vector"]
|
||||
else "",
|
||||
)
|
||||
)
|
||||
|
||||
if self.is_shared_ptr:
|
||||
# always pass by reference: https://stackoverflow.com/a/8741626/1236990
|
||||
typename = "{ns}::shared_ptr<{typename}>&".format(
|
||||
ns=shared_ptr_ns, typename=self.typename.to_cpp())
|
||||
elif self.is_ptr:
|
||||
typename = "{typename}*".format(typename=self.typename.to_cpp())
|
||||
elif self.is_ref or self.typename.name in ["Matrix", "Vector"]:
|
||||
typename = typename = "{typename}&".format(
|
||||
typename=self.typename.to_cpp())
|
||||
else:
|
||||
typename = self.typename.to_cpp()
|
||||
|
||||
return ("{const}{typename}".format(
|
||||
const="const " if
|
||||
(self.is_const
|
||||
or self.typename.name in ["Matrix", "Vector"]) else "",
|
||||
typename=typename))
|
||||
|
||||
|
||||
class Argument:
|
||||
|
@ -259,18 +290,18 @@ class Argument:
|
|||
|
||||
E.g.
|
||||
```
|
||||
void sayHello(/*s is the method argument with type `const string&`*/ const string& s);
|
||||
void sayHello(/*`s` is the method argument with type `const string&`*/ const string& s);
|
||||
```
|
||||
"""
|
||||
rule = (Type.rule("ctype") + IDENT("name")).setParseAction(
|
||||
lambda t: Argument(t.ctype, t.name)
|
||||
)
|
||||
rule = (Type.rule("ctype") +
|
||||
IDENT("name")).setParseAction(lambda t: Argument(t.ctype, t.name))
|
||||
|
||||
def __init__(self, ctype, name):
|
||||
def __init__(self, ctype: Type, name: str):
|
||||
self.ctype = ctype
|
||||
self.name = name
|
||||
self.parent: Union[ArgumentList, None] = None
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return '{} {}'.format(self.ctype.__repr__(), self.name)
|
||||
|
||||
|
||||
|
@ -282,27 +313,32 @@ class ArgumentList:
|
|||
lambda t: ArgumentList.from_parse_result(t.args_list)
|
||||
)
|
||||
|
||||
def __init__(self, args_list):
|
||||
def __init__(self, args_list: List[Argument]):
|
||||
self.args_list = args_list
|
||||
for arg in args_list:
|
||||
arg.parent = self
|
||||
self.parent: Union[Method, StaticMethod, Template, Constructor,
|
||||
GlobalFunction, None] = None
|
||||
|
||||
@staticmethod
|
||||
def from_parse_result(parse_result):
|
||||
def from_parse_result(parse_result: ParseResults):
|
||||
"""Return the result of parsing."""
|
||||
if parse_result:
|
||||
return ArgumentList(parse_result.asList())
|
||||
else:
|
||||
return ArgumentList([])
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return self.args_list.__repr__()
|
||||
|
||||
def args_names(self):
|
||||
def __len__(self) -> int:
|
||||
return len(self.args_list)
|
||||
|
||||
def args_names(self) -> List[str]:
|
||||
"""Return a list of the names of all the arguments."""
|
||||
return [arg.name for arg in self.args_list]
|
||||
|
||||
def to_cpp(self, use_boost):
|
||||
def to_cpp(self, use_boost: bool) -> List[str]:
|
||||
"""Generate the C++ code for wrapping."""
|
||||
return [arg.ctype.to_cpp(use_boost) for arg in self.args_list]
|
||||
|
||||
|
@ -314,40 +350,44 @@ class ReturnType:
|
|||
The return type can either be a single type or a pair such as <type1, type2>.
|
||||
"""
|
||||
_pair = (
|
||||
PAIR.suppress()
|
||||
+ LOPBRACK
|
||||
+ Type.rule("type1")
|
||||
+ COMMA
|
||||
+ Type.rule("type2")
|
||||
+ ROPBRACK
|
||||
PAIR.suppress() #
|
||||
+ LOPBRACK #
|
||||
+ Type.rule("type1") #
|
||||
+ COMMA #
|
||||
+ Type.rule("type2") #
|
||||
+ ROPBRACK #
|
||||
)
|
||||
rule = (_pair ^ Type.rule("type1")).setParseAction( # BR
|
||||
lambda t: ReturnType(t.type1, t.type2)
|
||||
)
|
||||
lambda t: ReturnType(t.type1, t.type2))
|
||||
|
||||
def __init__(self, type1, type2):
|
||||
def __init__(self, type1: Type, type2: Type):
|
||||
self.type1 = type1
|
||||
self.type2 = type2
|
||||
self.parent: Union[Method, StaticMethod, GlobalFunction, None] = None
|
||||
|
||||
def is_void(self):
|
||||
def is_void(self) -> bool:
|
||||
"""
|
||||
Check if the return type is void.
|
||||
"""
|
||||
return self.type1.typename.name == "void" and not self.type2
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "{}{}".format(
|
||||
self.type1, (', ' + self.type2.__repr__()) if self.type2 else ''
|
||||
)
|
||||
self.type1, (', ' + self.type2.__repr__()) if self.type2 else '')
|
||||
|
||||
def to_cpp(self):
|
||||
"""Generate the C++ code for wrapping."""
|
||||
def to_cpp(self, use_boost: bool) -> str:
|
||||
"""
|
||||
Generate the C++ code for wrapping.
|
||||
|
||||
If there are two return types, we return a pair<>,
|
||||
otherwise we return the regular return type.
|
||||
"""
|
||||
if self.type2:
|
||||
return "std::pair<{type1},{type2}>".format(
|
||||
type1=self.type1.to_cpp(), type2=self.type2.to_cpp()
|
||||
)
|
||||
type1=self.type1.to_cpp(use_boost),
|
||||
type2=self.type2.to_cpp(use_boost))
|
||||
else:
|
||||
return self.type1.to_cpp()
|
||||
return self.type1.to_cpp(use_boost)
|
||||
|
||||
|
||||
class Template:
|
||||
|
@ -365,20 +405,16 @@ class Template:
|
|||
template<typename POSE> // POSE is the Instantiation.
|
||||
"""
|
||||
rule = (
|
||||
IDENT("typename")
|
||||
+ Optional(
|
||||
EQUAL
|
||||
+ LBRACE
|
||||
+ ((delimitedList(Typename.rule)("instantiations")))
|
||||
+ RBRACE
|
||||
)
|
||||
).setParseAction(
|
||||
lambda t: Template.TypenameAndInstantiations(
|
||||
t.typename, t.instantiations
|
||||
)
|
||||
)
|
||||
IDENT("typename") #
|
||||
+ Optional( #
|
||||
EQUAL #
|
||||
+ LBRACE #
|
||||
+ ((delimitedList(Typename.rule)("instantiations"))) #
|
||||
+ RBRACE #
|
||||
)).setParseAction(lambda t: Template.TypenameAndInstantiations(
|
||||
t.typename, t.instantiations))
|
||||
|
||||
def __init__(self, typename, instantiations):
|
||||
def __init__(self, typename: str, instantiations: ParseResults):
|
||||
self.typename = typename
|
||||
|
||||
if instantiations:
|
||||
|
@ -387,22 +423,20 @@ class Template:
|
|||
self.instantiations = []
|
||||
|
||||
rule = ( # BR
|
||||
TEMPLATE
|
||||
+ LOPBRACK
|
||||
TEMPLATE #
|
||||
+ LOPBRACK #
|
||||
+ delimitedList(TypenameAndInstantiations.rule)(
|
||||
"typename_and_instantiations_list"
|
||||
)
|
||||
"typename_and_instantiations_list") #
|
||||
+ ROPBRACK # BR
|
||||
).setParseAction(
|
||||
lambda t: Template(t.typename_and_instantiations_list.asList())
|
||||
)
|
||||
lambda t: Template(t.typename_and_instantiations_list.asList()))
|
||||
|
||||
def __init__(self, typename_and_instantiations_list):
|
||||
def __init__(self, typename_and_instantiations_list: List[TypenameAndInstantiations]):
|
||||
ti_list = typename_and_instantiations_list
|
||||
self.typenames = [ti.typename for ti in ti_list]
|
||||
self.instantiations = [ti.instantiations for ti in ti_list]
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "<{0}>".format(", ".join(self.typenames))
|
||||
|
||||
|
||||
|
@ -418,21 +452,24 @@ class Method:
|
|||
```
|
||||
"""
|
||||
rule = (
|
||||
Optional(Template.rule("template"))
|
||||
+ ReturnType.rule("return_type")
|
||||
+ IDENT("name")
|
||||
+ LPAREN
|
||||
+ ArgumentList.rule("args_list")
|
||||
+ RPAREN
|
||||
+ Optional(CONST("is_const"))
|
||||
Optional(Template.rule("template")) #
|
||||
+ ReturnType.rule("return_type") #
|
||||
+ IDENT("name") #
|
||||
+ LPAREN #
|
||||
+ ArgumentList.rule("args_list") #
|
||||
+ RPAREN #
|
||||
+ Optional(CONST("is_const")) #
|
||||
+ SEMI_COLON # BR
|
||||
).setParseAction(
|
||||
lambda t: Method(
|
||||
t.template, t.name, t.return_type, t.args_list, t.is_const
|
||||
)
|
||||
)
|
||||
).setParseAction(lambda t: Method(t.template, t.name, t.return_type, t.
|
||||
args_list, t.is_const))
|
||||
|
||||
def __init__(self, template, name, return_type, args, is_const, parent=''):
|
||||
def __init__(self,
|
||||
template: str,
|
||||
name: str,
|
||||
return_type: ReturnType,
|
||||
args: ArgumentList,
|
||||
is_const: str,
|
||||
parent: Union[str, "Class"] = ''):
|
||||
self.template = template
|
||||
self.name = name
|
||||
self.return_type = return_type
|
||||
|
@ -441,7 +478,7 @@ class Method:
|
|||
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "Method: {} {} {}({}){}".format(
|
||||
self.template,
|
||||
self.return_type,
|
||||
|
@ -463,28 +500,31 @@ class StaticMethod:
|
|||
```
|
||||
"""
|
||||
rule = (
|
||||
STATIC
|
||||
+ ReturnType.rule("return_type")
|
||||
+ IDENT("name")
|
||||
+ LPAREN
|
||||
+ ArgumentList.rule("args_list")
|
||||
+ RPAREN
|
||||
STATIC #
|
||||
+ ReturnType.rule("return_type") #
|
||||
+ IDENT("name") #
|
||||
+ LPAREN #
|
||||
+ ArgumentList.rule("args_list") #
|
||||
+ RPAREN #
|
||||
+ SEMI_COLON # BR
|
||||
).setParseAction(
|
||||
lambda t: StaticMethod(t.name, t.return_type, t.args_list)
|
||||
)
|
||||
lambda t: StaticMethod(t.name, t.return_type, t.args_list))
|
||||
|
||||
def __init__(self, name, return_type, args, parent=''):
|
||||
def __init__(self,
|
||||
name: str,
|
||||
return_type: ReturnType,
|
||||
args: ArgumentList,
|
||||
parent: Union[str, "Class"] = ''):
|
||||
self.name = name
|
||||
self.return_type = return_type
|
||||
self.args = args
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "static {} {}{}".format(self.return_type, self.name, self.args)
|
||||
|
||||
def to_cpp(self):
|
||||
def to_cpp(self) -> str:
|
||||
"""Generate the C++ code for wrapping."""
|
||||
return self.name
|
||||
|
||||
|
@ -495,20 +535,20 @@ class Constructor:
|
|||
Can have 0 or more arguments.
|
||||
"""
|
||||
rule = (
|
||||
IDENT("name")
|
||||
+ LPAREN
|
||||
+ ArgumentList.rule("args_list")
|
||||
+ RPAREN
|
||||
IDENT("name") #
|
||||
+ LPAREN #
|
||||
+ ArgumentList.rule("args_list") #
|
||||
+ RPAREN #
|
||||
+ SEMI_COLON # BR
|
||||
).setParseAction(lambda t: Constructor(t.name, t.args_list))
|
||||
|
||||
def __init__(self, name, args, parent=''):
|
||||
def __init__(self, name: str, args: ArgumentList, parent: Union["Class", str] =''):
|
||||
self.name = name
|
||||
self.args = args
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "Constructor: {}".format(self.name)
|
||||
|
||||
|
||||
|
@ -523,21 +563,28 @@ class Property:
|
|||
};
|
||||
````
|
||||
"""
|
||||
rule = (Type.rule("ctype") + IDENT("name") + SEMI_COLON).setParseAction(
|
||||
lambda t: Property(t.ctype, t.name)
|
||||
)
|
||||
rule = (
|
||||
Type.rule("ctype") #
|
||||
+ IDENT("name") #
|
||||
+ SEMI_COLON #
|
||||
).setParseAction(lambda t: Property(t.ctype, t.name))
|
||||
|
||||
def __init__(self, ctype, name, parent=''):
|
||||
def __init__(self, ctype: Type, name: str, parent=''):
|
||||
self.ctype = ctype
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return '{} {}'.format(self.ctype.__repr__(), self.name)
|
||||
|
||||
|
||||
def collect_namespaces(obj):
|
||||
"""Get the chain of namespaces from the lowest to highest for the given object."""
|
||||
"""
|
||||
Get the chain of namespaces from the lowest to highest for the given object.
|
||||
|
||||
Args:
|
||||
obj: Object of type Namespace, Class or InstantiatedClass.
|
||||
"""
|
||||
namespaces = []
|
||||
ancestor = obj.parent
|
||||
while ancestor and ancestor.name:
|
||||
|
@ -565,7 +612,8 @@ class Class:
|
|||
Constructor.rule ^ StaticMethod.rule ^ Method.rule ^ Property.rule
|
||||
).setParseAction(lambda t: Class.MethodsAndProperties(t.asList()))
|
||||
|
||||
def __init__(self, methods_props):
|
||||
def __init__(self, methods_props: List[Union[Constructor, Method,
|
||||
StaticMethod, Property]]):
|
||||
self.ctors = []
|
||||
self.methods = []
|
||||
self.static_methods = []
|
||||
|
@ -582,17 +630,16 @@ class Class:
|
|||
|
||||
_parent = COLON + Typename.rule("parent_class")
|
||||
rule = (
|
||||
Optional(Template.rule("template"))
|
||||
+ Optional(VIRTUAL("is_virtual"))
|
||||
+ CLASS
|
||||
+ IDENT("name")
|
||||
+ Optional(_parent)
|
||||
+ LBRACE
|
||||
+ MethodsAndProperties.rule("methods_props")
|
||||
+ RBRACE
|
||||
Optional(Template.rule("template")) #
|
||||
+ Optional(VIRTUAL("is_virtual")) #
|
||||
+ CLASS #
|
||||
+ IDENT("name") #
|
||||
+ Optional(_parent) #
|
||||
+ LBRACE #
|
||||
+ MethodsAndProperties.rule("methods_props") #
|
||||
+ RBRACE #
|
||||
+ SEMI_COLON # BR
|
||||
).setParseAction(
|
||||
lambda t: Class(
|
||||
).setParseAction(lambda t: Class(
|
||||
t.template,
|
||||
t.is_virtual,
|
||||
t.name,
|
||||
|
@ -601,20 +648,19 @@ class Class:
|
|||
t.methods_props.methods,
|
||||
t.methods_props.static_methods,
|
||||
t.methods_props.properties,
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
template,
|
||||
is_virtual,
|
||||
name,
|
||||
parent_class,
|
||||
ctors,
|
||||
methods,
|
||||
static_methods,
|
||||
properties,
|
||||
parent='',
|
||||
template: Template,
|
||||
is_virtual: str,
|
||||
name: str,
|
||||
parent_class: list,
|
||||
ctors: List[Constructor],
|
||||
methods: List[Method],
|
||||
static_methods: List[StaticMethod],
|
||||
properties: List[Property],
|
||||
parent: str = '',
|
||||
):
|
||||
self.template = template
|
||||
self.is_virtual = is_virtual
|
||||
|
@ -647,10 +693,13 @@ class Class:
|
|||
for _property in self.properties:
|
||||
_property.parent = self
|
||||
|
||||
def namespaces(self):
|
||||
def namespaces(self) -> list:
|
||||
"""Get the namespaces which this class is nested under as a list."""
|
||||
return collect_namespaces(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "Class: {self.name}".format(self=self)
|
||||
|
||||
|
||||
class TypedefTemplateInstantiation:
|
||||
"""
|
||||
|
@ -669,7 +718,7 @@ class TypedefTemplateInstantiation:
|
|||
)
|
||||
)
|
||||
|
||||
def __init__(self, typename, new_name, parent=''):
|
||||
def __init__(self, typename: Typename, new_name: str, parent: str=''):
|
||||
self.typename = typename
|
||||
self.new_name = new_name
|
||||
self.parent = parent
|
||||
|
@ -683,11 +732,11 @@ class Include:
|
|||
INCLUDE + LOPBRACK + CharsNotIn('>')("header") + ROPBRACK
|
||||
).setParseAction(lambda t: Include(t.header))
|
||||
|
||||
def __init__(self, header, parent=''):
|
||||
def __init__(self, header: CharsNotIn, parent: str = ''):
|
||||
self.header = header
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "#include <{}>".format(self.header)
|
||||
|
||||
|
||||
|
@ -702,22 +751,26 @@ class ForwardDeclaration:
|
|||
+ Optional(COLON + Typename.rule("parent_type"))
|
||||
+ SEMI_COLON
|
||||
).setParseAction(
|
||||
lambda t: ForwardDeclaration(t.is_virtual, t.name, t.parent_type)
|
||||
lambda t: ForwardDeclaration(t.name, t.parent_type, t.is_virtual)
|
||||
)
|
||||
|
||||
def __init__(self, is_virtual, name, parent_type, parent=''):
|
||||
self.is_virtual = is_virtual
|
||||
def __init__(self,
|
||||
name: Typename,
|
||||
parent_type: str,
|
||||
is_virtual: str,
|
||||
parent: str = ''):
|
||||
self.name = name
|
||||
if parent_type:
|
||||
self.parent_type = Typename.from_parse_result(parent_type)
|
||||
else:
|
||||
self.parent_type = ''
|
||||
|
||||
self.is_virtual = is_virtual
|
||||
self.parent = parent
|
||||
|
||||
def __repr__(self):
|
||||
return "ForwardDeclaration: {} {}({})".format(
|
||||
self.is_virtual, self.name, self.parent
|
||||
)
|
||||
def __repr__(self) -> str:
|
||||
return "ForwardDeclaration: {} {}({})".format(self.is_virtual,
|
||||
self.name, self.parent)
|
||||
|
||||
|
||||
class GlobalFunction:
|
||||
|
@ -725,37 +778,43 @@ class GlobalFunction:
|
|||
Rule to parse functions defined in the global scope.
|
||||
"""
|
||||
rule = (
|
||||
ReturnType.rule("return_type")
|
||||
+ IDENT("name")
|
||||
+ LPAREN
|
||||
+ ArgumentList.rule("args_list")
|
||||
+ RPAREN
|
||||
+ SEMI_COLON
|
||||
).setParseAction(
|
||||
lambda t: GlobalFunction(t.name, t.return_type, t.args_list)
|
||||
)
|
||||
Optional(Template.rule("template"))
|
||||
+ ReturnType.rule("return_type") #
|
||||
+ IDENT("name") #
|
||||
+ LPAREN #
|
||||
+ ArgumentList.rule("args_list") #
|
||||
+ RPAREN #
|
||||
+ SEMI_COLON #
|
||||
).setParseAction(lambda t: GlobalFunction(t.name, t.return_type, t.
|
||||
args_list, t.template))
|
||||
|
||||
def __init__(self, name, return_type, args_list, parent=''):
|
||||
def __init__(self,
|
||||
name: str,
|
||||
return_type: ReturnType,
|
||||
args_list: ArgumentList,
|
||||
template: Template,
|
||||
parent: str = ''):
|
||||
self.name = name
|
||||
self.return_type = return_type
|
||||
self.args = args_list
|
||||
self.is_const = None
|
||||
self.template = template
|
||||
|
||||
self.parent = parent
|
||||
self.return_type.parent = self
|
||||
self.args.parent = self
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "GlobalFunction: {}{}({})".format(
|
||||
self.return_type, self.name, self.args
|
||||
)
|
||||
|
||||
def to_cpp(self):
|
||||
def to_cpp(self) -> str:
|
||||
"""Generate the C++ code for wrapping."""
|
||||
return self.name
|
||||
|
||||
|
||||
def find_sub_namespace(namespace, str_namespaces):
|
||||
def find_sub_namespace(namespace: "Namespace",
|
||||
str_namespaces: List["Namespace"]) -> list:
|
||||
"""
|
||||
Get the namespaces nested under `namespace`, filtered by a list of namespace strings.
|
||||
|
||||
|
@ -774,7 +833,7 @@ def find_sub_namespace(namespace, str_namespaces):
|
|||
ns for ns in sub_namespaces if ns.name == str_namespaces[0]
|
||||
]
|
||||
if not found_namespaces:
|
||||
return None
|
||||
return []
|
||||
|
||||
res = []
|
||||
for found_namespace in found_namespaces:
|
||||
|
@ -786,25 +845,24 @@ def find_sub_namespace(namespace, str_namespaces):
|
|||
|
||||
class Namespace:
|
||||
"""Rule for parsing a namespace in the interface file."""
|
||||
|
||||
rule = Forward()
|
||||
rule << (
|
||||
NAMESPACE
|
||||
+ IDENT("name")
|
||||
+ LBRACE
|
||||
NAMESPACE #
|
||||
+ IDENT("name") #
|
||||
+ LBRACE #
|
||||
+ ZeroOrMore( # BR
|
||||
ForwardDeclaration.rule
|
||||
^ Include.rule
|
||||
^ Class.rule
|
||||
^ TypedefTemplateInstantiation.rule
|
||||
^ GlobalFunction.rule
|
||||
^ rule
|
||||
)(
|
||||
"content"
|
||||
) # BR
|
||||
+ RBRACE
|
||||
ForwardDeclaration.rule #
|
||||
^ Include.rule #
|
||||
^ Class.rule #
|
||||
^ TypedefTemplateInstantiation.rule #
|
||||
^ GlobalFunction.rule #
|
||||
^ rule #
|
||||
)("content") # BR
|
||||
+ RBRACE #
|
||||
).setParseAction(lambda t: Namespace.from_parse_result(t))
|
||||
|
||||
def __init__(self, name, content, parent=''):
|
||||
def __init__(self, name: str, content: ZeroOrMore, parent=''):
|
||||
self.name = name
|
||||
self.content = content
|
||||
self.parent = parent
|
||||
|
@ -812,7 +870,7 @@ class Namespace:
|
|||
child.parent = self
|
||||
|
||||
@staticmethod
|
||||
def from_parse_result(t):
|
||||
def from_parse_result(t: ParseResults):
|
||||
"""Return the result of parsing."""
|
||||
if t.content:
|
||||
content = t.content.asList()
|
||||
|
@ -820,16 +878,18 @@ class Namespace:
|
|||
content = []
|
||||
return Namespace(t.name, content)
|
||||
|
||||
def find_class(self, typename):
|
||||
def find_class_or_function(
|
||||
self, typename: Typename) -> Union[Class, GlobalFunction]:
|
||||
"""
|
||||
Find the Class object given its typename.
|
||||
Find the Class or GlobalFunction object given its typename.
|
||||
We have to traverse the tree of namespaces.
|
||||
"""
|
||||
found_namespaces = find_sub_namespace(self, typename.namespaces)
|
||||
res = []
|
||||
for namespace in found_namespaces:
|
||||
classes = (c for c in namespace.content if isinstance(c, Class))
|
||||
res += [c for c in classes if c.name == typename.name]
|
||||
classes_and_funcs = (c for c in namespace.content
|
||||
if isinstance(c, (Class, GlobalFunction)))
|
||||
res += [c for c in classes_and_funcs if c.name == typename.name]
|
||||
if not res:
|
||||
raise ValueError(
|
||||
"Cannot find class {} in module!".format(typename.name)
|
||||
|
@ -843,17 +903,17 @@ class Namespace:
|
|||
else:
|
||||
return res[0]
|
||||
|
||||
def top_level(self):
|
||||
def top_level(self) -> "Namespace":
|
||||
"""Return the top leve namespace."""
|
||||
if self.name == '' or self.parent == '':
|
||||
return self
|
||||
else:
|
||||
return self.parent.top_level()
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return "Namespace: {}\n\t{}".format(self.name, self.content)
|
||||
|
||||
def full_namespaces(self):
|
||||
def full_namespaces(self) -> List["Namespace"]:
|
||||
"""Get the full namespace list."""
|
||||
ancestors = collect_namespaces(self)
|
||||
if self.name:
|
||||
|
@ -874,20 +934,18 @@ class Module:
|
|||
"""
|
||||
|
||||
rule = (
|
||||
ZeroOrMore(
|
||||
ForwardDeclaration.rule
|
||||
^ Include.rule
|
||||
^ Class.rule
|
||||
^ TypedefTemplateInstantiation.rule
|
||||
^ GlobalFunction.rule
|
||||
^ Namespace.rule
|
||||
).setParseAction(lambda t: Namespace('', t.asList()))
|
||||
+ stringEnd
|
||||
)
|
||||
ZeroOrMore(ForwardDeclaration.rule #
|
||||
^ Include.rule #
|
||||
^ Class.rule #
|
||||
^ TypedefTemplateInstantiation.rule #
|
||||
^ GlobalFunction.rule #
|
||||
^ Namespace.rule #
|
||||
).setParseAction(lambda t: Namespace('', t.asList())) +
|
||||
stringEnd)
|
||||
|
||||
rule.ignore(cppStyleComment)
|
||||
|
||||
@staticmethod
|
||||
def parseString(s: str):
|
||||
def parseString(s: str) -> ParseResults:
|
||||
"""Parse the source string and apply the rules."""
|
||||
return Module.rule.parseString(s)[0]
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@ Code generator for wrapping a C++ module with Pybind11
|
|||
Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
|
||||
"""
|
||||
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes, no-self-use, no-else-return, too-many-arguments, unused-format-string-argument
|
||||
# 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
|
||||
import textwrap
|
||||
|
@ -39,6 +39,9 @@ class PybindWrapper:
|
|||
self.module_template = module_template
|
||||
self.python_keywords = ['print', 'lambda']
|
||||
|
||||
# amount of indentation to add before each function/method declaration.
|
||||
self.method_indent = '\n' + (' ' * 8)
|
||||
|
||||
def _py_args_names(self, args_list):
|
||||
"""Set the argument names in Pybind11 format."""
|
||||
names = args_list.args_names()
|
||||
|
@ -60,7 +63,7 @@ class PybindWrapper:
|
|||
"""Wrap the constructors."""
|
||||
res = ""
|
||||
for ctor in my_class.ctors:
|
||||
res += ('\n' + ' ' * 8 + '.def(py::init<{args_cpp_types}>()'
|
||||
res += (self.method_indent + '.def(py::init<{args_cpp_types}>()'
|
||||
'{py_args_names})'.format(
|
||||
args_cpp_types=", ".join(ctor.args.to_cpp(self.use_boost)),
|
||||
py_args_names=self._py_args_names(ctor.args),
|
||||
|
@ -74,32 +77,19 @@ class PybindWrapper:
|
|||
if cpp_method in ["serialize", "serializable"]:
|
||||
if not cpp_class in self._serializing_classes:
|
||||
self._serializing_classes.append(cpp_class)
|
||||
return textwrap.dedent('''
|
||||
.def("serialize",
|
||||
[]({class_inst} self){{
|
||||
return gtsam::serialize(*self);
|
||||
}}
|
||||
)
|
||||
.def("deserialize",
|
||||
[]({class_inst} self, string serialized){{
|
||||
gtsam::deserialize(serialized, *self);
|
||||
}}, py::arg("serialized"))
|
||||
'''.format(class_inst=cpp_class + '*'))
|
||||
serialize_method = self.method_indent + \
|
||||
".def(\"serialize\", []({class_inst} self){{ return gtsam::serialize(*self); }})".format(class_inst=cpp_class + '*')
|
||||
deserialize_method = self.method_indent + \
|
||||
".def(\"deserialize\", []({class_inst} self, string serialized){{ gtsam::deserialize(serialized, *self); }}, py::arg(\"serialized\"))" \
|
||||
.format(class_inst=cpp_class + '*')
|
||||
return serialize_method + deserialize_method
|
||||
|
||||
if cpp_method == "pickle":
|
||||
if not cpp_class in self._serializing_classes:
|
||||
raise ValueError("Cannot pickle a class which is not serializable")
|
||||
return textwrap.dedent('''
|
||||
.def(py::pickle(
|
||||
[](const {cpp_class} &a){{ // __getstate__
|
||||
/* Returns a string that encodes the state of the object */
|
||||
return py::make_tuple(gtsam::serialize(a));
|
||||
}},
|
||||
[](py::tuple t){{ // __setstate__
|
||||
{cpp_class} obj;
|
||||
gtsam::deserialize(t[0].cast<std::string>(), obj);
|
||||
return obj;
|
||||
}}))
|
||||
'''.format(cpp_class=cpp_class))
|
||||
pickle_method = self.method_indent + \
|
||||
".def(py::pickle({indent} [](const {cpp_class} &a){{ /* __getstate__: Returns a string that encodes the state of the object */ return py::make_tuple(gtsam::serialize(a)); }},{indent} [](py::tuple t){{ /* __setstate__ */ {cpp_class} obj; gtsam::deserialize(t[0].cast<std::string>(), obj); return obj; }}))"
|
||||
return pickle_method.format(cpp_class=cpp_class, indent=self.method_indent)
|
||||
|
||||
is_method = isinstance(method, instantiator.InstantiatedMethod)
|
||||
is_static = isinstance(method, parser.StaticMethod)
|
||||
|
@ -128,14 +118,13 @@ class PybindWrapper:
|
|||
else py_method + "_",
|
||||
opt_self="{cpp_class}* self".format(
|
||||
cpp_class=cpp_class) if is_method else "",
|
||||
cpp_class=cpp_class,
|
||||
cpp_method=cpp_method,
|
||||
opt_comma=', ' if is_method and args_names else '',
|
||||
args_signature_with_names=args_signature_with_names,
|
||||
function_call=function_call,
|
||||
py_args_names=py_args_names,
|
||||
suffix=suffix,
|
||||
))
|
||||
|
||||
if method.name == 'print':
|
||||
type_list = method.args.to_cpp(self.use_boost)
|
||||
if len(type_list) > 0 and type_list[0].strip() == 'string':
|
||||
|
@ -163,7 +152,11 @@ class PybindWrapper:
|
|||
return ret
|
||||
|
||||
def wrap_methods(self, methods, cpp_class, prefix='\n' + ' ' * 8, suffix=''):
|
||||
"""Wrap all the methods in the `cpp_class`."""
|
||||
"""
|
||||
Wrap all the methods in the `cpp_class`.
|
||||
|
||||
This function is also used to wrap global functions.
|
||||
"""
|
||||
res = ""
|
||||
for method in methods:
|
||||
|
||||
|
@ -185,6 +178,7 @@ class PybindWrapper:
|
|||
prefix=prefix,
|
||||
suffix=suffix,
|
||||
)
|
||||
|
||||
return res
|
||||
|
||||
def wrap_properties(self, properties, cpp_class, prefix='\n' + ' ' * 8):
|
||||
|
@ -325,7 +319,8 @@ class PybindWrapper:
|
|||
# Global functions.
|
||||
all_funcs = [
|
||||
func for func in namespace.content
|
||||
if isinstance(func, parser.GlobalFunction)
|
||||
if isinstance(func, (parser.GlobalFunction,
|
||||
instantiator.InstantiatedGlobalFunction))
|
||||
]
|
||||
wrapped += self.wrap_methods(
|
||||
all_funcs,
|
||||
|
|
|
@ -45,6 +45,7 @@ def instantiate_type(ctype: parser.Type,
|
|||
return parser.Type(
|
||||
typename=instantiations[idx],
|
||||
is_const=ctype.is_const,
|
||||
is_shared_ptr=ctype.is_shared_ptr,
|
||||
is_ptr=ctype.is_ptr,
|
||||
is_ref=ctype.is_ref,
|
||||
is_basis=ctype.is_basis,
|
||||
|
@ -63,6 +64,7 @@ def instantiate_type(ctype: parser.Type,
|
|||
return parser.Type(
|
||||
typename=cpp_typename,
|
||||
is_const=ctype.is_const,
|
||||
is_shared_ptr=ctype.is_shared_ptr,
|
||||
is_ptr=ctype.is_ptr,
|
||||
is_ref=ctype.is_ref,
|
||||
is_basis=ctype.is_basis,
|
||||
|
@ -128,11 +130,69 @@ def instantiate_name(original_name, instantiations):
|
|||
for inst in instantiations:
|
||||
# Ensure the first character of the type is capitalized
|
||||
name = inst.instantiated_name()
|
||||
# Using `capitalize` on the complete causes other caps to be lower case
|
||||
# Using `capitalize` on the complete name causes other caps to be lower case
|
||||
instantiated_names.append(name.replace(name[0], name[0].capitalize()))
|
||||
|
||||
return "{}{}".format(original_name, "".join(instantiated_names))
|
||||
|
||||
class InstantiatedGlobalFunction(parser.GlobalFunction):
|
||||
"""
|
||||
Instantiate global functions.
|
||||
|
||||
E.g.
|
||||
template<T = {double}>
|
||||
T add(const T& x, const T& y);
|
||||
"""
|
||||
def __init__(self, original, instantiations=(), new_name=''):
|
||||
self.original = original
|
||||
self.instantiations = instantiations
|
||||
self.template = ''
|
||||
self.parent = original.parent
|
||||
|
||||
if not original.template:
|
||||
self.name = original.name
|
||||
self.return_type = original.return_type
|
||||
self.args = original.args
|
||||
else:
|
||||
self.name = instantiate_name(
|
||||
original.name, instantiations) if not new_name else new_name
|
||||
self.return_type = instantiate_return_type(
|
||||
original.return_type,
|
||||
self.original.template.typenames,
|
||||
self.instantiations,
|
||||
# Keyword type name `This` should already be replaced in the
|
||||
# previous class template instantiation round.
|
||||
cpp_typename='',
|
||||
)
|
||||
instantiated_args = instantiate_args_list(
|
||||
original.args.args_list,
|
||||
self.original.template.typenames,
|
||||
self.instantiations,
|
||||
# Keyword type name `This` should already be replaced in the
|
||||
# previous class template instantiation round.
|
||||
cpp_typename='',
|
||||
)
|
||||
self.args = parser.ArgumentList(instantiated_args)
|
||||
|
||||
super().__init__(self.name,
|
||||
self.return_type,
|
||||
self.args,
|
||||
self.template,
|
||||
parent=self.parent)
|
||||
|
||||
def to_cpp(self):
|
||||
"""Generate the C++ code for wrapping."""
|
||||
if self.original.template:
|
||||
instantiated_names = [inst.instantiated_name() for inst in self.instantiations]
|
||||
ret = "{}<{}>".format(self.original.name, ",".join(instantiated_names))
|
||||
else:
|
||||
ret = self.original.name
|
||||
return ret
|
||||
|
||||
def __repr__(self):
|
||||
return "Instantiated {}".format(
|
||||
super(InstantiatedGlobalFunction, self).__repr__()
|
||||
)
|
||||
|
||||
class InstantiatedMethod(parser.Method):
|
||||
"""
|
||||
|
@ -396,17 +456,38 @@ def instantiate_namespace_inplace(namespace):
|
|||
InstantiatedClass(original_class,
|
||||
list(instantiations)))
|
||||
|
||||
elif isinstance(element, parser.GlobalFunction):
|
||||
original_func = element
|
||||
if not original_func.template:
|
||||
instantiated_content.append(
|
||||
InstantiatedGlobalFunction(original_func, []))
|
||||
else:
|
||||
# Use itertools to get all possible combinations of instantiations
|
||||
# Works even if one template does not have an instantiation list
|
||||
for instantiations in itertools.product(
|
||||
*original_func.template.instantiations):
|
||||
instantiated_content.append(
|
||||
InstantiatedGlobalFunction(original_func,
|
||||
list(instantiations)))
|
||||
|
||||
elif isinstance(element, parser.TypedefTemplateInstantiation):
|
||||
typedef_inst = element
|
||||
original_class = namespace.top_level().find_class(
|
||||
top_level = namespace.top_level()
|
||||
original_element = top_level.find_class_or_function(
|
||||
typedef_inst.typename)
|
||||
|
||||
# Check if element is a typedef'd class or function.
|
||||
if isinstance(original_element, parser.Class):
|
||||
typedef_content.append(
|
||||
InstantiatedClass(
|
||||
original_class,
|
||||
InstantiatedClass(original_element,
|
||||
typedef_inst.typename.instantiations,
|
||||
typedef_inst.new_name
|
||||
)
|
||||
)
|
||||
typedef_inst.new_name))
|
||||
elif isinstance(original_element, parser.GlobalFunction):
|
||||
typedef_content.append(
|
||||
InstantiatedGlobalFunction(
|
||||
original_element, typedef_inst.typename.instantiations,
|
||||
typedef_inst.new_name))
|
||||
|
||||
elif isinstance(element, parser.Namespace):
|
||||
instantiate_namespace_inplace(element)
|
||||
instantiated_content.append(element)
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
pyparsing
|
||||
pytest
|
||||
loguru
|
|
@ -7,6 +7,12 @@
|
|||
%
|
||||
%-------Methods-------
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argChar(char a) : returns void
|
||||
%argUChar(unsigned char a) : returns void
|
||||
%dim() : returns int
|
||||
%eigenArguments(Vector v, Matrix m) : returns void
|
||||
|
@ -49,6 +55,42 @@ classdef Point2 < handle
|
|||
geometry_wrapper(4, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(5, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(6, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(7, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(8, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(9, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% ARGCHAR usage: argChar(char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
geometry_wrapper(10, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.argChar');
|
||||
end
|
||||
|
||||
|
@ -56,7 +98,7 @@ classdef Point2 < handle
|
|||
% ARGUCHAR usage: argUChar(unsigned char a) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'unsigned char')
|
||||
geometry_wrapper(5, this, varargin{:});
|
||||
geometry_wrapper(11, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.argUChar');
|
||||
|
@ -66,7 +108,7 @@ classdef Point2 < handle
|
|||
% DIM usage: dim() : returns int
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(6, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(12, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.dim');
|
||||
|
@ -76,7 +118,7 @@ classdef Point2 < handle
|
|||
% EIGENARGUMENTS usage: eigenArguments(Vector v, Matrix m) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 2 && isa(varargin{1},'double') && size(varargin{1},2)==1 && isa(varargin{2},'double')
|
||||
geometry_wrapper(7, this, varargin{:});
|
||||
geometry_wrapper(13, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.eigenArguments');
|
||||
|
@ -86,7 +128,7 @@ classdef Point2 < handle
|
|||
% RETURNCHAR usage: returnChar() : returns char
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(8, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(14, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.returnChar');
|
||||
|
@ -96,7 +138,7 @@ classdef Point2 < handle
|
|||
% VECTORCONFUSION usage: vectorConfusion() : returns VectorNotEigen
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(9, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(15, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.vectorConfusion');
|
||||
|
@ -106,7 +148,7 @@ classdef Point2 < handle
|
|||
% X usage: x() : returns double
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(10, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(16, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.x');
|
||||
|
@ -116,7 +158,7 @@ classdef Point2 < handle
|
|||
% Y usage: y() : returns double
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(11, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(17, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point2.y');
|
||||
|
|
|
@ -23,9 +23,9 @@ classdef Point3 < handle
|
|||
function obj = Point3(varargin)
|
||||
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
|
||||
my_ptr = varargin{2};
|
||||
geometry_wrapper(12, my_ptr);
|
||||
geometry_wrapper(18, my_ptr);
|
||||
elseif nargin == 3 && isa(varargin{1},'double') && isa(varargin{2},'double') && isa(varargin{3},'double')
|
||||
my_ptr = geometry_wrapper(13, varargin{1}, varargin{2}, varargin{3});
|
||||
my_ptr = geometry_wrapper(19, varargin{1}, varargin{2}, varargin{3});
|
||||
else
|
||||
error('Arguments do not match any overload of gtsam.Point3 constructor');
|
||||
end
|
||||
|
@ -33,7 +33,7 @@ classdef Point3 < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(14, obj.ptr_gtsamPoint3);
|
||||
geometry_wrapper(20, obj.ptr_gtsamPoint3);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
@ -44,7 +44,7 @@ classdef Point3 < handle
|
|||
% NORM usage: norm() : returns double
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(15, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(21, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function gtsam.Point3.norm');
|
||||
|
@ -54,7 +54,7 @@ classdef Point3 < handle
|
|||
% STRING_SERIALIZE usage: string_serialize() : returns string
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(16, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(22, this, varargin{:});
|
||||
else
|
||||
error('Arguments do not match any overload of function gtsam.Point3.string_serialize');
|
||||
end
|
||||
|
@ -71,7 +71,7 @@ classdef Point3 < handle
|
|||
% STATICFUNCTIONRET usage: StaticFunctionRet(double z) : returns Point3
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(17, varargin{:});
|
||||
varargout{1} = geometry_wrapper(23, varargin{:});
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -82,7 +82,7 @@ classdef Point3 < handle
|
|||
% STATICFUNCTION usage: staticFunction() : returns double
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(18, varargin{:});
|
||||
varargout{1} = geometry_wrapper(24, varargin{:});
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -93,7 +93,7 @@ classdef Point3 < handle
|
|||
% STRING_DESERIALIZE usage: string_deserialize() : returns gtsam.Point3
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1
|
||||
varargout{1} = geometry_wrapper(19, varargin{:});
|
||||
varargout{1} = geometry_wrapper(25, varargin{:});
|
||||
else
|
||||
error('Arguments do not match any overload of function gtsam.Point3.string_deserialize');
|
||||
end
|
||||
|
|
|
@ -11,9 +11,9 @@ classdef MyBase < handle
|
|||
if nargin == 2
|
||||
my_ptr = varargin{2};
|
||||
else
|
||||
my_ptr = geometry_wrapper(45, varargin{2});
|
||||
my_ptr = geometry_wrapper(51, varargin{2});
|
||||
end
|
||||
geometry_wrapper(44, my_ptr);
|
||||
geometry_wrapper(50, my_ptr);
|
||||
else
|
||||
error('Arguments do not match any overload of MyBase constructor');
|
||||
end
|
||||
|
@ -21,7 +21,7 @@ classdef MyBase < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(46, obj.ptr_MyBase);
|
||||
geometry_wrapper(52, obj.ptr_MyBase);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
|
|
@ -12,9 +12,9 @@ classdef MyFactorPosePoint2 < handle
|
|||
function obj = MyFactorPosePoint2(varargin)
|
||||
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
|
||||
my_ptr = varargin{2};
|
||||
geometry_wrapper(93, my_ptr);
|
||||
geometry_wrapper(99, my_ptr);
|
||||
elseif nargin == 4 && isa(varargin{1},'numeric') && isa(varargin{2},'numeric') && isa(varargin{3},'double') && isa(varargin{4},'gtsam.noiseModel.Base')
|
||||
my_ptr = geometry_wrapper(94, varargin{1}, varargin{2}, varargin{3}, varargin{4});
|
||||
my_ptr = geometry_wrapper(100, varargin{1}, varargin{2}, varargin{3}, varargin{4});
|
||||
else
|
||||
error('Arguments do not match any overload of MyFactorPosePoint2 constructor');
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ classdef MyFactorPosePoint2 < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(95, obj.ptr_MyFactorPosePoint2);
|
||||
geometry_wrapper(101, obj.ptr_MyFactorPosePoint2);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
|
|
@ -34,11 +34,11 @@ classdef MyTemplateMatrix < MyBase
|
|||
if nargin == 2
|
||||
my_ptr = varargin{2};
|
||||
else
|
||||
my_ptr = geometry_wrapper(64, varargin{2});
|
||||
my_ptr = geometry_wrapper(70, varargin{2});
|
||||
end
|
||||
base_ptr = geometry_wrapper(63, my_ptr);
|
||||
base_ptr = geometry_wrapper(69, my_ptr);
|
||||
elseif nargin == 0
|
||||
[ my_ptr, base_ptr ] = geometry_wrapper(65);
|
||||
[ my_ptr, base_ptr ] = geometry_wrapper(71);
|
||||
else
|
||||
error('Arguments do not match any overload of MyTemplateMatrix constructor');
|
||||
end
|
||||
|
@ -47,7 +47,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(66, obj.ptr_MyTemplateMatrix);
|
||||
geometry_wrapper(72, obj.ptr_MyTemplateMatrix);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
@ -58,7 +58,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% ACCEPT_T usage: accept_T(Matrix value) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
geometry_wrapper(67, this, varargin{:});
|
||||
geometry_wrapper(73, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.accept_T');
|
||||
|
@ -68,7 +68,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% ACCEPT_TPTR usage: accept_Tptr(Matrix value) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
geometry_wrapper(68, this, varargin{:});
|
||||
geometry_wrapper(74, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.accept_Tptr');
|
||||
|
@ -78,7 +78,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% CREATE_MIXEDPTRS usage: create_MixedPtrs() : returns pair< Matrix, Matrix >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(69, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(75, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.create_MixedPtrs');
|
||||
|
@ -88,7 +88,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% CREATE_PTRS usage: create_ptrs() : returns pair< Matrix, Matrix >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(70, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(76, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.create_ptrs');
|
||||
|
@ -98,7 +98,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% RETURN_T usage: return_T(Matrix value) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(71, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(77, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.return_T');
|
||||
|
@ -108,7 +108,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% RETURN_TPTR usage: return_Tptr(Matrix value) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(72, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(78, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.return_Tptr');
|
||||
|
@ -118,7 +118,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% RETURN_PTRS usage: return_ptrs(Matrix p1, Matrix p2) : returns pair< Matrix, Matrix >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 2 && isa(varargin{1},'double') && isa(varargin{2},'double')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(73, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(79, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.return_ptrs');
|
||||
|
@ -128,7 +128,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% TEMPLATEDMETHODMATRIX usage: templatedMethodMatrix(Matrix t) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(74, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(80, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.templatedMethodMatrix');
|
||||
|
@ -138,7 +138,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% TEMPLATEDMETHODPOINT2 usage: templatedMethodPoint2(Point2 t) : returns Point2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(75, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(81, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.templatedMethodPoint2');
|
||||
|
@ -148,7 +148,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% TEMPLATEDMETHODPOINT3 usage: templatedMethodPoint3(Point3 t) : returns Point3
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==3 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(76, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(82, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.templatedMethodPoint3');
|
||||
|
@ -158,7 +158,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% TEMPLATEDMETHODVECTOR usage: templatedMethodVector(Vector t) : returns Vector
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(77, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(83, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplateMatrix.templatedMethodVector');
|
||||
|
@ -171,7 +171,7 @@ classdef MyTemplateMatrix < MyBase
|
|||
% LEVEL usage: Level(Matrix K) : returns MyTemplateMatrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(78, varargin{:});
|
||||
varargout{1} = geometry_wrapper(84, varargin{:});
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ classdef MyTemplatePoint2 < MyBase
|
|||
if nargin == 2
|
||||
my_ptr = varargin{2};
|
||||
else
|
||||
my_ptr = geometry_wrapper(48, varargin{2});
|
||||
my_ptr = geometry_wrapper(54, varargin{2});
|
||||
end
|
||||
base_ptr = geometry_wrapper(47, my_ptr);
|
||||
base_ptr = geometry_wrapper(53, my_ptr);
|
||||
elseif nargin == 0
|
||||
[ my_ptr, base_ptr ] = geometry_wrapper(49);
|
||||
[ my_ptr, base_ptr ] = geometry_wrapper(55);
|
||||
else
|
||||
error('Arguments do not match any overload of MyTemplatePoint2 constructor');
|
||||
end
|
||||
|
@ -47,7 +47,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(50, obj.ptr_MyTemplatePoint2);
|
||||
geometry_wrapper(56, obj.ptr_MyTemplatePoint2);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
@ -58,7 +58,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% ACCEPT_T usage: accept_T(Point2 value) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
geometry_wrapper(51, this, varargin{:});
|
||||
geometry_wrapper(57, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.accept_T');
|
||||
|
@ -68,7 +68,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% ACCEPT_TPTR usage: accept_Tptr(Point2 value) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
geometry_wrapper(52, this, varargin{:});
|
||||
geometry_wrapper(58, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.accept_Tptr');
|
||||
|
@ -78,7 +78,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% CREATE_MIXEDPTRS usage: create_MixedPtrs() : returns pair< Point2, Point2 >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(53, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(59, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.create_MixedPtrs');
|
||||
|
@ -88,7 +88,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% CREATE_PTRS usage: create_ptrs() : returns pair< Point2, Point2 >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(54, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(60, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.create_ptrs');
|
||||
|
@ -98,7 +98,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% RETURN_T usage: return_T(Point2 value) : returns Point2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(55, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(61, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.return_T');
|
||||
|
@ -108,7 +108,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% RETURN_TPTR usage: return_Tptr(Point2 value) : returns Point2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(56, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(62, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.return_Tptr');
|
||||
|
@ -118,7 +118,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% RETURN_PTRS usage: return_ptrs(Point2 p1, Point2 p2) : returns pair< Point2, Point2 >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 2 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1 && isa(varargin{2},'double') && size(varargin{2},1)==2 && size(varargin{2},2)==1
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(57, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(63, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.return_ptrs');
|
||||
|
@ -128,7 +128,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% TEMPLATEDMETHODMATRIX usage: templatedMethodMatrix(Matrix t) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(58, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(64, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.templatedMethodMatrix');
|
||||
|
@ -138,7 +138,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% TEMPLATEDMETHODPOINT2 usage: templatedMethodPoint2(Point2 t) : returns Point2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(59, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(65, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.templatedMethodPoint2');
|
||||
|
@ -148,7 +148,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% TEMPLATEDMETHODPOINT3 usage: templatedMethodPoint3(Point3 t) : returns Point3
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==3 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(60, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(66, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.templatedMethodPoint3');
|
||||
|
@ -158,7 +158,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% TEMPLATEDMETHODVECTOR usage: templatedMethodVector(Vector t) : returns Vector
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(61, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(67, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function MyTemplatePoint2.templatedMethodVector');
|
||||
|
@ -171,7 +171,7 @@ classdef MyTemplatePoint2 < MyBase
|
|||
% LEVEL usage: Level(Point2 K) : returns MyTemplatePoint2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},1)==2 && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(62, varargin{:});
|
||||
varargout{1} = geometry_wrapper(68, varargin{:});
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ classdef MyVector12 < handle
|
|||
function obj = MyVector12(varargin)
|
||||
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
|
||||
my_ptr = varargin{2};
|
||||
geometry_wrapper(86, my_ptr);
|
||||
geometry_wrapper(92, my_ptr);
|
||||
elseif nargin == 0
|
||||
my_ptr = geometry_wrapper(87);
|
||||
my_ptr = geometry_wrapper(93);
|
||||
else
|
||||
error('Arguments do not match any overload of MyVector12 constructor');
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ classdef MyVector12 < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(88, obj.ptr_MyVector12);
|
||||
geometry_wrapper(94, obj.ptr_MyVector12);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
|
|
@ -12,9 +12,9 @@ classdef MyVector3 < handle
|
|||
function obj = MyVector3(varargin)
|
||||
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
|
||||
my_ptr = varargin{2};
|
||||
geometry_wrapper(83, my_ptr);
|
||||
geometry_wrapper(89, my_ptr);
|
||||
elseif nargin == 0
|
||||
my_ptr = geometry_wrapper(84);
|
||||
my_ptr = geometry_wrapper(90);
|
||||
else
|
||||
error('Arguments do not match any overload of MyVector3 constructor');
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ classdef MyVector3 < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(85, obj.ptr_MyVector3);
|
||||
geometry_wrapper(91, obj.ptr_MyVector3);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
|
|
@ -35,11 +35,11 @@ classdef Test < handle
|
|||
function obj = Test(varargin)
|
||||
if nargin == 2 && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
|
||||
my_ptr = varargin{2};
|
||||
geometry_wrapper(20, my_ptr);
|
||||
geometry_wrapper(26, my_ptr);
|
||||
elseif nargin == 0
|
||||
my_ptr = geometry_wrapper(21);
|
||||
my_ptr = geometry_wrapper(27);
|
||||
elseif nargin == 2 && isa(varargin{1},'double') && isa(varargin{2},'double')
|
||||
my_ptr = geometry_wrapper(22, varargin{1}, varargin{2});
|
||||
my_ptr = geometry_wrapper(28, varargin{1}, varargin{2});
|
||||
else
|
||||
error('Arguments do not match any overload of Test constructor');
|
||||
end
|
||||
|
@ -47,7 +47,7 @@ classdef Test < handle
|
|||
end
|
||||
|
||||
function delete(obj)
|
||||
geometry_wrapper(23, obj.ptr_Test);
|
||||
geometry_wrapper(29, obj.ptr_Test);
|
||||
end
|
||||
|
||||
function display(obj), obj.print(''); end
|
||||
|
@ -58,7 +58,7 @@ classdef Test < handle
|
|||
% ARG_EIGENCONSTREF usage: arg_EigenConstRef(Matrix value) : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
geometry_wrapper(24, this, varargin{:});
|
||||
geometry_wrapper(30, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.arg_EigenConstRef');
|
||||
|
@ -68,7 +68,7 @@ classdef Test < handle
|
|||
% CREATE_MIXEDPTRS usage: create_MixedPtrs() : returns pair< Test, Test >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(25, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(31, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.create_MixedPtrs');
|
||||
|
@ -78,7 +78,7 @@ classdef Test < handle
|
|||
% CREATE_PTRS usage: create_ptrs() : returns pair< Test, Test >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(26, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(32, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.create_ptrs');
|
||||
|
@ -88,7 +88,7 @@ classdef Test < handle
|
|||
% PRINT usage: print() : returns void
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 0
|
||||
geometry_wrapper(27, this, varargin{:});
|
||||
geometry_wrapper(33, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.print');
|
||||
|
@ -98,7 +98,7 @@ classdef Test < handle
|
|||
% RETURN_POINT2PTR usage: return_Point2Ptr(bool value) : returns Point2
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'logical')
|
||||
varargout{1} = geometry_wrapper(28, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(34, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_Point2Ptr');
|
||||
|
@ -108,7 +108,7 @@ classdef Test < handle
|
|||
% RETURN_TEST usage: return_Test(Test value) : returns Test
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'Test')
|
||||
varargout{1} = geometry_wrapper(29, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(35, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_Test');
|
||||
|
@ -118,7 +118,7 @@ classdef Test < handle
|
|||
% RETURN_TESTPTR usage: return_TestPtr(Test value) : returns Test
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'Test')
|
||||
varargout{1} = geometry_wrapper(30, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(36, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_TestPtr');
|
||||
|
@ -128,7 +128,7 @@ classdef Test < handle
|
|||
% RETURN_BOOL usage: return_bool(bool value) : returns bool
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'logical')
|
||||
varargout{1} = geometry_wrapper(31, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(37, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_bool');
|
||||
|
@ -138,7 +138,7 @@ classdef Test < handle
|
|||
% RETURN_DOUBLE usage: return_double(double value) : returns double
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(32, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(38, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_double');
|
||||
|
@ -148,7 +148,7 @@ classdef Test < handle
|
|||
% RETURN_FIELD usage: return_field(Test t) : returns bool
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'Test')
|
||||
varargout{1} = geometry_wrapper(33, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(39, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_field');
|
||||
|
@ -158,7 +158,7 @@ classdef Test < handle
|
|||
% RETURN_INT usage: return_int(int value) : returns int
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'numeric')
|
||||
varargout{1} = geometry_wrapper(34, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(40, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_int');
|
||||
|
@ -168,7 +168,7 @@ classdef Test < handle
|
|||
% RETURN_MATRIX1 usage: return_matrix1(Matrix value) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(35, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(41, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_matrix1');
|
||||
|
@ -178,7 +178,7 @@ classdef Test < handle
|
|||
% RETURN_MATRIX2 usage: return_matrix2(Matrix value) : returns Matrix
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double')
|
||||
varargout{1} = geometry_wrapper(36, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(42, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_matrix2');
|
||||
|
@ -188,13 +188,13 @@ classdef Test < handle
|
|||
% RETURN_PAIR usage: return_pair(Vector v, Matrix A) : returns pair< Vector, Matrix >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 2 && isa(varargin{1},'double') && size(varargin{1},2)==1 && isa(varargin{2},'double')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(37, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(43, this, varargin{:});
|
||||
return
|
||||
end
|
||||
% RETURN_PAIR usage: return_pair(Vector v) : returns pair< Vector, Matrix >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},2)==1
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(38, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(44, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_pair');
|
||||
|
@ -204,7 +204,7 @@ classdef Test < handle
|
|||
% RETURN_PTRS usage: return_ptrs(Test p1, Test p2) : returns pair< Test, Test >
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 2 && isa(varargin{1},'Test') && isa(varargin{2},'Test')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(39, this, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(45, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_ptrs');
|
||||
|
@ -214,7 +214,7 @@ classdef Test < handle
|
|||
% RETURN_SIZE_T usage: return_size_t(size_t value) : returns size_t
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'numeric')
|
||||
varargout{1} = geometry_wrapper(40, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(46, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_size_t');
|
||||
|
@ -224,7 +224,7 @@ classdef Test < handle
|
|||
% RETURN_STRING usage: return_string(string value) : returns string
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'char')
|
||||
varargout{1} = geometry_wrapper(41, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(47, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_string');
|
||||
|
@ -234,7 +234,7 @@ classdef Test < handle
|
|||
% RETURN_VECTOR1 usage: return_vector1(Vector value) : returns Vector
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(42, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(48, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_vector1');
|
||||
|
@ -244,7 +244,7 @@ classdef Test < handle
|
|||
% RETURN_VECTOR2 usage: return_vector2(Vector value) : returns Vector
|
||||
% Doxygen can be found at https://gtsam.org/doxygen/
|
||||
if length(varargin) == 1 && isa(varargin{1},'double') && size(varargin{1},2)==1
|
||||
varargout{1} = geometry_wrapper(43, this, varargin{:});
|
||||
varargout{1} = geometry_wrapper(49, this, varargin{:});
|
||||
return
|
||||
end
|
||||
error('Arguments do not match any overload of function Test.return_vector2');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function varargout = aGlobalFunction(varargin)
|
||||
if length(varargin) == 0
|
||||
varargout{1} = geometry_wrapper(99, varargin{:});
|
||||
varargout{1} = geometry_wrapper(105, varargin{:});
|
||||
else
|
||||
error('Arguments do not match any overload of function aGlobalFunction');
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,10 @@
|
|||
function varargout = load2D(varargin)
|
||||
if length(varargin) == 5 && isa(varargin{1},'char') && isa(varargin{2},'Test') && isa(varargin{3},'numeric') && isa(varargin{4},'logical') && isa(varargin{5},'logical')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(96, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(102, varargin{:});
|
||||
elseif length(varargin) == 5 && isa(varargin{1},'char') && isa(varargin{2},'gtsam.noiseModel.Diagonal') && isa(varargin{3},'numeric') && isa(varargin{4},'logical') && isa(varargin{5},'logical')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(97, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(103, varargin{:});
|
||||
elseif length(varargin) == 2 && isa(varargin{1},'char') && isa(varargin{2},'gtsam.noiseModel.Diagonal')
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(98, varargin{:});
|
||||
[ varargout{1} varargout{2} ] = geometry_wrapper(104, varargin{:});
|
||||
else
|
||||
error('Arguments do not match any overload of function load2D');
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
function varargout = overloadedGlobalFunction(varargin)
|
||||
if length(varargin) == 1 && isa(varargin{1},'numeric')
|
||||
varargout{1} = geometry_wrapper(100, varargin{:});
|
||||
varargout{1} = geometry_wrapper(106, varargin{:});
|
||||
elseif length(varargin) == 2 && isa(varargin{1},'numeric') && isa(varargin{2},'double')
|
||||
varargout{1} = geometry_wrapper(101, varargin{:});
|
||||
varargout{1} = geometry_wrapper(107, varargin{:});
|
||||
else
|
||||
error('Arguments do not match any overload of function overloadedGlobalFunction');
|
||||
end
|
||||
|
|
|
@ -35,55 +35,29 @@ PYBIND11_MODULE(geometry_py, m_) {
|
|||
.def("dim",[](gtsam::Point2* self){return self->dim();})
|
||||
.def("returnChar",[](gtsam::Point2* self){return self->returnChar();})
|
||||
.def("argChar",[](gtsam::Point2* self, char a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, std::shared_ptr<char>& a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, char& a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, char* a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, const std::shared_ptr<char>& a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, const char& a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argChar",[](gtsam::Point2* self, const char* a){ self->argChar(a);}, py::arg("a"))
|
||||
.def("argUChar",[](gtsam::Point2* self, unsigned char a){ self->argUChar(a);}, py::arg("a"))
|
||||
.def("eigenArguments",[](gtsam::Point2* self, const gtsam::Vector& v, const gtsam::Matrix& m){ self->eigenArguments(v, m);}, py::arg("v"), py::arg("m"))
|
||||
.def("vectorConfusion",[](gtsam::Point2* self){return self->vectorConfusion();})
|
||||
.def("serialize",
|
||||
[](gtsam::Point2* self){
|
||||
return gtsam::serialize(*self);
|
||||
}
|
||||
)
|
||||
.def("deserialize",
|
||||
[](gtsam::Point2* self, string serialized){
|
||||
gtsam::deserialize(serialized, *self);
|
||||
}, py::arg("serialized"))
|
||||
|
||||
.def("serialize", [](gtsam::Point2* self){ return gtsam::serialize(*self); })
|
||||
.def("deserialize", [](gtsam::Point2* self, string serialized){ gtsam::deserialize(serialized, *self); }, py::arg("serialized"))
|
||||
.def(py::pickle(
|
||||
[](const gtsam::Point2 &a){ // __getstate__
|
||||
/* Returns a string that encodes the state of the object */
|
||||
return py::make_tuple(gtsam::serialize(a));
|
||||
},
|
||||
[](py::tuple t){ // __setstate__
|
||||
gtsam::Point2 obj;
|
||||
gtsam::deserialize(t[0].cast<std::string>(), obj);
|
||||
return obj;
|
||||
}))
|
||||
;
|
||||
[](const gtsam::Point2 &a){ /* __getstate__: Returns a string that encodes the state of the object */ return py::make_tuple(gtsam::serialize(a)); },
|
||||
[](py::tuple t){ /* __setstate__ */ gtsam::Point2 obj; gtsam::deserialize(t[0].cast<std::string>(), obj); return obj; }));
|
||||
|
||||
py::class_<gtsam::Point3, std::shared_ptr<gtsam::Point3>>(m_gtsam, "Point3")
|
||||
.def(py::init<double, double, double>(), py::arg("x"), py::arg("y"), py::arg("z"))
|
||||
.def("norm",[](gtsam::Point3* self){return self->norm();})
|
||||
.def("serialize",
|
||||
[](gtsam::Point3* self){
|
||||
return gtsam::serialize(*self);
|
||||
}
|
||||
)
|
||||
.def("deserialize",
|
||||
[](gtsam::Point3* self, string serialized){
|
||||
gtsam::deserialize(serialized, *self);
|
||||
}, py::arg("serialized"))
|
||||
|
||||
.def("serialize", [](gtsam::Point3* self){ return gtsam::serialize(*self); })
|
||||
.def("deserialize", [](gtsam::Point3* self, string serialized){ gtsam::deserialize(serialized, *self); }, py::arg("serialized"))
|
||||
.def(py::pickle(
|
||||
[](const gtsam::Point3 &a){ // __getstate__
|
||||
/* Returns a string that encodes the state of the object */
|
||||
return py::make_tuple(gtsam::serialize(a));
|
||||
},
|
||||
[](py::tuple t){ // __setstate__
|
||||
gtsam::Point3 obj;
|
||||
gtsam::deserialize(t[0].cast<std::string>(), obj);
|
||||
return obj;
|
||||
}))
|
||||
|
||||
[](const gtsam::Point3 &a){ /* __getstate__: Returns a string that encodes the state of the object */ return py::make_tuple(gtsam::serialize(a)); },
|
||||
[](py::tuple t){ /* __setstate__ */ gtsam::Point3 obj; gtsam::deserialize(t[0].cast<std::string>(), obj); return obj; }))
|
||||
.def_static("staticFunction",[](){return gtsam::Point3::staticFunction();})
|
||||
.def_static("StaticFunctionRet",[](double z){return gtsam::Point3::StaticFunctionRet(z);}, py::arg("z"));
|
||||
|
||||
|
@ -104,11 +78,11 @@ PYBIND11_MODULE(geometry_py, m_) {
|
|||
.def("arg_EigenConstRef",[](Test* self, const gtsam::Matrix& value){ self->arg_EigenConstRef(value);}, py::arg("value"))
|
||||
.def("return_field",[](Test* self, const Test& t){return self->return_field(t);}, py::arg("t"))
|
||||
.def("return_TestPtr",[](Test* self, const std::shared_ptr<Test>& value){return self->return_TestPtr(value);}, py::arg("value"))
|
||||
.def("return_Test",[](Test* self,const std::shared_ptr<Test>& value){return self->return_Test(value);}, py::arg("value"))
|
||||
.def("return_Test",[](Test* self, std::shared_ptr<Test>& value){return self->return_Test(value);}, py::arg("value"))
|
||||
.def("return_Point2Ptr",[](Test* self, bool value){return self->return_Point2Ptr(value);}, py::arg("value"))
|
||||
.def("create_ptrs",[](Test* self){return self->create_ptrs();})
|
||||
.def("create_MixedPtrs",[](Test* self){return self->create_MixedPtrs();})
|
||||
.def("return_ptrs",[](Test* self,const std::shared_ptr<Test>& p1,const std::shared_ptr<Test>& p2){return self->return_ptrs(p1, p2);}, py::arg("p1"), py::arg("p2"))
|
||||
.def("return_ptrs",[](Test* self, std::shared_ptr<Test>& p1, std::shared_ptr<Test>& p2){return self->return_ptrs(p1, p2);}, py::arg("p1"), py::arg("p2"))
|
||||
.def("print_",[](Test* self){ self->print();})
|
||||
.def("__repr__",
|
||||
[](const Test &a) {
|
||||
|
@ -127,12 +101,12 @@ PYBIND11_MODULE(geometry_py, m_) {
|
|||
.def("templatedMethodVector",[](MyTemplate<gtsam::Point2>* self, const gtsam::Vector& t){return self->templatedMethod<gtsam::Vector>(t);}, py::arg("t"))
|
||||
.def("templatedMethodMatrix",[](MyTemplate<gtsam::Point2>* self, const gtsam::Matrix& t){return self->templatedMethod<gtsam::Matrix>(t);}, py::arg("t"))
|
||||
.def("accept_T",[](MyTemplate<gtsam::Point2>* self, const gtsam::Point2& value){ self->accept_T(value);}, py::arg("value"))
|
||||
.def("accept_Tptr",[](MyTemplate<gtsam::Point2>* self,const std::shared_ptr<gtsam::Point2>& value){ self->accept_Tptr(value);}, py::arg("value"))
|
||||
.def("return_Tptr",[](MyTemplate<gtsam::Point2>* self,const std::shared_ptr<gtsam::Point2>& value){return self->return_Tptr(value);}, py::arg("value"))
|
||||
.def("return_T",[](MyTemplate<gtsam::Point2>* self,const std::shared_ptr<gtsam::Point2>& value){return self->return_T(value);}, py::arg("value"))
|
||||
.def("accept_Tptr",[](MyTemplate<gtsam::Point2>* self, std::shared_ptr<gtsam::Point2>& value){ self->accept_Tptr(value);}, py::arg("value"))
|
||||
.def("return_Tptr",[](MyTemplate<gtsam::Point2>* self, std::shared_ptr<gtsam::Point2>& value){return self->return_Tptr(value);}, py::arg("value"))
|
||||
.def("return_T",[](MyTemplate<gtsam::Point2>* self, gtsam::Point2* value){return self->return_T(value);}, py::arg("value"))
|
||||
.def("create_ptrs",[](MyTemplate<gtsam::Point2>* self){return self->create_ptrs();})
|
||||
.def("create_MixedPtrs",[](MyTemplate<gtsam::Point2>* self){return self->create_MixedPtrs();})
|
||||
.def("return_ptrs",[](MyTemplate<gtsam::Point2>* self,const std::shared_ptr<gtsam::Point2>& p1,const std::shared_ptr<gtsam::Point2>& p2){return self->return_ptrs(p1, p2);}, py::arg("p1"), py::arg("p2"))
|
||||
.def("return_ptrs",[](MyTemplate<gtsam::Point2>* self, std::shared_ptr<gtsam::Point2>& p1, std::shared_ptr<gtsam::Point2>& p2){return self->return_ptrs(p1, p2);}, py::arg("p1"), py::arg("p2"))
|
||||
.def_static("Level",[](const gtsam::Point2& K){return MyTemplate<gtsam::Point2>::Level(K);}, py::arg("K"));
|
||||
|
||||
py::class_<MyTemplate<gtsam::Matrix>, MyBase, std::shared_ptr<MyTemplate<gtsam::Matrix>>>(m_, "MyTemplateMatrix")
|
||||
|
@ -144,7 +118,7 @@ PYBIND11_MODULE(geometry_py, m_) {
|
|||
.def("accept_T",[](MyTemplate<gtsam::Matrix>* self, const gtsam::Matrix& value){ self->accept_T(value);}, py::arg("value"))
|
||||
.def("accept_Tptr",[](MyTemplate<gtsam::Matrix>* self, const std::shared_ptr<gtsam::Matrix>& value){ self->accept_Tptr(value);}, py::arg("value"))
|
||||
.def("return_Tptr",[](MyTemplate<gtsam::Matrix>* self, const std::shared_ptr<gtsam::Matrix>& value){return self->return_Tptr(value);}, py::arg("value"))
|
||||
.def("return_T",[](MyTemplate<gtsam::Matrix>* self,const std::shared_ptr<gtsam::Matrix>& value){return self->return_T(value);}, py::arg("value"))
|
||||
.def("return_T",[](MyTemplate<gtsam::Matrix>* self, const gtsam::Matrix* value){return self->return_T(value);}, py::arg("value"))
|
||||
.def("create_ptrs",[](MyTemplate<gtsam::Matrix>* self){return self->create_ptrs();})
|
||||
.def("create_MixedPtrs",[](MyTemplate<gtsam::Matrix>* self){return self->create_MixedPtrs();})
|
||||
.def("return_ptrs",[](MyTemplate<gtsam::Matrix>* self, const std::shared_ptr<gtsam::Matrix>& p1, const std::shared_ptr<gtsam::Matrix>& p2){return self->return_ptrs(p1, p2);}, py::arg("p1"), py::arg("p2"))
|
||||
|
@ -167,12 +141,15 @@ PYBIND11_MODULE(geometry_py, m_) {
|
|||
py::class_<MyFactor<gtsam::Pose2, gtsam::Matrix>, std::shared_ptr<MyFactor<gtsam::Pose2, gtsam::Matrix>>>(m_, "MyFactorPosePoint2")
|
||||
.def(py::init<size_t, size_t, double, const std::shared_ptr<gtsam::noiseModel::Base>&>(), py::arg("key1"), py::arg("key2"), py::arg("measured"), py::arg("noiseModel"));
|
||||
|
||||
m_.def("load2D",[]( string filename,const std::shared_ptr<Test>& model, int maxID, bool addNoise, bool smart){return ::load2D(filename, model, maxID, addNoise, smart);}, py::arg("filename"), py::arg("model"), py::arg("maxID"), py::arg("addNoise"), py::arg("smart"));
|
||||
m_.def("load2D",[](string filename, std::shared_ptr<Test>& model, int maxID, bool addNoise, bool smart){return ::load2D(filename, model, maxID, addNoise, smart);}, py::arg("filename"), py::arg("model"), py::arg("maxID"), py::arg("addNoise"), py::arg("smart"));
|
||||
m_.def("load2D",[](string filename, const std::shared_ptr<gtsam::noiseModel::Diagonal>& model, int maxID, bool addNoise, bool smart){return ::load2D(filename, model, maxID, addNoise, smart);}, py::arg("filename"), py::arg("model"), py::arg("maxID"), py::arg("addNoise"), py::arg("smart"));
|
||||
m_.def("load2D",[]( string filename,const std::shared_ptr<gtsam::noiseModel::Diagonal>& model){return ::load2D(filename, model);}, py::arg("filename"), py::arg("model"));
|
||||
m_.def("load2D",[](string filename, gtsam::noiseModel::Diagonal* model){return ::load2D(filename, model);}, py::arg("filename"), py::arg("model"));
|
||||
m_.def("aGlobalFunction",[](){return ::aGlobalFunction();});
|
||||
m_.def("overloadedGlobalFunction",[](int a){return ::overloadedGlobalFunction(a);}, py::arg("a"));
|
||||
m_.def("overloadedGlobalFunction",[](int a, double b){return ::overloadedGlobalFunction(a, b);}, py::arg("a"), py::arg("b"));
|
||||
m_.def("MultiTemplatedFunctionStringSize_tDouble",[](const T& x, size_t y){return ::MultiTemplatedFunction<string,size_t,double>(x, y);}, py::arg("x"), py::arg("y"));
|
||||
m_.def("MultiTemplatedFunctionDoubleSize_tDouble",[](const T& x, size_t y){return ::MultiTemplatedFunction<double,size_t,double>(x, y);}, py::arg("x"), py::arg("y"));
|
||||
m_.def("TemplatedFunctionRot3",[](const gtsam::Rot3& t){ ::TemplatedFunction<Rot3>(t);}, py::arg("t"));
|
||||
|
||||
#include "python/specializations.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
|
||||
#include <pybind11/eigen.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include "gtsam/nonlinear/utilities.h" // for RedirectCout.
|
||||
|
||||
#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"
|
||||
|
||||
#include "wrap/serialization.h"
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_MODULE(testNamespaces_py, m_) {
|
||||
m_.doc() = "pybind11 wrapper of testNamespaces_py";
|
||||
|
||||
pybind11::module m_ns1 = m_.def_submodule("ns1", "ns1 submodule");
|
||||
|
||||
py::class_<ns1::ClassA, std::shared_ptr<ns1::ClassA>>(m_ns1, "ClassA")
|
||||
.def(py::init<>());
|
||||
|
||||
py::class_<ns1::ClassB, std::shared_ptr<ns1::ClassB>>(m_ns1, "ClassB")
|
||||
.def(py::init<>());
|
||||
|
||||
m_ns1.def("aGlobalFunction",[](){return ns1::aGlobalFunction();}); pybind11::module m_ns2 = m_.def_submodule("ns2", "ns2 submodule");
|
||||
|
||||
py::class_<ns2::ClassA, std::shared_ptr<ns2::ClassA>>(m_ns2, "ClassA")
|
||||
.def(py::init<>())
|
||||
.def("memberFunction",[](ns2::ClassA* self){return self->memberFunction();})
|
||||
.def("nsArg",[](ns2::ClassA* self, const ns1::ClassB& arg){return self->nsArg(arg);}, py::arg("arg"))
|
||||
.def("nsReturn",[](ns2::ClassA* self, double q){return self->nsReturn(q);}, py::arg("q"))
|
||||
.def_static("afunction",[](){return ns2::ClassA::afunction();});
|
||||
pybind11::module m_ns2_ns3 = m_ns2.def_submodule("ns3", "ns3 submodule");
|
||||
|
||||
py::class_<ns2::ns3::ClassB, std::shared_ptr<ns2::ns3::ClassB>>(m_ns2_ns3, "ClassB")
|
||||
.def(py::init<>());
|
||||
|
||||
py::class_<ns2::ClassC, std::shared_ptr<ns2::ClassC>>(m_ns2, "ClassC")
|
||||
.def(py::init<>());
|
||||
|
||||
m_ns2.def("aGlobalFunction",[](){return ns2::aGlobalFunction();});
|
||||
m_ns2.def("overloadedGlobalFunction",[](const ns1::ClassA& a){return ns2::overloadedGlobalFunction(a);}, py::arg("a"));
|
||||
m_ns2.def("overloadedGlobalFunction",[](const ns1::ClassA& a, double b){return ns2::overloadedGlobalFunction(a, b);}, py::arg("a"), py::arg("b"));
|
||||
py::class_<ClassD, std::shared_ptr<ClassD>>(m_, "ClassD")
|
||||
.def(py::init<>());
|
||||
|
||||
|
||||
#include "python/specializations.h"
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,12 @@ class Point2 {
|
|||
int dim() const;
|
||||
char returnChar() const;
|
||||
void argChar(char a) const;
|
||||
void argChar(char* a) const;
|
||||
void argChar(char& a) const;
|
||||
void argChar(char@ a) const;
|
||||
void argChar(const char* a) const;
|
||||
void argChar(const char& a) const;
|
||||
void argChar(const char@ a) const;
|
||||
void argUChar(unsigned char a) const;
|
||||
void eigenArguments(Vector v, Matrix m) const;
|
||||
VectorNotEigen vectorConfusion();
|
||||
|
@ -87,7 +93,7 @@ class Test {
|
|||
|
||||
bool return_field(const Test& t) const;
|
||||
|
||||
Test* return_TestPtr(Test* value) const;
|
||||
Test* return_TestPtr(const Test* value) const;
|
||||
Test return_Test(Test* value) const;
|
||||
|
||||
gtsam::Point2* return_Point2Ptr(bool value) const;
|
||||
|
@ -104,8 +110,8 @@ class Test {
|
|||
};
|
||||
|
||||
pair<gtsam::NonlinearFactorGraph*, gtsam::Values*> load2D(string filename, Test* model, int maxID, bool addNoise, bool smart);
|
||||
pair<gtsam::NonlinearFactorGraph*, gtsam::Values*> load2D(string filename, gtsam::noiseModel::Diagonal* model, int maxID, bool addNoise, bool smart);
|
||||
pair<gtsam::NonlinearFactorGraph*, gtsam::Values*> load2D(string filename, gtsam::noiseModel::Diagonal* model);
|
||||
pair<gtsam::NonlinearFactorGraph*, gtsam::Values*> load2D(string filename, const gtsam::noiseModel::Diagonal* model, int maxID, bool addNoise, bool smart);
|
||||
pair<gtsam::NonlinearFactorGraph*, gtsam::Values*> load2D(string filename, gtsam::noiseModel::Diagonal@ model);
|
||||
|
||||
Vector aGlobalFunction();
|
||||
|
||||
|
@ -130,7 +136,7 @@ virtual class MyTemplate : MyBase {
|
|||
void accept_T(const T& value) const;
|
||||
void accept_Tptr(T* value) const;
|
||||
T* return_Tptr(T* value) const;
|
||||
T return_T(T* value) const;
|
||||
T return_T(T@ value) const;
|
||||
pair<T*,T*> create_ptrs () const;
|
||||
pair<T ,T*> create_MixedPtrs () const;
|
||||
pair<T*,T*> return_ptrs (T* p1, T* p2) const;
|
||||
|
@ -167,3 +173,13 @@ class MyVector {
|
|||
// Class with multiple instantiated templates
|
||||
template<T = {int}, U = {double, float}>
|
||||
class MultipleTemplates {};
|
||||
|
||||
// A templated free/global function. Multiple templates supported.
|
||||
template<T1 = {string, double}, T2 = {size_t}, R = {double}>
|
||||
R MultiTemplatedFunction(const T& x, T2 y);
|
||||
|
||||
// Check if we can typedef the templated function
|
||||
template<T>
|
||||
void TemplatedFunction(const T& t);
|
||||
|
||||
typedef TemplatedFunction<gtsam::Rot3> TemplatedFunctionRot3;
|
||||
|
|
|
@ -1,258 +0,0 @@
|
|||
# TODO(duy): make them proper tests!!!
|
||||
import unittest
|
||||
|
||||
import sys, os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from gtwrap.interface_parser import *
|
||||
|
||||
|
||||
class TestPyparsing(unittest.TestCase):
|
||||
def test_argument_list(self):
|
||||
arg_string = "int a, C1 c1, C2& c2, C3* c3, "\
|
||||
"const C4 c4, const C5& c5,"\
|
||||
"const C6* c6"
|
||||
args = ArgumentList.rule.parseString(arg_string)
|
||||
print(ArgumentList(args))
|
||||
|
||||
|
||||
empty_args = ArgumentList.rule.parseString("")[0]
|
||||
print(empty_args)
|
||||
|
||||
arg_string = "int a, C1 c1, C2& c2, C3* c3, "\
|
||||
"const C4 c4, const C5& c5,"\
|
||||
"const C6* c6"
|
||||
args = ArgumentList.rule.parseString(arg_string)[0]
|
||||
print(args)
|
||||
|
||||
# Test ReturnType
|
||||
ReturnType.rule.parseString("pair<fdsa, rewcds>")[0]
|
||||
ReturnType.rule.parseString("cdwdc")[0]
|
||||
|
||||
# expect throw
|
||||
# ReturnType.parseString("int&")
|
||||
# ReturnType.parseString("const int")
|
||||
|
||||
ret = Class.rule.parseString("""
|
||||
virtual class SymbolicFactorGraph {
|
||||
SymbolicFactorGraph();
|
||||
SymbolicFactorGraph(const gtsam::SymbolicBayesNet& bayesNet);
|
||||
SymbolicFactorGraph(const gtsam::SymbolicBayesTree& bayesTree);
|
||||
|
||||
// From FactorGraph.
|
||||
void push_back(gtsam::SymbolicFactor* factor);
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::SymbolicFactorGraph& rhs, double tol) const;
|
||||
size_t size() const;
|
||||
bool exists(size_t idx) const;
|
||||
|
||||
// Standard interface
|
||||
gtsam::KeySet keys() const;
|
||||
void push_back(const gtsam::SymbolicFactorGraph& graph);
|
||||
void push_back(const gtsam::SymbolicBayesNet& bayesNet);
|
||||
void push_back(const gtsam::SymbolicBayesTree& bayesTree);
|
||||
|
||||
/* Advanced interface */
|
||||
void push_factor(size_t key);
|
||||
void push_factor(size_t key1, size_t key2);
|
||||
void push_factor(size_t key1, size_t key2, size_t key3);
|
||||
void push_factor(size_t key1, size_t key2, size_t key3, size_t key4);
|
||||
|
||||
gtsam::SymbolicBayesNet* eliminateSequential();
|
||||
gtsam::SymbolicBayesNet* eliminateSequential(
|
||||
const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesTree* eliminateMultifrontal();
|
||||
gtsam::SymbolicBayesTree* eliminateMultifrontal(
|
||||
const gtsam::Ordering& ordering);
|
||||
pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialSequential(const gtsam::Ordering& ordering);
|
||||
pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialSequential(const gtsam::KeyVector& keys);
|
||||
pair<gtsam::SymbolicBayesTree*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialMultifrontal(const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
|
||||
const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
|
||||
const gtsam::KeyVector& key_vector,
|
||||
const gtsam::Ordering& marginalizedVariableOrdering);
|
||||
gtsam::SymbolicFactorGraph* marginal(const gtsam::KeyVector& key_vector);
|
||||
};
|
||||
""")[0]
|
||||
|
||||
ret = Class.rule.parseString("""
|
||||
virtual class Base {
|
||||
};
|
||||
""")[0]
|
||||
|
||||
ret = Class.rule.parseString("""
|
||||
virtual class Null: gtsam::noiseModel::mEstimator::Base {
|
||||
Null();
|
||||
void print(string s) const;
|
||||
static gtsam::noiseModel::mEstimator::Null* Create();
|
||||
|
||||
// enabling serialization functionality
|
||||
void serializable() const;
|
||||
};
|
||||
""")[0]
|
||||
|
||||
retFactorIndices = Class.rule.parseString("""
|
||||
class FactorIndices {};
|
||||
""")[0]
|
||||
|
||||
retIsam2 = Class.rule.parseString("""
|
||||
class ISAM2 {
|
||||
ISAM2();
|
||||
ISAM2(const gtsam::ISAM2Params& params);
|
||||
ISAM2(const gtsam::ISAM2& other);
|
||||
|
||||
bool equals(const gtsam::ISAM2& other, double tol) const;
|
||||
void print(string s) const;
|
||||
void printStats() const;
|
||||
void saveGraph(string s) const;
|
||||
|
||||
gtsam::ISAM2Result update();
|
||||
gtsam::ISAM2Result update(const gtsam::NonlinearFactorGraph& newFactors,
|
||||
const gtsam::Values& newTheta);
|
||||
gtsam::ISAM2Result update(const gtsam::NonlinearFactorGraph& newFactors,
|
||||
const gtsam::Values& newTheta, const gtsam::FactorIndices&
|
||||
removeFactorIndices);
|
||||
gtsam::ISAM2Result update(const gtsam::NonlinearFactorGraph& newFactors,
|
||||
const gtsam::Values& newTheta,
|
||||
const gtsam::FactorIndices& removeFactorIndices,
|
||||
const gtsam::KeyGroupMap& constrainedKeys);
|
||||
|
||||
gtsam::Values getLinearizationPoint() const;
|
||||
gtsam::Values calculateEstimate() const;
|
||||
template <VALUE = {gtsam::Point2, gtsam::Rot2, gtsam::Pose2, gtsam::Point3,
|
||||
gtsam::Rot3, gtsam::Pose3, gtsam::Cal3_S2, gtsam::Cal3DS2,
|
||||
gtsam::Cal3Bundler, gtsam::EssentialMatrix,
|
||||
gtsam::SimpleCamera, Vector, Matrix}>
|
||||
VALUE calculateEstimate(size_t key) const;
|
||||
gtsam::Values calculateBestEstimate() const;
|
||||
Matrix marginalCovariance(size_t key) const;
|
||||
gtsam::VectorValues getDelta() const;
|
||||
gtsam::NonlinearFactorGraph getFactorsUnsafe() const;
|
||||
gtsam::VariableIndex getVariableIndex() const;
|
||||
gtsam::ISAM2Params params() const;
|
||||
};
|
||||
""")[0]
|
||||
# if __name__ == '__main__':
|
||||
# unittest.main()
|
||||
|
||||
typename = Typename.rule.parseString("rew")[0]
|
||||
ret = ReturnType.rule.parseString("pair<fdsa, rewcds>")[0]
|
||||
ret1 = Method.rule.parseString(
|
||||
"int f(const int x, const Class& c, Class* t) const;")[0]
|
||||
ret = Method.rule.parseString("int f() const;")[0]
|
||||
|
||||
ret1 = StaticMethod.rule.parseString(
|
||||
"static int f(const int x, const Class& c, Class* t);")[0]
|
||||
ret = StaticMethod.rule.parseString("static int f();")[0]
|
||||
ret1 = Constructor.rule.parseString(
|
||||
"f(const int x, const Class& c, Class* t);")[0]
|
||||
ret = Constructor.rule.parseString("f();")[0]
|
||||
|
||||
typedef = TypedefTemplateInstantiation.rule.parseString("""
|
||||
typedef gtsam::BearingFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2>
|
||||
BearingFactor2D;
|
||||
""")[0]
|
||||
|
||||
include = Include.rule.parseString("#include <gtsam/slam/PriorFactor.h>")[0]
|
||||
print(include)
|
||||
|
||||
fwd = ForwardDeclaration.rule.parseString(
|
||||
"virtual class Test:gtsam::Point3;")[0]
|
||||
|
||||
func = GlobalFunction.rule.parseString("""
|
||||
gtsam::Values localToWorld(const gtsam::Values& local,
|
||||
const gtsam::Pose2& base, const gtsam::KeyVector& keys);
|
||||
""")[0]
|
||||
print(func)
|
||||
|
||||
try:
|
||||
namespace = Namespace.rule.parseString("""
|
||||
namespace gtsam {
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
class Point2 {
|
||||
Point2();
|
||||
Point2(double x, double y);
|
||||
double x() const;
|
||||
double y() const;
|
||||
int dim() const;
|
||||
char returnChar() const;
|
||||
void argChar(char a) const;
|
||||
void argUChar(unsigned char a) const;
|
||||
void eigenArguments(Vector v, Matrix m) const;
|
||||
VectorNotEigen vectorConfusion();
|
||||
};
|
||||
|
||||
#include <gtsam/geometry/Point3.h>
|
||||
class Point3 {
|
||||
Point3(double x, double y, double z);
|
||||
double norm() const;
|
||||
|
||||
// static functions - use static keyword and uppercase
|
||||
static double staticFunction();
|
||||
static gtsam::Point3 StaticFunctionRet(double z);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const; // Just triggers a flag internally
|
||||
};
|
||||
|
||||
}
|
||||
""")
|
||||
except ParseException as pe:
|
||||
print(pe.markInputline())
|
||||
|
||||
# filename = "tools/workspace/pybind_wrapper/gtsam.h"
|
||||
# with open(filename, "r") as f:
|
||||
# content = f.read()
|
||||
# module = Module.parseString(content)
|
||||
|
||||
module = Module.parseString("""
|
||||
namespace one {
|
||||
namespace two {
|
||||
namespace three {
|
||||
class Class123 {
|
||||
};
|
||||
}
|
||||
class Class12a {
|
||||
};
|
||||
}
|
||||
namespace two_dummy {
|
||||
namespace three_dummy{
|
||||
|
||||
}
|
||||
namespace fourth_dummy{
|
||||
|
||||
}
|
||||
}
|
||||
namespace two {
|
||||
class Class12b {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Global{
|
||||
};
|
||||
""")
|
||||
|
||||
print("module: ", module)
|
||||
|
||||
sub_namespace = find_sub_namespace(module, ['one', 'two', 'three'])
|
||||
print("Found namespace:", sub_namespace[0].name)
|
||||
print(find_sub_namespace(module, ['one', 'two_test', 'three']))
|
||||
print(find_sub_namespace(module, ['one', 'two']))
|
||||
|
||||
found_class = module.find_class(
|
||||
Typename(namespaces_name=['one', 'two', 'three', 'Class123']))
|
||||
print(found_class)
|
||||
|
||||
found_class = module.find_class(
|
||||
Typename(namespaces_name=['one', 'two', 'Class12b']))
|
||||
print(found_class.name)
|
||||
|
||||
found_class = module.find_class(
|
||||
Typename(namespaces_name=['one', 'two', 'Class12a']))
|
||||
print(found_class.name)
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
Unit test for documentation generation
|
||||
Author: Matthew Sklar
|
||||
Author: Matthew Sklar, Varun Agrawal
|
||||
Date: May 2019
|
||||
"""
|
||||
import filecmp
|
||||
|
@ -16,7 +16,6 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|||
import docs.parser.parse_doxygen_xml as parser
|
||||
from docs.docs import ClassDoc, Doc, Docs, FreeDoc
|
||||
|
||||
|
||||
tree_root = ET.Element('a')
|
||||
tree_left = ET.SubElement(tree_root, 'b')
|
||||
tree_right = ET.SubElement(tree_root, 1)
|
||||
|
@ -31,6 +30,7 @@ d2 = ET.SubElement(d, 'd')
|
|||
|
||||
|
||||
class TestDocument(unittest.TestCase):
|
||||
"""Test class for document generation utilities."""
|
||||
DIR_NAME = path.dirname(__file__)
|
||||
|
||||
DOC_DIR = 'doc-test-files'
|
||||
|
@ -42,33 +42,39 @@ class TestDocument(unittest.TestCase):
|
|||
EXPECTED_XML_DIR_PATH = path.abspath(path.join(DIR_NAME, EXPECTED_XML_DIR))
|
||||
|
||||
def test_generate_xml(self):
|
||||
'''Test parse_xml.generate_xml'''
|
||||
"""Test parse_xml.generate_xml"""
|
||||
if path.exists(self.OUTPUT_XML_DIR_PATH):
|
||||
shutil.rmtree(self.OUTPUT_XML_DIR_PATH, ignore_errors=True)
|
||||
parser.generate_xml(
|
||||
self.DOC_DIR_PATH, self.OUTPUT_XML_DIR_PATH, quiet=True)
|
||||
parser.generate_xml(self.DOC_DIR_PATH,
|
||||
self.OUTPUT_XML_DIR_PATH,
|
||||
quiet=True)
|
||||
|
||||
self.assertTrue(os.path.isdir(self.OUTPUT_XML_DIR_PATH))
|
||||
|
||||
shutil.rmtree(path.join(self.OUTPUT_XML_DIR_PATH, 'xml'))
|
||||
parser.generate_xml(
|
||||
self.DOC_DIR_PATH, self.OUTPUT_XML_DIR_PATH, quiet=True)
|
||||
xml_path = path.join(self.OUTPUT_XML_DIR_PATH, 'xml')
|
||||
if path.exists(xml_path):
|
||||
shutil.rmtree(xml_path)
|
||||
parser.generate_xml(self.DOC_DIR_PATH,
|
||||
self.OUTPUT_XML_DIR_PATH,
|
||||
quiet=True)
|
||||
|
||||
dircmp = filecmp.dircmp(
|
||||
self.OUTPUT_XML_DIR_PATH, self.EXPECTED_XML_DIR_PATH)
|
||||
dircmp = filecmp.dircmp(self.OUTPUT_XML_DIR_PATH,
|
||||
self.EXPECTED_XML_DIR_PATH)
|
||||
|
||||
self.assertTrue(not dircmp.diff_files and not dircmp.funny_files)
|
||||
|
||||
def test_parse(self):
|
||||
docs = parser.ParseDoxygenXML(
|
||||
self.DOC_DIR_PATH, self.OUTPUT_XML_DIR_PATH).run()
|
||||
"""Test the parsing of the XML generated by Doxygen."""
|
||||
docs = parser.ParseDoxygenXML(self.DOC_DIR_PATH,
|
||||
self.OUTPUT_XML_DIR_PATH).run()
|
||||
|
||||
for class_name in docs.get_class_docs_keys_list():
|
||||
actual_tree_root = docs.get_class_docs(
|
||||
class_name).get_tree().getroot()
|
||||
expected_tree_root = ET.parse(class_name).getroot()
|
||||
|
||||
self.assertEqual(
|
||||
ET.tostring(actual_tree_root), ET.tostring(expected_tree_root))
|
||||
self.assertEqual(ET.tostring(actual_tree_root),
|
||||
ET.tostring(expected_tree_root))
|
||||
|
||||
|
||||
class TestDocTemplate(unittest.TestCase):
|
||||
|
@ -102,7 +108,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
|
||||
# ClassDoc
|
||||
def test_class_doc(self):
|
||||
'''Test the constructor in ClassDoc'''
|
||||
"""Test the constructor in ClassDoc"""
|
||||
self.assertIs(self.class_doc_root.tree, tree_root)
|
||||
self.assertIs(self.class_doc_left.tree, tree_left)
|
||||
self.assertIs(self.class_doc_right.tree, tree_right)
|
||||
|
@ -110,7 +116,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
self.assertIs(self.class_doc_recursive.tree, tree_recursive)
|
||||
|
||||
def test_class_doc_get_tree(self):
|
||||
'''Test the get_tree() method is ClassDoc'''
|
||||
"""Test the get_tree() method is ClassDoc"""
|
||||
self.assertIs(self.class_doc_root.get_tree(), tree_root)
|
||||
self.assertIs(self.class_doc_left.get_tree(), tree_left)
|
||||
self.assertIs(self.class_doc_right.get_tree(), tree_right)
|
||||
|
@ -118,7 +124,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
self.assertIs(self.class_doc_recursive.get_tree(), tree_recursive)
|
||||
|
||||
def test_class_doc_eq(self):
|
||||
'''Test ClassDoc.__eq__'''
|
||||
"""Test ClassDoc.__eq__"""
|
||||
doc1 = ClassDoc(ET.ElementTree(a))
|
||||
doc2 = ClassDoc(ET.ElementTree(d))
|
||||
doc3 = ClassDoc(ET.ElementTree(d2))
|
||||
|
@ -132,7 +138,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
|
||||
# FreeDoc
|
||||
def test_free_doc(self):
|
||||
'''Test the constructor in FreeDoc'''
|
||||
"""Test the constructor in FreeDoc"""
|
||||
self.assertIs(self.free_doc_root.tree, tree_root)
|
||||
self.assertIs(self.free_doc_left.tree, tree_left)
|
||||
self.assertIs(self.free_doc_right.tree, tree_right)
|
||||
|
@ -140,7 +146,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
self.assertIs(self.free_doc_recursive.tree, tree_recursive)
|
||||
|
||||
def test_free_doc_get_tree(self):
|
||||
'''Test the get_tree() method is FreeDoc'''
|
||||
"""Test the get_tree() method is FreeDoc"""
|
||||
self.assertIs(self.free_doc_root.get_tree(), tree_root)
|
||||
self.assertIs(self.free_doc_left.get_tree(), tree_left)
|
||||
self.assertIs(self.free_doc_right.get_tree(), tree_right)
|
||||
|
@ -148,7 +154,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
self.assertIs(self.free_doc_recursive.get_tree(), tree_recursive)
|
||||
|
||||
def test_free_doc_eq(self):
|
||||
'''Test FreeDoc.__eq__'''
|
||||
"""Test FreeDoc.__eq__"""
|
||||
doc1 = FreeDoc(ET.ElementTree(a))
|
||||
doc2 = FreeDoc(ET.ElementTree(d))
|
||||
doc3 = FreeDoc(ET.ElementTree(d2))
|
||||
|
@ -162,7 +168,7 @@ class TestDocTemplate(unittest.TestCase):
|
|||
|
||||
# Docs
|
||||
def test_docs(self):
|
||||
'''Test Docs template constructor'''
|
||||
"""Test Docs template constructor"""
|
||||
docs = Docs(self.CLASS_DOCS, self.FREE_DOCS)
|
||||
|
||||
self.assertIs(docs.class_docs, self.CLASS_DOCS)
|
||||
|
@ -172,15 +178,15 @@ class TestDocTemplate(unittest.TestCase):
|
|||
docs = Docs(self.CLASS_DOCS, self.FREE_DOCS)
|
||||
|
||||
for doc_name in self.CLASS_DOCS.keys():
|
||||
self.assertIs(
|
||||
self.CLASS_DOCS.get(doc_name), docs.get_class_docs(doc_name))
|
||||
self.assertIs(self.CLASS_DOCS.get(doc_name),
|
||||
docs.get_class_docs(doc_name))
|
||||
|
||||
def test_get_free_docs(self):
|
||||
docs = Docs(self.CLASS_DOCS, self.FREE_DOCS)
|
||||
|
||||
for doc_name in self.FREE_DOCS.keys():
|
||||
self.assertIs(
|
||||
self.FREE_DOCS.get(doc_name), docs.get_free_docs(doc_name))
|
||||
self.assertIs(self.FREE_DOCS.get(doc_name),
|
||||
docs.get_free_docs(doc_name))
|
||||
|
||||
def test_get_class_docs_keys_list(self):
|
||||
docs = Docs(self.CLASS_DOCS, self.FREE_DOCS)
|
||||
|
|
|
@ -0,0 +1,372 @@
|
|||
"""
|
||||
GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
|
||||
Atlanta, Georgia 30332-0415
|
||||
All Rights Reserved
|
||||
|
||||
See LICENSE for the license information
|
||||
|
||||
Tests for interface_parser.
|
||||
|
||||
Author: Varun Agrawal
|
||||
"""
|
||||
|
||||
# pylint: disable=import-error,wrong-import-position
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from pyparsing import ParseException
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from gtwrap.interface_parser import (ArgumentList, Class, Constructor,
|
||||
ForwardDeclaration, GlobalFunction,
|
||||
Include, Method, Module, Namespace,
|
||||
ReturnType, StaticMethod, Type,
|
||||
TypedefTemplateInstantiation, Typename,
|
||||
find_sub_namespace)
|
||||
|
||||
|
||||
class TestInterfaceParser(unittest.TestCase):
|
||||
"""Test driver for all classes in interface_parser.py."""
|
||||
def test_typename(self):
|
||||
"""Test parsing of Typename."""
|
||||
typename = Typename.rule.parseString("size_t")[0]
|
||||
self.assertEqual("size_t", typename.name)
|
||||
|
||||
typename = Typename.rule.parseString("gtsam::PinholeCamera<gtsam::Cal3S2>")[0]
|
||||
self.assertEqual("PinholeCamera", typename.name)
|
||||
self.assertEqual(["gtsam"], typename.namespaces)
|
||||
self.assertEqual("Cal3S2", typename.instantiations[0].name)
|
||||
self.assertEqual(["gtsam"], typename.instantiations[0].namespaces)
|
||||
|
||||
def test_type(self):
|
||||
"""Test for Type."""
|
||||
t = Type.rule.parseString("int x")[0]
|
||||
self.assertEqual("int", t.typename.name)
|
||||
self.assertTrue(t.is_basis)
|
||||
|
||||
t = Type.rule.parseString("T x")[0]
|
||||
self.assertEqual("T", t.typename.name)
|
||||
self.assertTrue(not t.is_basis)
|
||||
|
||||
t = Type.rule.parseString("const int x")[0]
|
||||
self.assertEqual("int", t.typename.name)
|
||||
self.assertTrue(t.is_basis)
|
||||
self.assertTrue(t.is_const)
|
||||
|
||||
def test_empty_arguments(self):
|
||||
"""Test no arguments."""
|
||||
empty_args = ArgumentList.rule.parseString("")[0]
|
||||
self.assertEqual(0, len(empty_args))
|
||||
|
||||
def test_argument_list(self):
|
||||
"""Test arguments list for a method/function."""
|
||||
arg_string = "int a, C1 c1, C2& c2, C3* c3, "\
|
||||
"const C4 c4, const C5& c5,"\
|
||||
"const C6* c6"
|
||||
args = ArgumentList.rule.parseString(arg_string)[0]
|
||||
|
||||
self.assertEqual(7, len(args.args_list))
|
||||
self.assertEqual(['a', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6'],
|
||||
args.args_names())
|
||||
|
||||
def test_argument_list_qualifiers(self):
|
||||
"""
|
||||
Test arguments list where the arguments are qualified with `const`
|
||||
and can be either raw pointers, shared pointers or references.
|
||||
"""
|
||||
arg_string = "double x1, double* x2, double& x3, double@ x4, " \
|
||||
"const double x5, const double* x6, const double& x7, const double@ x8"
|
||||
args = ArgumentList.rule.parseString(arg_string)[0].args_list
|
||||
self.assertEqual(8, len(args))
|
||||
self.assertFalse(args[1].ctype.is_ptr and args[1].ctype.is_shared_ptr
|
||||
and args[1].ctype.is_ref)
|
||||
self.assertTrue(args[1].ctype.is_shared_ptr)
|
||||
self.assertTrue(args[2].ctype.is_ref)
|
||||
self.assertTrue(args[3].ctype.is_ptr)
|
||||
self.assertTrue(args[4].ctype.is_const)
|
||||
self.assertTrue(args[5].ctype.is_shared_ptr and args[5].ctype.is_const)
|
||||
self.assertTrue(args[6].ctype.is_ref and args[6].ctype.is_const)
|
||||
self.assertTrue(args[7].ctype.is_ptr and args[7].ctype.is_const)
|
||||
|
||||
def test_return_type(self):
|
||||
"""Test ReturnType"""
|
||||
# Test void
|
||||
return_type = ReturnType.rule.parseString("void")[0]
|
||||
self.assertEqual("void", return_type.type1.typename.name)
|
||||
self.assertTrue(return_type.type1.is_basis)
|
||||
|
||||
# Test basis type
|
||||
return_type = ReturnType.rule.parseString("size_t")[0]
|
||||
self.assertEqual("size_t", return_type.type1.typename.name)
|
||||
self.assertTrue(not return_type.type2)
|
||||
self.assertTrue(return_type.type1.is_basis)
|
||||
|
||||
# Test with qualifiers
|
||||
return_type = ReturnType.rule.parseString("int&")[0]
|
||||
self.assertEqual("int", return_type.type1.typename.name)
|
||||
self.assertTrue(return_type.type1.is_basis
|
||||
and return_type.type1.is_ref)
|
||||
|
||||
return_type = ReturnType.rule.parseString("const int")[0]
|
||||
self.assertEqual("int", return_type.type1.typename.name)
|
||||
self.assertTrue(return_type.type1.is_basis
|
||||
and return_type.type1.is_const)
|
||||
|
||||
# Test pair return
|
||||
return_type = ReturnType.rule.parseString("pair<char, int>")[0]
|
||||
self.assertEqual("char", return_type.type1.typename.name)
|
||||
self.assertEqual("int", return_type.type2.typename.name)
|
||||
|
||||
def test_method(self):
|
||||
"""Test for a class method."""
|
||||
ret = Method.rule.parseString("int f();")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(0, len(ret.args))
|
||||
self.assertTrue(not ret.is_const)
|
||||
|
||||
ret = Method.rule.parseString("int f() const;")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(0, len(ret.args))
|
||||
self.assertTrue(ret.is_const)
|
||||
|
||||
ret = Method.rule.parseString(
|
||||
"int f(const int x, const Class& c, Class* t) const;")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(3, len(ret.args))
|
||||
|
||||
def test_static_method(self):
|
||||
"""Test for static methods."""
|
||||
ret = StaticMethod.rule.parseString("static int f();")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(0, len(ret.args))
|
||||
|
||||
ret = StaticMethod.rule.parseString(
|
||||
"static int f(const int x, const Class& c, Class* t);")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(3, len(ret.args))
|
||||
|
||||
def test_constructor(self):
|
||||
"""Test for class constructor."""
|
||||
ret = Constructor.rule.parseString("f();")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(0, len(ret.args))
|
||||
|
||||
ret = Constructor.rule.parseString(
|
||||
"f(const int x, const Class& c, Class* t);")[0]
|
||||
self.assertEqual("f", ret.name)
|
||||
self.assertEqual(3, len(ret.args))
|
||||
|
||||
def test_typedef_template_instantiation(self):
|
||||
"""Test for typedef'd instantiation of a template."""
|
||||
typedef = TypedefTemplateInstantiation.rule.parseString("""
|
||||
typedef gtsam::BearingFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2>
|
||||
BearingFactor2D;
|
||||
""")[0]
|
||||
self.assertEqual("BearingFactor2D", typedef.new_name)
|
||||
self.assertEqual("BearingFactor", typedef.typename.name)
|
||||
self.assertEqual(["gtsam"], typedef.typename.namespaces)
|
||||
self.assertEqual(3, len(typedef.typename.instantiations))
|
||||
|
||||
def test_base_class(self):
|
||||
"""Test a base class."""
|
||||
ret = Class.rule.parseString("""
|
||||
virtual class Base {
|
||||
};
|
||||
""")[0]
|
||||
self.assertEqual("Base", ret.name)
|
||||
self.assertEqual(0, len(ret.ctors))
|
||||
self.assertEqual(0, len(ret.methods))
|
||||
self.assertEqual(0, len(ret.static_methods))
|
||||
self.assertEqual(0, len(ret.properties))
|
||||
self.assertTrue(ret.is_virtual)
|
||||
|
||||
def test_empty_class(self):
|
||||
"""Test an empty class declaration."""
|
||||
ret = Class.rule.parseString("""
|
||||
class FactorIndices {};
|
||||
""")[0]
|
||||
self.assertEqual("FactorIndices", ret.name)
|
||||
self.assertEqual(0, len(ret.ctors))
|
||||
self.assertEqual(0, len(ret.methods))
|
||||
self.assertEqual(0, len(ret.static_methods))
|
||||
self.assertEqual(0, len(ret.properties))
|
||||
self.assertTrue(not ret.is_virtual)
|
||||
|
||||
def test_class(self):
|
||||
"""Test a non-trivial class."""
|
||||
ret = Class.rule.parseString("""
|
||||
class SymbolicFactorGraph {
|
||||
SymbolicFactorGraph();
|
||||
SymbolicFactorGraph(const gtsam::SymbolicBayesNet& bayesNet);
|
||||
SymbolicFactorGraph(const gtsam::SymbolicBayesTree& bayesTree);
|
||||
|
||||
// Dummy static method
|
||||
static gtsam::SymbolidFactorGraph CreateGraph();
|
||||
|
||||
void push_back(gtsam::SymbolicFactor* factor);
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::SymbolicFactorGraph& rhs, double tol) const;
|
||||
size_t size() const;
|
||||
bool exists(size_t idx) const;
|
||||
|
||||
// Standard interface
|
||||
gtsam::KeySet keys() const;
|
||||
void push_back(const gtsam::SymbolicFactorGraph& graph);
|
||||
void push_back(const gtsam::SymbolicBayesNet& bayesNet);
|
||||
void push_back(const gtsam::SymbolicBayesTree& bayesTree);
|
||||
|
||||
/* Advanced interface */
|
||||
void push_factor(size_t key);
|
||||
void push_factor(size_t key1, size_t key2);
|
||||
void push_factor(size_t key1, size_t key2, size_t key3);
|
||||
void push_factor(size_t key1, size_t key2, size_t key3, size_t key4);
|
||||
|
||||
gtsam::SymbolicBayesNet* eliminateSequential();
|
||||
gtsam::SymbolicBayesNet* eliminateSequential(
|
||||
const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesTree* eliminateMultifrontal();
|
||||
gtsam::SymbolicBayesTree* eliminateMultifrontal(
|
||||
const gtsam::Ordering& ordering);
|
||||
pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialSequential(const gtsam::Ordering& ordering);
|
||||
pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialSequential(const gtsam::KeyVector& keys);
|
||||
pair<gtsam::SymbolicBayesTree*, gtsam::SymbolicFactorGraph*>
|
||||
eliminatePartialMultifrontal(const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
|
||||
const gtsam::Ordering& ordering);
|
||||
gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
|
||||
const gtsam::KeyVector& key_vector,
|
||||
const gtsam::Ordering& marginalizedVariableOrdering);
|
||||
gtsam::SymbolicFactorGraph* marginal(const gtsam::KeyVector& key_vector);
|
||||
};
|
||||
""")[0]
|
||||
|
||||
self.assertEqual("SymbolicFactorGraph", ret.name)
|
||||
self.assertEqual(3, len(ret.ctors))
|
||||
self.assertEqual(23, len(ret.methods))
|
||||
self.assertEqual(1, len(ret.static_methods))
|
||||
self.assertEqual(0, len(ret.properties))
|
||||
self.assertTrue(not ret.is_virtual)
|
||||
|
||||
def test_class_inheritance(self):
|
||||
"""Test for class inheritance."""
|
||||
ret = Class.rule.parseString("""
|
||||
virtual class Null: gtsam::noiseModel::mEstimator::Base {
|
||||
Null();
|
||||
void print(string s) const;
|
||||
static gtsam::noiseModel::mEstimator::Null* Create();
|
||||
|
||||
// enabling serialization functionality
|
||||
void serializable() const;
|
||||
};
|
||||
""")[0]
|
||||
self.assertEqual("Null", ret.name)
|
||||
self.assertEqual(1, len(ret.ctors))
|
||||
self.assertEqual(2, len(ret.methods))
|
||||
self.assertEqual(1, len(ret.static_methods))
|
||||
self.assertEqual(0, len(ret.properties))
|
||||
self.assertEqual("Base", ret.parent_class.name)
|
||||
self.assertEqual(["gtsam", "noiseModel", "mEstimator"],
|
||||
ret.parent_class.namespaces)
|
||||
self.assertTrue(ret.is_virtual)
|
||||
|
||||
def test_include(self):
|
||||
"""Test for include statements."""
|
||||
include = Include.rule.parseString(
|
||||
"#include <gtsam/slam/PriorFactor.h>")[0]
|
||||
self.assertEqual("gtsam/slam/PriorFactor.h", include.header)
|
||||
|
||||
def test_forward_declaration(self):
|
||||
"""Test for forward declarations."""
|
||||
fwd = ForwardDeclaration.rule.parseString(
|
||||
"virtual class Test:gtsam::Point3;")[0]
|
||||
|
||||
fwd_name = fwd.name.asList()[0]
|
||||
self.assertEqual("Test", fwd_name.name)
|
||||
self.assertTrue(fwd.is_virtual)
|
||||
|
||||
def test_function(self):
|
||||
"""Test for global/free function."""
|
||||
func = GlobalFunction.rule.parseString("""
|
||||
gtsam::Values localToWorld(const gtsam::Values& local,
|
||||
const gtsam::Pose2& base, const gtsam::KeyVector& keys);
|
||||
""")[0]
|
||||
self.assertEqual("localToWorld", func.name)
|
||||
self.assertEqual("Values", func.return_type.type1.typename.name)
|
||||
self.assertEqual(3, len(func.args))
|
||||
|
||||
def test_namespace(self):
|
||||
"""Test for namespace parsing."""
|
||||
namespace = Namespace.rule.parseString("""
|
||||
namespace gtsam {
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
class Point2 {
|
||||
Point2();
|
||||
Point2(double x, double y);
|
||||
double x() const;
|
||||
double y() const;
|
||||
int dim() const;
|
||||
char returnChar() const;
|
||||
void argChar(char a) const;
|
||||
void argUChar(unsigned char a) const;
|
||||
};
|
||||
|
||||
#include <gtsam/geometry/Point3.h>
|
||||
class Point3 {
|
||||
Point3(double x, double y, double z);
|
||||
double norm() const;
|
||||
|
||||
// static functions - use static keyword and uppercase
|
||||
static double staticFunction();
|
||||
static gtsam::Point3 StaticFunctionRet(double z);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const; // Just triggers a flag internally
|
||||
};
|
||||
}""")[0]
|
||||
self.assertEqual("gtsam", namespace.name)
|
||||
|
||||
def test_module(self):
|
||||
"""Test module parsing."""
|
||||
module = Module.parseString("""
|
||||
namespace one {
|
||||
namespace two {
|
||||
namespace three {
|
||||
class Class123 {
|
||||
};
|
||||
}
|
||||
class Class12a {
|
||||
};
|
||||
}
|
||||
namespace two_dummy {
|
||||
namespace three_dummy{
|
||||
|
||||
}
|
||||
namespace fourth_dummy{
|
||||
|
||||
}
|
||||
}
|
||||
namespace two {
|
||||
class Class12b {
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Global{
|
||||
};
|
||||
""")
|
||||
|
||||
# print("module: ", module)
|
||||
# print(dir(module.content[0].name))
|
||||
self.assertEqual(["one", "Global"], [x.name for x in module.content])
|
||||
self.assertEqual(["two", "two_dummy", "two"],
|
||||
[x.name for x in module.content[0].content])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -10,6 +10,8 @@ import os
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from loguru import logger
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
import gtwrap.interface_parser as parser
|
||||
|
@ -25,6 +27,10 @@ class TestWrap(unittest.TestCase):
|
|||
MATLAB_TEST_DIR = TEST_DIR + "expected-matlab/"
|
||||
MATLAB_ACTUAL_DIR = 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")
|
||||
|
||||
def generate_content(self, cc_content, path=''):
|
||||
"""Generate files and folders from matlab wrapper content.
|
||||
|
||||
|
@ -41,7 +47,7 @@ class TestWrap(unittest.TestCase):
|
|||
if isinstance(c, list):
|
||||
if len(c) == 0:
|
||||
continue
|
||||
print("c object: {}".format(c[0][0]), file=sys.stderr)
|
||||
logger.debug("c object: {}".format(c[0][0]))
|
||||
path_to_folder = path + '/' + c[0][0]
|
||||
|
||||
if not os.path.isdir(path_to_folder):
|
||||
|
@ -51,13 +57,13 @@ class TestWrap(unittest.TestCase):
|
|||
pass
|
||||
|
||||
for sub_content in c:
|
||||
print("sub object: {}".format(sub_content[1][0][0]), file=sys.stderr)
|
||||
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 = path + '/' + c[0]
|
||||
|
||||
print("[generate_content_global]: {}".format(path_to_folder), file=sys.stderr)
|
||||
logger.debug("[generate_content_global]: {}".format(path_to_folder))
|
||||
if not os.path.isdir(path_to_folder):
|
||||
try:
|
||||
os.makedirs(path_to_folder, exist_ok=True)
|
||||
|
@ -65,14 +71,15 @@ class TestWrap(unittest.TestCase):
|
|||
pass
|
||||
for sub_content in c[1]:
|
||||
path_to_file = path_to_folder + '/' + sub_content[0]
|
||||
print("[generate_global_method]: {}".format(path_to_file), file=sys.stderr)
|
||||
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 = path + '/' + c[0]
|
||||
|
||||
print("[generate_content]: {}".format(path_to_file), file=sys.stderr)
|
||||
logger.debug("[generate_content]: {}".format(path_to_file))
|
||||
if not os.path.isdir(path_to_file):
|
||||
try:
|
||||
os.mkdir(path)
|
||||
|
@ -122,23 +129,16 @@ class TestWrap(unittest.TestCase):
|
|||
self.assertTrue(os.path.isdir(self.MATLAB_ACTUAL_DIR + '+gtsam'))
|
||||
|
||||
files = [
|
||||
'+gtsam/Point2.m',
|
||||
'+gtsam/Point3.m',
|
||||
'Test.m',
|
||||
'MyBase.m',
|
||||
'load2D.m',
|
||||
'MyTemplatePoint2.m',
|
||||
'MyTemplateMatrix.m',
|
||||
'MyVector3.m',
|
||||
'MyVector12.m',
|
||||
'MyFactorPosePoint2.m',
|
||||
'aGlobalFunction.m',
|
||||
'overloadedGlobalFunction.m',
|
||||
'+gtsam/Point2.m', '+gtsam/Point3.m', 'Test.m', 'MyBase.m',
|
||||
'load2D.m', 'MyTemplatePoint2.m', 'MyTemplateMatrix.m',
|
||||
'MyVector3.m', 'MyVector12.m', 'MyFactorPosePoint2.m',
|
||||
'aGlobalFunction.m', 'overloadedGlobalFunction.m',
|
||||
'geometry_wrapper.cpp'
|
||||
]
|
||||
|
||||
for file in files:
|
||||
compare_and_diff(file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -26,15 +26,10 @@ class TestWrap(unittest.TestCase):
|
|||
"""Tests for Python wrapper based on Pybind11."""
|
||||
TEST_DIR = os.path.dirname(os.path.realpath(__file__)) + "/"
|
||||
|
||||
def test_geometry_python(self):
|
||||
def wrap_content(self, content, module_name, output_dir):
|
||||
"""
|
||||
Check generation of python geometry wrapper.
|
||||
python3 ../pybind_wrapper.py --src geometry.h --module_name
|
||||
geometry_py --out output/geometry_py.cc"
|
||||
Common function to wrap content.
|
||||
"""
|
||||
with open(os.path.join(self.TEST_DIR, 'geometry.h'), 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
module = parser.Module.parseString(content)
|
||||
|
||||
instantiator.instantiate_namespace_inplace(module)
|
||||
|
@ -45,7 +40,7 @@ class TestWrap(unittest.TestCase):
|
|||
# Create Pybind wrapper instance
|
||||
wrapper = PybindWrapper(
|
||||
module=module,
|
||||
module_name='geometry_py',
|
||||
module_name=module_name,
|
||||
use_boost=False,
|
||||
top_module_namespaces=[''],
|
||||
ignore_classes=[''],
|
||||
|
@ -54,14 +49,27 @@ class TestWrap(unittest.TestCase):
|
|||
|
||||
cc_content = wrapper.wrap()
|
||||
|
||||
output = path.join(self.TEST_DIR, 'actual-python/geometry_py.cpp')
|
||||
output = path.join(self.TEST_DIR, output_dir, module_name + ".cpp")
|
||||
|
||||
if not path.exists(path.join(self.TEST_DIR, 'actual-python')):
|
||||
os.mkdir(path.join(self.TEST_DIR, 'actual-python'))
|
||||
if not path.exists(path.join(self.TEST_DIR, output_dir)):
|
||||
os.mkdir(path.join(self.TEST_DIR, output_dir))
|
||||
|
||||
with open(output, 'w') as f:
|
||||
f.write(cc_content)
|
||||
|
||||
return output
|
||||
|
||||
def test_geometry_python(self):
|
||||
"""
|
||||
Check generation of python geometry wrapper.
|
||||
python3 ../pybind_wrapper.py --src geometry.h --module_name
|
||||
geometry_py --out output/geometry_py.cc
|
||||
"""
|
||||
with open(os.path.join(self.TEST_DIR, 'geometry.h'), 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
output = self.wrap_content(content, 'geometry_py', 'actual-python')
|
||||
|
||||
expected = path.join(self.TEST_DIR, 'expected-python/geometry_pybind.cpp')
|
||||
success = filecmp.cmp(output, expected)
|
||||
|
||||
|
@ -69,5 +77,23 @@ class TestWrap(unittest.TestCase):
|
|||
os.system("diff {} {}".format(output, expected))
|
||||
self.assertTrue(success)
|
||||
|
||||
def test_namespaces(self):
|
||||
"""
|
||||
Check generation of python geometry wrapper.
|
||||
python3 ../pybind_wrapper.py --src testNamespaces.h --module_name
|
||||
testNamespaces_py --out output/testNamespaces_py.cc
|
||||
"""
|
||||
with open(os.path.join(self.TEST_DIR, 'testNamespaces.h'), 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
output = self.wrap_content(content, 'testNamespaces_py', 'actual-python')
|
||||
|
||||
expected = path.join(self.TEST_DIR, 'expected-python/testNamespaces_py.cpp')
|
||||
success = filecmp.cmp(output, expected)
|
||||
|
||||
if not success:
|
||||
os.system("diff {} {}".format(output, expected))
|
||||
self.assertTrue(success)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue