Added support for the D programming languge.

It is still a bit rough around some edges, particularly with regard to multi-threading and operator overloading, and there are some documentation bits missing, but it should be fine for basic use.

The test-suite should build and run fine with the current versions of DMD, LDC and Tango (at least) on Linux x86_64 and Mac OS X 10.6.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12299 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
David Nadlinger 2010-11-18 00:24:02 +00:00
commit 03aefbc6e9
176 changed files with 16449 additions and 29 deletions

View file

@ -18,6 +18,7 @@
%include <chicken/chickenkw.swg>
%include <csharp/csharpkw.swg>
%include <d/dkw.swg>
%include <java/javakw.swg>
%include <php/phpkw.swg>
%include <pike/pikekw.swg>

201
Lib/d/boost_shared_ptr.i Normal file
View file

@ -0,0 +1,201 @@
%include <shared_ptr.i>
%define SWIG_SHARED_PTR_TYPEMAPS(CONST, TYPE...)
%naturalvar TYPE;
%naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
// destructor mods
%feature("unref") TYPE
//"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter<SWIG_null_deleter>(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ((*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\"))) << \"]\" << endl << flush; }\n"
"(void)arg1; delete smartarg1;"
// plain value
%typemap(in, canthrow=1) CONST TYPE ($&1_type argp = 0) %{
argp = ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0;
if (!argp) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Attempt to dereference null $1_type");
return $null;
}
$1 = *argp; %}
%typemap(out) CONST TYPE
%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
// plain pointer
%typemap(in, canthrow=1) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
smartarg = (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input;
$1 = (TYPE *)(smartarg ? smartarg->get() : 0); %}
%typemap(out, fragment="SWIG_null_deleter") CONST TYPE * %{
$result = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner) : 0;
%}
// plain reference
%typemap(in, canthrow=1) CONST TYPE & %{
$1 = ($1_ltype)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
if (!$1) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type reference is null");
return $null;
} %}
%typemap(out, fragment="SWIG_null_deleter") CONST TYPE &
%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_$owner); %}
// plain pointer by reference
%typemap(in) TYPE *CONST& ($*1_ltype temp = 0)
%{ temp = (TYPE *)(((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input) ? ((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)$input)->get() : 0);
$1 = &temp; %}
%typemap(out, fragment="SWIG_null_deleter") TYPE *CONST&
%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_$owner); %}
// shared_ptr by value
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
%{ if ($input) $1 = *($&1_ltype)$input; %}
%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >
%{ $result = $1 ? new $1_ltype($1) : 0; %}
// shared_ptr by reference
%typemap(in, canthrow=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &
%{ $result = *$1 ? new $*1_ltype(*$1) : 0; %}
// shared_ptr by pointer
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
if ($owner) delete $1; %}
// shared_ptr by pointer reference
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempnull, $*1_ltype temp = 0)
%{ temp = $input ? *($1_ltype)&$input : &tempnull;
$1 = &temp; %}
%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
%{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %}
// various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug
%typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{
#error "typemaps for $1_type not available"
%}
%typemap(out) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{
#error "typemaps for $1_type not available"
%}
%typemap (cwtype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "void *"
%typemap (dwtype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "void*"
%typemap (dptype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(dptype, TYPE)"
%typemap(din) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(dptype, TYPE).swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) CONST TYPE {
auto ret = new $typemap(dptype, TYPE)($wcall, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) CONST TYPE & {
auto ret = new $typemap(dptype, TYPE)($wcall, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) CONST TYPE * {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
%typemap(dout, excode=SWIGEXCODE) TYPE *CONST& {
void* cPtr = $wcall;
auto ret = (cPtr is null) ? null : new $typemap(dptype, TYPE)(cPtr, true);$excode
return ret;
}
// For shared pointers, both the derived and the base class have to »own« their
// pointer; otherwise the reference count is not decreased properly on destruction.
%typemap(dbody) SWIGTYPE %{
private void* swigCPtr;
private bool swigCMemOwn;
public this(void* cObject, bool ownCObject) {
swigCPtr = cObject;
swigCMemOwn = ownCObject;
}
public static void* swigGetCPtr($dclassname obj) {
return (obj is null) ? null : obj.swigCPtr;
}
%}
%typemap(dbody_derived) SWIGTYPE %{
private void* swigCPtr;
private bool swigCMemOwn;
public this(void* cObject, bool ownCObject) {
super($wrapdmodule.$dclassnameSmartPtrUpcast(cObject), ownCObject);
swigCPtr = cObject;
swigCMemOwn = ownCObject;
}
public static void* swigGetCPtr($dclassname obj) {
return (obj is null) ? null : obj.swigCPtr;
}
%}
%typemap(ddispose, methodname="dispose", methodmodifiers="public") TYPE {
synchronized(this) {
if (swigCPtr !is null) {
if (swigCMemOwn) {
swigCMemOwn = false;
$wcall;
}
swigCPtr = null;
}
}
}
%typemap(ddispose_derived, methodname="dispose", methodmodifiers="public") TYPE {
synchronized(this) {
if (swigCPtr !is null) {
if (swigCMemOwn) {
swigCMemOwn = false;
$wcall;
}
swigCPtr = null;
super.dispose();
}
}
}
%template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
%enddef

111
Lib/d/carrays.i Normal file
View file

@ -0,0 +1,111 @@
/* -----------------------------------------------------------------------------
* carrays.i
*
* D-specific version of ../carrays.i.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* %array_functions(TYPE,NAME)
*
* Generates functions for creating and accessing elements of a C array
* (as pointers). Creates the following functions:
*
* TYPE *new_NAME(int nelements)
* void delete_NAME(TYPE *);
* TYPE NAME_getitem(TYPE *, int index);
* void NAME_setitem(TYPE *, int index, TYPE value);
*
* ----------------------------------------------------------------------------- */
%define %array_functions(TYPE,NAME)
%{
static TYPE *new_##NAME(int nelements) { %}
#ifdef __cplusplus
%{ return new TYPE[nelements]; %}
#else
%{ return (TYPE *) calloc(nelements,sizeof(TYPE)); %}
#endif
%{}
static void delete_##NAME(TYPE *ary) { %}
#ifdef __cplusplus
%{ delete [] ary; %}
#else
%{ free(ary); %}
#endif
%{}
static TYPE NAME##_getitem(TYPE *ary, int index) {
return ary[index];
}
static void NAME##_setitem(TYPE *ary, int index, TYPE value) {
ary[index] = value;
}
%}
TYPE *new_##NAME(int nelements);
void delete_##NAME(TYPE *ary);
TYPE NAME##_getitem(TYPE *ary, int index);
void NAME##_setitem(TYPE *ary, int index, TYPE value);
%enddef
/* -----------------------------------------------------------------------------
* %array_class(TYPE,NAME)
*
* Generates a class wrapper around a C array. The class has the following
* interface:
*
* struct NAME {
* NAME(int nelements);
* ~NAME();
* TYPE getitem(int index);
* void setitem(int index, TYPE value);
* TYPE * ptr();
* static NAME *frompointer(TYPE *t);
* }
*
* ----------------------------------------------------------------------------- */
%define %array_class(TYPE,NAME)
%{
typedef TYPE NAME;
%}
typedef struct NAME {} NAME;
%extend NAME {
#ifdef __cplusplus
NAME(int nelements) {
return new TYPE[nelements];
}
~NAME() {
delete [] self;
}
#else
NAME(int nelements) {
return (TYPE *) calloc(nelements,sizeof(TYPE));
}
~NAME() {
free(self);
}
#endif
TYPE getitem(int index) {
return self[index];
}
void setitem(int index, TYPE value) {
self[index] = value;
}
TYPE * ptr() {
return self;
}
static NAME *frompointer(TYPE *t) {
return (NAME *) t;
}
};
%types(NAME = TYPE);
%enddef

171
Lib/d/cpointer.i Normal file
View file

@ -0,0 +1,171 @@
/* -----------------------------------------------------------------------------
* cpointer.i
*
* D-specific version of ../cpointer.i.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* %pointer_class(type,name)
*
* Places a simple proxy around a simple type like 'int', 'float', or whatever.
* The proxy provides this interface:
*
* class type {
* public:
* type();
* ~type();
* type value();
* void assign(type value);
* };
*
* Example:
*
* %pointer_class(int, intp);
*
* int add(int *x, int *y) { return *x + *y; }
*
* In python (with proxies)
*
* >>> a = intp()
* >>> a.assign(10)
* >>> a.value()
* 10
* >>> b = intp()
* >>> b.assign(20)
* >>> print add(a,b)
* 30
*
* As a general rule, this macro should not be used on class/structures that
* are already defined in the interface.
* ----------------------------------------------------------------------------- */
%define %pointer_class(TYPE, NAME)
%{
typedef TYPE NAME;
%}
typedef struct {
} NAME;
%extend NAME {
#ifdef __cplusplus
NAME() {
return new TYPE();
}
~NAME() {
if (self) delete self;
}
#else
NAME() {
return (TYPE *) calloc(1,sizeof(TYPE));
}
~NAME() {
if (self) free(self);
}
#endif
}
%extend NAME {
void assign(TYPE value) {
*self = value;
}
TYPE value() {
return *self;
}
TYPE * ptr() {
return self;
}
static NAME * frompointer(TYPE *t) {
return (NAME *) t;
}
}
%types(NAME = TYPE);
%enddef
/* -----------------------------------------------------------------------------
* %pointer_functions(type,name)
*
* Create functions for allocating/deallocating pointers. This can be used
* if you don't want to create a proxy class or if the pointer is complex.
*
* %pointer_functions(int, intp)
*
* int add(int *x, int *y) { return *x + *y; }
*
* In python (with proxies)
*
* >>> a = copy_intp(10)
* >>> intp_value(a)
* 10
* >>> b = new_intp()
* >>> intp_assign(b,20)
* >>> print add(a,b)
* 30
* >>> delete_intp(a)
* >>> delete_intp(b)
*
* ----------------------------------------------------------------------------- */
%define %pointer_functions(TYPE,NAME)
%{
static TYPE *new_##NAME() { %}
#ifdef __cplusplus
%{ return new TYPE(); %}
#else
%{ return (TYPE *) calloc(1,sizeof(TYPE)); %}
#endif
%{}
static TYPE *copy_##NAME(TYPE value) { %}
#ifdef __cplusplus
%{ return new TYPE(value); %}
#else
%{ TYPE *self = (TYPE *) calloc(1,sizeof(TYPE));
*self = value;
return self; %}
#endif
%{}
static void delete_##NAME(TYPE *self) { %}
#ifdef __cplusplus
%{ if (self) delete self; %}
#else
%{ if (self) free(self); %}
#endif
%{}
static void NAME ##_assign(TYPE *self, TYPE value) {
*self = value;
}
static TYPE NAME ##_value(TYPE *self) {
return *self;
}
%}
TYPE *new_##NAME();
TYPE *copy_##NAME(TYPE value);
void delete_##NAME(TYPE *self);
void NAME##_assign(TYPE *self, TYPE value);
TYPE NAME##_value(TYPE *self);
%enddef
/* -----------------------------------------------------------------------------
* %pointer_cast(type1,type2,name)
*
* Generates a pointer casting function.
* ----------------------------------------------------------------------------- */
%define %pointer_cast(TYPE1,TYPE2,NAME)
%inline %{
TYPE2 NAME(TYPE1 x) {
return (TYPE2) x;
}
%}
%enddef

46
Lib/d/d.swg Normal file
View file

@ -0,0 +1,46 @@
/* -----------------------------------------------------------------------------
* d.swg
*
* Main library file for the D language module. See the D chapter in the SWIG
* manual for explanation on the typemaps, pragmas, etc. used.
* ----------------------------------------------------------------------------- */
// Typemaps for exception handling.
%include <dexception.swg>
// Typemaps for primitive types.
%include <dprimitives.swg>
// Typemaps for non-primitive types (C/C++ classes and structs).
%include <dswigtype.swg>
// Typemaps for enumeration types.
%include <denums.swg>
// Typemaps for member function pointers.
%include <dmemberfunctionpointers.swg>
// Typemaps for wrapping pointers to/arrays of C chars as D strings.
%include <dstrings.swg>
// Typemaps for handling void function return types and empty parameter lists.
%include <dvoid.swg>
// Typemaps containing D code used when generating D proxy classes.
%include <dclassgen.swg>
// Mapping of C++ operator overloading methods to D.
%include <doperators.swg>
// Helper code string and exception handling.
%include <dhead.swg>
// Wrapper loader code for dynamically linking the C wrapper library from the D
// wrapper module.
%include <wrapperloader.swg>
// List of all reserved D keywords.
%include <dkw.swg>
// D-specific directives.
%include <ddirectives.swg>

172
Lib/d/dclassgen.swg Normal file
View file

@ -0,0 +1,172 @@
/* -----------------------------------------------------------------------------
* dclassgen.swg
*
* Typemaps containing D code used when generating D proxy classes.
* ----------------------------------------------------------------------------- */
%typemap(dbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
%typemap(dclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "class"
%typemap(dcode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
%typemap(dimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
%typemap(dinterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
%typemap(dinterfaces_derived) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
// See <denums.swg>.
%typemap(dclassmodifiers) enum SWIGTYPE "enum"
%typemap(dcode) enum SWIGTYPE ""
/*
* Proxy classes.
*/
%typemap(dconstructor, excode=SWIGEXCODE,directorconnect="\n swigDirectorConnect();") SWIGTYPE {
this($wcall, true);$excode$directorconnect
}
%typemap(ddestructor) SWIGTYPE %{
~this() {
dispose();
}
%}
// We do not use »override« attribute for generated dispose() methods to stay
// somewhat compatible to Phobos and older Tango versions where Object.dispose()
// does not exist.
%typemap(ddispose, methodname="dispose", methodmodifiers="public") SWIGTYPE {
synchronized(this) {
if (swigCPtr !is null) {
if (swigCMemOwn) {
swigCMemOwn = false;
$wcall;
}
swigCPtr = null;
}
}
}
%typemap(ddispose_derived, methodname="dispose", methodmodifiers="public") SWIGTYPE {
synchronized(this) {
if (swigCPtr !is null) {
if (swigCMemOwn) {
swigCMemOwn = false;
$wcall;
}
swigCPtr = null;
super.dispose();
}
}
}
%define SWIGD_CLASS_BODIES(OP_EQUALS_RETURN)
// Unfortunately, the »package« visibility attribute does not work in D when the
// module in question is in the root package (happens if no -package is specified
// at the SWIG command line), so we are stuck with public visibility for
// swigGetCPtr().
%typemap(dbody) SWIGTYPE %{
private void* swigCPtr;
protected bool swigCMemOwn;
public this(void* cObject, bool ownCObject) {
swigCPtr = cObject;
swigCMemOwn = ownCObject;
}
public override OP_EQUALS_RETURN opEquals(Object rhs) {
if (auto other = cast($dclassname)rhs) {
return (swigCPtr == other.swigCPtr);
}
return super.opEquals(rhs);
}
public static void* swigGetCPtr($dclassname obj) {
return (obj is null) ? null : obj.swigCPtr;
}
%}
%typemap(dbody_derived) SWIGTYPE %{
private void* swigCPtr;
public this(void* cObject, bool ownCObject) {
super($wrapdmodule.$dclassnameUpcast(cObject), ownCObject);
swigCPtr = cObject;
}
public override OP_EQUALS_RETURN opEquals(Object rhs) {
if (auto other = cast($dclassname)rhs) {
return (swigCPtr == other.swigCPtr);
}
return super.opEquals(rhs);
}
public static void* swigGetCPtr($dclassname obj) {
return (obj is null) ? null : obj.swigCPtr;
}
%}
/*
* Type wrapper classes.
*/
%typemap(dbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
private void* swigCPtr;
public this(void* cObject, bool futureUse) {
swigCPtr = cObject;
}
protected this() {
swigCPtr = null;
}
public override OP_EQUALS_RETURN opEquals(Object rhs) {
if (auto other = cast($dclassname)rhs) {
return (swigCPtr == other.swigCPtr);
}
return super.opEquals(rhs);
}
public static void* swigGetCPtr($dclassname obj) {
return (obj is null) ? null : obj.swigCPtr;
}
%}
/*
* Member function pointer wrapper classes (see <dmemberfunctionpointers.swg>).
*/
%typemap(dbody) SWIGTYPE (CLASS::*) %{
private char* m_swigCMemberPtr;
public this(char* cMemberPtr, bool futureUse) {
m_swigCMemberPtr = cMemberPtr;
}
protected this() {
m_swigCMemberPtr = null;
}
public override OP_EQUALS_RETURN opEquals(Object rhs) {
if (auto other = cast($dclassname)rhs) {
return (m_swigCMemberPtr == other.m_swigCMemberPtr);
}
return super.opEquals(rhs);
}
package static char* swigGetCMemberPtr($dclassname obj) {
return (obj is null) ? null : obj.m_swigCMemberPtr;
}
%}
%enddef
#if SWIG_D_VERSION == 1
SWIGD_CLASS_BODIES(int)
#else
SWIGD_CLASS_BODIES(bool)
#endif
#undef SWIGD_CLASS_BODIES

11
Lib/d/ddirectives.swg Normal file
View file

@ -0,0 +1,11 @@
/* -----------------------------------------------------------------------------
* ddirectives.swg
*
* D-specifiv directives.
* ----------------------------------------------------------------------------- */
#define %dnativeconst %feature("d:nativeconst")
#define %dconstvalue(value) %feature("d:constvalue",value)
#define %dmethodmodifiers %feature("d:methodmodifiers")
#define %dstripprefix %feature("d:stripprefix")
#define %dnothrowexception %feature("except")

60
Lib/d/denums.swg Normal file
View file

@ -0,0 +1,60 @@
/* -----------------------------------------------------------------------------
* denums.swg
*
* Typemaps for enumerations.
* ----------------------------------------------------------------------------- */
/*
* Typemaps for enumeration types.
*/
%typemap(cwtype) enum SWIGTYPE "int"
%typemap(dwtype) enum SWIGTYPE "int"
%typemap(dptype, cprimitive="1") enum SWIGTYPE "$dclassname"
%typecheck(SWIG_TYPECHECK_POINTER) enum SWIGTYPE ""
%typemap(in) enum SWIGTYPE %{ $1 = ($1_ltype)$input; %}
%typemap(out) enum SWIGTYPE %{ $result = $1; %}
%typemap(directorout) enum SWIGTYPE %{ $result = ($1_ltype)$input; %}
%typemap(directorin) enum SWIGTYPE "$input = $1;"
%typemap(ddirectorin) enum SWIGTYPE "cast($dclassname)$winput"
%typemap(ddirectorout) enum SWIGTYPE "cast(int)$dpcall"
%typemap(din) enum SWIGTYPE "cast(int)$dinput"
%typemap(dout, excode=SWIGEXCODE) enum SWIGTYPE {
$dclassname ret = cast($dclassname)$wcall;$excode
return ret;
}
/*
* Typemaps for (const) references to enumeration types.
*/
%typemap(cwtype) const enum SWIGTYPE & "int"
%typemap(dwtype) const enum SWIGTYPE & "int"
%typemap(dptype) const enum SWIGTYPE & "$*dclassname"
%typecheck(SWIG_TYPECHECK_POINTER) const enum SWIGTYPE & ""
%typemap(in) const enum SWIGTYPE & ($*1_ltype temp)
%{ temp = ($*1_ltype)$input;
$1 = &temp; %}
%typemap(out) const enum SWIGTYPE & %{ $result = *$1; %}
%typemap(directorin) const enum SWIGTYPE & "$input = $1_name;"
%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const enum SWIGTYPE &
%{ static $*1_ltype temp = ($*1_ltype)$input;
$result = &temp; %}
%typemap(ddirectorin) const enum SWIGTYPE & "cast($*dclassname)$winput"
%typemap(ddirectorout) const enum SWIGTYPE & "cast(int)$dpcall"
%typemap(din) const enum SWIGTYPE & "cast(int)$dinput"
%typemap(dout, excode=SWIGEXCODE) const enum SWIGTYPE & {
$*dclassname ret = cast($*dclassname)$wcall;$excode
return ret;
}

30
Lib/d/dexception.swg Normal file
View file

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
* dexception.swg
*
* Typemaps used for propagating C++ exceptions to D.
* ----------------------------------------------------------------------------- */
// Code which is inserted into the dout typemaps and class constructors via
// excode if exceptions can be thrown.
%define SWIGEXCODE "\n if ($wrapdmodule.SwigPendingException.isPending) throw $wrapdmodule.SwigPendingException.retrieve();" %enddef
%typemap(throws, canthrow=1) int,
long,
short,
unsigned int,
unsigned long,
unsigned short
%{ char error_msg[256];
sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
SWIG_DSetPendingException(SWIG_DException, error_msg);
return $null; %}
%typemap(throws, canthrow=1) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [ANY],
enum SWIGTYPE, const enum SWIGTYPE &
%{ (void)$1;
SWIG_DSetPendingException(SWIG_DException, "C++ $1_type exception thrown");
return $null; %}
%typemap(throws, canthrow=1) char *
%{ SWIG_DSetPendingException(SWIG_DException, $1);
return $null; %}

310
Lib/d/dhead.swg Normal file
View file

@ -0,0 +1,310 @@
/* -----------------------------------------------------------------------------
* dhead.swg
*
* Support code for exceptions if the SWIG_D_NO_EXCEPTION_HELPER is not defined
* Support code for strings if the SWIG_D_NO_STRING_HELPER is not defined
* ----------------------------------------------------------------------------- */
%insert(runtime) %{
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
%}
#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
%insert(runtime) %{
// Support for throwing D exceptions from C/C++.
typedef enum {
SWIG_DException = 0,
SWIG_DIllegalArgumentException,
SWIG_DIllegalElementException,
SWIG_DIOException,
SWIG_DNoSuchElementException,
} SWIG_DExceptionCodes;
typedef void (SWIGSTDCALL* SWIG_DExceptionCallback_t)(const char *);
typedef struct {
SWIG_DExceptionCodes code;
SWIG_DExceptionCallback_t callback;
} SWIG_DException_t;
static SWIG_DException_t SWIG_d_exceptions[] = {
{ SWIG_DException, NULL },
{ SWIG_DIllegalArgumentException, NULL },
{ SWIG_DIllegalElementException, NULL },
{ SWIG_DIOException, NULL },
{ SWIG_DNoSuchElementException, NULL }
};
static void SWIGUNUSED SWIG_DSetPendingException(SWIG_DExceptionCodes code, const char *msg) {
if ((size_t)code < sizeof(SWIG_d_exceptions)/sizeof(SWIG_DException_t)) {
SWIG_d_exceptions[code].callback(msg);
} else {
SWIG_d_exceptions[SWIG_DException].callback(msg);
}
}
#ifdef __cplusplus
extern "C"
#endif
SWIGEXPORT void SWIGSTDCALL SWIGRegisterExceptionCallbacks_$module(
SWIG_DExceptionCallback_t exceptionCallback,
SWIG_DExceptionCallback_t illegalArgumentCallback,
SWIG_DExceptionCallback_t illegalElementCallback,
SWIG_DExceptionCallback_t ioCallback,
SWIG_DExceptionCallback_t noSuchElementCallback) {
SWIG_d_exceptions[SWIG_DException].callback = exceptionCallback;
SWIG_d_exceptions[SWIG_DIllegalArgumentException].callback = illegalArgumentCallback;
SWIG_d_exceptions[SWIG_DIllegalElementException].callback = illegalElementCallback;
SWIG_d_exceptions[SWIG_DIOException].callback = ioCallback;
SWIG_d_exceptions[SWIG_DNoSuchElementException].callback = noSuchElementCallback;
}
%}
#if (SWIG_D_VERSION == 1)
%pragma(d) wrapdmoduleimports=%{
// Exception throwing support currently requires Tango, but there is no reason
// why it could not support Phobos.
static import tango.core.Exception;
static import tango.core.Thread;
static import tango.stdc.stringz;
%}
%pragma(d) wrapdmodulecode=%{
private class SwigExceptionHelper {
static this() {
swigRegisterExceptionCallbacks(
&setException,
&setIllegalArgumentException,
&setIllegalElementException,
&setIOException,
&setNoSuchElementException);
}
static void setException(char* message) {
auto exception = new Exception(tango.stdc.stringz.fromStringz(message).dup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
static void setIllegalArgumentException(char* message) {
auto exception = new tango.core.Exception.IllegalArgumentException(tango.stdc.stringz.fromStringz(message).dup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
static void setIllegalElementException(char* message) {
auto exception = new tango.core.Exception.IllegalElementException(tango.stdc.stringz.fromStringz(message).dup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
static void setIOException(char* message) {
auto exception = new tango.core.Exception.IOException(tango.stdc.stringz.fromStringz(message).dup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
static void setNoSuchElementException(char* message) {
auto exception = new tango.core.Exception.NoSuchElementException(tango.stdc.stringz.fromStringz(message).dup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
}
package class SwigPendingException {
public:
static this() {
m_sPendingCount = 0;
m_sPendingException = new ThreadLocalData(null);
}
static bool isPending() {
bool pending = false;
if (m_sPendingCount > 0) {
if (m_sPendingException.val !is null) {
pending = true;
}
}
return pending;
}
static void set(Exception e) {
if (m_sPendingException.val !is null) {
throw new Exception("FATAL: An earlier pending exception from C/C++ code " ~
"was missed and thus not thrown (" ~ m_sPendingException.val.classinfo.name ~
": " ~ m_sPendingException.val.msg ~ ")!", e);
}
m_sPendingException.val = e;
synchronized {
++m_sPendingCount;
}
}
static Exception retrieve() {
Exception e = null;
if (m_sPendingCount > 0) {
if (m_sPendingException.val !is null) {
e = m_sPendingException.val;
m_sPendingException.val = null;
synchronized {
--m_sPendingCount;
}
}
}
return e;
}
private:
// The pending exception counter is stored thread-global.
static int m_sPendingCount;
// The reference to the pending exception (if any) is stored thread-local.
alias tango.core.Thread.ThreadLocal!(Exception) ThreadLocalData;
static ThreadLocalData m_sPendingException;
}
alias void function(char* message) SwigExceptionCallback;
%}
#else
%pragma(d) wrapdmoduleimports=%{
static import std.conv;
%}
%pragma(d) wrapdmodulecode=%{
private class SwigExceptionHelper {
static this() {
// The D1/Tango version maps C++ exceptions to multiple exception types.
swigRegisterExceptionCallbacks(
&setException,
&setException,
&setException,
&setException,
&setException
);
}
static void setException(char* message) {
auto exception = new Exception(std.conv.to!string(message).idup);
exception.next = SwigPendingException.retrieve();
SwigPendingException.set(exception);
}
}
package struct SwigPendingException {
public:
static this() {
m_sPendingCount = 0;
m_sPendingException = null;
}
static bool isPending() {
bool pending = false;
if (m_sPendingCount > 0) {
if (m_sPendingException !is null) {
pending = true;
}
}
return pending;
}
static void set(Exception e) {
if (m_sPendingException !is null) {
throw new Exception("FATAL: An earlier pending exception from C/C++ code " ~
"was missed and thus not thrown (" ~ m_sPendingException.classinfo.name ~
": " ~ m_sPendingException.msg ~ ")!", e);
}
m_sPendingException = e;
synchronized {
++m_sPendingCount;
}
}
static Exception retrieve() {
Exception e = null;
if (m_sPendingCount > 0) {
if (m_sPendingException !is null) {
e = m_sPendingException;
m_sPendingException = null;
synchronized {
--m_sPendingCount;
}
}
}
return e;
}
private:
// The pending exception counter is stored thread-global.
static shared int m_sPendingCount;
// The reference to the pending exception (if any) is stored thread-local.
static Exception m_sPendingException;
}
alias void function(const char* message) SwigExceptionCallback;
%}
#endif
// Callback registering function in wrapperloader.swg.
#endif // SWIG_D_NO_EXCEPTION_HELPER
#if !defined(SWIG_D_NO_STRING_HELPER)
%insert(runtime) %{
// Callback for returning strings to D without leaking memory.
typedef char * (SWIGSTDCALL* SWIG_DStringHelperCallback)(const char *);
static SWIG_DStringHelperCallback SWIG_d_string_callback = NULL;
#ifdef __cplusplus
extern "C"
#endif
SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_$module(SWIG_DStringHelperCallback callback) {
SWIG_d_string_callback = callback;
}
%}
#if (SWIG_D_VERSION == 1)
%pragma(d) wrapdmoduleimports = "static import tango.stdc.stringz;";
%pragma(d) wrapdmodulecode = %{
private class SwigStringHelper {
static this() {
swigRegisterStringCallback(&createString);
}
static char* createString(char* cString) {
// We are effectively dup'ing the string here.
return tango.stdc.stringz.toStringz(tango.stdc.stringz.fromStringz(cString));
}
}
alias char* function(char* cString) SwigStringCallback;
%}
#else
%pragma(d) wrapdmoduleimports = %{
static import std.conv;
static import std.string;
%}
%pragma(d) wrapdmodulecode = %{
private class SwigStringHelper {
static this() {
swigRegisterStringCallback(&createString);
}
static const(char)* createString(const(char*) cString) {
// We are effectively dup'ing the string here.
// TODO: Is this also correct for D2/Phobos?
return std.string.toStringz(std.conv.to!string(cString));
}
}
alias const(char)* function(const(char*) cString) SwigStringCallback;
%}
#endif
// Callback registering function in wrapperloader.swg.
#endif // SWIG_D_NO_STRING_HELPER
%insert(runtime) %{
/* Contract support. */
#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } else
%}

46
Lib/d/director.swg Normal file
View file

@ -0,0 +1,46 @@
/* -----------------------------------------------------------------------------
* director.swg
*
* This file contains support for director classes so that D proxy
* methods can be called from C++.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
#if defined(DEBUG_DIRECTOR_OWNED)
#include <iostream>
#endif
#include <string>
namespace Swig {
// Director base class not used in D directors.
class Director {
};
// Base class for director exceptions.
class DirectorException {
protected:
std::string swig_msg;
public:
DirectorException(const char* msg) : swig_msg(msg) {
}
DirectorException(const std::string &msg) : swig_msg(msg) {
}
const std::string& what() const {
return swig_msg;
}
virtual ~DirectorException() {
}
};
// Exception which is thrown when attempting to call a pure virtual method
// from D code thorugh the director layer.
class DirectorPureVirtualException : public Swig::DirectorException {
public:
DirectorPureVirtualException(const char* msg) : DirectorException(std::string("Attempted to invoke pure virtual method ") + msg) {
}
};
}
#endif /* __cplusplus */

126
Lib/d/dkw.swg Normal file
View file

@ -0,0 +1,126 @@
#ifndef D_DKW_SWG_
#define D_DKW_SWG_
/* Warnings for D keywords */
#define DKEYWORD(x) %keywordwarn("'" `x` "' is a D keyword, renaming to '_" `x` "'",rename="_%s") `x`
// Source: http://www.digitalmars.com/d/{1.0,2.0}/lex.html and
DKEYWORD(Object);
DKEYWORD(__FILE__);
DKEYWORD(__LINE__);
DKEYWORD(__gshared);
DKEYWORD(__thread);
DKEYWORD(__traits);
DKEYWORD(abstract);
DKEYWORD(alias);
DKEYWORD(align);
DKEYWORD(asm);
DKEYWORD(assert);
DKEYWORD(auto);
DKEYWORD(body);
DKEYWORD(bool);
DKEYWORD(break);
DKEYWORD(byte);
DKEYWORD(case);
DKEYWORD(cast);
DKEYWORD(catch);
DKEYWORD(cdouble);
DKEYWORD(cent);
DKEYWORD(cfloat);
DKEYWORD(char);
DKEYWORD(class);
DKEYWORD(const);
DKEYWORD(continue);
DKEYWORD(creal);
DKEYWORD(dchar);
DKEYWORD(debug);
DKEYWORD(default);
DKEYWORD(delegate);
DKEYWORD(delete);
DKEYWORD(deprecated);
DKEYWORD(do);
DKEYWORD(double);
DKEYWORD(dstring);
DKEYWORD(else);
DKEYWORD(enum);
DKEYWORD(export);
DKEYWORD(extern);
DKEYWORD(false);
DKEYWORD(final);
DKEYWORD(finally);
DKEYWORD(float);
DKEYWORD(for);
DKEYWORD(foreach);
DKEYWORD(foreach_reverse);
DKEYWORD(function);
DKEYWORD(goto);
DKEYWORD(idouble);
DKEYWORD(if);
DKEYWORD(ifloat);
DKEYWORD(immutable);
DKEYWORD(import);
DKEYWORD(in);
DKEYWORD(inout);
DKEYWORD(int);
DKEYWORD(interface);
DKEYWORD(invariant);
DKEYWORD(ireal);
DKEYWORD(is);
DKEYWORD(lazy);
DKEYWORD(long);
DKEYWORD(macro);
DKEYWORD(mixin);
DKEYWORD(module);
DKEYWORD(new);
DKEYWORD(nothrow);
DKEYWORD(null);
DKEYWORD(out);
DKEYWORD(override);
DKEYWORD(package);
DKEYWORD(pragma);
DKEYWORD(private);
DKEYWORD(protected);
DKEYWORD(public);
DKEYWORD(pure);
DKEYWORD(real);
DKEYWORD(ref);
DKEYWORD(return);
DKEYWORD(scope);
DKEYWORD(shared);
DKEYWORD(short);
DKEYWORD(static);
DKEYWORD(string);
DKEYWORD(struct);
DKEYWORD(super);
DKEYWORD(switch);
DKEYWORD(synchronized);
DKEYWORD(template);
DKEYWORD(this);
DKEYWORD(throw);
DKEYWORD(true);
DKEYWORD(try);
DKEYWORD(typedef);
DKEYWORD(typeid);
DKEYWORD(typeof);
DKEYWORD(ubyte);
DKEYWORD(ucent);
DKEYWORD(uint);
DKEYWORD(ulong);
DKEYWORD(union);
DKEYWORD(unittest);
DKEYWORD(ushort);
DKEYWORD(version);
DKEYWORD(void);
DKEYWORD(volatile);
DKEYWORD(wchar);
DKEYWORD(while);
DKEYWORD(with);
DKEYWORD(wstring);
// Not really a keyword, but dispose() methods are generated in proxy classes
// and it's a special method name for D1/Tango.
DKEYWORD(dispose);
#undef DKEYWORD
#endif //D_DKW_SWG_

View file

@ -0,0 +1,92 @@
/* -----------------------------------------------------------------------------
* dmemberfunctionpointers.swg
*
* Typemaps for member function pointers.
* ----------------------------------------------------------------------------- */
%typemap(cwtype) SWIGTYPE (CLASS::*) "char *"
%typemap(dwtype) SWIGTYPE (CLASS::*) "char*"
%typemap(dptype) SWIGTYPE (CLASS::*) "$dclassname"
%typecheck(SWIG_TYPECHECK_POINTER)
SWIGTYPE (CLASS::*)
""
/*
* Conversion generation typemaps.
*/
%typemap(in, fragment="SWIG_UnPackData") SWIGTYPE (CLASS::*) %{
SWIG_UnpackData($input, (void *)&$1, sizeof($1));
%}
%typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{
char buf[128];
char *data = SWIG_PackData(buf, (void *)&$1, sizeof($1));
*data = '\0';
$result = SWIG_d_string_callback(buf);
%}
%typemap(directorin) SWIGTYPE (CLASS::*) "$input = (void *) $1;"
%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE (CLASS::*)
"$result = ($1_ltype)$input;"
%typemap(ddirectorin) SWIGTYPE (CLASS::*)
"($winput is null) ? null : new $dclassname($winput, false)"
%typemap(ddirectorout) SWIGTYPE (CLASS::*) "$dclassname.swigGetCPtr($dpcall)"
%typemap(din) SWIGTYPE (CLASS::*) "$dclassname.swigGetCMemberPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIGTYPE (CLASS::*) {
char* cMemberPtr = $wcall;
$dclassname ret = (cMemberPtr is null) ? null : new $dclassname(cMemberPtr, $owner);$excode
return ret;
}
/*
* Helper functions to pack/unpack arbitrary binary data (member function
* pointers in this case) into a string.
*/
%fragment("SWIG_PackData", "header") {
/* Pack binary data into a string */
SWIGINTERN char * SWIG_PackData(char *c, void *ptr, size_t sz) {
static const char hex[17] = "0123456789abcdef";
register const unsigned char *u = (unsigned char *) ptr;
register const unsigned char *eu = u + sz;
for (; u != eu; ++u) {
register unsigned char uu = *u;
*(c++) = hex[(uu & 0xf0) >> 4];
*(c++) = hex[uu & 0xf];
}
return c;
}
}
%fragment("SWIG_UnPackData", "header") {
/* Unpack binary data from a string */
SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
register unsigned char *u = (unsigned char *) ptr;
register const unsigned char *eu = u + sz;
for (; u != eu; ++u) {
register char d = *(c++);
register unsigned char uu;
if ((d >= '0') && (d <= '9'))
uu = ((d - '0') << 4);
else if ((d >= 'a') && (d <= 'f'))
uu = ((d - ('a'-10)) << 4);
else
return (char *) 0;
d = *(c++);
if ((d >= '0') && (d <= '9'))
uu |= (d - '0');
else if ((d >= 'a') && (d <= 'f'))
uu |= (d - ('a'-10));
else
return (char *) 0;
*u = uu;
}
return c;
}
}

77
Lib/d/doperators.swg Normal file
View file

@ -0,0 +1,77 @@
/* -----------------------------------------------------------------------------
* doperators.swg
*
* Mapping of C++ operator overloading methods to D.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
#if (SWIG_D_VERSION == 1)
%rename(opAdd) *::operator+;
%rename(opPos) *::operator+();
%rename(opAddAssign) *::operator+=;
%rename(opSub) *::operator-;
%rename(opNeg) *::operator-();
%rename(opSubAssign) *::operator-=;
%rename(opMul) *::operator*;
%rename(opMulAssign) *::operator*=;
%rename(opDiv) *::operator/;
%rename(opDivAssign) *::operator/=;
%rename(opMod) *::operator%;
%rename(opModAssign) *::operator%=;
%rename(opCom) *::operator~();
%rename(opAnd) *::operator&;
%rename(opAndAssign) *::operator&=;
%rename(opOr) *::operator|;
%rename(opOrAssign) *::operator|=;
%rename(opXor) *::operator^;
%rename(opXorAssign) *::operator^=;
%rename(opShl) *::operator<<;
%rename(opShlAssign) *::operator<<=;
%rename(opShr) *::operator>>;
%rename(opShrAssign) *::operator>>=;
%rename(opIndex) *::operator[](unsigned) const;
%rename(opIndexAssign) *::operator[](unsigned);
%rename(opCall) *::operator();
// !a is not overrideable in D1.
%ignoreoperator(LNOT) operator!;
// a != b is rewritten as !a.opEquals(b) in D.
// For now, just ignore both of them, since there would be quite a bit of magic
// needed to correctly generate a wrapper method for non-primitives types (there is
// only one opEquals overload with an Object parameter in D).
%ignoreoperator(EQ) operator==;
%ignoreoperator(NOTEQUAL) operator!=;
// opCmp is used in D.
%ignoreoperator(LT) operator<;
%ignoreoperator(LTEQUAL) operator<=;
%ignoreoperator(GT) operator>;
%ignoreoperator(GTEQUAL) operator>=;
// The logic operators are not overrideable in D.
%ignoreoperator(LAND) operator&&;
%ignoreoperator(LOR) operator||;
// ++/--a is rewritten as a +/-= 1 in D.
%ignoreoperator(PLUSPLUS) operator++();
%ignoreoperator(MINUSMINUS) operator--();
%ignoreoperator(PLUSPLUS) operator++(int);
%ignoreoperator(MINUSMINUS) operator--(int);
// The C++ assignment operator does not translate well to D where custom types
// have reference semantics.
%ignoreoperator(EQ) operator=;
#else
// Operator overloading works completely different in D2, proper support will
// probably need fairly extensive code generation support.
#endif
#endif

158
Lib/d/dprimitives.swg Normal file
View file

@ -0,0 +1,158 @@
/* -----------------------------------------------------------------------------
* dprimitves.swg
*
* Typemaps for primitive types.
* ----------------------------------------------------------------------------- */
/*
* The SWIG_D_PRIMITIVE macro is used to define the typemaps for the primitive
* types, because are more or less the same for all of them. The few special
* cases are handeled below.
*/
%define SWIG_D_PRIMITIVE(TYPE, DTYPE)
%typemap(cwtype) TYPE, const TYPE & "TYPE"
%typemap(dwtype) TYPE, const TYPE & "DTYPE"
%typemap(dptype, cprimitive="1") TYPE, const TYPE & "DTYPE"
%typemap(in) TYPE "$1 = ($1_ltype)$input;"
%typemap(out) TYPE "$result = $1;"
%typemap(directorin) TYPE "$input = $1;"
%typemap(directorout) TYPE "$result = ($1_ltype)$input;"
%typemap(ddirectorin) TYPE "$winput"
%typemap(ddirectorout) TYPE "$dpcall"
%typemap(in) const TYPE & ($*1_ltype temp)
%{ temp = ($*1_ltype)$input;
$1 = &temp; %}
%typemap(out) const TYPE & "$result = *$1;"
%typemap(directorin) const TYPE & "$input = $1_name;"
%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const TYPE &
%{ static $*1_ltype temp;
temp = ($*1_ltype)$input;
$result = &temp; %}
%typemap(ddirectorin) const TYPE & "$winput"
%typemap(ddirectorout) const TYPE & "$dpcall"
%typemap(din) TYPE, const TYPE & "$dinput"
%typemap(dout, excode=SWIGEXCODE) TYPE, const TYPE & {
auto ret = $wcall;$excode
return ret;
}
%enddef
SWIG_D_PRIMITIVE(bool, bool)
SWIG_D_PRIMITIVE(char, char)
SWIG_D_PRIMITIVE(signed char, byte)
SWIG_D_PRIMITIVE(unsigned char, ubyte)
SWIG_D_PRIMITIVE(short, short)
SWIG_D_PRIMITIVE(unsigned short, ushort)
SWIG_D_PRIMITIVE(int, int)
SWIG_D_PRIMITIVE(unsigned int, uint)
SWIG_D_PRIMITIVE(long, int)
SWIG_D_PRIMITIVE(unsigned long, uint)
SWIG_D_PRIMITIVE(size_t, size_t)
SWIG_D_PRIMITIVE(long long, long)
SWIG_D_PRIMITIVE(unsigned long long, ulong)
SWIG_D_PRIMITIVE(float, float)
SWIG_D_PRIMITIVE(double, double)
// The C++ boolean type needs some special casing since it is not part of the
// C standard and is thus represented as unsigned int in the C wrapper layer.
%typemap(cwtype) bool, const bool & "unsigned int"
%typemap(dwtype) bool, const bool & "uint"
%typemap(in) bool "$1 = $input ? true : false;"
%typemap(in) const bool & ($*1_ltype temp)
%{ temp = $input ? true : false;
$1 = &temp; %}
%typemap(directorout) bool
"$result = $input ? true : false;"
%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const bool &
%{ static $*1_ltype temp;
temp = $input ? true : false;
$result = &temp; %}
%typemap(ddirectorin) bool "($winput ? true : false)"
%typemap(dout, excode=SWIGEXCODE) bool, const bool & {
bool ret = $wcall ? true : false;$excode
return ret;
}
// Judging from the history of the C# module, the explicit casts are needed for
// certain versions of VC++.
%typemap(out) unsigned long "$result = (unsigned long)$1;"
%typemap(out) const unsigned long & "$result = (unsigned long)*$1;"
/*
* Typecheck typemaps.
*/
%typecheck(SWIG_TYPECHECK_BOOL)
bool,
const bool &
""
%typecheck(SWIG_TYPECHECK_CHAR)
char,
const char &
""
%typecheck(SWIG_TYPECHECK_INT8)
signed char,
const signed char &
""
%typecheck(SWIG_TYPECHECK_UINT8)
unsigned char,
const unsigned char &
""
%typecheck(SWIG_TYPECHECK_INT16)
short,
const short &
""
%typecheck(SWIG_TYPECHECK_UINT16)
unsigned short,
const unsigned short &
""
%typecheck(SWIG_TYPECHECK_INT32)
int,
long,
const int &,
const long &
""
%typecheck(SWIG_TYPECHECK_UINT32)
unsigned int,
unsigned long,
const unsigned int &,
const unsigned long &
""
%typecheck(SWIG_TYPECHECK_INT64)
long long,
const long long &
""
%typecheck(SWIG_TYPECHECK_UINT64)
unsigned long long,
const unsigned long long &
""
%typecheck(SWIG_TYPECHECK_FLOAT)
float,
const float &
""
%typecheck(SWIG_TYPECHECK_DOUBLE)
double,
const double &
""

80
Lib/d/dstrings.swg Normal file
View file

@ -0,0 +1,80 @@
/* -----------------------------------------------------------------------------
* dstrings.swg
*
* Typemaps for wrapping pointers to/arrays of C chars as D strings.
* ----------------------------------------------------------------------------- */
%define SWIGD_STRING_TYPEMAPS(DW_STRING_TYPE, DP_STRING_TYPE, FROM_STRINGZ, TO_STRINGZ)
%typemap(cwtype) char *, char *&, char[ANY], char[] "char *"
%typemap(dwtype) char *, char *&, char[ANY], char[] #DW_STRING_TYPE
%typemap(dptype) char *, char *&, char[ANY], char[] #DP_STRING_TYPE
/*
* char* typemaps.
*/
%typemap(in) char * %{ $1 = ($1_ltype)$input; %}
%typemap(out) char * %{ $result = SWIG_d_string_callback((const char *)$1); %}
%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) char * %{ $result = ($1_ltype)$input; %}
%typemap(directorin) char * %{ $input = SWIG_d_string_callback((const char *)$1); %}
%typemap(ddirectorin) char * "FROM_STRINGZ($winput)"
%typemap(ddirectorout) char * "TO_STRINGZ($dpcall)"
/*
* char*& typemaps.
*/
%typemap(in) char *& ($*1_ltype temp = 0) %{
temp = ($*1_ltype)$input;
$1 = &temp;
%}
%typemap(out) char *& %{ if ($1) $result = SWIG_d_string_callback((const char *)*$1); %}
/*
* char array typemaps.
*/
%typemap(in) char[ANY], char[] %{ $1 = ($1_ltype)$input; %}
%typemap(out) char[ANY], char[] %{ $result = SWIG_d_string_callback((const char *)$1); %}
%typemap(directorout) char[ANY], char[] %{ $result = ($1_ltype)$input; %}
%typemap(directorin) char[ANY], char[] %{ $input = SWIG_d_string_callback((const char *)$1); %}
%typemap(ddirectorin) char[ANY], char[] "$winput"
%typemap(ddirectorout) char[ANY], char[] "$dpcall"
%typemap(din) char *, char *&, char[ANY], char[] "($dinput ? TO_STRINGZ($dinput) : null)"
%typemap(dout, excode=SWIGEXCODE) char *, char *&, char[ANY], char[] {
DP_STRING_TYPE ret = FROM_STRINGZ ## ($wcall);$excode
return ret;
}
%typecheck(SWIG_TYPECHECK_STRING)
char *,
char *&,
char[ANY],
char[]
""
%enddef
// We need to have the \0-terminated string conversion functions available in
// the D proxy modules.
#if (SWIG_D_VERSION == 1)
// Could be easily extended to support Phobos as well.
SWIGD_STRING_TYPEMAPS(char*, char[], tango.stdc.stringz.fromStringz, tango.stdc.stringz.toStringz)
%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
#else
SWIGD_STRING_TYPEMAPS(const(char)*, string, std.conv.to!string, std.string.toStringz)
%pragma(d) globalproxyimports = %{
static import std.conv;
static import std.string;
%}
#endif
#undef SWIGD_STRING_TYPEMAPS

177
Lib/d/dswigtype.swg Normal file
View file

@ -0,0 +1,177 @@
/* -----------------------------------------------------------------------------
* dswigtype.swg
*
* Typemaps for non-primitive types (C/C++ classes and structs).
* ----------------------------------------------------------------------------- */
%typemap(cwtype) SWIGTYPE "void *"
%typemap(dwtype) SWIGTYPE "void*"
%typemap(dptype) SWIGTYPE "$&dclassname"
%typemap(cwtype) SWIGTYPE [] "void *"
%typemap(dwtype) SWIGTYPE [] "void*"
%typemap(dptype) SWIGTYPE [] "$dclassname"
%typemap(cwtype) SWIGTYPE * "void *"
%typemap(dwtype) SWIGTYPE * "void*"
%typemap(dptype, nativepointer="$dptype") SWIGTYPE * "$dclassname"
%typemap(cwtype) SWIGTYPE & "void *"
%typemap(dwtype) SWIGTYPE & "void*"
%typemap(dptype) SWIGTYPE & "$dclassname"
%typemap(cwtype) SWIGTYPE *const& "void *"
%typemap(dwtype) SWIGTYPE *const& "void*"
%typemap(dptype) SWIGTYPE *const& "$*dclassname"
%typecheck(SWIG_TYPECHECK_POINTER)
SWIGTYPE,
SWIGTYPE *,
SWIGTYPE &,
SWIGTYPE [],
SWIGTYPE *const&
""
/*
* By-value conversion typemaps (parameter is converted to a pointer).
*/
%typemap(in, canthrow=1) SWIGTYPE ($&1_type argp)
%{ argp = ($&1_ltype)$input;
if (!argp) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Attempt to dereference null $1_type");
return $null;
}
$1 = *argp; %}
%typemap(out) SWIGTYPE
#ifdef __cplusplus
%{ $result = new $1_ltype((const $1_ltype &)$1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
memmove($1ptr, &$1, sizeof($1_type));
$result = $1ptr;
}
#endif
%typemap(directorin) SWIGTYPE
"$input = (void *)&$1;"
%typemap(directorout) SWIGTYPE
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
return $null;
}
$result = *($&1_ltype)$input; %}
%typemap(ddirectorin) SWIGTYPE "new $&dclassname($winput, false)"
%typemap(ddirectorout) SWIGTYPE "$&dclassname.swigGetCPtr($dpcall)"
%typemap(din) SWIGTYPE "$&dclassname.swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIGTYPE {
$&dclassname ret = new $&dclassname($wcall, true);$excode
return ret;
}
/*
* Pointer conversion typemaps.
*/
%typemap(in) SWIGTYPE * "$1 = ($1_ltype)$input;"
%typemap(out) SWIGTYPE * "$result = (void *)$1;"
%typemap(directorin) SWIGTYPE *
"$input = (void *) $1;"
%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *
"$result = ($1_ltype)$input;"
%typemap(ddirectorin,
nativepointer="cast($dptype)$winput"
) SWIGTYPE * "($winput is null) ? null : new $dclassname($winput, false)"
%typemap(ddirectorout,
nativepointer="cast(void*)$dpcall"
) SWIGTYPE * "$dclassname.swigGetCPtr($dpcall)"
%typemap(din,
nativepointer="cast(void*)$dinput"
) SWIGTYPE * "$dclassname.swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE,
nativepointer="{\n auto ret = cast($dptype)$wcall;$excode\n return ret;\n}"
) SWIGTYPE * {
void* cPtr = $wcall;
$dclassname ret = (cPtr is null) ? null : new $dclassname(cPtr, $owner);$excode
return ret;
}
// Use the same typemaps for const pointers.
%apply SWIGTYPE * { SWIGTYPE *const }
/*
* Reference conversion typemaps.
*/
%typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
if (!$1) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null");
return $null;
} %}
%typemap(out) SWIGTYPE & "$result = (void *)$1;"
%typemap(directorin) SWIGTYPE &
"$input = ($1_ltype) &$1;"
%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
return $null;
}
$result = ($1_ltype)$input; %}
%typemap(ddirectorin) SWIGTYPE & "new $dclassname($winput, false)"
%typemap(ddirectorout) SWIGTYPE & "$dclassname.swigGetCPtr($dpcall)"
%typemap(din) SWIGTYPE & "$dclassname.swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIGTYPE & {
$dclassname ret = new $dclassname($wcall, $owner);$excode
return ret;
}
/*
* Array conversion typemaps.
*/
%typemap(in) SWIGTYPE [] %{ $1 = ($1_ltype)$input; %}
%typemap(out) SWIGTYPE [] %{ $result = $1; %}
%typemap(din) SWIGTYPE [] "$dclassname.swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIGTYPE [] {
void* cPtr = $wcall;
$dclassname ret = (cPtr is null) ? null : new $dclassname(cPtr, $owner);$excode
return ret;
}
// Treat references to arrays like like references to a single element.
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
/*
* Pointer reference conversion typemaps.
*/
%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0)
%{ temp = ($*1_ltype)$input;
$1 = ($1_ltype)&temp; %}
%typemap(out) SWIGTYPE *const&
%{ $result = (void *)*$1; %}
%typemap(din) SWIGTYPE *const& "$*dclassname.swigGetCPtr($dinput)"
%typemap(dout, excode=SWIGEXCODE) SWIGTYPE *const& {
void* cPtr = $wcall;
$*dclassname ret = (cPtr is null) ? null : new $*dclassname(cPtr, $owner);$excode
return ret;
}

18
Lib/d/dvoid.swg Normal file
View file

@ -0,0 +1,18 @@
/* -----------------------------------------------------------------------------
* dvoid.swg
*
* Typemaps for handling void function return types and empty parameter lists.
* ----------------------------------------------------------------------------- */
%typemap(cwtype) void "void"
%typemap(dwtype) void "void"
%typemap(dptype, cprimitive="1") void "void"
%typemap(out, null="") void ""
%typemap(ddirectorin) void "$winput"
%typemap(ddirectorout) void "$dpcall"
%typemap(directorin) void ""
%typemap(dout, excode=SWIGEXCODE) void {
$wcall;$excode
}

5
Lib/d/std_common.i Normal file
View file

@ -0,0 +1,5 @@
%include <std_except.i>
%apply size_t { std::size_t };
%apply const size_t& { const std::size_t& };

1
Lib/d/std_deque.i Normal file
View file

@ -0,0 +1 @@
%include <std/_std_deque.i>

30
Lib/d/std_except.i Normal file
View file

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
* std_except.i
*
* Typemaps used by the STL wrappers that throw exceptions. These typemaps are
* used when methods are declared with an STL exception specification, such as
* size_t at() const throw (std::out_of_range);
* ----------------------------------------------------------------------------- */
%{
#include <stdexcept>
%}
namespace std
{
%ignore exception;
struct exception {};
}
%typemap(throws, canthrow=1) std::bad_exception "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::domain_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::exception "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::invalid_argument "SWIG_DSetPendingException(SWIG_DIllegalArgumentException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::length_error "SWIG_DSetPendingException(SWIG_DNoSuchElementException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::logic_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::out_of_range "SWIG_DSetPendingException(SWIG_DNoSuchElementException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::overflow_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::range_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::runtime_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"
%typemap(throws, canthrow=1) std::underflow_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;"

59
Lib/d/std_map.i Normal file
View file

@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------------
* std_map.i
*
* SWIG typemaps for std::map
* ----------------------------------------------------------------------------- */
%include <std_common.i>
// ------------------------------------------------------------------------
// std::map
// ------------------------------------------------------------------------
%{
#include <map>
#include <algorithm>
#include <stdexcept>
%}
// exported class
namespace std {
template<class K, class T> class map {
// add typemaps here
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef K key_type;
typedef T mapped_type;
map();
map(const map<K,T> &);
unsigned int size() const;
bool empty() const;
void clear();
%extend {
const T& get(const K& key) throw (std::out_of_range) {
std::map<K,T >::iterator i = self->find(key);
if (i != self->end())
return i->second;
else
throw std::out_of_range("key not found");
}
void set(const K& key, const T& x) {
(*self)[key] = x;
}
void del(const K& key) throw (std::out_of_range) {
std::map<K,T >::iterator i = self->find(key);
if (i != self->end())
self->erase(i);
else
throw std::out_of_range("key not found");
}
bool has_key(const K& key) {
std::map<K,T >::iterator i = self->find(key);
return i != self->end();
}
}
};
}

34
Lib/d/std_pair.i Normal file
View file

@ -0,0 +1,34 @@
/* -----------------------------------------------------------------------------
* std_pair.i
*
* SWIG typemaps for std::pair
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%include <exception.i>
// ------------------------------------------------------------------------
// std::pair
// ------------------------------------------------------------------------
%{
#include <utility>
%}
namespace std {
template<class T, class U> struct pair {
pair();
pair(T t, U u);
pair(const pair& p);
template <class U1, class U2> pair(const pair<U1, U2> &p);
T first;
U second;
};
// add specializations here
}

2
Lib/d/std_shared_ptr.i Normal file
View file

@ -0,0 +1,2 @@
#define SWIG_SHARED_PTR_NAMESPACE std
%include <boost_shared_ptr.i>

98
Lib/d/std_string.i Normal file
View file

@ -0,0 +1,98 @@
/* -----------------------------------------------------------------------------
* std_string.i
*
* Typemaps for std::string and const std::string&
* These are mapped to a D char[] and are passed around by value.
*
* To use non-const std::string references, use the following %apply. Note
* that they are passed by value.
* %apply const std::string & {std::string &};
* ----------------------------------------------------------------------------- */
%{
#include <string>
%}
namespace std {
%naturalvar string;
class string;
%define SWIGD_STD_STRING_TYPEMAPS(DW_STRING_TYPE, DP_STRING_TYPE, FROM_STRINGZ, TO_STRINGZ)
// string
%typemap(cwtype) string, const string & "char *"
%typemap(dwtype) string, const string & #DW_STRING_TYPE
%typemap(dptype) string, const string & #DP_STRING_TYPE
%typemap(in, canthrow=1) string, const string &
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "null string");
return $null;
}
$1.assign($input); %}
%typemap(in, canthrow=1) const string &
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "null string");
return $null;
}
std::string $1_str($input);
$1 = &$1_str; %}
%typemap(out) string %{ $result = SWIG_d_string_callback($1.c_str()); %}
%typemap(out) const string & %{ $result = SWIG_d_string_callback($1->c_str()); %}
%typemap(din) string, const string & "($dinput ? TO_STRINGZ($dinput) : null)"
%typemap(dout, excode=SWIGEXCODE) string, const string & {
DP_STRING_TYPE ret = FROM_STRINGZ($wcall);$excode
return ret;
}
%typemap(directorin) string, const string & %{ $input = SWIG_d_string_callback($1.c_str()); %}
%typemap(directorout, canthrow=1) string
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "null string");
return $null;
}
$result.assign($input); %}
%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string &
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "null string");
return $null;
}
/* possible thread/reentrant code problem */
static std::string $1_str;
$1_str = $input;
$result = &$1_str; %}
%typemap(ddirectorin) string, const string & "FROM_STRINGZ($winput)"
%typemap(ddirectorout) string, const string & "TO_STRINGZ($dpcall)"
%typemap(throws, canthrow=1) string, const string &
%{ SWIG_DSetPendingException(SWIG_DException, $1.c_str());
return $null; %}
%typemap(typecheck) string, const string & = char *;
%enddef
// We need to have the \0-terminated string conversion functions available in
// the D proxy modules.
#if (SWIG_D_VERSION == 1)
// Could be easily extended to support Phobos as well.
SWIGD_STD_STRING_TYPEMAPS(char*, char[], tango.stdc.stringz.fromStringz, tango.stdc.stringz.toStringz)
%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
#else
SWIGD_STD_STRING_TYPEMAPS(const(char)*, string, std.conv.to!string, std.string.toStringz)
%pragma(d) globalproxyimports = %{
static import std.conv;
static import std.string;
%}
#endif
#undef SWIGD_STD_STRING_TYPEMAPS
} // namespace std

591
Lib/d/std_vector.i Normal file
View file

@ -0,0 +1,591 @@
/* -----------------------------------------------------------------------------
* std_vector.i
*
* SWIG typemaps for std::vector<T>, D implementation.
*
* The D wrapper is made to loosely resemble a tango.util.container.more.Vector
* and to provide built-in array-like access.
*
* If T does define an operator==, then use the SWIG_STD_VECTOR_ENHANCED
* macro to obtain enhanced functionality (none yet), for example:
*
* SWIG_STD_VECTOR_ENHANCED(SomeNamespace::Klass)
* %template(VectKlass) std::vector<SomeNamespace::Klass>;
*
* Warning: heavy macro usage in this file. Use swig -E to get a sane view on
* the real file contents!
* ----------------------------------------------------------------------------- */
// Warning: Use the typemaps here in the expectation that the macros they are in will change name.
%include <std_common.i>
// MACRO for use within the std::vector class body
%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CONST_REFERENCE, CWTYPE...)
#if (SWIG_D_VERSION == 1)
%typemap(dimports) std::vector< CWTYPE > "static import tango.core.Exception;"
%typemap(dcode) std::vector< CWTYPE > %{
public this($typemap(dptype, CWTYPE)[] values) {
this();
append(values);
}
alias push_back add;
alias push_back push;
alias push_back opCatAssign;
alias size length;
alias opSlice slice;
public $typemap(dptype, CWTYPE) opIndexAssign($typemap(dptype, CWTYPE) value, size_t index) {
if (index >= size()) {
throw new tango.core.Exception.NoSuchElementException("Tried to assign to element out of vector bounds.");
}
setElement(index, value);
return value;
}
public $typemap(dptype, CWTYPE) opIndex(size_t index) {
if (index >= size()) {
throw new tango.core.Exception.NoSuchElementException("Tried to read from element out of vector bounds.");
}
return getElement(index);
}
public void append($typemap(dptype, CWTYPE)[] value...) {
foreach (v; value) {
add(v);
}
}
public $typemap(dptype, CWTYPE)[] opSlice() {
$typemap(dptype, CWTYPE)[] array = new $typemap(dptype, CWTYPE)[size()];
foreach (i, ref value; array) {
value = getElement(i);
}
return array;
}
public int opApply(int delegate(ref $typemap(dptype, CWTYPE) value) dg) {
int result;
size_t currentSize = size();
for (size_t i = 0; i < currentSize; ++i) {
auto value = getElement(i);
result = dg(value);
setElement(i, value);
}
return result;
}
public int opApply(int delegate(ref size_t index, ref $typemap(dptype, CWTYPE) value) dg) {
int result;
size_t currentSize = size();
for (size_t i = 0; i < currentSize; ++i) {
auto value = getElement(i);
// Workaround for http://d.puremagic.com/issues/show_bug.cgi?id=2443.
auto index = i;
result = dg(index, value);
setElement(i, value);
}
return result;
}
public void capacity(size_t value) {
if (value < size()) {
throw new tango.core.Exception.IllegalArgumentException("Tried to make the capacity of a vector smaller than its size.");
}
reserve(value);
}
%}
public:
typedef size_t size_type;
typedef CWTYPE value_type;
typedef CONST_REFERENCE const_reference;
void clear();
void push_back(CWTYPE const& x);
size_type size() const;
size_type capacity() const;
void reserve(size_type n) throw (std::length_error);
vector();
vector(const vector &other);
%extend {
vector(size_type capacity) throw (std::length_error) {
std::vector< CWTYPE >* pv = 0;
pv = new std::vector< CWTYPE >();
// Might throw std::length_error.
pv->reserve(capacity);
return pv;
}
size_type unused() const {
return $self->capacity() - $self->size();
}
const_reference remove() throw (std::out_of_range) {
if ($self->empty()) {
throw std::out_of_range("Tried to remove last element from empty vector.");
}
std::vector< CWTYPE >::const_reference value = $self->back();
$self->pop_back();
return value;
}
const_reference remove(size_type index) throw (std::out_of_range) {
if (index >= $self->size()) {
throw std::out_of_range("Tried to remove element with invalid index.");
}
std::vector< CWTYPE >::iterator it = $self->begin() + index;
std::vector< CWTYPE >::const_reference value = *it;
$self->erase(it);
return value;
}
}
// Wrappers for setting/getting items with the possibly thrown exception
// specified (important for SWIG wrapper generation).
%extend {
const_reference getElement(size_type index) throw (std::out_of_range) {
if ((index < 0) || ($self->size() <= index)) {
throw std::out_of_range("Tried to get value of element with invalid index.");
}
return (*$self)[index];
}
}
// Use CWTYPE const& instead of const_reference to work around SWIG code
// generation issue when using const pointers as vector elements (like
// std::vector< const int* >).
%extend {
void setElement(size_type index, CWTYPE const& val) throw (std::out_of_range) {
if ((index < 0) || ($self->size() <= index)) {
throw std::out_of_range("Tried to set value of element with invalid index.");
}
(*$self)[index] = val;
}
}
%dmethodmodifiers std::vector::getElement "private"
%dmethodmodifiers std::vector::setElement "private"
%dmethodmodifiers std::vector::reserve "private"
#else
%typemap(dimports) std::vector< CWTYPE > %{
static import std.algorithm;
static import std.exception;
static import std.range;
static import std.traits;
%}
%typemap(dcode) std::vector< CWTYPE > %{
alias size_t KeyType;
alias $typemap(dptype, CWTYPE) ValueType;
this(ValueType[] values...) {
this();
reserve(values.length);
foreach (e; values) {
this ~= e;
}
}
struct Range {
private $typemap(dptype, std::vector< CWTYPE >) _outer;
private size_t _a, _b;
this($typemap(dptype, std::vector< CWTYPE >) data, size_t a, size_t b) {
_outer = data;
_a = a;
_b = b;
}
@property bool empty() const {
assert((cast($typemap(dptype, std::vector< CWTYPE >))_outer).length >= _b);
return _a >= _b;
}
@property Range save() {
return this;
}
@property ValueType front() {
std.exception.enforce(!empty);
return _outer[_a];
}
@property void front(ValueType value) {
std.exception.enforce(!empty);
_outer[_a] = std.algorithm.move(value);
}
void popFront() {
std.exception.enforce(!empty);
++_a;
}
void opIndexAssign(ValueType value, size_t i) {
i += _a;
std.exception.enforce(i < _b && _b <= _outer.length);
_outer[i] = value;
}
void opIndexOpAssign(string op)(ValueType value, size_t i) {
std.exception.enforce(_outer && _a + i < _b && _b <= _outer.length);
auto element = _outer[i];
mixin("element "~op~"= value;");
_outer[i] = element;
}
}
// TODO: dup?
Range opSlice() {
return Range(this, 0, length);
}
Range opSlice(size_t a, size_t b) {
std.exception.enforce(a <= b && b <= length);
return Range(this, a, b);
}
size_t opDollar() const {
return length;
}
@property ValueType front() {
std.exception.enforce(!empty);
return getElement(0);
}
@property void front(ValueType value) {
std.exception.enforce(!empty);
setElement(0, value);
}
@property ValueType back() {
std.exception.enforce(!empty);
return getElement(length - 1);
}
@property void back(ValueType value) {
std.exception.enforce(!empty);
setElement(length - 1, value);
}
ValueType opIndex(size_t i) {
return getElement(i);
}
void opIndexAssign(ValueType value, size_t i) {
setElement(i, value);
}
void opIndexOpAssign(string op)(ValueType value, size_t i) {
auto element = this[i];
mixin("element "~op~"= value;");
this[i] = element;
}
ValueType[] opBinary(string op, Stuff)(Stuff stuff) if (op == "~") {
ValueType[] result;
result ~= this[];
assert(result.length == length);
result ~= stuff[];
return result;
}
void opOpAssign(string op, Stuff)(Stuff stuff) if (op == "~") {
static if (is(typeof(insertBack(stuff)))) {
insertBack(stuff);
} else if (is(typeof(insertBack(stuff[])))) {
insertBack(stuff[]);
} else {
static assert(false, "Cannot append " ~ Stuff.stringof ~ " to " ~ typeof(this).stringof);
}
}
alias size length;
alias remove removeAny;
alias removeAny stableRemoveAny;
size_t insertBack(Stuff)(Stuff stuff)
if (std.traits.isImplicitlyConvertible!(Stuff, ValueType)){
push_back(stuff);
return 1;
}
size_t insertBack(Stuff)(Stuff stuff)
if (std.range.isInputRange!Stuff &&
std.traits.isImplicitlyConvertible!(std.range.ElementType!Stuff, ValueType)) {
size_t itemCount;
foreach(item; stuff) {
insertBack(item);
++itemCount;
}
return itemCount;
}
alias insertBack insert;
alias pop_back removeBack;
alias pop_back stableRemoveBack;
size_t insertBefore(Stuff)(Range r, Stuff stuff)
if (std.traits.isImplicitlyConvertible!(Stuff, ValueType)) {
std.exception.enforce(r._outer.swigCPtr == swigCPtr && r._a < length);
insertAt(r._a, stuff);
return 1;
}
size_t insertBefore(Stuff)(Range r, Stuff stuff)
if (std.range.isInputRange!Stuff && std.traits.isImplicitlyConvertible!(ElementType!Stuff, ValueType)) {
std.exception.enforce(r._outer.swigCPtr == swigCPtr && r._a <= length);
size_t insertCount;
foreach(i, item; stuff) {
insertAt(r._a + i, item);
++insertCount;
}
return insertCount;
}
size_t insertAfter(Stuff)(Range r, Stuff stuff) {
// TODO: optimize
immutable offset = r._a + r.length;
std.exception.enforce(offset <= length);
auto result = insertBack(stuff);
std.algorithm.bringToFront(this[offset .. length - result],
this[length - result .. length]);
return result;
}
size_t replace(Stuff)(Range r, Stuff stuff)
if (std.range.isInputRange!Stuff &&
std.traits.isImplicitlyConvertible!(ElementType!Stuff, ValueType)) {
immutable offset = r._a;
std.exception.enforce(offset <= length);
size_t result;
for (; !stuff.empty; stuff.popFront()) {
if (r.empty) {
// append the rest
return result + insertBack(stuff);
}
r.front = stuff.front;
r.popFront();
++result;
}
// Remove remaining stuff in r
remove(r);
return result;
}
size_t replace(Stuff)(Range r, Stuff stuff)
if (std.traits.isImplicitlyConvertible!(Stuff, ValueType))
{
if (r.empty)
{
insertBefore(r, stuff);
}
else
{
r.front = stuff;
r.popFront();
remove(r);
}
return 1;
}
Range linearRemove(Range r) {
std.exception.enforce(r._a <= r._b && r._b <= length);
immutable tailLength = length - r._b;
linearRemove(r._a, r._b);
return this[length - tailLength .. length];
}
alias remove stableLinearRemove;
int opApply(int delegate(ref $typemap(dptype, CWTYPE) value) dg) {
int result;
size_t currentSize = size();
for (size_t i = 0; i < currentSize; ++i) {
auto value = getElement(i);
result = dg(value);
setElement(i, value);
}
return result;
}
int opApply(int delegate(ref size_t index, ref $typemap(dptype, CWTYPE) value) dg) {
int result;
size_t currentSize = size();
for (size_t i = 0; i < currentSize; ++i) {
auto value = getElement(i);
// Workaround for http://d.puremagic.com/issues/show_bug.cgi?id=2443.
auto index = i;
result = dg(index, value);
setElement(i, value);
}
return result;
}
%}
public:
typedef size_t size_type;
typedef CWTYPE value_type;
typedef CONST_REFERENCE const_reference;
bool empty() const;
void clear();
void push_back(CWTYPE const& x);
void pop_back();
size_type size() const;
size_type capacity() const;
void reserve(size_type n) throw (std::length_error);
vector();
vector(const vector &other);
%extend {
vector(size_type capacity) throw (std::length_error) {
std::vector< CWTYPE >* pv = 0;
pv = new std::vector< CWTYPE >();
// Might throw std::length_error.
pv->reserve(capacity);
return pv;
}
const_reference remove() throw (std::out_of_range) {
if ($self->empty()) {
throw std::out_of_range("Tried to remove last element from empty vector.");
}
std::vector< CWTYPE >::const_reference value = $self->back();
$self->pop_back();
return value;
}
const_reference remove(size_type index) throw (std::out_of_range) {
if (index >= $self->size()) {
throw std::out_of_range("Tried to remove element with invalid index.");
}
std::vector< CWTYPE >::iterator it = $self->begin() + index;
std::vector< CWTYPE >::const_reference value = *it;
$self->erase(it);
return value;
}
void removeBack(size_type how_many) throw (std::out_of_range) {
std::vector< CWTYPE >::iterator end = $self->end();
std::vector< CWTYPE >::iterator start = end - how_many;
$self->erase(start, end);
}
void linearRemove(size_type start_index, size_type end_index) throw (std::out_of_range) {
std::vector< CWTYPE >::iterator start = $self->begin() + start_index;
std::vector< CWTYPE >::iterator end = $self->begin() + end_index;
$self->erase(start, end);
}
void insertAt(size_type index, CWTYPE const& x) throw (std::out_of_range) {
std::vector< CWTYPE >::iterator it = $self->begin() + index;
$self->insert(it, x);
}
}
// Wrappers for setting/getting items with the possibly thrown exception
// specified (important for SWIG wrapper generation).
%extend {
const_reference getElement(size_type index) throw (std::out_of_range) {
if ((index < 0) || ($self->size() <= index)) {
throw std::out_of_range("Tried to get value of element with invalid index.");
}
return (*$self)[index];
}
}
// Use CWTYPE const& instead of const_reference to work around SWIG code
// generation issue when using const pointers as vector elements (like
// std::vector< const int* >).
%extend {
void setElement(size_type index, CWTYPE const& val) throw (std::out_of_range) {
if ((index < 0) || ($self->size() <= index)) {
throw std::out_of_range("Tried to set value of element with invalid index.");
}
(*$self)[index] = val;
}
}
%dmethodmodifiers std::vector::getElement "private"
%dmethodmodifiers std::vector::setElement "private"
#endif
%enddef
// Extra methods added to the collection class if operator== is defined for the class being wrapped
// The class will then implement IList<>, which adds extra functionality
%define SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CWTYPE...)
%extend {
}
%enddef
// For vararg handling in macros, from swigmacros.swg
#define %arg(X...) X
// Macros for std::vector class specializations/enhancements
%define SWIG_STD_VECTOR_ENHANCED(CWTYPE...)
namespace std {
template<> class vector<CWTYPE > {
SWIG_STD_VECTOR_MINIMUM_INTERNAL(%arg(CWTYPE const&), %arg(CWTYPE))
SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(CWTYPE)
};
}
%enddef
%{
#include <vector>
#include <stdexcept>
%}
namespace std {
// primary (unspecialized) class template for std::vector
// does not require operator== to be defined
template<class T> class vector {
SWIG_STD_VECTOR_MINIMUM_INTERNAL(T const&, T)
};
// specializations for pointers
template<class T> class vector<T *> {
SWIG_STD_VECTOR_MINIMUM_INTERNAL(T *const&, T *)
SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(T *)
};
// bool is a bit different in the C++ standard - const_reference in particular
template<> class vector<bool> {
SWIG_STD_VECTOR_MINIMUM_INTERNAL(bool, bool)
SWIG_STD_VECTOR_EXTRA_OP_EQUALS_EQUALS(bool)
};
}
// template specializations for std::vector
// these provide extra collections methods as operator== is defined
SWIG_STD_VECTOR_ENHANCED(char)
SWIG_STD_VECTOR_ENHANCED(signed char)
SWIG_STD_VECTOR_ENHANCED(unsigned char)
SWIG_STD_VECTOR_ENHANCED(short)
SWIG_STD_VECTOR_ENHANCED(unsigned short)
SWIG_STD_VECTOR_ENHANCED(int)
SWIG_STD_VECTOR_ENHANCED(unsigned int)
SWIG_STD_VECTOR_ENHANCED(long)
SWIG_STD_VECTOR_ENHANCED(unsigned long)
SWIG_STD_VECTOR_ENHANCED(long long)
SWIG_STD_VECTOR_ENHANCED(unsigned long long)
SWIG_STD_VECTOR_ENHANCED(float)
SWIG_STD_VECTOR_ENHANCED(double)
SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>

12
Lib/d/stl.i Normal file
View file

@ -0,0 +1,12 @@
/* -----------------------------------------------------------------------------
* stl.i
*
* Initial STL definition. extended as needed in each language
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%include <std_string.i>
%include <std_vector.i>
%include <std_map.i>
%include <std_pair.i>

298
Lib/d/typemaps.i Normal file
View file

@ -0,0 +1,298 @@
/* -----------------------------------------------------------------------------
* typemaps.i
*
* Pointer and reference handling typemap library
*
* These mappings provide support for input/output arguments and common
* uses for C/C++ pointers and C++ references.
* ----------------------------------------------------------------------------- */
/*
INPUT typemaps
--------------
These typemaps are used for pointer/reference parameters that are input only
and are mapped to a D input parameter.
The following typemaps can be applied to turn a pointer or reference into a simple
input value. That is, instead of passing a pointer or reference to an object,
you would use a real value instead.
bool *INPUT, bool &INPUT
signed char *INPUT, signed char &INPUT
unsigned char *INPUT, unsigned char &INPUT
short *INPUT, short &INPUT
unsigned short *INPUT, unsigned short &INPUT
int *INPUT, int &INPUT
unsigned int *INPUT, unsigned int &INPUT
long *INPUT, long &INPUT
unsigned long *INPUT, unsigned long &INPUT
long long *INPUT, long long &INPUT
unsigned long long *INPUT, unsigned long long &INPUT
float *INPUT, float &INPUT
double *INPUT, double &INPUT
To use these, suppose you had a C function like this :
double fadd(double *a, double *b) {
return *a+*b;
}
You could wrap it with SWIG as follows :
%include <typemaps.i>
double fadd(double *INPUT, double *INPUT);
or you can use the %apply directive :
%include <typemaps.i>
%apply double *INPUT { double *a, double *b };
double fadd(double *a, double *b);
In D you could then use it like this:
double answer = fadd(10.0, 20.0);
*/
%define INPUT_TYPEMAP(TYPE, CWTYPE, DTYPE)
%typemap(cwtype) TYPE *INPUT, TYPE &INPUT "CWTYPE"
%typemap(dwtype) TYPE *INPUT, TYPE &INPUT "DTYPE"
%typemap(dptype) TYPE *INPUT, TYPE &INPUT "DTYPE"
%typemap(din) TYPE *INPUT, TYPE &INPUT "$dinput"
%typemap(ddirectorin) TYPE *INPUT, TYPE &INPUT "$winput"
%typemap(ddirectorout) TYPE *INPUT, TYPE &INPUT "$dpcall"
%typemap(in) TYPE *INPUT, TYPE &INPUT
%{ $1 = ($1_ltype)&$input; %}
%typemap(directorout) TYPE *INPUT, TYPE &INPUT
%{ $result = ($1_ltype)&$input; %}
%typemap(directorin) TYPE &INPUT
%{ $input = (CWTYPE *)$1; %}
%typemap(directorin) TYPE *INPUT
%{ $input = (CWTYPE *)$1; %}
%typemap(typecheck) TYPE *INPUT = TYPE;
%typemap(typecheck) TYPE &INPUT = TYPE;
%enddef
INPUT_TYPEMAP(bool, unsigned int, bool)
//INPUT_TYPEMAP(char, char, char) // Why was this commented out?
INPUT_TYPEMAP(signed char, signed char, byte)
INPUT_TYPEMAP(unsigned char, unsigned char, ubyte)
INPUT_TYPEMAP(short, short, short)
INPUT_TYPEMAP(unsigned short, unsigned short, ushort)
INPUT_TYPEMAP(int, int, int)
INPUT_TYPEMAP(unsigned int, unsigned int, uint)
INPUT_TYPEMAP(long, long, int)
INPUT_TYPEMAP(unsigned long, unsigned long, uint)
INPUT_TYPEMAP(long long, long long, long)
INPUT_TYPEMAP(unsigned long long, unsigned long long, ulong)
INPUT_TYPEMAP(float, float, float)
INPUT_TYPEMAP(double, double, double)
INPUT_TYPEMAP(enum SWIGTYPE, unsigned int, int)
%typemap(dptype) enum SWIGTYPE *INPUT, enum SWIGTYPE &INPUT "$*dclassname"
#undef INPUT_TYPEMAP
/*
OUTPUT typemaps
---------------
These typemaps are used for pointer/reference parameters that are output only and
are mapped to a D output parameter.
The following typemaps can be applied to turn a pointer or reference into an
"output" value. When calling a function, no input value would be given for
a parameter, but an output value would be returned. In D, the 'out' keyword is
used when passing the parameter to a function that takes an output parameter.
bool *OUTPUT, bool &OUTPUT
signed char *OUTPUT, signed char &OUTPUT
unsigned char *OUTPUT, unsigned char &OUTPUT
short *OUTPUT, short &OUTPUT
unsigned short *OUTPUT, unsigned short &OUTPUT
int *OUTPUT, int &OUTPUT
unsigned int *OUTPUT, unsigned int &OUTPUT
long *OUTPUT, long &OUTPUT
unsigned long *OUTPUT, unsigned long &OUTPUT
long long *OUTPUT, long long &OUTPUT
unsigned long long *OUTPUT, unsigned long long &OUTPUT
float *OUTPUT, float &OUTPUT
double *OUTPUT, double &OUTPUT
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters):
double modf(double x, double *ip);
You could wrap it with SWIG as follows :
%include <typemaps.i>
double modf(double x, double *OUTPUT);
or you can use the %apply directive :
%include <typemaps.i>
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
The D output of the function would be the function return value and the
value returned in the second output parameter. In D you would use it like this:
double dptr;
double fraction = modf(5, dptr);
*/
%define OUTPUT_TYPEMAP(TYPE, CWTYPE, DTYPE, TYPECHECKPRECEDENCE)
%typemap(cwtype) TYPE *OUTPUT, TYPE &OUTPUT "CWTYPE *"
%typemap(dwtype) TYPE *OUTPUT, TYPE &OUTPUT "out DTYPE"
%typemap(dptype) TYPE *OUTPUT, TYPE &OUTPUT "out DTYPE"
%typemap(din) TYPE *OUTPUT, TYPE &OUTPUT "$dinput"
%typemap(ddirectorin) TYPE *OUTPUT, TYPE &OUTPUT "$winput"
%typemap(ddirectorout) TYPE *OUTPUT, TYPE &OUTPUT "$dpcall"
%typemap(in) TYPE *OUTPUT, TYPE &OUTPUT
%{ $1 = ($1_ltype)$input; %}
%typemap(directorout,warning="Need to provide TYPE *OUTPUT directorout typemap") TYPE *OUTPUT, TYPE &OUTPUT {
}
%typemap(directorin) TYPE &OUTPUT
%{ $input = &$1; %}
%typemap(directorin,warning="Need to provide TYPE *OUTPUT directorin typemap, TYPE array length is unknown") TYPE *OUTPUT
{
}
%typecheck(SWIG_TYPECHECK_##TYPECHECKPRECEDENCE) TYPE *OUTPUT, TYPE &OUTPUT ""
%enddef
OUTPUT_TYPEMAP(bool, unsigned int, bool, BOOL_PTR)
//OUTPUT_TYPEMAP(char, char, char, CHAR_PTR) // Why was this commented out?
OUTPUT_TYPEMAP(signed char, signed char, ubyte, INT8_PTR)
OUTPUT_TYPEMAP(unsigned char, unsigned char, byte, UINT8_PTR)
OUTPUT_TYPEMAP(short, short, short, INT16_PTR)
OUTPUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
OUTPUT_TYPEMAP(int, int, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
OUTPUT_TYPEMAP(long, long, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
OUTPUT_TYPEMAP(long long, long long, long, INT64_PTR)
OUTPUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
OUTPUT_TYPEMAP(float, float, float, FLOAT_PTR)
OUTPUT_TYPEMAP(double, double, double, DOUBLE_PTR)
OUTPUT_TYPEMAP(enum SWIGTYPE, unsigned int, int, INT32_PTR)
%typemap(dptype) enum SWIGTYPE *OUTPUT, enum SWIGTYPE &OUTPUT "out $*dclassname"
#undef OUTPUT_TYPEMAP
%typemap(in) bool *OUTPUT, bool &OUTPUT
%{ *$input = 0;
$1 = ($1_ltype)$input; %}
/*
INOUT typemaps
--------------
These typemaps are for pointer/reference parameters that are both input and
output and are mapped to a D reference parameter.
The following typemaps can be applied to turn a pointer or reference into a
reference parameters, that is the parameter is both an input and an output.
In D, the 'ref' keyword is used for reference parameters.
bool *INOUT, bool &INOUT
signed char *INOUT, signed char &INOUT
unsigned char *INOUT, unsigned char &INOUT
short *INOUT, short &INOUT
unsigned short *INOUT, unsigned short &INOUT
int *INOUT, int &INOUT
unsigned int *INOUT, unsigned int &INOUT
long *INOUT, long &INOUT
unsigned long *INOUT, unsigned long &INOUT
long long *INOUT, long long &INOUT
unsigned long long *INOUT, unsigned long long &INOUT
float *INOUT, float &INOUT
double *INOUT, double &INOUT
For example, suppose you were trying to wrap the following function :
void neg(double *x) {
*x = -(*x);
}
You could wrap it with SWIG as follows :
%include <typemaps.i>
void neg(double *INOUT);
or you can use the %apply directive :
%include <typemaps.i>
%apply double *INOUT { double *x };
void neg(double *x);
The D output of the function would be the new value returned by the
reference parameter. In D you would use it like this:
double x = 5.0;
neg(x);
The implementation of the OUTPUT and INOUT typemaps is different to the scripting
languages in that the scripting languages will return the output value as part
of the function return value.
*/
%define INOUT_TYPEMAP(TYPE, CWTYPE, DTYPE, TYPECHECKPRECEDENCE)
%typemap(cwtype) TYPE *INOUT, TYPE &INOUT "CWTYPE *"
%typemap(dwtype) TYPE *INOUT, TYPE &INOUT "ref DTYPE"
%typemap(dptype) TYPE *INOUT, TYPE &INOUT "ref DTYPE"
%typemap(din) TYPE *INOUT, TYPE &INOUT "$dinput"
%typemap(ddirectorin) TYPE *INOUT, TYPE &INOUT "$winput"
%typemap(ddirectorout) TYPE *INOUT, TYPE &INOUT "$dpcall"
%typemap(in) TYPE *INOUT, TYPE &INOUT
%{ $1 = ($1_ltype)$input; %}
%typemap(directorout,warning="Need to provide TYPE *INOUT directorout typemap") TYPE *INOUT, TYPE &INOUT {
}
%typemap(directorin) TYPE &INOUT
%{ $input = &$1; %}
%typemap(directorin,warning="Need to provide TYPE *INOUT directorin typemap, TYPE array length is unknown") TYPE *INOUT, TYPE &INOUT
{
}
%typecheck(SWIG_TYPECHECK_##TYPECHECKPRECEDENCE) TYPE *INOUT, TYPE &INOUT ""
%enddef
INOUT_TYPEMAP(bool, unsigned int, bool, BOOL_PTR)
//INOUT_TYPEMAP(char, char, char, CHAR_PTR)
INOUT_TYPEMAP(signed char, signed char, ubyte, INT8_PTR)
INOUT_TYPEMAP(unsigned char, unsigned char, byte, UINT8_PTR)
INOUT_TYPEMAP(short, short, short, INT16_PTR)
INOUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
INOUT_TYPEMAP(int, int, int, INT32_PTR)
INOUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
INOUT_TYPEMAP(long, long, int, INT32_PTR)
INOUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
INOUT_TYPEMAP(long long, long long, long, INT64_PTR)
INOUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
INOUT_TYPEMAP(float, float, float, FLOAT_PTR)
INOUT_TYPEMAP(double, double, double, DOUBLE_PTR)
INOUT_TYPEMAP(enum SWIGTYPE, unsigned int, int, INT32_PTR)
%typemap(dptype) enum SWIGTYPE *INOUT, enum SWIGTYPE &INOUT "ref $*dclassname"
#undef INOUT_TYPEMAP

303
Lib/d/wrapperloader.swg Normal file
View file

@ -0,0 +1,303 @@
/* -----------------------------------------------------------------------------
* wrapperloader.swg
*
* Support code for dynamically linking the C wrapper library from the D
* wrapper module.
*
* The loading code was adapted from the Derelict project and is used with
* permission from Michael Parker, the original author.
* ----------------------------------------------------------------------------- */
%pragma(d) wrapperloadercode = %{
private {
version(linux) {
version = Nix;
} else version(darwin) {
version = Nix;
} else version(OSX) {
version = Nix;
} else version(FreeBSD) {
version = Nix;
version = freebsd;
} else version(freebsd) {
version = Nix;
} else version(Unix) {
version = Nix;
} else version(Posix) {
version = Nix;
}
version(Tango) {
static import tango.stdc.string;
static import tango.stdc.stringz;
version (PhobosCompatibility) {
} else {
alias char[] string;
alias wchar[] wstring;
alias dchar[] dstring;
}
} else {
version(D_Version2) {
static import std.conv;
}
static import std.string;
static import std.c.string;
}
version(D_Version2) {
mixin("alias const(char)* CCPTR;");
} else {
alias char* CCPTR;
}
CCPTR swigToCString(string str) {
version(Tango) {
return tango.stdc.stringz.toStringz(str);
} else {
return std.string.toStringz(str);
}
}
string swigToDString(CCPTR cstr) {
version(Tango) {
return tango.stdc.stringz.fromStringz(cstr);
} else {
version(D_Version2) {
mixin("return std.conv.to!string(cstr);");
} else {
return std.c.string.toString(cstr);
}
}
}
}
class SwigSwigSharedLibLoadException : Exception {
this(in string[] libNames, in string[] reasons) {
string msg = "Failed to load one or more shared libraries:";
foreach(i, n; libNames) {
msg ~= "\n\t" ~ n ~ " - ";
if(i < reasons.length)
msg ~= reasons[i];
else
msg ~= "Unknown";
}
super(msg);
}
}
class SwigSymbolLoadException : Exception {
this(string SwigSharedLibName, string symbolName) {
super("Failed to load symbol " ~ symbolName ~ " from shared library " ~ SwigSharedLibName);
_symbolName = symbolName;
}
string symbolName() {
return _symbolName;
}
private:
string _symbolName;
}
private {
version(Nix) {
version(freebsd) {
// the dl* functions are in libc on FreeBSD
}
else {
pragma(lib, "dl");
}
version(Tango) {
import tango.sys.Common;
} else version(linux) {
import std.c.linux.linux;
} else {
extern(C) {
const RTLD_NOW = 2;
void *dlopen(CCPTR file, int mode);
int dlclose(void* handle);
void *dlsym(void* handle, CCPTR name);
CCPTR dlerror();
}
}
alias void* SwigSharedLibHandle;
SwigSharedLibHandle swigLoadSharedLib(string libName) {
return dlopen(swigToCString(libName), RTLD_NOW);
}
void swigUnloadSharedLib(SwigSharedLibHandle hlib) {
dlclose(hlib);
}
void* swigGetSymbol(SwigSharedLibHandle hlib, string symbolName) {
return dlsym(hlib, swigToCString(symbolName));
}
string swigGetErrorStr() {
CCPTR err = dlerror();
if (err is null) {
return "Unknown Error";
}
return swigToDString(err);
}
} else version(Windows) {
alias uint DWORD;
alias CCPTR LPCSTR;
alias void* HMODULE;
alias void* HLOCAL;
alias int function() FARPROC;
struct VA_LIST {}
extern (Windows) {
HMODULE LoadLibraryA(LPCSTR);
FARPROC GetProcAddress(HMODULE, LPCSTR);
void FreeLibrary(HMODULE);
DWORD GetLastError();
DWORD FormatMessageA(DWORD, in void*, DWORD, DWORD, LPCSTR, DWORD, VA_LIST*);
HLOCAL LocalFree(HLOCAL);
}
enum {
LANG_NEUTRAL = 0,
SUBLANG_DEFAULT = 1,
FORMAT_MESSAGE_ALLOCATE_BUFFER = 256,
FORMAT_MESSAGE_IGNORE_INSERTS = 512,
FORMAT_MESSAGE_FROM_SYSTEM = 4096
}
alias HMODULE SwigSharedLibHandle;
SwigSharedLibHandle swigLoadSharedLib(string libName) {
return LoadLibraryA(swigToCString(libName));
}
void swigUnloadSharedLib(SwigSharedLibHandle hlib) {
FreeLibrary(hlib);
}
void* swigGetSymbol(SwigSharedLibHandle hlib, string symbolName) {
return GetProcAddress(hlib, swigToCString(symbolName));
}
string swigGetErrorStr() {
DWORD errcode = GetLastError();
LPCSTR msgBuf;
DWORD i = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
null,
errcode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
cast(LPCSTR)&msgBuf,
0,
null);
string text = swigToDString(msgBuf);
LocalFree(cast(HLOCAL)msgBuf);
if (i >= 2) {
i -= 2;
}
return text[0 .. i];
}
} else {
static assert(0, "Operating system not supported by the wrapper loading code.");
}
final class SwigSharedLib {
void load(string[] names) {
if (_hlib !is null) return;
string[] failedLibs;
string[] reasons;
foreach(n; names) {
_hlib = swigLoadSharedLib(n);
if (_hlib is null) {
failedLibs ~= n;
reasons ~= swigGetErrorStr();
continue;
}
_name = n;
break;
}
if (_hlib is null) {
throw new SwigSwigSharedLibLoadException(failedLibs, reasons);
}
}
void* loadSymbol(string symbolName, bool doThrow = true) {
void* sym = swigGetSymbol(_hlib, symbolName);
if(doThrow && (sym is null)) {
throw new SwigSymbolLoadException(_name, symbolName);
}
return sym;
}
void unload() {
if(_hlib !is null) {
swigUnloadSharedLib(_hlib);
_hlib = null;
}
}
private:
string _name;
SwigSharedLibHandle _hlib;
}
}
static this() {
string[] possibleFileNames;
version (Posix) {
version (OSX) {
possibleFileNames ~= ["lib$wraplibrary.dylib", "lib$wraplibrary.bundle"];
}
possibleFileNames ~= ["lib$wraplibrary.so"];
} else version (Windows) {
possibleFileNames ~= ["$wraplibrary.dll", "lib$wraplibrary.so"];
} else {
static assert(false, "Operating system not supported by the wrapper loading code.");
}
auto library = new SwigSharedLib;
library.load(possibleFileNames);
string bindCode(string functionPointer, string symbol) {
return functionPointer ~ " = cast(typeof(" ~ functionPointer ~
"))library.loadSymbol(`" ~ symbol ~ "`);";
}
//#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
mixin(bindCode("swigRegisterExceptionCallbacks", "SWIGRegisterExceptionCallbacks_$module"));
//#endif // SWIG_D_NO_EXCEPTION_HELPER
//#if !defined(SWIG_D_NO_STRING_HELPER)
mixin(bindCode("swigRegisterStringCallback", "SWIGRegisterStringCallback_$module"));
//#endif // SWIG_D_NO_STRING_HELPER
$wrapperloaderbindcode
}
//#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
extern(C) void function(
SwigExceptionCallback exceptionCallback,
SwigExceptionCallback illegalArgumentCallback,
SwigExceptionCallback illegalElementCallback,
SwigExceptionCallback ioCallback,
SwigExceptionCallback noSuchElementCallback) swigRegisterExceptionCallbacks;
//#endif // SWIG_D_NO_EXCEPTION_HELPER
//#if !defined(SWIG_D_NO_STRING_HELPER)
extern(C) void function(SwigStringCallback callback) swigRegisterStringCallback;
//#endif // SWIG_D_NO_STRING_HELPER
%}
%pragma(d) wrapperloaderbindcommand = %{
mixin(bindCode("$function", "$symbol"));%}

View file

@ -209,6 +209,40 @@ SWIGINTERN void SWIG_CSharpException(int code, const char *msg) {
#endif // SWIGLUA
#ifdef SWIGD
%{
SWIGINTERN void SWIG_DThrowException(int code, const char *msg) {
SWIG_DExceptionCodes exception_code;
switch(code) {
case SWIG_IndexError:
exception_code = SWIG_DNoSuchElementException;
break;
case SWIG_IOError:
exception_code = SWIG_DIOException;
break;
case SWIG_ValueError:
exception_code = SWIG_DIllegalArgumentException;
break;
case SWIG_DivisionByZero:
case SWIG_MemoryError:
case SWIG_OverflowError:
case SWIG_RuntimeError:
case SWIG_TypeError:
case SWIG_SyntaxError:
case SWIG_SystemError:
case SWIG_UnknownError:
default:
exception_code = SWIG_DException;
break;
}
SWIG_DSetPendingException(exception_code, msg);
}
%}
#define SWIG_exception(code, msg)\
{ SWIG_DThrowException(code, msg); return $null; }
#endif // SWIGD
#ifdef __cplusplus
/*
You can use the SWIG_CATCH_STDEXCEPT macro with the %exception
@ -259,7 +293,7 @@ SWIGINTERN void SWIG_CSharpException(int code, const char *msg) {
/* rethrow the unknown exception */
#ifdef SWIGCSHARP
#if defined(SWIGCSHARP) || defined(SWIGD)
%typemap(throws,noblock=1, canthrow=1) (...) {
SWIG_exception(SWIG_RuntimeError,"unknown exception");
}

View file

@ -19,7 +19,7 @@
* a new std_except.i file in the target library directory.
* ----------------------------------------------------------------------------- */
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGUILE) || defined(SWIGUTL)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGUILE) || defined(SWIGUTL) || defined(SWIGD)
#error "This version of std_except.i should not be used"
#endif

View file

@ -77,7 +77,7 @@
#define %clearoldnodefault %feature("oldnodefault","")
/* the %exception directive */
#ifdef SWIGCSHARP
#if defined(SWIGCSHARP) || defined(SWIGD)
#define %exception %feature("except", canthrow=1)
#else
#define %exception %feature("except")
@ -95,7 +95,7 @@
to set/get variable methods. You don't need to use the
%allowexception directive when using %exceptionvar.
*/
#ifdef SWIGCSHARP
#if defined(SWIGCSHARP) || defined(SWIGD)
#define %exceptionvar %feature("exceptvar", canthrow=1)
#else
#define %exceptionvar %feature("exceptvar")