Merge branch 'perl5-directors-minimal' of https://github.com/talby-/swig into talby--perl5-directors-minimal
* 'perl5-directors-minimal' of https://github.com/talby-/swig: try adding travis ci to this branch ran "beautify-file" make target over perl5.cxx patch hunks and rewrote callback and extend examples in the style of existing examples prefer polymorphism on existing destructor over custom destructor method fix string mangled by tidy eliminate dead director code and convert remaining blocks mitigate ConvertPtr director cost when directors are not enabled steals python director docs and adapts to perl5 adds "callback" and "extend" examples don't forget the most important part steals python directors and adapts to perl5
This commit is contained in:
commit
d1bb451eab
40 changed files with 2740 additions and 5 deletions
352
Lib/perl5/director.swg
Normal file
352
Lib/perl5/director.swg
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* director.swg
|
||||
*
|
||||
* This file contains support for director classes that proxy
|
||||
* method calls from C++ to Python extensions.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef SWIG_DIRECTOR_PERL_HEADER_
|
||||
#define SWIG_DIRECTOR_PERL_HEADER_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
/*
|
||||
Use -DSWIG_DIRECTOR_NORTTI if you prefer to avoid the use of the
|
||||
native C++ RTTI and dynamic_cast<>. But be aware that directors
|
||||
could stop working when using this option.
|
||||
*/
|
||||
#ifdef SWIG_DIRECTOR_NORTTI
|
||||
/*
|
||||
When we don't use the native C++ RTTI, we implement a minimal one
|
||||
only for Directors.
|
||||
*/
|
||||
# ifndef SWIG_DIRECTOR_RTDIR
|
||||
# define SWIG_DIRECTOR_RTDIR
|
||||
#include <map>
|
||||
|
||||
namespace Swig {
|
||||
class Director;
|
||||
SWIGINTERN std::map<void*,Director*>& get_rtdir_map() {
|
||||
static std::map<void*,Director*> rtdir_map;
|
||||
return rtdir_map;
|
||||
}
|
||||
|
||||
SWIGINTERNINLINE void set_rtdir(void *vptr, Director *rtdir) {
|
||||
get_rtdir_map()[vptr] = rtdir;
|
||||
}
|
||||
|
||||
SWIGINTERNINLINE Director *get_rtdir(void *vptr) {
|
||||
std::map<void*,Director*>::const_iterator pos = get_rtdir_map().find(vptr);
|
||||
Director *rtdir = (pos != get_rtdir_map().end()) ? pos->second : 0;
|
||||
return rtdir;
|
||||
}
|
||||
}
|
||||
# endif /* SWIG_DIRECTOR_RTDIR */
|
||||
|
||||
# define SWIG_DIRECTOR_CAST(ARG) Swig::get_rtdir(static_cast<void*>(ARG))
|
||||
# define SWIG_DIRECTOR_RGTR(ARG1, ARG2) Swig::set_rtdir(static_cast<void*>(ARG1), ARG2)
|
||||
|
||||
#else
|
||||
|
||||
# define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
|
||||
# define SWIG_DIRECTOR_RGTR(ARG1, ARG2)
|
||||
|
||||
#endif /* SWIG_DIRECTOR_NORTTI */
|
||||
|
||||
extern "C" {
|
||||
struct swig_type_info;
|
||||
}
|
||||
|
||||
namespace Swig {
|
||||
|
||||
/* memory handler */
|
||||
struct GCItem
|
||||
{
|
||||
virtual ~GCItem() {}
|
||||
|
||||
virtual int get_own() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct GCItem_var
|
||||
{
|
||||
GCItem_var(GCItem *item = 0) : _item(item)
|
||||
{
|
||||
}
|
||||
|
||||
GCItem_var& operator=(GCItem *item)
|
||||
{
|
||||
GCItem *tmp = _item;
|
||||
_item = item;
|
||||
delete tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~GCItem_var()
|
||||
{
|
||||
delete _item;
|
||||
}
|
||||
|
||||
GCItem * operator->() const
|
||||
{
|
||||
return _item;
|
||||
}
|
||||
|
||||
private:
|
||||
GCItem *_item;
|
||||
};
|
||||
|
||||
struct GCItem_Object : GCItem
|
||||
{
|
||||
GCItem_Object(int own) : _own(own)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCItem_Object()
|
||||
{
|
||||
}
|
||||
|
||||
int get_own() const
|
||||
{
|
||||
return _own;
|
||||
}
|
||||
|
||||
private:
|
||||
int _own;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct GCItem_T : GCItem
|
||||
{
|
||||
GCItem_T(Type *ptr) : _ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCItem_T()
|
||||
{
|
||||
delete _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_ptr;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct GCArray_T : GCItem
|
||||
{
|
||||
GCArray_T(Type *ptr) : _ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~GCArray_T()
|
||||
{
|
||||
delete[] _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_ptr;
|
||||
};
|
||||
|
||||
/* base class for director exceptions */
|
||||
class DirectorException {
|
||||
public:
|
||||
virtual const char *getMessage() const = 0;
|
||||
virtual SV *getNative() const = 0;
|
||||
};
|
||||
/* exceptions emitted by Perl */
|
||||
class DirectorMethodException : public Swig::DirectorException {
|
||||
protected:
|
||||
SV *err;
|
||||
public:
|
||||
DirectorMethodException(SV *sv = sv_mortalcopy(ERRSV))
|
||||
: err(sv)
|
||||
{
|
||||
SvREFCNT_inc(err);
|
||||
}
|
||||
~DirectorMethodException()
|
||||
{
|
||||
SvREFCNT_dec(err);
|
||||
}
|
||||
const char *getMessage() const
|
||||
{
|
||||
return SvPV_nolen(err);
|
||||
}
|
||||
SV *getNative() const
|
||||
{
|
||||
return sv_2mortal(newSVsv(err));
|
||||
}
|
||||
static void raise(SV *sv)
|
||||
{
|
||||
throw DirectorMethodException(sv);
|
||||
}
|
||||
};
|
||||
/* exceptions emitted by wrap code */
|
||||
class DirectorWrapException : public Swig::DirectorException {
|
||||
protected:
|
||||
std::string msg;
|
||||
DirectorWrapException(const char *str)
|
||||
: msg(str)
|
||||
{
|
||||
}
|
||||
public:
|
||||
virtual const char *getMessage() const
|
||||
{
|
||||
return msg.c_str();
|
||||
}
|
||||
virtual SV *getNative() const {
|
||||
return sv_2mortal(newSVpvn(msg.data(), msg.size()));
|
||||
}
|
||||
};
|
||||
class DirectorTypeMismatchException : public Swig::DirectorWrapException {
|
||||
public:
|
||||
DirectorTypeMismatchException(const char *str)
|
||||
: DirectorWrapException(str)
|
||||
{
|
||||
}
|
||||
static void raise(const char *type, const char *msg)
|
||||
{
|
||||
std::string err = std::string(type);
|
||||
err += ": ";
|
||||
err += msg;
|
||||
throw DirectorTypeMismatchException(err.c_str());
|
||||
}
|
||||
};
|
||||
class DirectorPureVirtualException : public Swig::DirectorWrapException {
|
||||
public:
|
||||
DirectorPureVirtualException(const char *name)
|
||||
: DirectorWrapException("SWIG director pure virtual method called: ")
|
||||
{
|
||||
msg += name;
|
||||
}
|
||||
static void raise(const char *name)
|
||||
{
|
||||
throw DirectorPureVirtualException(name);
|
||||
}
|
||||
};
|
||||
|
||||
/* director base class */
|
||||
class Director {
|
||||
private:
|
||||
/* pointer to the wrapped perl object */
|
||||
SV *swig_self;
|
||||
/* class of wrapped perl object */
|
||||
std::string swig_class;
|
||||
/* flag indicating whether the object is owned by perl or c++ */
|
||||
mutable bool swig_disown_flag;
|
||||
|
||||
/* decrement the reference count of the wrapped perl object */
|
||||
void swig_decref() const {
|
||||
if (swig_disown_flag) {
|
||||
SvREFCNT_dec(swig_self);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/* wrap a python object, optionally taking ownership */
|
||||
Director(SV *pkg) : swig_disown_flag(false) {
|
||||
STRLEN len;
|
||||
char *str = SvPV(pkg, len);
|
||||
swig_class = std::string(str, len);
|
||||
swig_self = newRV_inc((SV *)newHV());
|
||||
swig_incref();
|
||||
}
|
||||
|
||||
|
||||
/* discard our reference at destruction */
|
||||
virtual ~Director() {
|
||||
swig_decref();
|
||||
}
|
||||
|
||||
|
||||
/* return a pointer to the wrapped python object */
|
||||
SV *swig_get_self() const {
|
||||
return swig_self;
|
||||
}
|
||||
|
||||
const char *swig_get_class() const {
|
||||
return swig_class.c_str();
|
||||
}
|
||||
|
||||
/* acquire ownership of the wrapped python object (the sense of "disown"
|
||||
* is from python) */
|
||||
void swig_disown() const {
|
||||
if (!swig_disown_flag) {
|
||||
swig_disown_flag=true;
|
||||
swig_incref();
|
||||
}
|
||||
}
|
||||
|
||||
/* increase the reference count of the wrapped python object */
|
||||
void swig_incref() const {
|
||||
if (swig_disown_flag) {
|
||||
SvREFCNT_inc(swig_self);
|
||||
}
|
||||
}
|
||||
|
||||
/* methods to implement pseudo protected director members */
|
||||
virtual bool swig_get_inner(const char* /* swig_protected_method_name */) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void swig_set_inner(const char* /* swig_protected_method_name */, bool /* swig_val */) const {
|
||||
}
|
||||
|
||||
/* ownership management */
|
||||
private:
|
||||
typedef std::map<void*, GCItem_var> swig_ownership_map;
|
||||
mutable swig_ownership_map swig_owner;
|
||||
|
||||
public:
|
||||
template <typename Type>
|
||||
void swig_acquire_ownership_array(Type *vptr) const
|
||||
{
|
||||
if (vptr) {
|
||||
swig_owner[vptr] = new GCArray_T<Type>(vptr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void swig_acquire_ownership(Type *vptr) const
|
||||
{
|
||||
if (vptr) {
|
||||
swig_owner[vptr] = new GCItem_T<Type>(vptr);
|
||||
}
|
||||
}
|
||||
|
||||
void swig_acquire_ownership_obj(void *vptr, int own) const
|
||||
{
|
||||
if (vptr && own) {
|
||||
swig_owner[vptr] = new GCItem_Object(own);
|
||||
}
|
||||
}
|
||||
|
||||
int swig_release_ownership(void *vptr) const
|
||||
{
|
||||
int own = 0;
|
||||
if (vptr) {
|
||||
swig_ownership_map::iterator iter = swig_owner.find(vptr);
|
||||
if (iter != swig_owner.end()) {
|
||||
own = iter->second->get_own();
|
||||
swig_owner.erase(iter);
|
||||
}
|
||||
}
|
||||
return own;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#define SWIG_ConvertPtr(obj, pp, type, flags) SWIG_Perl_ConvertPtr(SWIG_PERL_OBJECT_CALL obj, pp, type, flags)
|
||||
#define SWIG_ConvertPtrAndOwn(obj, pp, type, flags,own) SWIG_Perl_ConvertPtrAndOwn(SWIG_PERL_OBJECT_CALL obj, pp, type, flags, own)
|
||||
#define SWIG_NewPointerObj(p, type, flags) SWIG_Perl_NewPointerObj(SWIG_PERL_OBJECT_CALL p, type, flags)
|
||||
#define swig_owntype int
|
||||
|
||||
/* for raw packed data */
|
||||
#define SWIG_ConvertPacked(obj, p, s, type) SWIG_Perl_ConvertPacked(SWIG_PERL_OBJECT_CALL obj, p, s, type)
|
||||
|
|
@ -288,7 +289,11 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_
|
|||
/* Now see if the types match */
|
||||
char *_c = HvNAME(SvSTASH(SvRV(sv)));
|
||||
tc = SWIG_TypeProxyCheck(_c,_t);
|
||||
#ifdef SWIG_DIRECTORS
|
||||
if (!tc && !sv_derived_from(sv,SWIG_Perl_TypeProxyName(_t))) {
|
||||
#else
|
||||
if (!tc) {
|
||||
#endif
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@
|
|||
* Unified typemap section
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
/* No director supported in Perl */
|
||||
#ifdef SWIG_DIRECTOR_TYPEMAPS
|
||||
#undef SWIG_DIRECTOR_TYPEMAPS
|
||||
/* director support in Perl is experimental */
|
||||
#ifndef SWIG_DIRECTOR_TYPEMAPS
|
||||
#define SWIG_DIRECTOR_TYPEMAPS
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue