www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - wrapping C++ templates to D templates (via SWIG)

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)
May 31 2012