%module template_partial_specialization_more // (1) Based on https://stackoverflow.com/questions/9757642/wrapping-specialised-c-template-class-with-swig %inline %{ template struct Vect {}; template class Foo { public: Foo() {} virtual ~Foo() {} T primary() const { return T(); } }; template class Foo, TTS> { public: Foo() {} virtual ~Foo() {} TS partially_specialized(TS parmin) const { return parmin; } }; template<> class Foo, double> { public: Foo() {} virtual ~Foo() {} double value_fully_specialized(double d) const { return d; } }; template class Foo { public: Foo() {} virtual ~Foo() {} int pointer_specialize(T myT) const { return 0; } }; %} %template(VectInt) Vect; %template(FooVectIntDouble) Foo, double>; // was failing %template(FooShortPtrDouble) Foo; %template(FooVectVectInt) Foo >, int>; // was failing // (2) Same types in both args %inline %{ template struct Hey { void primary() {} }; template struct Hey { void special_hey() {} }; %} %template(HeyInts) Hey; // was failing, was calling primary // (3) Partial specialization using one template parameter instead of two %inline %{ struct PlainStruct {}; template struct XX { void primary() {} }; template struct XX { void special1() {} }; // r.$1 template struct XX { void special2() {} }; // r.q(const).$1 template struct XX { void special3() {} }; // r.q(const).p.$1 %} %template(XX1) XX; // was failing, was calling primary %template(XX2) XX; %template(XX3) XX; // (4) Switching parameters around %inline %{ #include template struct Partialler { void primary(P1, P2) {}; }; template struct Partialler { void special(S1*, S2, bool) {}; }; %} %template(PartiallerPrimary) Partialler; %template(PartiallerSpecial) Partialler; // (5) Default args used in specialization, like std::list %include %inline %{ template struct Allocator {}; template > struct Lyst { void primary(T, Allocator) {} }; template struct Lyst { void specialized1(TT, XXAlloc) {} }; template struct Lyst > { void specialized2(TTT, YY) {} }; template struct Lyst { void specialized3(TTTT) {} }; void test_list() { double mydouble = 0; Lyst().primary(mydouble, Allocator()); Lyst >().primary(mydouble, Allocator()); PlainStruct ps; int myint = 0; std::string mystring = 0; Lyst().specialized1(ps, Allocator()); Lyst().specialized2(mydouble, (double **)0); Lyst().specialized3(myint); // Specifying the default still calls the partially specialized template Lyst >().specialized3(mystring); } %} %template(AllocatorDouble) Allocator; %template(AllocatorShort) Allocator; %template(AllocatorPlainStructPtr) Allocator; %template(LystDouble) Lyst; %template(LystShort) Lyst >; %template(LystPlainStructPtr) Lyst; %template(LystDoublePtrPtr) Lyst; // called specialized1 instead of specialized2 %template(LystConstIntRef) Lyst; %template(LystConstStringRef) Lyst >; %inline %{ // Both parameters in each of the functions below are the same type void UseLystDouble(Lyst a, Lyst > b) {} void UseLystShort(Lyst a, Lyst > b) {} void UseLystPlainStructPtr(Lyst a, Lyst > b) {} void UseLystDoublePtrPtr(Lyst a, Lyst > b) {} void UseLystConstIntRef(Lyst a, Lyst > b) {} void UseLystConstStringRef(Lyst a, Lyst > b) {} %} // (6) Default args used in specialization, more variations specifying / not specifying default %inline %{ template struct Spec { void spec_primary(P p, Q q) {} }; template struct Spec { void spec_specialized(PP pp) {} }; %} %template(SpecDoubleInt) Spec; %template(SpecStringInt) Spec; %inline %{ void UseSpec1(Spec x, Spec y) {} void UseSpec2(Spec x, Spec y) {} void test_spec() { double mydouble = 0.0; Spec().spec_specialized(mydouble); Spec().spec_specialized(mydouble); std::string mystring; Spec().spec_specialized(mystring); Spec().spec_specialized(mystring); } %}