typemaps.i: $descriptor usage correction.

ocaml.cxx: director classes (needs more testing, but my Qt example works).
director.swg: Core director class for Ocaml.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4480 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Art Yerkes 2003-03-08 17:11:19 +00:00
commit 8dd475f93e
7 changed files with 1115 additions and 248 deletions

164
Lib/ocaml/director.swg Normal file
View file

@ -0,0 +1,164 @@
/* -*- C++ -*- */
/***********************************************************************
* director.swg
*
* This file contains support for director classes that proxy
* method calls from C++ to Ocaml extensions.
*
* Modified for Ocaml by : Art Yerkes
* Original Author : Mark Rose (mrose@stm.lbl.gov)
************************************************************************/
%insert(runtime) %{
#ifdef __cplusplus
#include <string>
/* base class for director exceptions */
class SWIG_DIRECTOR_EXCEPTION {
protected:
std::string _msg;
public:
SWIG_DIRECTOR_EXCEPTION(const char* msg="") {
}
const char *getMessage() { return _msg.c_str(); }
virtual ~SWIG_DIRECTOR_EXCEPTION() { }
};
/* type mismatch in the return value from a ocaml method call */
class SWIG_DIRECTOR_TYPE_MISMATCH: public SWIG_DIRECTOR_EXCEPTION {
public:
SWIG_DIRECTOR_TYPE_MISMATCH(const char* msg="") {
_msg = "Swig director type mismatch: ";
_msg += msg;
failwith((char *)_msg.c_str());
}
};
/* any ocaml exception that occurs during a director method call */
class SWIG_DIRECTOR_METHOD_EXCEPTION: public SWIG_DIRECTOR_EXCEPTION { };
/* simple thread abstraction for pthreads or win32 */
#ifdef __THREAD__
#define __PTHREAD__
#if defined(_WIN32) || defined(__WIN32__)
#define pthread_mutex_lock EnterCriticalSection
#define pthread_mutex_unlock LeaveCriticalSection
#define pthread_mutex_t CRITICAL_SECTION
#define MUTEX_INIT(var) CRITICAL_SECTION var
#else
#include <pthread.h>
#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
#endif
#endif
/* director base class */
class __DIRECTOR__ {
private:
/* pointer to the wrapped ocaml object */
value _self;
/* flag indicating whether the object is owned by ocaml or c++ */
mutable int _disown;
/* shared flag for breaking recursive director calls */
static int _up;
#ifdef __PTHREAD__
/* locks for sharing the _up flag in a threaded environment */
static pthread_mutex_t _mutex_up;
static int _mutex_active;
static pthread_t _mutex_thread;
#endif
/* reset the _up flag once the routing direction has been determined */
#ifdef __PTHREAD__
void __clear_up() const {
__DIRECTOR__::_up = 0;
__DIRECTOR__::_mutex_active = 0;
pthread_mutex_unlock(&_mutex_up);
}
#else
void __clear_up() const {
__DIRECTOR__::_up = 0;
}
#endif
public:
/* the default constructor should not be called */
__DIRECTOR__() {
assert(0);
}
/* wrap a ocaml object, optionally taking ownership */
__DIRECTOR__(value self, int disown): _self(self), _disown(disown) {
}
/* discard our reference at destruction */
virtual ~__DIRECTOR__() {
}
/* return a pointer to the wrapped ocaml object */
value __get_self() const {
return _self;
}
/* get the _up flag to determine if the method call should be routed
* to the c++ base class or through the wrapped ocaml object
*/
#ifdef __PTHREAD__
int __get_up() const {
if (__DIRECTOR__::_mutex_active) {
if (pthread_equal(__DIRECTOR__::_mutex_thread, pthread_self())) {
int up = _up;
__clear_up();
return up;
}
}
return 0;
}
#else
int __get_up() const {
int up = _up;
_up = 0;
return up;
}
#endif
/* set the _up flag if the next method call should be directed to
* the c++ base class rather than the wrapped ocaml object
*/
#ifdef __PTHREAD__
void __set_up() const {
pthread_mutex_lock(&__DIRECTOR__::_mutex_up);
__DIRECTOR__::_mutex_thread = pthread_self();
__DIRECTOR__::_mutex_active = 1;
__DIRECTOR__::_up = 1;
}
#else
void __set_up() const {
__DIRECTOR__::_up = 1;
}
#endif
/* acquire ownership of the wrapped ocaml object (the sense of "disown"
* is from ocaml) */
void __disown() const {
assert(_self);
if (!_disown) {
_disown=1;
}
}
};
int __DIRECTOR__::_up = 0;
#ifdef __PTHREAD__
MUTEX_INIT(__DIRECTOR__::_mutex_up);
pthread_t __DIRECTOR__::_mutex_thread;
int __DIRECTOR__::_mutex_active = 0;
#endif
#endif /* __cplusplus */
%}

View file

@ -28,6 +28,7 @@ exception NotEnumType of c_obj
exception LabelNotFromThisEnum of c_obj
let invoke obj = match obj with C_obj o -> o | _ -> raise (NotObject obj)
let _ = Callback.register "swig_runmethod" invoke
let fnhelper fin f arg =
let args = match arg with C_list l -> l | C_void -> [] | _ -> [ arg ] in
match f args with

View file

@ -30,6 +30,12 @@ extern "C" {
SWIG_Cast (void *source, swig_type_info *source_type,
void **ptr, swig_type_info *dest_type)
{
if( !source ) { // Special case for NULL. This is a popular question
// for other modules on the list, so I want an easy way out...
*ptr = 0;
return 0;
}
#ifdef TYPE_CAST_VERBOSE
fprintf( stderr, "Trying to cast %s to %s\n",
source_type ? source_type->str : "<none>",
@ -400,11 +406,26 @@ extern "C" {
void *outptr = NULL;
swig_type_info *outdescr = NULL;
if( v == Val_unit ) {
*out = 0;
CAMLreturn(0);
}
if( !Is_block(v) ) return -1;
switch( Tag_val(v) ) {
case C_int:
if( !caml_long_val( v ) ) {
*out = 0;
CAMLreturn(0);
} else {
*out = 0;
CAMLreturn(1);
}
break;
case C_obj:
return caml_ptr_val_internal
(callback(*caml_named_value("caml_obj_ptr"),v),out,descriptor);
CAMLreturn
(caml_ptr_val_internal
(callback(*caml_named_value("caml_obj_ptr"),v),
out,descriptor));
case C_string:
outptr = (void *)String_val(Field(v,0));
break;
@ -418,7 +439,7 @@ extern "C" {
break;
}
CAMLreturn(SWIG_GetPtr(outptr,out,descriptor,outdescr));
CAMLreturn(SWIG_GetPtr(outptr,out,outdescr,descriptor));
}
SWIGSTATIC void *caml_ptr_val( value v, swig_type_info *descriptor ) {

View file

@ -41,202 +41,202 @@
namespace std{
template<class T> class list
{
public:
template<class T> class list
{
public:
typedef T &reference;
typedef const T& const_reference;
typedef T &iterator;
typedef const T& const_iterator;
typedef T &reference;
typedef const T& const_reference;
typedef T &iterator;
typedef const T& const_iterator;
list();
list(unsigned int size, const T& value = T());
list(const list<T> &);
list();
list(unsigned int size, const T& value = T());
list(const list<T> &);
~list();
void assign(unsigned int n, const T& value);
void swap(list<T> &x);
~list();
void assign(unsigned int n, const T& value);
void swap(list<T> &x);
const_reference front();
const_reference back();
const_iterator begin();
const_iterator end();
const_reference front();
const_reference back();
const_iterator begin();
const_iterator end();
void resize(unsigned int n, T c = T());
bool empty() const;
void resize(unsigned int n, T c = T());
bool empty() const;
void push_front(const T& x);
void push_back(const T& x);
void push_front(const T& x);
void push_back(const T& x);
void pop_front();
void pop_back();
void clear();
unsigned int size() const;
unsigned int max_size() const;
void resize(unsigned int n, const T& value);
void pop_front();
void pop_back();
void clear();
unsigned int size() const;
unsigned int max_size() const;
void resize(unsigned int n, const T& value);
void remove(const T& value);
void unique();
void reverse();
void sort();
void remove(const T& value);
void unique();
void reverse();
void sort();
%extend
%extend
{
const_reference __getitem__(int i)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
for (int k=0;k<i;k++)
{
first++;
}
return *first;
}
else throw std::out_of_range("list index out of range");
}
void __setitem__(int i, const T& x)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
for (int k=0;k<i;k++)
{
first++;
}
*first = x;
}
else throw std::out_of_range("list index out of range");
}
void __delitem__(int i)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
for (int k=0;k<i;k++)
{
first++;
}
self->erase(first);
}
else throw std::out_of_range("list index out of range");
}
std::list<T> __getslice__(int i,int j)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
if (i>=j) i=j;
if (i>=0 && i<size && j>=0)
{
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<j;m++)
{
end++;
}
std::list<T> tmp(j-i);
if (j>i) std::copy(first,end,tmp.begin());
return tmp;
}
else throw std::out_of_range("list index out of range");
}
void __delslice__(int i,int j)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<=j;m++)
{
end++;
}
self->erase(first,end);
}
void __setslice__(int i,int j, const std::list<T>& v)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<=j;m++)
{
end++;
}
if (int(v.size()) == j-i)
{
std::copy(v.begin(),v.end(),first);
}
else {
self->erase(first,end);
if (i+1 <= self->size())
const_reference __getitem__(int i)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
first = self->begin();
for (int k=0;k<i;k++)
{
first++;
}
self->insert(first,v.begin(),v.end());
for (int k=0;k<i;k++)
{
first++;
}
return *first;
}
else throw std::out_of_range("list index out of range");
}
void __setitem__(int i, const T& x)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
for (int k=0;k<i;k++)
{
first++;
}
*first = x;
}
else throw std::out_of_range("list index out of range");
}
void __delitem__(int i)
{
std::list<T>::iterator first = self->begin();
int size = int(self->size());
if (i<0) i += size;
if (i>=0 && i<size)
{
for (int k=0;k<i;k++)
{
first++;
}
self->erase(first);
}
else throw std::out_of_range("list index out of range");
}
std::list<T> __getslice__(int i,int j)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
if (i>=j) i=j;
if (i>=0 && i<size && j>=0)
{
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<j;m++)
{
end++;
}
std::list<T> tmp(j-i);
if (j>i) std::copy(first,end,tmp.begin());
return tmp;
}
else throw std::out_of_range("list index out of range");
}
void __delslice__(int i,int j)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<=j;m++)
{
end++;
}
self->erase(first,end);
}
void __setslice__(int i,int j, const std::list<T>& v)
{
std::list<T>::iterator first = self->begin();
std::list<T>::iterator end = self->end();
int size = int(self->size());
if (i<0) i += size;
if (j<0) j += size;
if (i<0) i = 0;
if (j>size) j = size;
for (int k=0;k<i;k++)
{
first++;
}
for (int m=0;m<=j;m++)
{
end++;
}
if (int(v.size()) == j-i)
{
std::copy(v.begin(),v.end(),first);
}
else {
self->erase(first,end);
if (i+1 <= self->size())
{
first = self->begin();
for (int k=0;k<i;k++)
{
first++;
}
self->insert(first,v.begin(),v.end());
}
else self->insert(self->end(),v.begin(),v.end());
}
else self->insert(self->end(),v.begin(),v.end());
}
}
unsigned int __len__()
{
return self->size();
}
bool __nonzero__()
{
return !(self->empty());
}
void append(const T& x)
{
self->push_back(x);
}
void pop()
{
self->pop_back();
}
}
unsigned int __len__()
{
return self->size();
}
bool __nonzero__()
{
return !(self->empty());
}
void append(const T& x)
{
self->push_back(x);
}
void pop()
{
self->pop_back();
}
};
};
};
}

View file

@ -37,7 +37,6 @@
// exported class
namespace std {
template<class K, class T> class map {
// add typemaps here
public:
@ -186,5 +185,4 @@ namespace std {
%enddef
// add specializations here
}

View file

@ -44,28 +44,28 @@
}
%typemap(ocaml,in) SWIGTYPE * {
$1 = ($ltype)caml_ptr_val($input,$*1_descriptor);
$1 = ($ltype)caml_ptr_val($input,$1_descriptor);
}
%typemap(ocaml,out) SWIGTYPE * {
value *fromval = caml_named_value("create_$ntype_from_ptr");
if( fromval ) {
$result = callback(*fromval,caml_val_ptr((void *)$1,$*1_descriptor));
$result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor));
} else {
$result = caml_val_ptr ((void *)$1,$*1_descriptor);
$result = caml_val_ptr ((void *)$1,$1_descriptor);
}
}
%typemap(ocaml,varin) SWIGTYPE * {
$1 = ($ltype)caml_ptr_val($input,$*1_descriptor);
$1 = ($ltype)caml_ptr_val($input,$1_descriptor);
}
%typemap(ocaml,varout) SWIGTYPE * {
value *fromval = caml_named_value("create_$ntype_from_ptr");
if( fromval ) {
$result = callback(*fromval,caml_val_ptr((void *)$1,$*1_descriptor));
$result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor));
} else {
$result = caml_val_ptr ((void *)$1,$*1_descriptor);
$result = caml_val_ptr ((void *)$1,$1_descriptor);
}
}
@ -74,15 +74,15 @@
#ifdef __cplusplus
%typemap(ocaml,in) SWIGTYPE & {
$1 = ($ltype) caml_ptr_val($input,$*1_descriptor);
$1 = ($ltype) caml_ptr_val($input,$1_descriptor);
}
%typemap(ocaml,out) SWIGTYPE & {
value *fromval = caml_named_value("create_$ntype_from_ptr");
if( fromval ) {
$result = callback(*fromval,caml_val_ptr((void *) $1,$*1_descriptor));
$result = callback(*fromval,caml_val_ptr((void *) $1,$1_descriptor));
} else {
$result = caml_val_ptr ((void *) $1,$*1_descriptor);
$result = caml_val_ptr ((void *) $1,$1_descriptor);
}
}
@ -92,16 +92,16 @@
swig_result =
caml_list_append(swig_result,
callback(*fromval,caml_val_ptr((void *) $1,
$*1_descriptor)));
$1_descriptor)));
} else {
swig_result =
caml_list_append(swig_result,
caml_val_ptr ((void *) $1,$*1_descriptor));
caml_val_ptr ((void *) $1,$1_descriptor));
}
}
%typemap(ocaml,in) SWIGTYPE {
$1 = *(($&1_ltype) caml_ptr_val($input,$descriptor)) ;
$1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
}
%typemap(ocaml,out) SWIGTYPE {
@ -109,16 +109,16 @@
value *fromval = caml_named_value("create_$ntype_from_ptr");
*(($ltype *)temp) = $1;
if( fromval ) {
$result = callback(*fromval,caml_val_ptr((void *)temp,$descriptor));
$result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor));
} else {
$result = caml_val_ptr ((void *)temp,$descriptor);
$result = caml_val_ptr ((void *)temp,$&1_descriptor);
}
}
#else
%typemap(ocaml,in) SWIGTYPE {
$1 = *(($&1_ltype) caml_ptr_val($input,$descriptor)) ;
$1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
}
%typemap(ocaml,out) SWIGTYPE {
@ -126,9 +126,9 @@
value *fromval = caml_named_value("create_$ntype_from_ptr");
*(($ltype *)temp) = $1;
if( fromval ) {
$result = callback(*fromval,caml_val_ptr((void *)temp,$descriptor));
$result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor));
} else {
$result = caml_val_ptr ((void *)temp,$descriptor);
$result = caml_val_ptr ((void *)temp,$&1_descriptor);
}
}