Skip to content
5 changes: 2 additions & 3 deletions gtwrap/interface_parser/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def from_parse_result(parse_result: ParseResults):
return ArgumentList([])

def __repr__(self) -> str:
return ",".join([repr(x) for x in self.args_list])
return ", ".join([repr(x) for x in self.args_list])

def __len__(self) -> int:
return len(self.args_list)
Expand Down Expand Up @@ -182,8 +182,7 @@ def __init__(self,
self.args.parent = self

def __repr__(self) -> str:
return "GlobalFunction: {}{}({})".format(self.return_type, self.name,
self.args)
return f"GlobalFunction: {self.name}({self.args}) -> {self.return_type}"

def to_cpp(self) -> str:
"""Generate the C++ code for wrapping."""
Expand Down
2 changes: 1 addition & 1 deletion gtwrap/interface_parser/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class TypenameAndInstantiations:
"""
Rule to parse the template parameters.

template<typename POSE> // POSE is the Instantiation.
template<typename POSE = {Pose2, Pose3}> // Pos2 and Pose3 are the `Instantiation`s.
"""
rule = (
IDENT("typename") #
Expand Down
39 changes: 23 additions & 16 deletions gtwrap/interface_parser/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class Typename:
"""

namespaces_name_rule = delimitedList(IDENT, "::")
instantiation_name_rule = delimitedList(IDENT, "::")
rule = (
namespaces_name_rule("namespaces_and_name") #
).setParseAction(lambda t: Typename(t))
Expand Down Expand Up @@ -164,7 +163,7 @@ class Type:
"""
rule = (
Optional(CONST("is_const")) #
+ (BasicType.rule("basic") | CustomType.rule("qualified")) # BR
+ (BasicType.rule("basic") | CustomType.rule("custom")) # BR
+ Optional(
SHARED_POINTER("is_shared_ptr") | RAW_POINTER("is_ptr")
| REF("is_ref")) #
Expand Down Expand Up @@ -192,9 +191,9 @@ def from_parse_result(t: ParseResults):
is_ref=t.is_ref,
is_basic=True,
)
elif t.qualified:
elif t.custom:
return Type(
typename=t.qualified.typename,
typename=t.custom.typename,
is_const=t.is_const,
is_shared_ptr=t.is_shared_ptr,
is_ptr=t.is_ptr,
Expand All @@ -212,6 +211,13 @@ def __repr__(self) -> str:
is_const="const " if self.is_const else "",
is_ptr_or_ref=" " + is_ptr_or_ref if is_ptr_or_ref else "")

def get_typename(self):
"""
Get the typename of this type without any qualifiers.
E.g. for `const gtsam::Pose3& pose` this will return `gtsam::Pose3`.
"""
return self.typename.to_cpp()

def to_cpp(self) -> str:
"""
Generate the C++ code for wrapping.
Expand All @@ -221,22 +227,18 @@ def to_cpp(self) -> str:

if self.is_shared_ptr:
typename = "std::shared_ptr<{typename}>".format(
typename=self.typename.to_cpp())
typename=self.get_typename())
elif self.is_ptr:
typename = "{typename}*".format(typename=self.typename.to_cpp())
elif self.is_ref:
typename = typename = "{typename}&".format(
typename=self.typename.to_cpp())
typename=self.get_typename())
else:
typename = self.typename.to_cpp()
typename = self.get_typename()

return ("{const}{typename}".format(
const="const " if self.is_const else "", typename=typename))

def get_typename(self):
"""Convenience method to get the typename of this type."""
return self.typename.name


class TemplatedType:
"""
Expand Down Expand Up @@ -283,16 +285,21 @@ def __repr__(self):
return "TemplatedType({typename.namespaces}::{typename.name})".format(
typename=self.typename)

def to_cpp(self):
def get_typename(self):
"""
Generate the C++ code for wrapping.
Get the typename of this type without any qualifiers.
E.g. for `const std::vector<double>& indices` this will return `std::vector<double>`.
"""
# Use Type.to_cpp to do the heavy lifting for the template parameters.
template_args = ", ".join([t.to_cpp() for t in self.template_params])

typename = "{typename}<{template_args}>".format(
typename=self.typename.qualified_name(),
template_args=template_args)
return f"{self.typename.qualified_name()}<{template_args}>"

def to_cpp(self):
"""
Generate the C++ code for wrapping.
"""
typename = self.get_typename()

if self.is_shared_ptr:
typename = f"std::shared_ptr<{typename}>"
Expand Down
3 changes: 3 additions & 0 deletions gtwrap/matlab_wrapper/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ def _format_type_name(self,
if name not in self.ignore_namespace and namespace != '':
formatted_type_name += namespace + separator

# Get string representation so we can use as dict key.
name = str(name)

if is_constructor:
formatted_type_name += self.data_type.get(name) or name
elif is_method:
Expand Down
12 changes: 7 additions & 5 deletions gtwrap/matlab_wrapper/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ def _update_wrapper_id(self,

Args:
collector_function: tuple storing info about the wrapper function
(namespace, class instance, function name, function object)
(namespace, class/function instance,
type of collector function, method object if class instance)
id_diff: constant to add to the id in the map
function_name: Optional custom function_name.

Expand Down Expand Up @@ -578,6 +579,7 @@ def wrap_global_function(self, function):
# Get all combinations of parameters
param_wrap = ''

# Iterate through possible overloads of the function
for i, overload in enumerate(function):
param_wrap += ' if' if i == 0 else ' elseif'
param_wrap += ' length(varargin) == '
Expand Down Expand Up @@ -1218,7 +1220,7 @@ def wrap_namespace(self, namespace, add_mex_file=True):
if isinstance(func, parser.GlobalFunction)
]

self.wrap_methods(all_funcs, True, global_ns=namespace)
self.wrap_methods(all_funcs, global_funcs=True, global_ns=namespace)

return wrapped

Expand Down Expand Up @@ -1365,8 +1367,8 @@ def wrap_collector_function_return(self, method, instantiated_class=None):
method_name += method.original.name

elif isinstance(method, parser.GlobalFunction):
method_name = self._format_global_function(method, '::')
method_name += method.name
namespace = self._format_global_function(method, '::')
method_name = namespace + method.to_cpp()

else:
if isinstance(method.parent, instantiator.InstantiatedClass):
Expand Down Expand Up @@ -1624,7 +1626,7 @@ def generate_collector_function(self, func_id):

body += self._wrapper_unwrap_arguments(collector_func[1].args)[1]
body += self.wrap_collector_function_return(
collector_func[1]) + '\n}\n'
collector_func[1]) + "\n}\n"

collector_function += body

Expand Down
9 changes: 4 additions & 5 deletions gtwrap/template_instantiator/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class InstantiatedGlobalFunction(parser.GlobalFunction):
template<T = {double}>
T add(const T& x, const T& y);
"""

def __init__(self, original, instantiations=(), new_name=''):
self.original = original
self.instantiations = instantiations
Expand Down Expand Up @@ -54,16 +55,14 @@ def __init__(self, original, instantiations=(), new_name=''):
def to_cpp(self):
"""Generate the C++ code for wrapping."""
if self.original.template:
instantiated_names = [
instantiated_params = [
"::".join(inst.namespaces + [inst.instantiated_name()])
for inst in self.instantiations
]
ret = "{}<{}>".format(self.original.name,
",".join(instantiated_names))
ret = f"{self.original.name}<{','.join(instantiated_params)}>"
else:
ret = self.original.name
return ret

def __repr__(self):
return "Instantiated {}".format(
super(InstantiatedGlobalFunction, self).__repr__())
return f"Instantiated {self.__repr__}"
3 changes: 2 additions & 1 deletion gtwrap/template_instantiator/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def instantiate_type(
ctype.typename.instantiations[idx].name =\
instantiations[template_idx]


str_arg_typename = str(ctype.typename)

# Check if template is a scoped template e.g. T::Value where T is the template
Expand All @@ -88,6 +87,7 @@ def instantiate_type(
is_ref=ctype.is_ref,
is_basic=ctype.is_basic,
)

# Check for exact template match.
elif str_arg_typename in template_typenames:
idx = template_typenames.index(str_arg_typename)
Expand Down Expand Up @@ -228,6 +228,7 @@ class InstantiationHelper:
parent=parent)
```
"""

def __init__(self, instantiation_type: InstantiatedMembers):
self.instantiation_type = instantiation_type

Expand Down
7 changes: 7 additions & 0 deletions tests/expected/matlab/EliminateDiscrete.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = EliminateDiscrete(varargin)
if length(varargin) == 2 && isa(varargin{1},'gtsam.DiscreteFactorGraph') && isa(varargin{2},'gtsam.Ordering')
[ varargout{1} varargout{2} ] = functions_wrapper(25, varargin{:});
else
error('Arguments do not match any overload of function EliminateDiscrete');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanPoint2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanPoint2(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Point2')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is std.vectorgtsam really what’s intended?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct, but this is a drawback of the Mex C API since there is no std::vector in C. We will have to migrate to the Mex C++ API (something we discussed in the past as a possible Google Summer of Code project).

This is an issue in other existing classes as well (such as Ordering).

varargout{1} = functions_wrapper(28, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanPoint2');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanPoint3.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanPoint3(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Point3')
varargout{1} = functions_wrapper(28, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanPoint3');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanPose2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanPose2(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Pose2')
varargout{1} = functions_wrapper(30, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanPose2');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanPose3.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanPose3(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Pose3')
varargout{1} = functions_wrapper(31, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanPose3');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanRot2.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanRot2(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Rot2')
varargout{1} = functions_wrapper(29, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanRot2');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanRot3.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanRot3(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::Rot3')
varargout{1} = functions_wrapper(31, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanRot3');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanSO3.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanSO3(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::SO3')
varargout{1} = functions_wrapper(29, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanSO3');
end
end
7 changes: 7 additions & 0 deletions tests/expected/matlab/FindKarcherMeanSO4.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function varargout = FindKarcherMeanSO4(varargin)
if length(varargin) == 1 && isa(varargin{1},'std.vectorgtsam::SO4')
varargout{1} = functions_wrapper(30, varargin{:});
else
error('Arguments do not match any overload of function FindKarcherMeanSO4');
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function varargout = MultiTemplatedFunctionDoubleSize_tDouble(varargin)
if length(varargin) == 2 && isa(varargin{1},'T') && isa(varargin{2},'numeric')
if length(varargin) == 2 && isa(varargin{1},'double') && isa(varargin{2},'numeric')
varargout{1} = functions_wrapper(7, varargin{:});
else
error('Arguments do not match any overload of function MultiTemplatedFunctionDoubleSize_tDouble');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function varargout = MultiTemplatedFunctionStringSize_tDouble(varargin)
if length(varargin) == 2 && isa(varargin{1},'T') && isa(varargin{2},'numeric')
if length(varargin) == 2 && isa(varargin{1},'char') && isa(varargin{2},'numeric')
varargout{1} = functions_wrapper(6, varargin{:});
else
error('Arguments do not match any overload of function MultiTemplatedFunctionStringSize_tDouble');
Expand Down
2 changes: 1 addition & 1 deletion tests/expected/matlab/TemplatedFunctionRot3.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function varargout = TemplatedFunctionRot3(varargin)
if length(varargin) == 1 && isa(varargin{1},'gtsam.Rot3')
functions_wrapper(26, varargin{:});
functions_wrapper(32, varargin{:});
else
error('Arguments do not match any overload of function TemplatedFunctionRot3');
end
Expand Down
Loading
Loading