Skip to content

Commit f1a6956

Browse files
authored
Merge pull request #2587 from thatdudegrantt/sync/update-wrap-subtree
Sync/update wrap subtree
2 parents 36f5b0f + 560f966 commit f1a6956

8 files changed

Lines changed: 239 additions & 5 deletions

File tree

wrap/gtwrap/matlab_wrapper/wrapper.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,10 +1269,15 @@ def wrap_collector_function_return_types(self, return_type, func_id):
12691269
return_type_text = self.wrap_collector_function_shared_return(
12701270
return_type.typename, shared_obj, func_id, func_id == 0)
12711271
else:
1272-
return_type_text += 'wrap_shared_ptr({0},"{1}", false);{new_line}' \
1272+
is_virtual = any(
1273+
cls.name == return_type.typename.name and cls.is_virtual
1274+
for cls in self.classes
1275+
)
1276+
return_type_text += 'wrap_shared_ptr({0},"{1}", {2});{new_line}' \
12731277
.format(shared_obj,
12741278
self._format_type_name(return_type.typename,
12751279
separator='.'),
1280+
'true' if is_virtual else 'false',
12761281
new_line=new_line)
12771282
else:
12781283
return_type_text += 'wrap< {0} >(pairResult.{1});{2}'.format(
@@ -1339,8 +1344,13 @@ def _collector_return(self,
13391344
obj=obj)
13401345

13411346
if ctype.typename.name not in self.ignore_namespace:
1347+
is_virtual = any(
1348+
cls.name == ctype.typename.name and cls.is_virtual
1349+
for cls in self.classes
1350+
)
13421351
expanded += textwrap.indent(
1343-
'out[0] = wrap_shared_ptr({0}, false);'.format(shared_obj),
1352+
'out[0] = wrap_shared_ptr({0}, {1});'.format(
1353+
shared_obj, 'true' if is_virtual else 'false'),
13441354
prefix=' ')
13451355
else:
13461356
expanded += ' out[0] = wrap< {0} >({1});'.format(
@@ -1741,8 +1751,9 @@ def generate_preamble(self):
17411751

17421752
if cls.is_virtual:
17431753
class_name, class_name_sep = self.get_class_name(cls)
1754+
matlab_class_name = self._format_class_name(cls, separator='.')
17441755
rtti_classes += ' types.insert(std::make_pair(typeid({}).name(), "{}"));\n' \
1745-
.format(class_name_sep, class_name)
1756+
.format(class_name_sep, matlab_class_name)
17461757

17471758
# Generate the typedef instances string
17481759
typedef_instances = "\n".join(typedef_instances)

wrap/matlab.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,15 @@ mxArray* wrap<bool>(const bool& value) {
160160
return result;
161161
}
162162

163-
// specialization to size_t
163+
// specialization to size_t but skip Win64 size check & CUDACC check
164+
#if (!defined(_WIN64) && !defined(__LP64__)) || defined(__CUDACC__)
164165
template<>
165166
mxArray* wrap<size_t>(const size_t& value) {
166167
mxArray *result = scalar(mxUINT32OR64_CLASS);
167168
*(size_t*)mxGetData(result) = value;
168169
return result;
169170
}
171+
#endif
170172

171173
// specialization to int
172174
template<>
@@ -346,12 +348,16 @@ uint64_t unwrap<uint64_t>(const mxArray* array) {
346348
return myGetScalar<uint64_t>(array);
347349
}
348350

349-
// specialization to size_t
351+
// specialization to size_t; omit it on Win64 because size_t is uint64_t there
352+
// and would duplicate unwrap<uint64_t>. The __CUDACC__ case intentionally
353+
// bypasses the Win64 guard when compiling with CUDA.
354+
#if (!defined(_WIN64) && !defined(__LP64__)) || defined(__CUDACC__)
350355
template<>
351356
size_t unwrap<size_t>(const mxArray* array) {
352357
checkScalar(array, "unwrap<size_t>");
353358
return myGetScalar<size_t>(array);
354359
}
360+
#endif
355361

356362
// specialization to double
357363
template<>

wrap/tests/expected/matlab/Base.m

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
%class Base, see Doxygen page for details
2+
%at https://gtsam.org/doxygen/
3+
%
4+
%-------Static Methods-------
5+
%Create(double x) : returns gtsam::Base
6+
%
7+
%-------Serialization Interface-------
8+
%string_serialize() : returns string
9+
%string_deserialize(string serialized) : returns Base
10+
%
11+
classdef Base < handle
12+
properties
13+
ptr_Base = 0
14+
end
15+
methods
16+
function obj = Base(varargin)
17+
if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
18+
if nargin == 2
19+
my_ptr = varargin{2};
20+
else
21+
my_ptr = inheritance_wrapper(58, varargin{2});
22+
end
23+
inheritance_wrapper(57, my_ptr);
24+
else
25+
error('Arguments do not match any overload of Base constructor');
26+
end
27+
obj.ptr_Base = my_ptr;
28+
end
29+
30+
function delete(obj)
31+
inheritance_wrapper(59, obj.ptr_Base);
32+
end
33+
34+
function display(obj), obj.print(''); end
35+
%DISPLAY Calls print on the object
36+
function disp(obj), obj.display; end
37+
%DISP Calls print on the object
38+
end
39+
40+
methods(Static = true)
41+
function varargout = Create(varargin)
42+
% CREATE usage: Create(double x) : returns gtsam.Base
43+
% Doxygen can be found at https://gtsam.org/doxygen/
44+
if length(varargin) == 1 && isa(varargin{1},'double')
45+
varargout{1} = inheritance_wrapper(60, varargin{:});
46+
return
47+
end
48+
49+
error('Arguments do not match any overload of function Base.Create');
50+
end
51+
52+
end
53+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
%class Derived, see Doxygen page for details
2+
%at https://gtsam.org/doxygen/
3+
%
4+
classdef Derived < Base
5+
properties
6+
ptr_Derived = 0
7+
end
8+
methods
9+
function obj = Derived(varargin)
10+
if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682)
11+
if nargin == 2
12+
my_ptr = varargin{2};
13+
else
14+
my_ptr = inheritance_wrapper(62, varargin{2});
15+
end
16+
base_ptr = inheritance_wrapper(61, my_ptr);
17+
else
18+
error('Arguments do not match any overload of Derived constructor');
19+
end
20+
obj = obj@Base(uint64(5139824614673773682), base_ptr);
21+
obj.ptr_Derived = my_ptr;
22+
end
23+
24+
function delete(obj)
25+
inheritance_wrapper(63, obj.ptr_Derived);
26+
end
27+
28+
function display(obj), obj.print(''); end
29+
%DISPLAY Calls print on the object
30+
function disp(obj), obj.display; end
31+
%DISP Calls print on the object
32+
end
33+
34+
methods(Static = true)
35+
end
36+
end

wrap/tests/expected/matlab/inheritance_wrapper.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ typedef std::set<std::shared_ptr<ForwardKinematicsFactor>*> Collector_ForwardKin
2020
static Collector_ForwardKinematicsFactor collector_ForwardKinematicsFactor;
2121
typedef std::set<std::shared_ptr<ParentHasTemplateDouble>*> Collector_ParentHasTemplateDouble;
2222
static Collector_ParentHasTemplateDouble collector_ParentHasTemplateDouble;
23+
typedef std::set<std::shared_ptr<Base>*> Collector_Base;
24+
static Collector_Base collector_Base;
25+
typedef std::set<std::shared_ptr<Derived>*> Collector_Derived;
26+
static Collector_Derived collector_Derived;
2327

2428

2529
void _deleteAllObjects()
@@ -64,6 +68,18 @@ void _deleteAllObjects()
6468
collector_ParentHasTemplateDouble.erase(iter++);
6569
anyDeleted = true;
6670
} }
71+
{ for(Collector_Base::iterator iter = collector_Base.begin();
72+
iter != collector_Base.end(); ) {
73+
delete *iter;
74+
collector_Base.erase(iter++);
75+
anyDeleted = true;
76+
} }
77+
{ for(Collector_Derived::iterator iter = collector_Derived.begin();
78+
iter != collector_Derived.end(); ) {
79+
delete *iter;
80+
collector_Derived.erase(iter++);
81+
anyDeleted = true;
82+
} }
6783

6884
if(anyDeleted)
6985
cout <<
@@ -84,6 +100,8 @@ void _inheritance_RTTIRegister() {
84100
types.insert(std::make_pair(typeid(MyTemplateA).name(), "MyTemplateA"));
85101
types.insert(std::make_pair(typeid(ForwardKinematicsFactor).name(), "ForwardKinematicsFactor"));
86102
types.insert(std::make_pair(typeid(ParentHasTemplateDouble).name(), "ParentHasTemplateDouble"));
103+
types.insert(std::make_pair(typeid(Base).name(), "Base"));
104+
types.insert(std::make_pair(typeid(Derived).name(), "Derived"));
87105

88106

89107
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
@@ -698,6 +716,79 @@ void ParentHasTemplateDouble_deconstructor_56(int nargout, mxArray *out[], int n
698716
delete self;
699717
}
700718

719+
void Base_collectorInsertAndMakeBase_57(int nargout, mxArray *out[], int nargin, const mxArray *in[])
720+
{
721+
mexAtExit(&_deleteAllObjects);
722+
typedef std::shared_ptr<Base> Shared;
723+
724+
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
725+
collector_Base.insert(self);
726+
}
727+
728+
void Base_upcastFromVoid_58(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
729+
mexAtExit(&_deleteAllObjects);
730+
typedef std::shared_ptr<Base> Shared;
731+
std::shared_ptr<void> *asVoid = *reinterpret_cast<std::shared_ptr<void>**> (mxGetData(in[0]));
732+
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
733+
Shared *self = new Shared(std::static_pointer_cast<Base>(*asVoid));
734+
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
735+
}
736+
737+
void Base_deconstructor_59(int nargout, mxArray *out[], int nargin, const mxArray *in[])
738+
{
739+
typedef std::shared_ptr<Base> Shared;
740+
checkArguments("delete_Base",nargout,nargin,1);
741+
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
742+
Collector_Base::iterator item;
743+
item = collector_Base.find(self);
744+
if(item != collector_Base.end()) {
745+
collector_Base.erase(item);
746+
}
747+
delete self;
748+
}
749+
750+
void Base_Create_60(int nargout, mxArray *out[], int nargin, const mxArray *in[])
751+
{
752+
checkArguments("Base.Create",nargout,nargin,1);
753+
double x = unwrap< double >(in[0]);
754+
out[0] = wrap_shared_ptr(Base::Create(x),"gtsam.Base", true);
755+
}
756+
757+
void Derived_collectorInsertAndMakeBase_61(int nargout, mxArray *out[], int nargin, const mxArray *in[])
758+
{
759+
mexAtExit(&_deleteAllObjects);
760+
typedef std::shared_ptr<Derived> Shared;
761+
762+
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
763+
collector_Derived.insert(self);
764+
765+
typedef std::shared_ptr<Base> SharedBase;
766+
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
767+
*reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self);
768+
}
769+
770+
void Derived_upcastFromVoid_62(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {
771+
mexAtExit(&_deleteAllObjects);
772+
typedef std::shared_ptr<Derived> Shared;
773+
std::shared_ptr<void> *asVoid = *reinterpret_cast<std::shared_ptr<void>**> (mxGetData(in[0]));
774+
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
775+
Shared *self = new Shared(std::static_pointer_cast<Derived>(*asVoid));
776+
*reinterpret_cast<Shared**>(mxGetData(out[0])) = self;
777+
}
778+
779+
void Derived_deconstructor_63(int nargout, mxArray *out[], int nargin, const mxArray *in[])
780+
{
781+
typedef std::shared_ptr<Derived> Shared;
782+
checkArguments("delete_Derived",nargout,nargin,1);
783+
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
784+
Collector_Derived::iterator item;
785+
item = collector_Derived.find(self);
786+
if(item != collector_Derived.end()) {
787+
collector_Derived.erase(item);
788+
}
789+
delete self;
790+
}
791+
701792

702793
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
703794
{
@@ -881,6 +972,27 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
881972
case 56:
882973
ParentHasTemplateDouble_deconstructor_56(nargout, out, nargin-1, in+1);
883974
break;
975+
case 57:
976+
Base_collectorInsertAndMakeBase_57(nargout, out, nargin-1, in+1);
977+
break;
978+
case 58:
979+
Base_upcastFromVoid_58(nargout, out, nargin-1, in+1);
980+
break;
981+
case 59:
982+
Base_deconstructor_59(nargout, out, nargin-1, in+1);
983+
break;
984+
case 60:
985+
Base_Create_60(nargout, out, nargin-1, in+1);
986+
break;
987+
case 61:
988+
Derived_collectorInsertAndMakeBase_61(nargout, out, nargin-1, in+1);
989+
break;
990+
case 62:
991+
Derived_upcastFromVoid_62(nargout, out, nargin-1, in+1);
992+
break;
993+
case 63:
994+
Derived_deconstructor_63(nargout, out, nargin-1, in+1);
995+
break;
884996
}
885997
} catch(const std::exception& e) {
886998
mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str());

wrap/tests/expected/python/inheritance_pybind.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ PYBIND11_MODULE(inheritance_py, m_) {
8585

8686
py::class_<ParentHasTemplate<double>, MyTemplate<double>, std::shared_ptr<ParentHasTemplate<double>>>(m_, "ParentHasTemplateDouble");
8787

88+
py::class_<Base, std::shared_ptr<Base>>(m_, "Base")
89+
.def_static("Create",[](double x){return Base::Create(x);}, gtwrap::internal::py_arg<double>("x"));
90+
91+
py::class_<Derived, Base, std::shared_ptr<Derived>>(m_, "Derived");
92+
8893

8994
#include "python/specializations.h"
9095

wrap/tests/fixtures/inheritance.i

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ virtual class ForwardKinematicsFactor : gtsam::BetweenFactor<gtsam::Pose3> {};
2727

2828
template <T = {double}>
2929
virtual class ParentHasTemplate : MyTemplate<T> {};
30+
31+
// A base class with a smart static factory that may downcast
32+
virtual class Base {
33+
static gtsam::Base* Create(double x);
34+
};
35+
36+
// A derived class returned by Base::Create when appropriate
37+
virtual class Derived : Base {
38+
};

wrap/tests/test_matlab_wrapper.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ def test_inheritance(self):
256256
'MyTemplatePoint2.m',
257257
'ForwardKinematicsFactor.m',
258258
'ParentHasTemplateDouble.m',
259+
'Base.m',
260+
'Derived.m',
259261
]
260262

261263
for file in files:

0 commit comments

Comments
 (0)