From 30a39a0bdbb7f4116b0bb30f9ebd8995a78f8ca8 Mon Sep 17 00:00:00 2001 From: Varun Agrawal Date: Wed, 24 May 2023 12:12:22 -0400 Subject: [PATCH] Squashed 'wrap/' changes from 520dbca0f..2f136936d 2f136936d Merge pull request #159 from borglab/fix-matlab-enum d1da38776 fix pybind test 2a00e255b additional enum test and wrapper update to pass test f0076ec18 fixp python enum fixture a0c87e0df don't cast enum to shared ptr a6ad343af improve enum wrapping e0a504328 is_enum method in mixin 8d9d380c7 fix bug in fully qualified enum type 0491a8361 update docstrings to reflect update from basis to basic d1fb05c41 improve docs and clean up fdc1a00b8 rename Basis to Basic for basic c++ types 00ee34133 specify full namespace for enum-type arg f86724e30 add docstrings 38fb0e3a3 docs for enum wrapping functions 9d3bd43c0 add test fixtures git-subtree-dir: wrap git-subtree-split: 2f136936dbc33d9c3875952d6f0b29c43b8e26b4 --- gtwrap/interface_parser/tokens.py | 9 +- gtwrap/interface_parser/type.py | 30 +++-- gtwrap/matlab_wrapper/mixins.py | 26 ++++- gtwrap/matlab_wrapper/wrapper.py | 70 ++++++------ matlab.h | 16 ++- tests/expected/matlab/enum_wrapper.cpp | 108 +++++++++++++----- .../expected/matlab/special_cases_wrapper.cpp | 4 +- tests/expected/python/enum_pybind.cpp | 9 +- tests/fixtures/enum.i | 13 ++- tests/test_interface_parser.py | 4 +- 10 files changed, 190 insertions(+), 99 deletions(-) diff --git a/gtwrap/interface_parser/tokens.py b/gtwrap/interface_parser/tokens.py index 0f8d38d86..02e6d82f8 100644 --- a/gtwrap/interface_parser/tokens.py +++ b/gtwrap/interface_parser/tokens.py @@ -10,9 +10,10 @@ All the token definitions. Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert """ -from pyparsing import (Keyword, Literal, OneOrMore, Or, # type: ignore - QuotedString, Suppress, Word, alphanums, alphas, - nestedExpr, nums, originalTextFor, printables) +from pyparsing import Or # type: ignore +from pyparsing import (Keyword, Literal, OneOrMore, QuotedString, Suppress, + Word, alphanums, alphas, nestedExpr, nums, + originalTextFor, printables) # rule for identifiers (e.g. variable names) IDENT = Word(alphas + '_', alphanums + '_') ^ Word(nums) @@ -52,7 +53,7 @@ CONST, VIRTUAL, CLASS, STATIC, PAIR, TEMPLATE, TYPEDEF, INCLUDE = map( ) ENUM = Keyword("enum") ^ Keyword("enum class") ^ Keyword("enum struct") NAMESPACE = Keyword("namespace") -BASIS_TYPES = map( +BASIC_TYPES = map( Keyword, [ "void", diff --git a/gtwrap/interface_parser/type.py b/gtwrap/interface_parser/type.py index deb2e2256..e56a2f015 100644 --- a/gtwrap/interface_parser/type.py +++ b/gtwrap/interface_parser/type.py @@ -17,15 +17,13 @@ from typing import List, Sequence, Union from pyparsing import ParseResults # type: ignore from pyparsing import Forward, Optional, Or, delimitedList -from .tokens import (BASIS_TYPES, CONST, IDENT, LOPBRACK, RAW_POINTER, REF, +from .tokens import (BASIC_TYPES, CONST, IDENT, LOPBRACK, RAW_POINTER, REF, ROPBRACK, SHARED_POINTER) class Typename: """ - 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. + Class which holds a type's name, full namespace, and template arguments. E.g. ``` @@ -89,7 +87,6 @@ class Typename: 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: cpp_name = self.name + "<{}>".format(", ".join( [inst.to_cpp() for inst in self.instantiations])) @@ -116,7 +113,7 @@ class BasicType: """ Basic types are the fundamental built-in types in C++ such as double, int, char, etc. - When using templates, the basis type will take on the same form as the template. + When using templates, the basic type will take on the same form as the template. E.g. ``` @@ -127,16 +124,16 @@ class BasicType: will give ``` - m_.def("CoolFunctionDoubleDouble",[](const double& s) { - return wrap_example::CoolFunction(s); - }, py::arg("s")); + m_.def("funcDouble",[](const double& x){ + ::func(x); + }, py::arg("x")); ``` """ - rule = (Or(BASIS_TYPES)("typename")).setParseAction(lambda t: BasicType(t)) + rule = (Or(BASIC_TYPES)("typename")).setParseAction(lambda t: BasicType(t)) def __init__(self, t: ParseResults): - self.typename = Typename(t.asList()) + self.typename = Typename(t) class CustomType: @@ -160,9 +157,9 @@ class CustomType: class Type: """ - Parsed datatype, can be either a fundamental type or a custom datatype. + Parsed datatype, can be either a fundamental/basic type or a custom datatype. E.g. void, double, size_t, Matrix. - Think of this as a high-level type which encodes the typename and other + Think of this as a high-level type which encodes the typename and other characteristics of the type. The type can optionally be a raw pointer, shared pointer or reference. @@ -170,7 +167,7 @@ class Type: """ rule = ( Optional(CONST("is_const")) # - + (BasicType.rule("basis") | CustomType.rule("qualified")) # BR + + (BasicType.rule("basic") | CustomType.rule("qualified")) # BR + Optional( SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr") | REF("is_ref")) # @@ -188,9 +185,10 @@ class Type: @staticmethod def from_parse_result(t: ParseResults): """Return the resulting Type from parsing the source.""" - if t.basis: + # If the type is a basic/fundamental c++ type (e.g int, bool) + if t.basic: return Type( - typename=t.basis.typename, + typename=t.basic.typename, is_const=t.is_const, is_shared_ptr=t.is_shared_ptr, is_ptr=t.is_ptr, diff --git a/gtwrap/matlab_wrapper/mixins.py b/gtwrap/matlab_wrapper/mixins.py index ed5c5dbc6..df4de98f3 100644 --- a/gtwrap/matlab_wrapper/mixins.py +++ b/gtwrap/matlab_wrapper/mixins.py @@ -61,9 +61,29 @@ class CheckMixin: arg_type.is_ref def is_class_enum(self, arg_type: parser.Type, class_: parser.Class): - """Check if `arg_type` is an enum in the class `class_`.""" - enums = (enum.name for enum in class_.enums) - return arg_type.ctype.typename.name in enums + """Check if arg_type is an enum in the class `class_`.""" + if class_: + class_enums = [enum.name for enum in class_.enums] + return arg_type.typename.name in class_enums + else: + return False + + def is_global_enum(self, arg_type: parser.Type, class_: parser.Class): + """Check if arg_type is a global enum.""" + if class_: + # Get the enums in the class' namespace + global_enums = [ + member.name for member in class_.parent.content + if isinstance(member, parser.Enum) + ] + return arg_type.typename.name in global_enums + else: + return False + + def is_enum(self, arg_type: parser.Type, class_: parser.Class): + """Check if `arg_type` is an enum.""" + return self.is_class_enum(arg_type, class_) or self.is_global_enum( + arg_type, class_) class FormatMixin: diff --git a/gtwrap/matlab_wrapper/wrapper.py b/gtwrap/matlab_wrapper/wrapper.py index c2a8468c1..146209c44 100755 --- a/gtwrap/matlab_wrapper/wrapper.py +++ b/gtwrap/matlab_wrapper/wrapper.py @@ -341,23 +341,14 @@ class MatlabWrapper(CheckMixin, FormatMixin): return check_statement - def _unwrap_argument(self, - arg, - arg_id=0, - constructor=False, - instantiated_class=None): + def _unwrap_argument(self, arg, arg_id=0, instantiated_class=None): ctype_camel = self._format_type_name(arg.ctype.typename, separator='') ctype_sep = self._format_type_name(arg.ctype.typename) if instantiated_class and \ - self.is_class_enum(arg, instantiated_class): - - if instantiated_class.original.template: - enum_type = f"{arg.ctype.typename}" - else: - enum_type = f"{instantiated_class.name}::{arg.ctype}" - - arg_type = f"std::shared_ptr<{enum_type}>" + self.is_enum(arg.ctype, instantiated_class): + enum_type = f"{arg.ctype.typename}" + arg_type = f"{enum_type}" unwrap = f'unwrap_enum<{enum_type}>(in[{arg_id}]);' elif self.is_ref(arg.ctype): # and not constructor: @@ -390,7 +381,6 @@ class MatlabWrapper(CheckMixin, FormatMixin): def _wrapper_unwrap_arguments(self, args, arg_id=0, - constructor=False, instantiated_class=None): """Format the interface_parser.Arguments. @@ -403,10 +393,7 @@ class MatlabWrapper(CheckMixin, FormatMixin): for arg in args.list(): arg_type, unwrap = self._unwrap_argument( - arg, - arg_id, - constructor, - instantiated_class=instantiated_class) + arg, arg_id, instantiated_class=instantiated_class) body_args += textwrap.indent(textwrap.dedent('''\ {arg_type} {name} = {unwrap} @@ -428,7 +415,8 @@ class MatlabWrapper(CheckMixin, FormatMixin): continue if not self.is_ref(arg.ctype) and (self.is_shared_ptr(arg.ctype) or \ - self.is_ptr(arg.ctype) or self.can_be_pointer(arg.ctype))and \ + self.is_ptr(arg.ctype) or self.can_be_pointer(arg.ctype)) and \ + not self.is_enum(arg.ctype, instantiated_class) and \ arg.ctype.typename.name not in self.ignore_namespace: if arg.ctype.is_shared_ptr: call_type = arg.ctype.is_shared_ptr @@ -1147,7 +1135,7 @@ class MatlabWrapper(CheckMixin, FormatMixin): def wrap_enum(self, enum): """ - Wrap an enum definition. + Wrap an enum definition as a Matlab class. Args: enum: The interface_parser.Enum instance @@ -1285,15 +1273,23 @@ class MatlabWrapper(CheckMixin, FormatMixin): def _collector_return(self, obj: str, ctype: parser.Type, - class_property: parser.Variable = None, instantiated_class: InstantiatedClass = None): """Helper method to get the final statement before the return in the collector function.""" expanded = '' - if class_property and instantiated_class and \ - self.is_class_enum(class_property, instantiated_class): - class_name = ".".join(instantiated_class.namespaces()[1:] + [instantiated_class.name]) - enum_type = f"{class_name}.{ctype.typename.name}" + if instantiated_class and \ + self.is_enum(ctype, instantiated_class): + if self.is_class_enum(ctype, instantiated_class): + class_name = ".".join(instantiated_class.namespaces()[1:] + + [instantiated_class.name]) + else: + # Get the full namespace + class_name = ".".join(instantiated_class.parent.full_namespaces()[1:]) + + if class_name != "": + class_name += '.' + + enum_type = f"{class_name}{ctype.typename.name}" expanded = textwrap.indent( f'out[0] = wrap_enum({obj},\"{enum_type}\");', prefix=' ') @@ -1340,13 +1336,14 @@ class MatlabWrapper(CheckMixin, FormatMixin): return expanded - def wrap_collector_function_return(self, method): + def wrap_collector_function_return(self, method, instantiated_class=None): """ Wrap the complete return type of the function. """ expanded = '' - params = self._wrapper_unwrap_arguments(method.args, arg_id=1)[0] + params = self._wrapper_unwrap_arguments( + method.args, arg_id=1, instantiated_class=instantiated_class)[0] return_1 = method.return_type.type1 return_count = self._return_count(method.return_type) @@ -1382,7 +1379,8 @@ class MatlabWrapper(CheckMixin, FormatMixin): if return_1_name != 'void': if return_count == 1: - expanded += self._collector_return(obj, return_1) + expanded += self._collector_return( + obj, return_1, instantiated_class=instantiated_class) elif return_count == 2: return_2 = method.return_type.type2 @@ -1405,10 +1403,8 @@ class MatlabWrapper(CheckMixin, FormatMixin): property_name = class_property.name obj = 'obj->{}'.format(property_name) - ctype = class_property.ctype return self._collector_return(obj, - ctype, - class_property=class_property, + class_property.ctype, instantiated_class=instantiated_class) def wrap_collector_function_upcast_from_void(self, class_name, func_id, @@ -1468,9 +1464,7 @@ class MatlabWrapper(CheckMixin, FormatMixin): elif collector_func[2] == 'constructor': base = '' params, body_args = self._wrapper_unwrap_arguments( - extra.args, - constructor=True, - instantiated_class=collector_func[1]) + extra.args, instantiated_class=collector_func[1]) if collector_func[1].parent_class: base += textwrap.indent(textwrap.dedent(''' @@ -1534,7 +1528,9 @@ class MatlabWrapper(CheckMixin, FormatMixin): extra.args, arg_id=1 if is_method else 0, instantiated_class=collector_func[1]) - return_body = self.wrap_collector_function_return(extra) + + return_body = self.wrap_collector_function_return( + extra, collector_func[1]) shared_obj = '' @@ -1591,7 +1587,8 @@ class MatlabWrapper(CheckMixin, FormatMixin): # Setter if "_set_" in method_name: - is_ptr_type = self.can_be_pointer(extra.ctype) + is_ptr_type = self.can_be_pointer(extra.ctype) and \ + not self.is_enum(extra.ctype, collector_func[1]) return_body = ' obj->{0} = {1}{0};'.format( extra.name, '*' if is_ptr_type else '') @@ -1930,4 +1927,3 @@ class MatlabWrapper(CheckMixin, FormatMixin): self.generate_content(self.content, path) return self.content - diff --git a/matlab.h b/matlab.h index 7be5589dd..f44294770 100644 --- a/matlab.h +++ b/matlab.h @@ -118,10 +118,10 @@ void checkArguments(const string& name, int nargout, int nargin, int expected) { } //***************************************************************************** -// wrapping C++ basis types in MATLAB arrays +// wrapping C++ basic types in MATLAB arrays //***************************************************************************** -// default wrapping throws an error: only basis types are allowed in wrap +// default wrapping throws an error: only basic types are allowed in wrap template mxArray* wrap(const Class& value) { error("wrap internal error: attempted wrap of invalid type"); @@ -228,6 +228,10 @@ mxArray* wrap(const gtsam::Matrix& A) { return wrap_Matrix(A); } +/// @brief Wrap the C++ enum to Matlab mxArray +/// @tparam T The C++ enum type +/// @param x C++ enum +/// @param classname Matlab enum classdef used to call Matlab constructor template mxArray* wrap_enum(const T x, const std::string& classname) { // create double array to store value in @@ -254,11 +258,13 @@ T unwrap(const mxArray* array) { return T(); } +/// @brief Unwrap from matlab array to C++ enum type +/// @tparam T The C++ enum type +/// @param array Matlab mxArray template -shared_ptr unwrap_enum(const mxArray* array) { +T unwrap_enum(const mxArray* array) { // Make duplicate to remove const-ness mxArray* a = mxDuplicateArray(array); - std::cout << "unwrap enum type: " << typeid(array).name() << std::endl; // convert void* to int32* array mxArray* a_int32; @@ -267,7 +273,7 @@ shared_ptr unwrap_enum(const mxArray* array) { // Get the value in the input array int32_T* value = (int32_T*)mxGetData(a_int32); // cast int32 to enum type - return std::make_shared(static_cast(*value)); + return static_cast(*value); } // specialization to string diff --git a/tests/expected/matlab/enum_wrapper.cpp b/tests/expected/matlab/enum_wrapper.cpp index 9d041ee77..4860f9b8d 100644 --- a/tests/expected/matlab/enum_wrapper.cpp +++ b/tests/expected/matlab/enum_wrapper.cpp @@ -93,8 +93,8 @@ void Pet_constructor_1(int nargout, mxArray *out[], int nargin, const mxArray *i typedef std::shared_ptr Shared; string& name = *unwrap_shared_ptr< string >(in[0], "ptr_string"); - std::shared_ptr type = unwrap_enum(in[1]); - Shared *self = new Shared(new Pet(name,*type)); + Pet::Kind type = unwrap_enum(in[1]); + Shared *self = new Shared(new Pet(name,type)); collector_Pet.insert(self); out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); *reinterpret_cast (mxGetData(out[0])) = self; @@ -113,14 +113,29 @@ void Pet_deconstructor_2(int nargout, mxArray *out[], int nargin, const mxArray delete self; } -void Pet_get_name_3(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void Pet_getColor_3(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("getColor",nargout,nargin-1,0); + auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); + out[0] = wrap_enum(obj->getColor(),"Color"); +} + +void Pet_setColor_4(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("setColor",nargout,nargin-1,1); + auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); + Color color = unwrap_enum(in[1]); + obj->setColor(color); +} + +void Pet_get_name_5(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("name",nargout,nargin-1,0); auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); out[0] = wrap< string >(obj->name); } -void Pet_set_name_4(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void Pet_set_name_6(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("name",nargout,nargin-1,1); auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); @@ -128,22 +143,22 @@ void Pet_set_name_4(int nargout, mxArray *out[], int nargin, const mxArray *in[] obj->name = name; } -void Pet_get_type_5(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void Pet_get_type_7(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("type",nargout,nargin-1,0); auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); out[0] = wrap_enum(obj->type,"Pet.Kind"); } -void Pet_set_type_6(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void Pet_set_type_8(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("type",nargout,nargin-1,1); auto obj = unwrap_shared_ptr(in[0], "ptr_Pet"); - std::shared_ptr type = unwrap_enum(in[1]); - obj->type = *type; + Pet::Kind type = unwrap_enum(in[1]); + obj->type = type; } -void gtsamMCU_collectorInsertAndMakeBase_7(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamMCU_collectorInsertAndMakeBase_9(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef std::shared_ptr Shared; @@ -152,7 +167,7 @@ void gtsamMCU_collectorInsertAndMakeBase_7(int nargout, mxArray *out[], int narg collector_gtsamMCU.insert(self); } -void gtsamMCU_constructor_8(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamMCU_constructor_10(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef std::shared_ptr Shared; @@ -163,7 +178,7 @@ void gtsamMCU_constructor_8(int nargout, mxArray *out[], int nargin, const mxArr *reinterpret_cast (mxGetData(out[0])) = self; } -void gtsamMCU_deconstructor_9(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamMCU_deconstructor_11(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { typedef std::shared_ptr Shared; checkArguments("delete_gtsamMCU",nargout,nargin,1); @@ -176,7 +191,7 @@ void gtsamMCU_deconstructor_9(int nargout, mxArray *out[], int nargin, const mxA delete self; } -void gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_10(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_12(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef std::shared_ptr> Shared; @@ -185,7 +200,19 @@ void gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_10(int nargout, collector_gtsamOptimizerGaussNewtonParams.insert(self); } -void gtsamOptimizerGaussNewtonParams_deconstructor_11(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamOptimizerGaussNewtonParams_constructor_13(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + mexAtExit(&_deleteAllObjects); + typedef std::shared_ptr> Shared; + + Optimizer::Verbosity verbosity = unwrap_enum::Verbosity>(in[0]); + Shared *self = new Shared(new gtsam::Optimizer(verbosity)); + collector_gtsamOptimizerGaussNewtonParams.insert(self); + out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); + *reinterpret_cast (mxGetData(out[0])) = self; +} + +void gtsamOptimizerGaussNewtonParams_deconstructor_14(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { typedef std::shared_ptr> Shared; checkArguments("delete_gtsamOptimizerGaussNewtonParams",nargout,nargin,1); @@ -198,12 +225,26 @@ void gtsamOptimizerGaussNewtonParams_deconstructor_11(int nargout, mxArray *out[ delete self; } -void gtsamOptimizerGaussNewtonParams_setVerbosity_12(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void gtsamOptimizerGaussNewtonParams_getVerbosity_15(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("getVerbosity",nargout,nargin-1,0); + auto obj = unwrap_shared_ptr>(in[0], "ptr_gtsamOptimizerGaussNewtonParams"); + out[0] = wrap_enum(obj->getVerbosity(),"gtsam.OptimizerGaussNewtonParams.Verbosity"); +} + +void gtsamOptimizerGaussNewtonParams_getVerbosity_16(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("getVerbosity",nargout,nargin-1,0); + auto obj = unwrap_shared_ptr>(in[0], "ptr_gtsamOptimizerGaussNewtonParams"); + out[0] = wrap_enum(obj->getVerbosity(),"gtsam.VerbosityLM"); +} + +void gtsamOptimizerGaussNewtonParams_setVerbosity_17(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("setVerbosity",nargout,nargin-1,1); auto obj = unwrap_shared_ptr>(in[0], "ptr_gtsamOptimizerGaussNewtonParams"); - std::shared_ptr::Verbosity> value = unwrap_enum::Verbosity>(in[1]); - obj->setVerbosity(*value); + Optimizer::Verbosity value = unwrap_enum::Verbosity>(in[1]); + obj->setVerbosity(value); } @@ -228,34 +269,49 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) Pet_deconstructor_2(nargout, out, nargin-1, in+1); break; case 3: - Pet_get_name_3(nargout, out, nargin-1, in+1); + Pet_getColor_3(nargout, out, nargin-1, in+1); break; case 4: - Pet_set_name_4(nargout, out, nargin-1, in+1); + Pet_setColor_4(nargout, out, nargin-1, in+1); break; case 5: - Pet_get_type_5(nargout, out, nargin-1, in+1); + Pet_get_name_5(nargout, out, nargin-1, in+1); break; case 6: - Pet_set_type_6(nargout, out, nargin-1, in+1); + Pet_set_name_6(nargout, out, nargin-1, in+1); break; case 7: - gtsamMCU_collectorInsertAndMakeBase_7(nargout, out, nargin-1, in+1); + Pet_get_type_7(nargout, out, nargin-1, in+1); break; case 8: - gtsamMCU_constructor_8(nargout, out, nargin-1, in+1); + Pet_set_type_8(nargout, out, nargin-1, in+1); break; case 9: - gtsamMCU_deconstructor_9(nargout, out, nargin-1, in+1); + gtsamMCU_collectorInsertAndMakeBase_9(nargout, out, nargin-1, in+1); break; case 10: - gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_10(nargout, out, nargin-1, in+1); + gtsamMCU_constructor_10(nargout, out, nargin-1, in+1); break; case 11: - gtsamOptimizerGaussNewtonParams_deconstructor_11(nargout, out, nargin-1, in+1); + gtsamMCU_deconstructor_11(nargout, out, nargin-1, in+1); break; case 12: - gtsamOptimizerGaussNewtonParams_setVerbosity_12(nargout, out, nargin-1, in+1); + gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_12(nargout, out, nargin-1, in+1); + break; + case 13: + gtsamOptimizerGaussNewtonParams_constructor_13(nargout, out, nargin-1, in+1); + break; + case 14: + gtsamOptimizerGaussNewtonParams_deconstructor_14(nargout, out, nargin-1, in+1); + break; + case 15: + gtsamOptimizerGaussNewtonParams_getVerbosity_15(nargout, out, nargin-1, in+1); + break; + case 16: + gtsamOptimizerGaussNewtonParams_getVerbosity_16(nargout, out, nargin-1, in+1); + break; + case 17: + gtsamOptimizerGaussNewtonParams_setVerbosity_17(nargout, out, nargin-1, in+1); break; } } catch(const std::exception& e) { diff --git a/tests/expected/matlab/special_cases_wrapper.cpp b/tests/expected/matlab/special_cases_wrapper.cpp index 565368c2c..2fe55ec01 100644 --- a/tests/expected/matlab/special_cases_wrapper.cpp +++ b/tests/expected/matlab/special_cases_wrapper.cpp @@ -211,8 +211,8 @@ void gtsamGeneralSFMFactorCal3Bundler_set_verbosity_12(int nargout, mxArray *out { checkArguments("verbosity",nargout,nargin-1,1); auto obj = unwrap_shared_ptr, gtsam::Point3>>(in[0], "ptr_gtsamGeneralSFMFactorCal3Bundler"); - std::shared_ptr, gtsam::Point3>::Verbosity> verbosity = unwrap_enum, gtsam::Point3>::Verbosity>(in[1]); - obj->verbosity = *verbosity; + gtsam::GeneralSFMFactor, gtsam::Point3>::Verbosity verbosity = unwrap_enum, gtsam::Point3>::Verbosity>(in[1]); + obj->verbosity = verbosity; } diff --git a/tests/expected/python/enum_pybind.cpp b/tests/expected/python/enum_pybind.cpp index 2fa804ac9..c67bf1de0 100644 --- a/tests/expected/python/enum_pybind.cpp +++ b/tests/expected/python/enum_pybind.cpp @@ -23,7 +23,9 @@ PYBIND11_MODULE(enum_py, m_) { py::class_> pet(m_, "Pet"); pet - .def(py::init(), py::arg("name"), py::arg("type")) + .def(py::init(), py::arg("name"), py::arg("type")) + .def("setColor",[](Pet* self, const Color& color){ self->setColor(color);}, py::arg("color")) + .def("getColor",[](Pet* self){return self->getColor();}) .def_readwrite("name", &Pet::name) .def_readwrite("type", &Pet::type); @@ -65,7 +67,10 @@ PYBIND11_MODULE(enum_py, m_) { py::class_, std::shared_ptr>> optimizergaussnewtonparams(m_gtsam, "OptimizerGaussNewtonParams"); optimizergaussnewtonparams - .def("setVerbosity",[](gtsam::Optimizer* self, const Optimizer::Verbosity value){ self->setVerbosity(value);}, py::arg("value")); + .def(py::init::Verbosity&>(), py::arg("verbosity")) + .def("setVerbosity",[](gtsam::Optimizer* self, const Optimizer::Verbosity value){ self->setVerbosity(value);}, py::arg("value")) + .def("getVerbosity",[](gtsam::Optimizer* self){return self->getVerbosity();}) + .def("getVerbosity",[](gtsam::Optimizer* self){return self->getVerbosity();}); py::enum_::Verbosity>(optimizergaussnewtonparams, "Verbosity", py::arithmetic()) .value("SILENT", gtsam::Optimizer::Verbosity::SILENT) diff --git a/tests/fixtures/enum.i b/tests/fixtures/enum.i index 71918c25a..6e70d9c57 100644 --- a/tests/fixtures/enum.i +++ b/tests/fixtures/enum.i @@ -3,13 +3,16 @@ enum Color { Red, Green, Blue }; class Pet { enum Kind { Dog, Cat }; - Pet(const string &name, Kind type); + Pet(const string &name, Pet::Kind type); + void setColor(const Color& color); + Color getColor() const; string name; - Kind type; + Pet::Kind type; }; namespace gtsam { +// Test global enums enum VerbosityLM { SILENT, SUMMARY, @@ -21,6 +24,7 @@ enum VerbosityLM { TRYDELTA }; +// Test multiple enums in a classs class MCU { MCU(); @@ -50,7 +54,12 @@ class Optimizer { VERBOSE }; + Optimizer(const This::Verbosity& verbosity); + void setVerbosity(const This::Verbosity value); + + gtsam::Optimizer::Verbosity getVerbosity() const; + gtsam::VerbosityLM getVerbosity() const; }; typedef gtsam::Optimizer OptimizerGaussNewtonParams; diff --git a/tests/test_interface_parser.py b/tests/test_interface_parser.py index 19462a51a..45415995f 100644 --- a/tests/test_interface_parser.py +++ b/tests/test_interface_parser.py @@ -38,7 +38,7 @@ class TestInterfaceParser(unittest.TestCase): def test_basic_type(self): """Tests for BasicType.""" - # Check basis type + # Check basic type t = Type.rule.parseString("int x")[0] self.assertEqual("int", t.typename.name) self.assertTrue(t.is_basic) @@ -243,7 +243,7 @@ class TestInterfaceParser(unittest.TestCase): self.assertEqual("void", return_type.type1.typename.name) self.assertTrue(return_type.type1.is_basic) - # Test basis type + # Test basic type return_type = ReturnType.rule.parseString("size_t")[0] self.assertEqual("size_t", return_type.type1.typename.name) self.assertTrue(not return_type.type2)