extending std_string and more fixes

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5771 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-03-18 21:20:55 +00:00
commit a672ff61ef
11 changed files with 248 additions and 111 deletions

View file

@ -47,7 +47,7 @@
%define %implicit_code(...)
if (swigpy::check<__VA_ARGS__ >(obj)) {
if (val) *val = new value_type(swigpy::as<__VA_ARGS__ >(obj));
return 2;
return SWIG_NEWPTR;
}
%enddef
@ -73,7 +73,7 @@ namespace swigpy {
static swig_type_info* desc = SWIG_TypeQuery("Type *");
if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) {
if (val) *val = vptr;
return 1;
return SWIG_OLDPTR;
} else {
if (PyErr_Occurred()) PyErr_Clear();
%formacro_1(%implicit_code,__VA_ARGS__)
@ -112,7 +112,7 @@ namespace swigpy {
static swig_type_info* desc = SWIG_TypeQuery("Type *");
if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) {
if (val) *val = vptr;
return 1;
return SWIG_OLDPTR;
} else {
if (PyErr_Occurred()) PyErr_Clear();
%implicit_code(Imp1);
@ -153,7 +153,7 @@ namespace swigpy {
static swig_type_info* desc = SWIG_TypeQuery("Type *");
if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) {
if (val) *val = vptr;
return 1;
return SWIG_OLDPTR;
} else {
if (PyErr_Occurred()) PyErr_Clear();
%implicit_code(Imp1);
@ -197,7 +197,7 @@ namespace swigpy {
static swig_type_info* desc = SWIG_TypeQuery("Type *");
if ((SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0) != -1)) {
if (val) *val = vptr;
return 1;
return SWIG_OLDPTR;
} else {
if (PyErr_Occurred()) PyErr_Clear();
%implicit_code(Imp1);

View file

@ -37,7 +37,13 @@ namespace swigpy
operator T () const
{
swigpy::PyObject_var item = PySequence_GetItem(_seq, _index);
return swigpy::as<T>(item);
try {
return swigpy::as<T>(item, true);
} catch (std::exception& e) {
PyErr_Format(PyExc_TypeError,
"error in sequence element %d: %s", _index, e.what());
throw;
}
}
PySequence_Ref& operator=(const T& v)

View file

@ -1,6 +1,9 @@
%{
/* Auxiliar swig macros that appear in the header */
#define SWIG_OLDPTR 1
#define SWIG_NEWPTR 2
#ifdef __cplusplus
#define SWIGSTATICINLINE(a) static inline a
#define SWIGSTATIC(a) static a

View file

@ -572,7 +572,7 @@ _apply_macro(Macro, bool, __VA_ARGS__);
%define %apply_cpptypes(Macro,...)
%apply_otypes(Macro, __VA_ARGS__)
_apply_macro(Macro, bool, __VA_ARGS__);
_apply_macro(Macro, std::string, __VA_ARGS__);
_apply_macro(Macro, std::basic_string<char>, __VA_ARGS__);
_apply_macro(Macro, std::complex<float>, __VA_ARGS__);
_apply_macro(Macro, std::complex<double>, __VA_ARGS__);
%enddef

View file

@ -7,106 +7,66 @@
%define PYPTR_IN_TYPEMAP(pyobj_asptr,pyfrag,...)
%typemap(in,fragment=pyfrag) __VA_ARGS__ {
__VA_ARGS__ *ptr;
__VA_ARGS__ *ptr = (__VA_ARGS__ *)0;
int res = pyobj_asptr($input, &ptr);
if (!res) SWIG_fail;
if (!res || !ptr) SWIG_fail;
$1 = *ptr;
if (res > 1) delete ptr;
if (res == SWIG_NEWPTR) delete ptr;
}
%typemap(in,fragment=pyfrag) const __VA_ARGS__ & (int res = 0)
"if (!(res = pyobj_asptr($input, &$1))) SWIG_fail;";
"if (!(res = pyobj_asptr($input, &$1)) || !($1)) SWIG_fail;";
%typemap(freearg) const __VA_ARGS__ &
"if (res$argnum > 1) delete $1;";
%enddef
/* out */
%define PYPTR_OUT_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(out,fragment=pyfrag) __VA_ARGS__
"$result = pyobj_from($1);";
%typemap(out,fragment=pyfrag) const __VA_ARGS__&
"$result = pyobj_from(*($1));";
%enddef
/* varin */
%define PYPTR_VARIN_TYPEMAP(pyobj_asptr,pyfrag,...)
%typemap(varin,fragment=pyfrag) __VA_ARGS__ {
__VA_ARGS__ *ptr;
__VA_ARGS__ *ptr = (__VA_ARGS__ *)0;
int res = pyobj_asptr($input, &ptr);
if (!res) {
if (!res || !ptr) {
PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'");
return 1;
}
if (!res) SWIG_fail;
$1 = *ptr;
if (res > 1) delete ptr;
if (res == SWIG_NEWPTR) delete ptr;
}
%enddef
/* varout */
%define PYPTR_VAROUT_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(varout,fragment=pyfrag) __VA_ARGS__, const __VA_ARGS__&
"$result = pyobj_from($1);";
%enddef
/* Primitive types */
%define PYPTR_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(constcode,fragment=pyfrag) __VA_ARGS__
"PyDict_SetItemString(d,\"$symname\", pyobj_from($value));";
%enddef
/* directorin */
%define PYPTR_DIRECTORIN_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(directorin,fragment=pyfrag) __VA_ARGS__
"$input = pyobj_from($1_name);";
%enddef
/* directorout */
%define PYPTR_DIRECTOROUT_TYPEMAP(pyobj_asptr,pyfrag,...)
%typemap(directorargout,fragment=pyfrag) __VA_ARGS__ *DIRECTOROUT ($*1_ltype temp) {
__VA_ARGS__ *ptr;
__VA_ARGS__ *ptr = 0;
int res = pyobj_asptr($input, &ptr);
if (!res)
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr");
temp = *ptr;
$result = &temp;
if (res > 1) delete ptr;
if (res == SWIG_NEWPTR) delete ptr;
}
%typemap(directorout,fragment=pyfrag) __VA_ARGS__ {
__VA_ARGS__ *ptr;
__VA_ARGS__ *ptr = 0;
int res = pyobj_asptr($input, &ptr);
if (!res)
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr");
$result = *ptr;
if (res > 1) delete ptr;
if (res == SWIG_NEWPTR) delete ptr;
}
%typemap(directorout,fragment=pyfrag) const __VA_ARGS__& ($*1_ltype temp) {
__VA_ARGS__ *ptr;
__VA_ARGS__ *ptr = 0;
int res = pyobj_asptr($input, &ptr);
if (!res)
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using pyobj_asptr");
temp = *ptr;
$result = &temp;
if (res > 1) delete ptr;
if (res == SWIG_NEWPTR) delete ptr;
}
%typemap(directorout,fragment=pyfrag) __VA_ARGS__ &DIRECTOROUT = __VA_ARGS__
%enddef
/* throws */
%define PYPTR_THROWS_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(throws,fragment=pyfrag) __VA_ARGS__ {
PyErr_SetObject(PyExc_RuntimeError, pyobj_from($1));
SWIG_fail;
}
%enddef
/* typecheck */
%define PYPTR_TYPECHECK_TYPEMAP(check,pyobj_asptr,pyfrag,...)
@ -121,25 +81,40 @@
%define %typemap_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, ...)
PYPTR_IN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__);
PYPTR_OUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYPTR_VARIN_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__);
PYPTR_VAROUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYPTR_CONSTCODE_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYPTR_DIRECTORIN_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYPTR_DIRECTOROUT_TYPEMAP(SWIG_arg(AsPtrMeth), SWIG_arg(AsPtrFrag), __VA_ARGS__);
PYPTR_THROWS_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag),__VA_ARGS__);
PYPTR_TYPECHECK_TYPEMAP(SWIG_arg(CheckCode), SWIG_arg(AsPtrMeth),
SWIG_arg(AsPtrFrag), __VA_ARGS__);
SWIG_arg(AsPtrFrag), __VA_ARGS__);
PYVAL_DIRECTORIN_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYVAL_OUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYVAL_VAROUT_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYVAL_CONSTCODE_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag), __VA_ARGS__);
PYVAL_THROWS_TYPEMAP(SWIG_arg(FromMeth), SWIG_arg(FromFrag),__VA_ARGS__);
%enddef
/*
typemap for simple swig types with only AsPtr/From conversor methods
typemap for simple swig types with only AsPtr/From methods
*/
%define %typemap_asptrfromn(CheckCode, ...)
%fragment(SWIG_AsVal_frag(__VA_ARGS__),"header",
fragment=SWIG_AsPtr_frag(__VA_ARGS__)) %{
SWIGSTATICINLINE(int)
SWIG_AsVal_meth(__VA_ARGS__)(PyObject* obj, __VA_ARGS__ *val)
{
__VA_ARGS__ *v = (__VA_ARGS__ *)0;
int res = SWIG_AsPtr_meth(__VA_ARGS__)(obj, &v);
if (!res || !v) return 0;
if (val) {
*val = *v;
if (res == SWIG_NEWPTR) delete v;
}
return 1;
}
%}
%typemap_asptrfrom(SWIG_arg(CheckCode),
SWIG_AsPtr_meth(__VA_ARGS__),
SWIG_From_meth(__VA_ARGS__),
SWIG_arg(SWIG_AsPtr_meth(__VA_ARGS__)),
SWIG_arg(SWIG_From_meth(__VA_ARGS__)),
SWIG_arg(SWIG_AsPtr_frag(__VA_ARGS__)),
SWIG_arg(SWIG_From_frag(__VA_ARGS__)),
__VA_ARGS__);

View file

@ -18,7 +18,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size)
if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_info, 0) != -1) {
if (cptr) *cptr = vptr;
if (size) *size = vptr ? (strlen(vptr) + 1) : 0;
return 1;
return SWIG_OLDPTR;
} else {
if (PyString_Check(obj)) {
#if PY_VERSION_HEX >= 0x02000000
@ -29,7 +29,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size)
#endif
if (cptr) *cptr = vptr;
if (size) *size = vsize;
return 2;
return SWIG_NEWPTR;
}
}
if (cptr || size) {

View file

@ -35,6 +35,7 @@
%include "pyobject.swg"
%include "pystrings.swg"
%include "pyvaltypes.swg"
%include "pyptrtypes.swg"
%include "pyprimtypes.swg"
%include "pymisctypes.swg"

View file

@ -45,7 +45,7 @@
"$result = pyobj_from((__VA_ARGS__)$1);";
%enddef
/* Primitive types */
/* constant installation code */
%define PYVAL_CONSTCODE_TYPEMAP(pyobj_from,pyfrag,...)
%typemap(constcode,fragment=pyfrag) __VA_ARGS__
"PyDict_SetItemString(d,\"$symname\", pyobj_from((__VA_ARGS__)$value));";

View file

@ -143,7 +143,7 @@ namespace swigpy {
int res = asptr(obj, &p);
if (res) {
*val = *p;
if (res > 1) delete p;
if (res == SWIG_NEWPTR) delete p;
}
return res;
} else {
@ -167,16 +167,16 @@ namespace swigpy {
struct traits_as<Type, value_category>
{
typedef Type value_type;
static value_type as(PyObject *obj) {
static value_type as(PyObject *obj, bool throw_error) {
value_type v;
if (!asval(obj, &v)) {
std::string msg= "a value of type '";
if (!obj || !asval(obj, &v)) {
std::string msg = "a value of type '";
msg += swigpy::type_name<Type>();
msg += "' is expected";
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, msg.c_str());
}
throw std::invalid_argument(msg);
if (throw_error) throw std::invalid_argument(msg);
}
return v;
}
@ -186,9 +186,9 @@ namespace swigpy {
struct traits_as<Type, pointer_category>
{
typedef Type value_type;
static value_type as(PyObject *obj) {
static value_type as(PyObject *obj, bool throw_error) {
value_type *v = 0;
int res = asptr(obj, &v);
int res = obj ? asptr(obj, &v) : 0;
if (res) {
if (res > 1) {
value_type r(*v);
@ -198,20 +198,20 @@ namespace swigpy {
return *v;
}
} else {
std::string msg= "a value of type '";
std::string msg = "a value of type '";
msg += swigpy::type_name<Type>();
msg += "' is expected";
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, msg.c_str());
}
throw std::invalid_argument(msg);
if (throw_error) throw std::invalid_argument(msg);
}
}
};
template <class Type>
inline Type as(PyObject *obj) {
return traits_as<Type, typename traits<Type>::category>::as(obj);
inline Type as(PyObject *obj, bool te = false) {
return traits_as<Type, typename traits<Type>::category>::as(obj, te);
}
template <class Type, class Category>
@ -224,7 +224,7 @@ namespace swigpy {
{
typedef Type value_type;
static bool check(PyObject *obj) {
return asval(obj, (value_type *)(0));
return obj && asval(obj, (value_type *)(0));
}
};
@ -233,7 +233,7 @@ namespace swigpy {
{
typedef Type value_type;
static bool check(PyObject *obj) {
return asptr(obj, (value_type **)(0));
return obj && asptr(obj, (value_type **)(0));
}
};

View file

@ -134,7 +134,7 @@
sequence *pseq = new sequence();
assign(pyseq, pseq);
*seq = pseq;
return 2;
return SWIG_NEWPTR;
} else {
return pyseq.check();
}

View file

@ -12,42 +12,194 @@
// However, I think I'll wait until someone asks for it...
// ------------------------------------------------------------------------
%include exception.i
%include pycontainer.i
%{
#include <string>
%}
namespace std {
template <class _CharT>
class basic_string
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _CharT value_type;
typedef value_type reference;
typedef value_type const_reference;
static const size_type npos;
/* defining the std::string as/from methods */
basic_string();
basic_string(const basic_string& __str);
basic_string(const _CharT* __s, size_type __n);
%fragment(SWIG_AsVal_frag(std::string),"header",
// Capacity:
size_type size() const;
size_type length() const;
size_type max_size() const;
void resize(size_type __n, _CharT __c);
void resize(size_type __n);
size_type capacity() const;
void reserve(size_type __res_arg = 0);
void clear();
bool empty() const;
// Modifiers:
basic_string
operator+=(const basic_string& __str);
basic_string&
append(const basic_string& __str);
basic_string&
append(const basic_string& __str, size_type __pos, size_type __n);
basic_string&
append(const _CharT* __s, size_type __n);
basic_string&
append(size_type __n, _CharT __c);
void push_back(_CharT __c);
basic_string&
assign(const basic_string& __str);
basic_string&
assign(const basic_string& __str, size_type __pos, size_type __n);
basic_string&
assign(const _CharT* __s, size_type __n);
basic_string&
assign(size_type __n, _CharT __c);
basic_string&
insert(size_type __pos1, const basic_string& __str);
basic_string&
insert(size_type __pos1, const basic_string& __str,
size_type __pos2, size_type __n);
basic_string&
insert(size_type __pos, const _CharT* __s, size_type __n);
basic_string&
insert(size_type __pos, size_type __n, _CharT __c);
basic_string&
erase(size_type __pos = 0, size_type __n = npos);
basic_string&
replace(size_type __pos, size_type __n, const basic_string& __str);
basic_string&
replace(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2);
basic_string&
replace(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2);
basic_string&
replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c);
%ignore pop();
%pysequence_methods_val(std::basic_string<_CharT>);
#ifdef SWIG_EXPORT_ITERATOR_METHODS
iterator
insert(iterator __p, _CharT __c = _CharT());
iterator
erase(iterator __position);
iterator
erase(iterator __first, iterator __last);
void
insert(iterator __p, size_type __n, _CharT __c);
basic_string&
replace(iterator __i1, iterator __i2, const basic_string& __str);
basic_string&
replace(iterator __i1, iterator __i2,
const _CharT* __s, size_type __n);
basic_string&
replace(iterator __i1, iterator __i2, const _CharT* __s);
basic_string&
replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
basic_string&
replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2);
basic_string&
replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2);
basic_string&
replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2);
basic_string&
replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2);
#endif
};
typedef basic_string<char> string;
}
/* defining the std::string asptr/from methods */
%fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
fragment="SWIG_AsCharPtrAndSize") {
SWIGSTATICINLINE(int)
SWIG_AsVal_meth(std::string)(PyObject* obj, std::string *val)
{
char* buf = 0 ; size_t size = 0;
if (SWIG_AsCharPtrAndSize(obj, &buf, &size)) {
if (buf) {
if (val) val->assign(buf, size);
return 1;
SWIG_AsPtr_meth(std::basic_string<char>)(PyObject* obj, std::string **val)
{
static swig_type_info* string_info = SWIG_TypeQuery("std::basic_string<char> *");
std::string *vptr;
if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) != -1) {
if (val) *val = vptr;
return SWIG_OLDPTR;
} else {
char* buf = 0 ; size_t size = 0;
if (SWIG_AsCharPtrAndSize(obj, &buf, &size)) {
if (buf) {
if (val) *val = new std::string(buf, size);
return SWIG_NEWPTR;
}
} else {
PyErr_Clear();
}
if (val) {
PyErr_SetString(PyExc_TypeError,"a string is expected");
}
return 0;
}
} else {
PyErr_Clear();
}
if (val) {
PyErr_SetString(PyExc_TypeError,"a string is expected");
}
return 0;
}
}
%fragment(SWIG_From_frag(std::string),"header",
%fragment(SWIG_From_frag(std::basic_string<char>),"header",
fragment="SWIG_FromCharArray") {
SWIGSTATICINLINE(PyObject*)
SWIG_From_meth(std::string)(const std::string& s) {
return SWIG_FromCharArray(s.data(), s.size());
}
SWIG_From_meth(std::basic_string<char>)(const std::string& s)
{
return SWIG_FromCharArray(s.data(), s.size());
}
}
%typemap_primitive(SWIG_CCode(STRING), std::string);
%typemap_asptrfromn(SWIG_CCode(STRING), std::basic_string<char>);
/* declaring the typemaps */