wrapping C++ templates to D templates (via SWIG)
timotheecour
thelastmammoth at gmail.com
Thu May 31 18:59:06 PDT 2012
I was writing my own template code wrapper until I saw the
excellent SWIG for D tool; currently, given a C++ template
(class/function) "A<T>" and a set of instantiations in interface
file (eg T=double), SWIG seems to only output non-template
classes/functions with user-defined mangled names, eg A_double.
Is there currently a way for SWIG to output instead a D template
(class/function) "A(T)" ?
or rather, the corresponding instantiations, cf A(T:double), etc.
The advantage: simple client code (eg class A_array(T){A!T [] a;}
), similar C++ / D syntax, no magic name mangling or namespace
pollution required by the user, better encapsulation and easier
to keep D in sync with C++.
I have a workaround to achieve this by modifying SWIG output (see
below) but ideally, this could be directly generated in SWIG
(more convenient/efficient). Would it be possible to add this
feature in SWIG, say with a D specific command line switch
-preserve_class_templates and -preserve_function_templates.
In addition, the user shouldn't have to specify himself the name
manglings (eg %template(A_double) A<double>;) but could instead
write something like:
%instantiate(A<double>); in the swig interface file.
***********************
input: fun.h
template<class T> class A{
T x;
A(T x):x(x){}
};
interface:fun.i
%{
#include "fun.h"
%}
%template(A_double) A<double>;
current output: fun.d
class A_double {
private void* swigCPtr;
//..other wrapper code
public this(double x) {
this(fun_im.new_A_double(x), true);
}
}
desired output: fun_desired.d
class A(T:double) {
private void* swigCPtr;
//..other wrapper code
public this(double x) {
this(fun_im.new_A_double(x), true);
}
}
my current hack to get same behavior as desired output:
fun_hacked.d
private alias A ! double A_double;
class A(T:double) {
private alias typeof(this) A_double;
private void* swigCPtr;
//..other wrapper code
public this(double x) {
this(fun_im.new_A_double(x), true);
}
}
***********************
NOTE: in fun_hacked.d, which seems to work, I need to have 2
aliases: one inside (to avoid recursive definition error) and one
outside, which takes care of references to A_double that could
appear outside of the class definition.
This hack could of course be automated, with post-processing of
fun.d=>fun_hacked.d and in the interface file for eg:
%template(A_double) A<double>;
can be generalized using something like (untested):
#define INSTANTIATE_TPL(Atpl,T) %template(Atpl ## _ ## T) Atpl<T>;
INSTANTIATE_TPL(A,double)
More information about the Digitalmars-d
mailing list