diff options
author | robot-piglet <[email protected]> | 2023-12-02 01:45:21 +0300 |
---|---|---|
committer | robot-piglet <[email protected]> | 2023-12-02 02:42:50 +0300 |
commit | 9c43d58f75cf086b744cf4fe2ae180e8f37e4a0c (patch) | |
tree | 9f88a486917d371d099cd712efd91b4c122d209d /contrib/tools/swig | |
parent | 32fb6dda1feb24f9ab69ece5df0cb9ec238ca5e6 (diff) |
Intermediate changes
Diffstat (limited to 'contrib/tools/swig')
40 files changed, 5004 insertions, 0 deletions
diff --git a/contrib/tools/swig/Lib/exception.i b/contrib/tools/swig/Lib/exception.i new file mode 100644 index 00000000000..5cdea58e8b2 --- /dev/null +++ b/contrib/tools/swig/Lib/exception.i @@ -0,0 +1,332 @@ +/* ----------------------------------------------------------------------------- + * exception.i + * + * SWIG library file providing language independent exception handling + * ----------------------------------------------------------------------------- */ + +#if defined(SWIGUTL) +#error "This version of exception.i should not be used" +#endif + + +%insert("runtime") "swigerrors.swg" + + +#ifdef SWIGPHP +%{ +#if PHP_MAJOR_VERSION >= 8 +# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code) code == SWIG_ValueError ? zend_ce_value_error : +#else +# define SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code) +#endif +#define SWIG_exception(code, msg) do { zend_throw_exception( \ + code == SWIG_TypeError ? zend_ce_type_error : \ + SWIG_HANDLE_VALUE_ERROR_FOR_PHP8(code) \ + code == SWIG_DivisionByZero ? zend_ce_division_by_zero_error : \ + code == SWIG_SyntaxError ? zend_ce_parse_error : \ + code == SWIG_OverflowError ? zend_ce_arithmetic_error : \ + NULL, msg, code); SWIG_fail; } while (0) +%} +#endif + +#ifdef SWIGGUILE +%{ + SWIGINTERN void SWIG_exception_ (int code, const char *msg, + const char *subr) { +#define ERROR(scmerr) \ + scm_error(scm_from_locale_string((char *) (scmerr)), \ + (char *) subr, (char *) msg, \ + SCM_EOL, SCM_BOOL_F) +#define MAP(swigerr, scmerr) \ + case swigerr: \ + ERROR(scmerr); \ + break + switch (code) { + MAP(SWIG_MemoryError, "swig-memory-error"); + MAP(SWIG_IOError, "swig-io-error"); + MAP(SWIG_RuntimeError, "swig-runtime-error"); + MAP(SWIG_IndexError, "swig-index-error"); + MAP(SWIG_TypeError, "swig-type-error"); + MAP(SWIG_DivisionByZero, "swig-division-by-zero"); + MAP(SWIG_OverflowError, "swig-overflow-error"); + MAP(SWIG_SyntaxError, "swig-syntax-error"); + MAP(SWIG_ValueError, "swig-value-error"); + MAP(SWIG_SystemError, "swig-system-error"); + default: + ERROR("swig-error"); + } +#undef ERROR +#undef MAP + } + +#define SWIG_exception(a,b) SWIG_exception_(a, b, FUNC_NAME) +%} +#endif + +#ifdef SWIGMZSCHEME + +%{ +SWIGINTERN void SWIG_exception_ (int code, const char *msg) { +#define ERROR(errname) \ + scheme_signal_error(errname " (%s)", msg); +#define MAP(swigerr, errname) \ + case swigerr: \ + ERROR(errname); \ + break + switch (code) { + MAP(SWIG_MemoryError, "swig-memory-error"); + MAP(SWIG_IOError, "swig-io-error"); + MAP(SWIG_RuntimeError, "swig-runtime-error"); + MAP(SWIG_IndexError, "swig-index-error"); + MAP(SWIG_TypeError, "swig-type-error"); + MAP(SWIG_DivisionByZero, "swig-division-by-zero"); + MAP(SWIG_OverflowError, "swig-overflow-error"); + MAP(SWIG_SyntaxError, "swig-syntax-error"); + MAP(SWIG_ValueError, "swig-value-error"); + MAP(SWIG_SystemError, "swig-system-error"); + default: + ERROR("swig-error"); + } +#undef ERROR +#undef MAP + } + +#define SWIG_exception(a,b) SWIG_exception_(a, b) +%} +#endif + +#ifdef SWIGJAVA +%{ +SWIGINTERN void SWIG_JavaException(JNIEnv *jenv, int code, const char *msg) { + SWIG_JavaExceptionCodes exception_code = SWIG_JavaUnknownError; + switch(code) { + case SWIG_MemoryError: + exception_code = SWIG_JavaOutOfMemoryError; + break; + case SWIG_IOError: + exception_code = SWIG_JavaIOException; + break; + case SWIG_SystemError: + case SWIG_RuntimeError: + exception_code = SWIG_JavaRuntimeException; + break; + case SWIG_OverflowError: + case SWIG_IndexError: + exception_code = SWIG_JavaIndexOutOfBoundsException; + break; + case SWIG_DivisionByZero: + exception_code = SWIG_JavaArithmeticException; + break; + case SWIG_SyntaxError: + case SWIG_ValueError: + case SWIG_TypeError: + exception_code = SWIG_JavaIllegalArgumentException; + break; + case SWIG_UnknownError: + default: + exception_code = SWIG_JavaUnknownError; + break; + } + SWIG_JavaThrowException(jenv, exception_code, msg); +} +%} + +#define SWIG_exception(code, msg)\ +{ SWIG_JavaException(jenv, code, msg); return $null; } +#endif // SWIGJAVA + +#ifdef SWIGOCAML +%{ +SWIGINTERN void SWIG_OCamlException(int code, const char *msg) { + CAMLparam0(); + + SWIG_OCamlExceptionCodes exception_code = SWIG_OCamlUnknownError; + switch (code) { + case SWIG_DivisionByZero: + exception_code = SWIG_OCamlArithmeticException; + break; + case SWIG_IndexError: + exception_code = SWIG_OCamlIndexOutOfBoundsException; + break; + case SWIG_IOError: + case SWIG_SystemError: + exception_code = SWIG_OCamlSystemException; + break; + case SWIG_MemoryError: + exception_code = SWIG_OCamlOutOfMemoryError; + break; + case SWIG_OverflowError: + exception_code = SWIG_OCamlOverflowException; + break; + case SWIG_RuntimeError: + exception_code = SWIG_OCamlRuntimeException; + break; + case SWIG_SyntaxError: + case SWIG_TypeError: + case SWIG_ValueError: + exception_code = SWIG_OCamlIllegalArgumentException; + break; + case SWIG_UnknownError: + default: + exception_code = SWIG_OCamlUnknownError; + break; + } + SWIG_OCamlThrowException(exception_code, msg); + CAMLreturn0; +} +#define SWIG_exception(code, msg) SWIG_OCamlException(code, msg) +%} +#endif + + +#ifdef SWIGCSHARP +%{ +SWIGINTERN void SWIG_CSharpException(int code, const char *msg) { + if (code == SWIG_ValueError) { + SWIG_CSharpExceptionArgumentCodes exception_code = SWIG_CSharpArgumentOutOfRangeException; + SWIG_CSharpSetPendingExceptionArgument(exception_code, msg, 0); + } else { + SWIG_CSharpExceptionCodes exception_code = SWIG_CSharpApplicationException; + switch(code) { + case SWIG_MemoryError: + exception_code = SWIG_CSharpOutOfMemoryException; + break; + case SWIG_IndexError: + exception_code = SWIG_CSharpIndexOutOfRangeException; + break; + case SWIG_DivisionByZero: + exception_code = SWIG_CSharpDivideByZeroException; + break; + case SWIG_IOError: + exception_code = SWIG_CSharpIOException; + break; + case SWIG_OverflowError: + exception_code = SWIG_CSharpOverflowException; + break; + case SWIG_RuntimeError: + case SWIG_TypeError: + case SWIG_SyntaxError: + case SWIG_SystemError: + case SWIG_UnknownError: + default: + exception_code = SWIG_CSharpApplicationException; + break; + } + SWIG_CSharpSetPendingException(exception_code, msg); + } +} +%} + +#define SWIG_exception(code, msg)\ +{ SWIG_CSharpException(code, msg); return $null; } +#endif // SWIGCSHARP + +#ifdef SWIGLUA + +%{ +#define SWIG_exception(a,b)\ +{ lua_pushfstring(L,"%s:%s",#a,b);SWIG_fail; } +%} + +#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 + directive as follows: + + %exception { + try { + $action + } + catch (my_except& e) { + ... + } + SWIG_CATCH_STDEXCEPT // catch std::exception + catch (...) { + SWIG_exception(SWIG_UnknownError, "Unknown exception"); + } + } +*/ +%{ +#include <typeinfo> +#include <stdexcept> +%} +%define SWIG_CATCH_STDEXCEPT + /* catching std::exception */ + catch (std::invalid_argument& e) { + SWIG_exception(SWIG_ValueError, e.what() ); + } catch (std::domain_error& e) { + SWIG_exception(SWIG_ValueError, e.what() ); + } catch (std::overflow_error& e) { + SWIG_exception(SWIG_OverflowError, e.what() ); + } catch (std::out_of_range& e) { + SWIG_exception(SWIG_IndexError, e.what() ); + } catch (std::length_error& e) { + SWIG_exception(SWIG_IndexError, e.what() ); + } catch (std::runtime_error& e) { + SWIG_exception(SWIG_RuntimeError, e.what() ); + } catch (std::bad_cast& e) { + SWIG_exception(SWIG_TypeError, e.what() ); + } catch (std::exception& e) { + SWIG_exception(SWIG_SystemError, e.what() ); + } +%enddef +%define SWIG_CATCH_UNKNOWN + catch (std::exception& e) { + SWIG_exception(SWIG_SystemError, e.what() ); + } + catch (...) { + SWIG_exception(SWIG_UnknownError, "unknown exception"); + } +%enddef + +/* rethrow the unknown exception */ + +#if defined(SWIGCSHARP) || defined(SWIGD) +%typemap(throws,noblock=1, canthrow=1) (...) { + SWIG_exception(SWIG_RuntimeError,"unknown exception"); +} +#else +%typemap(throws,noblock=1) (...) { + SWIG_exception(SWIG_RuntimeError,"unknown exception"); +} +#endif + +#endif /* __cplusplus */ + +/* exception.i ends here */ diff --git a/contrib/tools/swig/Lib/go/exception.i b/contrib/tools/swig/Lib/go/exception.i new file mode 100644 index 00000000000..5abd306a4ed --- /dev/null +++ b/contrib/tools/swig/Lib/go/exception.i @@ -0,0 +1,7 @@ +%typemap(throws,noblock=1) (...) { + SWIG_exception(SWIG_RuntimeError,"unknown exception"); +} + +%insert("runtime") %{ +#define SWIG_exception(code, msg) _swig_gopanic(msg) +%} diff --git a/contrib/tools/swig/Lib/go/std_common.i b/contrib/tools/swig/Lib/go/std_common.i new file mode 100644 index 00000000000..c010facacd1 --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_common.i @@ -0,0 +1,4 @@ +%include <std_except.i> + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; diff --git a/contrib/tools/swig/Lib/go/std_except.i b/contrib/tools/swig/Lib/go/std_except.i new file mode 100644 index 00000000000..4f021a1264a --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_except.i @@ -0,0 +1,31 @@ +/* ----------------------------------------------------------------------------- + * 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 <typeinfo> +#include <stdexcept> +%} + +namespace std +{ + %ignore exception; + struct exception {}; +} + +%typemap(throws) std::bad_cast %{_swig_gopanic($1.what());%} +%typemap(throws) std::bad_exception %{_swig_gopanic($1.what());%} +%typemap(throws) std::domain_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::exception %{_swig_gopanic($1.what());%} +%typemap(throws) std::invalid_argument %{_swig_gopanic($1.what());%} +%typemap(throws) std::length_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::logic_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::out_of_range %{_swig_gopanic($1.what());%} +%typemap(throws) std::overflow_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::range_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::runtime_error %{_swig_gopanic($1.what());%} +%typemap(throws) std::underflow_error %{_swig_gopanic($1.what());%} diff --git a/contrib/tools/swig/Lib/go/std_string.i b/contrib/tools/swig/Lib/go/std_string.i new file mode 100644 index 00000000000..35b4a5e46b1 --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_string.i @@ -0,0 +1,162 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string& + * These are mapped to a Go string 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; + +%typemap(gotype) string, const string & "string" + +%typemap(in) string +%{ $1.assign($input.p, $input.n); %} + +%typemap(godirectorout) string +%{ + { + p := Swig_malloc(len($input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input)] + copy(s, $input) + $result = *(*string)(unsafe.Pointer(&s)) + } +%} + +%typemap(directorout) string +%{ + $result.assign($input.p, $input.n); + free($input.p); +%} + +%typemap(out,fragment="AllocateString") string +%{ $result = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(goout,fragment="CopyString") string +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") string +%{ $input = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(godirectorin,fragment="CopyString") string +%{ $result = swigCopyString($input) %} + +%typemap(throws) string +%{ _swig_gopanic($1.c_str()); %} + +%typemap(in) const string & +%{ + $*1_ltype $1_str($input.p, $input.n); + $1 = &$1_str; +%} + +%typemap(godirectorout) const string & +%{ + { + p := Swig_malloc(len($input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input)] + copy(s, $input) + $result = *(*string)(unsafe.Pointer(&s)) + } +%} + +%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string & +%{ + static $*1_ltype $1_str; + $1_str.assign($input.p, $input.n); + free($input.p); + $result = &$1_str; +%} + +%typemap(out,fragment="AllocateString") const string & +%{ $result = Swig_AllocateString((*$1).data(), (*$1).length()); %} + +%typemap(goout,fragment="CopyString") const string & +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") const string & +%{ $input = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(godirectorin,fragment="CopyString") const string & +%{ $result = swigCopyString($input) %} + +%typemap(throws) const string & +%{ _swig_gopanic($1.c_str()); %} + + +%typemap(gotype) string * "*string" + +%typemap(in) string * (string temp) +%{ + if ($input) { + temp.assign($input->p, $input->n); + $1 = &temp; + } else + $1 = 0; +%} + +%typemap(godirectorout) string * +%{ + if $input != nil { + p := Swig_malloc(len(*$input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len(*$input)] + copy(s, *$input) + $result = (*string)(unsafe.Pointer(&s)) + } else { + $result = nil + } +%} + +%typemap(directorout) string * (string temp) +%{ + temp.assign($input->p, $input->n); + $result = &temp; + free($input.p); +%} + +%typemap(out,fragment="AllocateString") string * (_gostring_ temp) +%{ + temp = Swig_AllocateString($1->data(), $1->length()); + $result = &temp; +%} + +%typemap(goout,fragment="CopyString") string * +%{ *$result = swigCopyString(*$1) %} + +%typemap(directorin,fragment="AllocateString") string * (_gostring_ temp) +%{ + if ($1) { + temp = Swig_AllocateString($1->data(), $1->length()); + $input = &temp; + } else + $input = 0; +%} + +%typemap(godirectorin,fragment="CopyString") string * +%{ *$result = swigCopyString(*$input); %} + +%typemap(argout,fragment="AllocateString") string * +%{ + if ($1) + *$input = Swig_AllocateString($1->data(), $1->length()); +%} + +%typemap(goargout,fragment="CopyString") string * +%{ + if $input != nil { + *$1 = swigCopyString(*$input) + } +%} + +} diff --git a/contrib/tools/swig/Lib/go/std_vector.i b/contrib/tools/swig/Lib/go/std_vector.i new file mode 100644 index 00000000000..679c707596e --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_vector.i @@ -0,0 +1,92 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%{ +#include <vector> +#include <stdexcept> +%} + +namespace std { + + template<class T> class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + vector(); + vector(size_type n); + vector(const vector& other); + + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, const value_type& val) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = val; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + + // bool specialization + template<> class vector<bool> { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef bool value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef bool const_reference; + + vector(); + vector(size_type n); + vector(const vector& other); + + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + bool get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, const value_type& val) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = val; + else + throw std::out_of_range("vector index out of range"); + } + } + }; +} diff --git a/contrib/tools/swig/Lib/java/std_common.i b/contrib/tools/swig/Lib/java/std_common.i new file mode 100644 index 00000000000..cee11e8caa5 --- /dev/null +++ b/contrib/tools/swig/Lib/java/std_common.i @@ -0,0 +1,5 @@ +%include <std_except.i> + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/contrib/tools/swig/Lib/java/std_except.i b/contrib/tools/swig/Lib/java/std_except.i new file mode 100644 index 00000000000..91d2f92cf14 --- /dev/null +++ b/contrib/tools/swig/Lib/java/std_except.i @@ -0,0 +1,32 @@ +/* ----------------------------------------------------------------------------- + * 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 <typeinfo> +#include <stdexcept> +%} + +namespace std +{ + %ignore exception; + struct exception {}; +} + +%typemap(throws) std::bad_cast "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::bad_exception "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::domain_error "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::exception "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::invalid_argument "SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, $1.what());\n return $null;" +%typemap(throws) std::length_error "SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, $1.what());\n return $null;" +%typemap(throws) std::logic_error "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::out_of_range "SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, $1.what());\n return $null;" +%typemap(throws) std::overflow_error "SWIG_JavaThrowException(jenv, SWIG_JavaArithmeticException, $1.what());\n return $null;" +%typemap(throws) std::range_error "SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, $1.what());\n return $null;" +%typemap(throws) std::runtime_error "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" +%typemap(throws) std::underflow_error "SWIG_JavaThrowException(jenv, SWIG_JavaArithmeticException, $1.what());\n return $null;" + diff --git a/contrib/tools/swig/Lib/java/std_string.i b/contrib/tools/swig/Lib/java/std_string.i new file mode 100644 index 00000000000..830a8961198 --- /dev/null +++ b/contrib/tools/swig/Lib/java/std_string.i @@ -0,0 +1,121 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string& + * These are mapped to a Java String 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; + +// string +%typemap(jni) string "jstring" +%typemap(jtype) string "String" +%typemap(jstype) string "String" +%typemap(javadirectorin) string "$jniinput" +%typemap(javadirectorout) string "$javacall" + +%typemap(in) string +%{ if(!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return $null; + } + const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!$1_pstr) return $null; + $1.assign($1_pstr); + jenv->ReleaseStringUTFChars($input, $1_pstr); %} + +%typemap(directorout) string +%{ if(!$input) { + if (!jenv->ExceptionCheck()) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + } + return $null; + } + const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!$1_pstr) return $null; + $result.assign($1_pstr); + jenv->ReleaseStringUTFChars($input, $1_pstr); %} + +%typemap(directorin,descriptor="Ljava/lang/String;") string +%{ $input = jenv->NewStringUTF($1.c_str()); + Swig::LocalRefGuard $1_refguard(jenv, $input); %} + +%typemap(out) string +%{ $result = jenv->NewStringUTF($1.c_str()); %} + +%typemap(javain) string "$javainput" + +%typemap(javaout) string { + return $jnicall; + } + +%typemap(typecheck) string = char *; + +%typemap(throws) string +%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.c_str()); + return $null; %} + +// const string & +%typemap(jni) const string & "jstring" +%typemap(jtype) const string & "String" +%typemap(jstype) const string & "String" +%typemap(javadirectorin) const string & "$jniinput" +%typemap(javadirectorout) const string & "$javacall" + +%typemap(in) const string & +%{ if(!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return $null; + } + const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!$1_pstr) return $null; + $*1_ltype $1_str($1_pstr); + $1 = &$1_str; + jenv->ReleaseStringUTFChars($input, $1_pstr); %} + +%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string & +%{ if(!$input) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return $null; + } + const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0); + if (!$1_pstr) return $null; + /* possible thread/reentrant code problem */ + static $*1_ltype $1_str; + $1_str = $1_pstr; + $result = &$1_str; + jenv->ReleaseStringUTFChars($input, $1_pstr); %} + +%typemap(directorin,descriptor="Ljava/lang/String;") const string & +%{ $input = jenv->NewStringUTF($1.c_str()); + Swig::LocalRefGuard $1_refguard(jenv, $input); %} + +%typemap(out) const string & +%{ $result = jenv->NewStringUTF($1->c_str()); %} + +%typemap(javain) const string & "$javainput" + +%typemap(javaout) const string & { + return $jnicall; + } + +%typemap(typecheck) const string & = char *; + +%typemap(throws) const string & +%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.c_str()); + return $null; %} + +} + diff --git a/contrib/tools/swig/Lib/java/std_vector.i b/contrib/tools/swig/Lib/java/std_vector.i new file mode 100644 index 00000000000..60ee23ebbe5 --- /dev/null +++ b/contrib/tools/swig/Lib/java/std_vector.i @@ -0,0 +1,185 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * + * SWIG typemaps for std::vector. + * The Java proxy class extends java.util.AbstractList and implements + * java.util.RandomAccess. The std::vector container looks and feels much like a + * java.util.ArrayList from Java. + * ----------------------------------------------------------------------------- */ + +%include <std_common.i> + +%{ +#include <vector> +#include <stdexcept> +%} + +%fragment("SWIG_VectorSize", "header", fragment="SWIG_JavaIntFromSize_t") { +SWIGINTERN jint SWIG_VectorSize(size_t size) { + jint sz = SWIG_JavaIntFromSize_t(size); + if (sz == -1) + throw std::out_of_range("vector size is too large to fit into a Java int"); + return sz; +} +} + +%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CTYPE, CONST_REFERENCE) +%typemap(javabase) std::vector< CTYPE > "java.util.AbstractList<$typemap(jboxtype, CTYPE)>" +%typemap(javainterfaces) std::vector< CTYPE > "java.util.RandomAccess" +%proxycode %{ + public $javaclassname($typemap(jstype, CTYPE)[] initialElements) { + this(); + reserve(initialElements.length); + + for ($typemap(jstype, CTYPE) element : initialElements) { + add(element); + } + } + + public $javaclassname(Iterable<$typemap(jboxtype, CTYPE)> initialElements) { + this(); + for ($typemap(jstype, CTYPE) element : initialElements) { + add(element); + } + } + + public $typemap(jboxtype, CTYPE) get(int index) { + return doGet(index); + } + + public $typemap(jboxtype, CTYPE) set(int index, $typemap(jboxtype, CTYPE) e) { + return doSet(index, e); + } + + public boolean add($typemap(jboxtype, CTYPE) e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, $typemap(jboxtype, CTYPE) e) { + modCount++; + doAdd(index, e); + } + + public $typemap(jboxtype, CTYPE) remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } +%} + + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef CTYPE value_type; + typedef CTYPE *pointer; + typedef CTYPE const *const_pointer; + typedef CTYPE &reference; + typedef CONST_REFERENCE const_reference; + + vector(); + vector(const vector &other); + + size_type capacity() const; + void reserve(size_type n) throw (std::length_error); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %extend { + %fragment("SWIG_VectorSize"); + + vector(jint count, const CTYPE &value) throw (std::out_of_range) { + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< CTYPE >(static_cast<std::vector< CTYPE >::size_type>(count), value); + } + + jint doSize() const throw (std::out_of_range) { + return SWIG_VectorSize(self->size()); + } + + void doAdd(const value_type& x) { + self->push_back(x); + } + + void doAdd(jint index, const value_type& x) throw (std::out_of_range) { + jint size = static_cast<jint>(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, x); + } else { + throw std::out_of_range("vector index out of range"); + } + } + + value_type doRemove(jint index) throw (std::out_of_range) { + jint size = static_cast<jint>(self->size()); + if (0 <= index && index < size) { + CTYPE const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } + + CONST_REFERENCE doGet(jint index) throw (std::out_of_range) { + jint size = static_cast<jint>(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } + + value_type doSet(jint index, const value_type& val) throw (std::out_of_range) { + jint size = static_cast<jint>(self->size()); + if (index >= 0 && index < size) { + CTYPE const old_value = (*self)[index]; + (*self)[index] = val; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } + + void doRemoveRange(jint fromIndex, jint toIndex) throw (std::out_of_range) { + jint size = static_cast<jint>(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } + } +%enddef + +%javamethodmodifiers std::vector::doSize "private"; +%javamethodmodifiers std::vector::doAdd "private"; +%javamethodmodifiers std::vector::doGet "private"; +%javamethodmodifiers std::vector::doSet "private"; +%javamethodmodifiers std::vector::doRemove "private"; +%javamethodmodifiers std::vector::doRemoveRange "private"; + +namespace std { + + template<class T> class vector { + SWIG_STD_VECTOR_MINIMUM_INTERNAL(T, const value_type&) + }; + + // bool specialization + template<> class vector<bool> { + SWIG_STD_VECTOR_MINIMUM_INTERNAL(bool, bool) + }; +} + +%define specialize_std_vector(T) +#warning "specialize_std_vector - specialization for type T no longer needed" +%enddef diff --git a/contrib/tools/swig/Lib/perl5/exception.i b/contrib/tools/swig/Lib/perl5/exception.i new file mode 100644 index 00000000000..b786f25e299 --- /dev/null +++ b/contrib/tools/swig/Lib/perl5/exception.i @@ -0,0 +1,5 @@ +%include <typemaps/exception.swg> + +%insert("runtime") { + %define_as(SWIG_exception(code, msg), %block(%error(code, msg); SWIG_fail; )) +} diff --git a/contrib/tools/swig/Lib/perl5/std_common.i b/contrib/tools/swig/Lib/perl5/std_common.i new file mode 100644 index 00000000000..7c1ff232899 --- /dev/null +++ b/contrib/tools/swig/Lib/perl5/std_common.i @@ -0,0 +1,28 @@ +/* ----------------------------------------------------------------------------- + * std_common.i + * + * SWIG typemaps for STL - common utilities + * ----------------------------------------------------------------------------- */ + +%include <std/std_except.i> + +%apply size_t { std::size_t }; + +%fragment("<string>"); +%{ +SWIGINTERN +double SwigSvToNumber(SV* sv) { + return SvIOK(sv) ? double(SvIVX(sv)) : SvNVX(sv); +} +SWIGINTERN +std::string SwigSvToString(SV* sv) { + STRLEN len; + char *ptr = SvPV(sv, len); + return std::string(ptr, len); +} +SWIGINTERN +void SwigSvFromString(SV* sv, const std::string& s) { + sv_setpvn(sv,s.data(),s.size()); +} +%} + diff --git a/contrib/tools/swig/Lib/perl5/std_except.i b/contrib/tools/swig/Lib/perl5/std_except.i new file mode 100644 index 00000000000..af98428f65d --- /dev/null +++ b/contrib/tools/swig/Lib/perl5/std_except.i @@ -0,0 +1 @@ +%include <typemaps/std_except.swg> diff --git a/contrib/tools/swig/Lib/perl5/std_string.i b/contrib/tools/swig/Lib/perl5/std_string.i new file mode 100644 index 00000000000..6f34f18475f --- /dev/null +++ b/contrib/tools/swig/Lib/perl5/std_string.i @@ -0,0 +1,2 @@ +%include <perlstrings.swg> +%include <typemaps/std_string.swg> diff --git a/contrib/tools/swig/Lib/perl5/std_vector.i b/contrib/tools/swig/Lib/perl5/std_vector.i new file mode 100644 index 00000000000..5bfd2c5ac8a --- /dev/null +++ b/contrib/tools/swig/Lib/perl5/std_vector.i @@ -0,0 +1,592 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * + * SWIG typemaps for std::vector types + * ----------------------------------------------------------------------------- */ + +%include <std_common.i> + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Perl as much as possible, namely, to allow the user to pass and +// be returned Perl arrays. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*): +// the parameter being read-only, either a Perl sequence or a +// previously wrapped std::vector<T> can be passed. +// -- f(std::vector<T>&), f(std::vector<T>*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector<T> f(): +// the vector is returned by copy; therefore, a Perl sequence of T:s +// is returned which is most easily used in other Perl functions +// -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(), +// const std::vector<T>* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include <vector> +%} +%fragment("<algorithm>"); +%fragment("<stdexcept>"); + +// exported class + +namespace std { + + template<class T> class vector { + %typemap(in) vector<T> (std::vector<T>* v) { + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,1) != -1) { + $1 = *v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + T* obj; + for (int i=0; i<len; i++) { + tv = av_fetch(av, i, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) { + $1.push_back(*obj); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(in) const vector<T>& (std::vector<T> temp, + std::vector<T>* v), + const vector<T>* (std::vector<T> temp, + std::vector<T>* v) { + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1) { + $1 = v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + T* obj; + for (int i=0; i<len; i++) { + tv = av_fetch(av, i, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) { + temp.push_back(*obj); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + $1 = &temp; + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(out) vector<T> { + size_t len = $1.size(); + SV **svs = new SV*[len]; + for (size_t i=0; i<len; i++) { + T* ptr = new T($1[i]); + svs[i] = sv_newmortal(); + SWIG_MakePtr(svs[i], (void*) ptr, + $descriptor(T *), $shadow|$owner); + } + AV *myav = av_make(len, svs); + delete[] svs; + $result = newRV_noinc((SV*) myav); + sv_2mortal($result); + argvi++; + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { + { + /* wrapped vector? */ + std::vector< T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* obj; + SV **tv = av_fetch(av, 0, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, + const vector<T>* { + { + /* wrapped vector? */ + std::vector< T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* obj; + SV **tv = av_fetch(av, 0, 0); + if (SWIG_ConvertPtr(*tv, (void **)&obj, + $descriptor(T *),0) != -1) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector& other); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(const T& x); + %extend { + T pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, const T& x) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = x; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + + // specializations for pointers + template<class T> class vector<T*> { + %typemap(in) vector<T*> (std::vector<T*>* v) { + int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0); + if (SWIG_IsOK(res)){ + $1 = *v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + I32 len = av_len(av) + 1; + for (int i=0; i<len; i++) { + void *v; + SV **tv = av_fetch(av, i, 0); + int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0); + if (SWIG_IsOK(res)) { + $1.push_back(%static_cast(v, T *)); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(in) const vector<T *>& (std::vector<T *> temp,std::vector<T *>* v), + const vector<T *>* (std::vector<T *> temp,std::vector<T *>* v) { + int res = SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0); + if (SWIG_IsOK(res)) { + $1 = v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + I32 len = av_len(av) + 1; + for (int i=0; i<len; i++) { + void *v; + SV **tv = av_fetch(av, i, 0); + int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0); + if (SWIG_IsOK(res)) { + temp.push_back(%static_cast(v, T *)); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + $1 = &temp; + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(out) vector<T *> { + size_t len = $1.size(); + SV **svs = new SV*[len]; + for (size_t i=0; i<len; i++) { + T *x = (($1_type &)$1)[i]; + svs[i] = sv_newmortal(); + sv_setsv(svs[i], SWIG_NewPointerObj(x, $descriptor(T *), 0)); + } + AV *myav = av_make(len, svs); + delete[] svs; + $result = newRV_noinc((SV*) myav); + sv_2mortal($result); + argvi++; + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector<T *> { + { + /* wrapped vector? */ + std::vector< T *>* v; + int res = SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0); + if (SWIG_IsOK(res)) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + void *v; + SV **tv = av_fetch(av, 0, 0); + int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0); + if (SWIG_IsOK(res)) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T *>&,const vector<T *>* { + { + /* wrapped vector? */ + std::vector< T *> *v; + int res = SWIG_ConvertPtr($input,%as_voidptrptr(&v), $1_descriptor,0); + if (SWIG_IsOK(res)) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + void *v; + SV **tv = av_fetch(av, 0, 0); + int res = SWIG_ConvertPtr(*tv, &v, $descriptor(T *),0); + if (SWIG_IsOK(res)) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + vector(unsigned int size = 0); + vector(unsigned int size, T *value); + vector(const vector& other); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(T *x); + %extend { + T *pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T *x = self->back(); + self->pop_back(); + return x; + } + T *get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, T *x) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = x; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + + + // specializations for built-ins + + %define specialize_std_vector(T,CHECK_T,TO_T,FROM_T) + template<> class vector<T> { + %typemap(in) vector<T> (std::vector<T>* v) { + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,1) != -1){ + $1 = *v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + for (int i=0; i<len; i++) { + tv = av_fetch(av, i, 0); + if (CHECK_T(*tv)) { + $1.push_back((T)TO_T(*tv)); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(in) const vector<T>& (std::vector<T> temp, + std::vector<T>* v), + const vector<T>* (std::vector<T> temp, + std::vector<T>* v) { + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,1) != -1) { + $1 = v; + } else if (SvROK($input)) { + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) != SVt_PVAV) + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + SV **tv; + I32 len = av_len(av) + 1; + for (int i=0; i<len; i++) { + tv = av_fetch(av, i, 0); + if (CHECK_T(*tv)) { + temp.push_back((T)TO_T(*tv)); + } else { + SWIG_croak("Type error in argument $argnum of " + "$symname. " + "Expected an array of " #T); + } + } + $1 = &temp; + } else { + SWIG_croak("Type error in argument $argnum of $symname. " + "Expected an array of " #T); + } + } + %typemap(out) vector<T> { + size_t len = $1.size(); + SV **svs = new SV*[len]; + for (size_t i=0; i<len; i++) { + svs[i] = sv_newmortal(); + FROM_T(svs[i], $1[i]); + } + AV *myav = av_make(len, svs); + delete[] svs; + $result = newRV_noinc((SV*) myav); + sv_2mortal($result); + argvi++; + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { + { + /* wrapped vector? */ + std::vector< T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor,0) != -1) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + SV **tv = av_fetch(av, 0, 0); + if (CHECK_T(*tv)) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, + const vector<T>* { + { + /* wrapped vector? */ + std::vector< T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor,0) != -1) { + $1 = 1; + } else if (SvROK($input)) { + /* native sequence? */ + AV *av = (AV *)SvRV($input); + if (SvTYPE(av) == SVt_PVAV) { + I32 len = av_len(av) + 1; + if (len == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + SV **tv = av_fetch(av, 0, 0); + if (CHECK_T(*tv)) + $1 = 1; + else + $1 = 0; + } + } + } else { + $1 = 0; + } + } + } + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + vector(unsigned int size = 0); + vector(unsigned int size, T value); + vector(const vector& other); + + unsigned int size() const; + bool empty() const; + void clear(); + %rename(push) push_back; + void push_back(T x); + %extend { + T pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, T x) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = x; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + %enddef + + specialize_std_vector(bool,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(char,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(int,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(short,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(long,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(unsigned char,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(unsigned int,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(unsigned short,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(unsigned long,SvIOK,SvIVX,sv_setiv); + specialize_std_vector(float,SvNIOK,SwigSvToNumber,sv_setnv); + specialize_std_vector(double,SvNIOK,SwigSvToNumber,sv_setnv); + specialize_std_vector(std::string,SvPOK,SwigSvToString,SwigSvFromString); +} + diff --git a/contrib/tools/swig/Lib/python/exception.i b/contrib/tools/swig/Lib/python/exception.i new file mode 100644 index 00000000000..bb0b15c9dde --- /dev/null +++ b/contrib/tools/swig/Lib/python/exception.i @@ -0,0 +1,6 @@ +%include <typemaps/exception.swg> + + +%insert("runtime") { + %define_as(SWIG_exception(code, msg), %block(%error(code, msg); SWIG_fail; )) +} diff --git a/contrib/tools/swig/Lib/python/pycontainer.swg b/contrib/tools/swig/Lib/python/pycontainer.swg new file mode 100644 index 00000000000..d6fdff08711 --- /dev/null +++ b/contrib/tools/swig/Lib/python/pycontainer.swg @@ -0,0 +1,1082 @@ +/* ----------------------------------------------------------------------------- + * pycontainer.swg + * + * Python sequence <-> C++ container wrapper + * + * This wrapper, and its iterator, allows a general use (and reuse) of + * the mapping between C++ and Python, thanks to the C++ templates. + * + * Of course, it needs the C++ compiler to support templates, but + * since we will use this wrapper with the STL containers, that should + * be the case. + * ----------------------------------------------------------------------------- */ + +%{ +#include <iostream> + +#if PY_VERSION_HEX >= 0x03020000 +# define SWIGPY_SLICEOBJECT PyObject +#else +# define SWIGPY_SLICEOBJECT PySliceObject +#endif +%} + + +#if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS) +# if !defined(SWIG_EXPORT_ITERATOR_METHODS) +# define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS +# endif +#endif + +%include <pyiterators.swg> + +/**** The PySequence C++ Wrap ***/ + +%fragment("<stdexcept>"); + +%include <std_except.i> + +%fragment("container_owner_attribute_init", "init") { + // thread safe initialization + swig::container_owner_attribute(); +} + +%fragment("reference_container_owner", "header", fragment="container_owner_attribute_init") { +namespace swig { + static PyObject* container_owner_attribute() { + static PyObject* attr = SWIG_Python_str_FromChar("__swig_container"); + return attr; + } + + template <typename T> + struct container_owner { + // By default, do not add the back-reference (for value types) + // Specialization below will check the reference for pointer types. + static bool back_reference(PyObject* /*child*/, PyObject* /*owner*/) { + return false; + } + }; + + template <> + struct container_owner<swig::pointer_category> { + /* + * Call to add a back-reference to the owning object when returning a + * reference from a container. Will only set the reference if child + * is a SWIG wrapper object that does not own the pointer. + * + * returns whether the reference was set or not + */ + static bool back_reference(PyObject* child, PyObject* owner) { + SwigPyObject* swigThis = SWIG_Python_GetSwigThis(child); + if (swigThis && (swigThis->own & SWIG_POINTER_OWN) != SWIG_POINTER_OWN) { + return PyObject_SetAttr(child, container_owner_attribute(), owner) != -1; + } + return false; + } + }; +} +} + +%fragment(SWIG_Traits_frag(swig::SwigPtr_PyObject),"header",fragment="StdTraits") { +namespace swig { + template <> struct traits<SwigPtr_PyObject > { + typedef value_category category; + static const char* type_name() { return "SwigPtr_PyObject"; } + }; + + template <> struct traits_from<SwigPtr_PyObject> { + typedef SwigPtr_PyObject value_type; + static PyObject *from(const value_type& val) { + PyObject *obj = static_cast<PyObject *>(val); + Py_XINCREF(obj); + return obj; + } + }; + + template <> + struct traits_check<SwigPtr_PyObject, value_category> { + static bool check(SwigPtr_PyObject) { + return true; + } + }; + + template <> struct traits_asval<SwigPtr_PyObject > { + typedef SwigPtr_PyObject value_type; + static int asval(PyObject *obj, value_type *val) { + if (val) *val = obj; + return SWIG_OK; + } + }; +} +} + +%fragment(SWIG_Traits_frag(swig::SwigVar_PyObject),"header",fragment="StdTraits") { +namespace swig { + template <> struct traits<SwigVar_PyObject > { + typedef value_category category; + static const char* type_name() { return "SwigVar_PyObject"; } + }; + + template <> struct traits_from<SwigVar_PyObject> { + typedef SwigVar_PyObject value_type; + static PyObject *from(const value_type& val) { + PyObject *obj = static_cast<PyObject *>(val); + Py_XINCREF(obj); + return obj; + } + }; + + template <> + struct traits_check<SwigVar_PyObject, value_category> { + static bool check(SwigVar_PyObject) { + return true; + } + }; + + template <> struct traits_asval<SwigVar_PyObject > { + typedef SwigVar_PyObject value_type; + static int asval(PyObject *obj, value_type *val) { + if (val) *val = obj; + return SWIG_OK; + } + }; +} +} + +%fragment("SwigPySequence_Base","header",fragment="<stddef.h>",fragment="StdTraits") +{ +%#include <functional> + +namespace std { + template <> + struct less <PyObject *> + { + bool + operator()(PyObject * v, PyObject *w) const + { + bool res; + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false; + /* This may fall into a case of inconsistent + eg. ObjA > ObjX > ObjB + but ObjA < ObjB + */ + if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) ) + { + /* Objects can't be compared, this mostly occurred in Python 3.0 */ + /* Compare their ptr directly for a workaround */ + res = (v < w); + PyErr_Clear(); + } + SWIG_PYTHON_THREAD_END_BLOCK; + return res; + } + }; + + template <> + struct less <swig::SwigPtr_PyObject> + { + bool + operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w) const + { + return std::less<PyObject *>()(v, w); + } + }; + + template <> + struct less <swig::SwigVar_PyObject> + { + bool + operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w) const + { + return std::less<PyObject *>()(v, w); + } + }; + +} + +namespace swig { + template <> struct traits<PyObject *> { + typedef value_category category; + static const char* type_name() { return "PyObject *"; } + }; + + template <> struct traits_asval<PyObject * > { + typedef PyObject * value_type; + static int asval(PyObject *obj, value_type *val) { + if (val) *val = obj; + return SWIG_OK; + } + }; + + template <> + struct traits_check<PyObject *, value_category> { + static bool check(PyObject *) { + return true; + } + }; + + template <> struct traits_from<PyObject *> { + typedef PyObject * value_type; + static PyObject *from(const value_type& val) { + Py_XINCREF(val); + return val; + } + }; + +} + +namespace swig { + template <class Difference> + inline size_t + check_index(Difference i, size_t size, bool insert = false) { + if ( i < 0 ) { + if ((size_t) (-i) <= size) + return (size_t) (i + size); + } else if ( (size_t) i < size ) { + return (size_t) i; + } else if (insert && ((size_t) i == size)) { + return size; + } + throw std::out_of_range("index out of range"); + } + + template <class Difference> + void + slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) { + if (step == 0) { + throw std::invalid_argument("slice step cannot be zero"); + } else if (step > 0) { + // Required range: 0 <= i < size, 0 <= j < size, i <= j + if (i < 0) { + ii = 0; + } else if (i < (Difference)size) { + ii = i; + } else if (insert && (i >= (Difference)size)) { + ii = (Difference)size; + } + if (j < 0) { + jj = 0; + } else { + jj = (j < (Difference)size) ? j : (Difference)size; + } + if (jj < ii) + jj = ii; + } else { + // Required range: -1 <= i < size-1, -1 <= j < size-1, i >= j + if (i < -1) { + ii = -1; + } else if (i < (Difference) size) { + ii = i; + } else if (i >= (Difference)(size-1)) { + ii = (Difference)(size-1); + } + if (j < -1) { + jj = -1; + } else { + jj = (j < (Difference)size ) ? j : (Difference)(size-1); + } + if (ii < jj) + ii = jj; + } + } + + template <class Sequence, class Difference> + inline typename Sequence::iterator + getpos(Sequence* self, Difference i) { + typename Sequence::iterator pos = self->begin(); + std::advance(pos, check_index(i,self->size())); + return pos; + } + + template <class Sequence, class Difference> + inline typename Sequence::const_iterator + cgetpos(const Sequence* self, Difference i) { + typename Sequence::const_iterator pos = self->begin(); + std::advance(pos, check_index(i,self->size())); + return pos; + } + + template <class Sequence> + inline void + erase(Sequence* seq, const typename Sequence::iterator& position) { + seq->erase(position); + } + + template <class Sequence> + struct traits_reserve { + static void reserve(Sequence & /*seq*/, typename Sequence::size_type /*n*/) { + // This should be specialized for types that support reserve + } + }; + + template <class Sequence, class Difference> + inline Sequence* + getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj); + + if (step > 0) { + typename Sequence::const_iterator sb = self->begin(); + typename Sequence::const_iterator se = self->begin(); + std::advance(sb,ii); + std::advance(se,jj); + if (step == 1) { + return new Sequence(sb, se); + } else { + Sequence *sequence = new Sequence(); + swig::traits_reserve<Sequence>::reserve(*sequence, (jj - ii + step - 1) / step); + typename Sequence::const_iterator it = sb; + while (it!=se) { + sequence->push_back(*it); + for (Py_ssize_t c=0; c<step && it!=se; ++c) + it++; + } + return sequence; + } + } else { + Sequence *sequence = new Sequence(); + swig::traits_reserve<Sequence>::reserve(*sequence, (ii - jj - step - 1) / -step); + typename Sequence::const_reverse_iterator sb = self->rbegin(); + typename Sequence::const_reverse_iterator se = self->rbegin(); + std::advance(sb,size-ii-1); + std::advance(se,size-jj-1); + typename Sequence::const_reverse_iterator it = sb; + while (it!=se) { + sequence->push_back(*it); + for (Py_ssize_t c=0; c<-step && it!=se; ++c) + it++; + } + return sequence; + } + } + + template <class Sequence, class Difference, class InputSeq> + inline void + setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj, true); + if (step > 0) { + if (step == 1) { + size_t ssize = jj - ii; + if (ssize <= is.size()) { + // expanding/staying the same size + swig::traits_reserve<Sequence>::reserve(*self, self->size() - ssize + is.size()); + typename Sequence::iterator sb = self->begin(); + typename InputSeq::const_iterator isit = is.begin(); + std::advance(sb,ii); + std::advance(isit, jj - ii); + self->insert(std::copy(is.begin(), isit, sb), isit, is.end()); + } else { + // shrinking + typename Sequence::iterator sb = self->begin(); + typename Sequence::iterator se = self->begin(); + std::advance(sb,ii); + std::advance(se,jj); + self->erase(sb,se); + sb = self->begin(); + std::advance(sb,ii); + self->insert(sb, is.begin(), is.end()); + } + } else { + size_t replacecount = (jj - ii + step - 1) / step; + if (is.size() != replacecount) { + char msg[1024]; + sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount); + throw std::invalid_argument(msg); + } + typename Sequence::const_iterator isit = is.begin(); + typename Sequence::iterator it = self->begin(); + std::advance(it,ii); + for (size_t rc=0; rc<replacecount && it != self->end(); ++rc) { + *it++ = *isit++; + for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) + it++; + } + } + } else { + size_t replacecount = (ii - jj - step - 1) / -step; + if (is.size() != replacecount) { + char msg[1024]; + sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount); + throw std::invalid_argument(msg); + } + typename Sequence::const_iterator isit = is.begin(); + typename Sequence::reverse_iterator it = self->rbegin(); + std::advance(it,size-ii-1); + for (size_t rc=0; rc<replacecount && it != self->rend(); ++rc) { + *it++ = *isit++; + for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it++; + } + } + } + + template <class Sequence, class Difference> + inline void + delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) { + typename Sequence::size_type size = self->size(); + Difference ii = 0; + Difference jj = 0; + swig::slice_adjust(i, j, step, size, ii, jj, true); + if (step > 0) { + typename Sequence::iterator sb = self->begin(); + std::advance(sb,ii); + if (step == 1) { + typename Sequence::iterator se = self->begin(); + std::advance(se,jj); + self->erase(sb,se); + } else { + typename Sequence::iterator it = sb; + size_t delcount = (jj - ii + step - 1) / step; + while (delcount) { + it = self->erase(it); + for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) + it++; + delcount--; + } + } + } else { + typename Sequence::reverse_iterator sb = self->rbegin(); + std::advance(sb,size-ii-1); + typename Sequence::reverse_iterator it = sb; + size_t delcount = (ii - jj - step - 1) / -step; + while (delcount) { + it = typename Sequence::reverse_iterator(self->erase((++it).base())); + for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it++; + delcount--; + } + } + } +} +} + +%fragment("SwigPySequence_Cont","header", + fragment="StdTraits", + fragment="SwigPySequence_Base", + fragment="SwigPyIterator_T") +{ +namespace swig +{ + template <class T> + struct SwigPySequence_Ref + { + SwigPySequence_Ref(PyObject* seq, Py_ssize_t index) + : _seq(seq), _index(index) + { + } + + operator T () const + { + swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index); + try { + return swig::as<T>(item); + } catch (const std::invalid_argument& e) { + char msg[1024]; + sprintf(msg, "in sequence element %d ", (int)_index); + if (!PyErr_Occurred()) { + ::%type_error(swig::type_name<T>()); + } + SWIG_Python_AddErrorMsg(msg); + SWIG_Python_AddErrorMsg(e.what()); + throw; + } + } + + SwigPySequence_Ref& operator=(const T& v) + { + PySequence_SetItem(_seq, _index, swig::from<T>(v)); + return *this; + } + + private: + PyObject* _seq; + Py_ssize_t _index; + }; + + template <class T> + struct SwigPySequence_ArrowProxy + { + SwigPySequence_ArrowProxy(const T& x): m_value(x) {} + const T* operator->() const { return &m_value; } + operator const T*() const { return &m_value; } + T m_value; + }; + + template <class T, class Reference > + struct SwigPySequence_InputIterator + { + typedef SwigPySequence_InputIterator<T, Reference > self; + + typedef std::random_access_iterator_tag iterator_category; + typedef Reference reference; + typedef T value_type; + typedef T* pointer; + typedef Py_ssize_t difference_type; + + SwigPySequence_InputIterator() + { + } + + SwigPySequence_InputIterator(PyObject* seq, Py_ssize_t index) + : _seq(seq), _index(index) + { + } + + reference operator*() const + { + return reference(_seq, _index); + } + + SwigPySequence_ArrowProxy<T> + operator->() const { + return SwigPySequence_ArrowProxy<T>(operator*()); + } + + bool operator==(const self& ri) const + { + return (_index == ri._index) && (_seq == ri._seq); + } + + bool operator!=(const self& ri) const + { + return !(operator==(ri)); + } + + self& operator ++ () + { + ++_index; + return *this; + } + + self& operator -- () + { + --_index; + return *this; + } + + self& operator += (difference_type n) + { + _index += n; + return *this; + } + + self operator +(difference_type n) const + { + return self(_seq, _index + n); + } + + self& operator -= (difference_type n) + { + _index -= n; + return *this; + } + + self operator -(difference_type n) const + { + return self(_seq, _index - n); + } + + difference_type operator - (const self& ri) const + { + return _index - ri._index; + } + + bool operator < (const self& ri) const + { + return _index < ri._index; + } + + reference + operator[](difference_type n) const + { + return reference(_seq, _index + n); + } + + private: + PyObject* _seq; + difference_type _index; + }; + + // STL container wrapper around a Python sequence + template <class T> + struct SwigPySequence_Cont + { + typedef SwigPySequence_Ref<T> reference; + typedef const SwigPySequence_Ref<T> const_reference; + typedef T value_type; + typedef T* pointer; + typedef Py_ssize_t difference_type; + typedef size_t size_type; + typedef const pointer const_pointer; + typedef SwigPySequence_InputIterator<T, reference> iterator; + typedef SwigPySequence_InputIterator<T, const_reference> const_iterator; + + SwigPySequence_Cont(PyObject* seq) : _seq(0) + { + if (!PySequence_Check(seq)) { + throw std::invalid_argument("a sequence is expected"); + } + _seq = seq; + Py_INCREF(_seq); + } + + ~SwigPySequence_Cont() + { + Py_XDECREF(_seq); + } + + size_type size() const + { + return static_cast<size_type>(PySequence_Size(_seq)); + } + + bool empty() const + { + return size() == 0; + } + + iterator begin() + { + return iterator(_seq, 0); + } + + const_iterator begin() const + { + return const_iterator(_seq, 0); + } + + iterator end() + { + return iterator(_seq, size()); + } + + const_iterator end() const + { + return const_iterator(_seq, size()); + } + + reference operator[](difference_type n) + { + return reference(_seq, n); + } + + const_reference operator[](difference_type n) const + { + return const_reference(_seq, n); + } + + bool check() const + { + Py_ssize_t s = size(); + for (Py_ssize_t i = 0; i < s; ++i) { + swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i); + if (!swig::check<value_type>(item)) + return false; + } + return true; + } + + private: + PyObject* _seq; + }; + +} +} + +%define %swig_sequence_iterator(Sequence...) + %swig_sequence_iterator_with_making_function(swig::make_output_iterator,Sequence...) +%enddef + +%define %swig_sequence_forward_iterator(Sequence...) + %swig_sequence_iterator_with_making_function(swig::make_output_forward_iterator,Sequence...) +%enddef + +%define %swig_sequence_iterator_with_making_function(Make_output_iterator,Sequence...) +#if defined(SWIG_EXPORT_ITERATOR_METHODS) + class iterator; + class reverse_iterator; + class const_iterator; + class const_reverse_iterator; + + %typemap(out,noblock=1,fragment="SwigPySequence_Cont") + iterator, reverse_iterator, const_iterator, const_reverse_iterator { + $result = SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &)), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); + } + %typemap(out,noblock=1,fragment="SwigPySequence_Cont") + std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> { + $result = PyTuple_New(2); + PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); + PyTuple_SetItem($result,1,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).second), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); + } + + %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="SwigPySequence_Cont") {} + + %typemap(out,noblock=1,fragment="SwigPyPairBoolOutputIterator") + std::pair<iterator, bool>, std::pair<const_iterator, bool> { + $result = PyTuple_New(2); + PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first), + swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); + PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second)); + } + + %typemap(in,noblock=1,fragment="SwigPySequence_Cont") + iterator(swig::SwigPyIterator *iter = 0, int res), + reverse_iterator(swig::SwigPyIterator *iter = 0, int res), + const_iterator(swig::SwigPyIterator *iter = 0, int res), + const_reverse_iterator(swig::SwigPyIterator *iter = 0, int res) { + res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + if (!SWIG_IsOK(res) || !iter) { + %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); + } else { + swig::SwigPyIterator_T<$type > *iter_t = dynamic_cast<swig::SwigPyIterator_T<$type > *>(iter); + if (iter_t) { + $1 = iter_t->get_current(); + } else { + %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); + } + } + } + + %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPySequence_Cont") + iterator, reverse_iterator, const_iterator, const_reverse_iterator { + swig::SwigPyIterator *iter = 0; + int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0); + $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<$type > *>(iter) != 0)); + } + + %fragment("SwigPySequence_Cont"); + + %newobject iterator(PyObject **PYTHON_SELF); + %extend { + swig::SwigPyIterator* iterator(PyObject **PYTHON_SELF) { + return Make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + } + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:slot", "tp_iter", functype="getiterfunc") iterator; +#else + %pythoncode %{def __iter__(self): + return self.iterator()%} +#endif + } + +#endif //SWIG_EXPORT_ITERATOR_METHODS +%enddef + + +/**** The python container methods ****/ + +%define %swig_container_methods(Container...) + +/* deprecated in Python 2 */ +#if 1 + %newobject __getslice__; +#endif + %newobject __getitem__(SWIGPY_SLICEOBJECT *slice); + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:slot", "nb_nonzero", functype="inquiry") __nonzero__; + %feature("python:slot", "sq_length", functype="lenfunc") __len__; +#endif // SWIGPYTHON_BUILTIN + + %extend { + bool __nonzero__() const { + return !(self->empty()); + } + + /* Alias for Python 3 compatibility */ + bool __bool__() const { + return !(self->empty()); + } + + size_type __len__() const { + return self->size(); + } + + // Although __getitem__, front, back actually use a const value_type& return type, the typemaps below + // use non-const so that they can be easily overridden by users if necessary. + %typemap(ret, fragment="reference_container_owner", noblock=1) value_type& __getitem__, value_type& front, value_type& back { + (void)swig::container_owner<swig::traits<$*1_ltype>::category>::back_reference($result, $self); + } + } +%enddef + + + +%define %swig_sequence_methods_common(Sequence...) + %swig_sequence_iterator(%arg(Sequence)) + %swig_container_methods(%arg(Sequence)) + + %fragment("SwigPySequence_Base"); + +#if defined(SWIGPYTHON_BUILTIN) + //%feature("python:slot", "sq_item", functype="ssizeargfunc") __getitem__; + //%feature("python:slot", "sq_slice", functype="ssizessizeargfunc") __getslice__; + //%feature("python:slot", "sq_ass_item", functype="ssizeobjargproc") __setitem__; + //%feature("python:slot", "sq_ass_slice", functype="ssizessizeobjargproc") __setslice__; + %feature("python:slot", "mp_subscript", functype="binaryfunc") __getitem__; + %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__; +#endif // SWIGPYTHON_BUILTIN + + %extend { + /* typemap for slice object support */ + %typemap(in) SWIGPY_SLICEOBJECT* { + if (!PySlice_Check($input)) { + %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); + } + $1 = (SWIGPY_SLICEOBJECT *) $input; + } + %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) SWIGPY_SLICEOBJECT* { + $1 = PySlice_Check($input); + } + +/* deprecated in Python 2 */ +#if 1 + Sequence* __getslice__(difference_type i, difference_type j) throw (std::out_of_range, std::invalid_argument) { + return swig::getslice(self, i, j, 1); + } + + void __setslice__(difference_type i, difference_type j) throw (std::out_of_range, std::invalid_argument) { + swig::setslice(self, i, j, 1, Sequence()); + } + + void __setslice__(difference_type i, difference_type j, const Sequence& v) throw (std::out_of_range, std::invalid_argument) { + swig::setslice(self, i, j, 1, v); + } + + void __delslice__(difference_type i, difference_type j) throw (std::out_of_range, std::invalid_argument) { + swig::delslice(self, i, j, 1); + } +#endif + + void __delitem__(difference_type i) throw (std::out_of_range, std::invalid_argument) { + swig::erase(self, swig::getpos(self, i)); + } + + /* Overloaded methods for Python 3 compatibility + * (Also useful in Python 2.x) + */ + Sequence* __getitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) { + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return NULL; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + Sequence::difference_type id = i; + Sequence::difference_type jd = j; + return swig::getslice(self, id, jd, step); + } + + void __setitem__(SWIGPY_SLICEOBJECT *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) { + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + Sequence::difference_type id = i; + Sequence::difference_type jd = j; + swig::setslice(self, id, jd, step, v); + } + + void __setitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) { + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + Sequence::difference_type id = i; + Sequence::difference_type jd = j; + swig::delslice(self, id, jd, step); + } + + void __delitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) { + Py_ssize_t i, j, step; + if( !PySlice_Check(slice) ) { + SWIG_Error(SWIG_TypeError, "Slice object expected."); + return; + } + PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step); + Sequence::difference_type id = i; + Sequence::difference_type jd = j; + swig::delslice(self, id, jd, step); + } + + } +%enddef + +%define %swig_sequence_methods_non_resizable(Sequence...) + %swig_sequence_methods_common(%arg(Sequence)) + %extend { + const value_type& __getitem__(difference_type i) const throw (std::out_of_range) { + return *(swig::cgetpos(self, i)); + } + + void __setitem__(difference_type i, const value_type& x) throw (std::out_of_range) { + *(swig::getpos(self,i)) = x; + } + +#if defined(SWIGPYTHON_BUILTIN) + // This will be called through the mp_ass_subscript slot to delete an entry. + void __setitem__(difference_type i) throw (std::out_of_range, std::invalid_argument) { + swig::erase(self, swig::getpos(self, i)); + } +#endif + + } +%enddef + +%define %swig_sequence_methods(Sequence...) + %swig_sequence_methods_non_resizable(%arg(Sequence)) + %extend { + value_type pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + Sequence::value_type x = self->back(); + self->pop_back(); + return x; + } + + void append(const value_type& x) { + self->push_back(x); + } + } +%enddef + +%define %swig_sequence_methods_non_resizable_val(Sequence...) + %swig_sequence_methods_common(%arg(Sequence)) + %extend { + value_type __getitem__(difference_type i) throw (std::out_of_range) { + return *(swig::cgetpos(self, i)); + } + + void __setitem__(difference_type i, value_type x) throw (std::out_of_range) { + *(swig::getpos(self,i)) = x; + } + +#if defined(SWIGPYTHON_BUILTIN) + // This will be called through the mp_ass_subscript slot to delete an entry. + void __setitem__(difference_type i) throw (std::out_of_range, std::invalid_argument) { + swig::erase(self, swig::getpos(self, i)); + } +#endif + } +%enddef + +%define %swig_sequence_methods_val(Sequence...) + %swig_sequence_methods_non_resizable_val(%arg(Sequence)) + %extend { + value_type pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + Sequence::value_type x = self->back(); + self->pop_back(); + return x; + } + + void append(value_type x) { + self->push_back(x); + } + } +%enddef + + + +// +// Common fragments +// + +%fragment("StdSequenceTraits","header", + fragment="StdTraits", + fragment="SwigPySequence_Cont") +{ +namespace swig { + template <class SwigPySeq, class Seq> + inline void + assign(const SwigPySeq& swigpyseq, Seq* seq) { + // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented + typedef typename SwigPySeq::value_type value_type; + typename SwigPySeq::const_iterator it = swigpyseq.begin(); + for (;it != swigpyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } + } + + template <class Seq, class T = typename Seq::value_type > + struct traits_asptr_stdseq { + typedef Seq sequence; + typedef T value_type; + + static int asptr(PyObject *obj, sequence **seq) { + if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) { + sequence *p; + swig_type_info *descriptor = swig::type_info<sequence>(); + if (descriptor && SWIG_IsOK(::SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { + if (seq) *seq = p; + return SWIG_OLDOBJ; + } + } else if (PySequence_Check(obj)) { + try { + SwigPySequence_Cont<value_type> swigpyseq(obj); + if (seq) { + sequence *pseq = new sequence(); + assign(swigpyseq, pseq); + *seq = pseq; + return SWIG_NEWOBJ; + } else { + return swigpyseq.check() ? SWIG_OK : SWIG_ERROR; + } + } catch (std::exception& e) { + if (seq) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, e.what()); + } + } + return SWIG_ERROR; + } + } + return SWIG_ERROR; + } + }; + + template <class Seq, class T = typename Seq::value_type > + struct traits_from_stdseq { + typedef Seq sequence; + typedef T value_type; + typedef typename Seq::size_type size_type; + typedef typename sequence::const_iterator const_iterator; + + static PyObject *from(const sequence& seq) { +%#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS + swig_type_info *desc = swig::type_info<sequence>(); + if (desc && desc->clientdata) { + return SWIG_InternalNewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN); + } +%#endif + size_type size = seq.size(); + if (size <= (size_type)INT_MAX) { + PyObject *obj = PyTuple_New((Py_ssize_t)size); + Py_ssize_t i = 0; + for (const_iterator it = seq.begin(); it != seq.end(); ++it, ++i) { + PyTuple_SetItem(obj,i,swig::from<value_type>(*it)); + } + return obj; + } else { + PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python"); + return NULL; + } + } + }; +} +} diff --git a/contrib/tools/swig/Lib/python/pyiterators.swg b/contrib/tools/swig/Lib/python/pyiterators.swg new file mode 100644 index 00000000000..cb15e35cda4 --- /dev/null +++ b/contrib/tools/swig/Lib/python/pyiterators.swg @@ -0,0 +1,458 @@ +/* ----------------------------------------------------------------------------- + * pyiterators.swg + * + * Implement a python 'output' iterator for Python 2.2 or higher. + * + * Users can derive form the SwigPyIterator to implement their + * own iterators. As an example (real one since we use it for STL/STD + * containers), the template SwigPyIterator_T does the + * implementation for generic C++ iterators. + * ----------------------------------------------------------------------------- */ + +%include <std_common.i> + +%fragment("SwigPyIterator","header",fragment="<stddef.h>") { +namespace swig { + struct stop_iteration { + }; + + struct SwigPyIterator { + private: + SwigPtr_PyObject _seq; + + protected: + SwigPyIterator(PyObject *seq) : _seq(seq) + { + } + + public: + virtual ~SwigPyIterator() {} + + // Access iterator method, required by Python + virtual PyObject *value() const = 0; + + // Forward iterator method, required by Python + virtual SwigPyIterator *incr(size_t n = 1) = 0; + + // Backward iterator method, very common in C++, but not required in Python + virtual SwigPyIterator *decr(size_t /*n*/ = 1) + { + throw stop_iteration(); + } + + // Random access iterator methods, but not required in Python + virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const + { + throw std::invalid_argument("operation not supported"); + } + + virtual bool equal (const SwigPyIterator &/*x*/) const + { + throw std::invalid_argument("operation not supported"); + } + + // C++ common/needed methods + virtual SwigPyIterator *copy() const = 0; + + PyObject *next() + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads + PyObject *obj = value(); + incr(); + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads + return obj; + } + + /* Make an alias for Python 3.x */ + PyObject *__next__() + { + return next(); + } + + PyObject *previous() + { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads + decr(); + PyObject *obj = value(); + SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads + return obj; + } + + SwigPyIterator *advance(ptrdiff_t n) + { + return (n > 0) ? incr(n) : decr(-n); + } + + bool operator == (const SwigPyIterator& x) const + { + return equal(x); + } + + bool operator != (const SwigPyIterator& x) const + { + return ! operator==(x); + } + + SwigPyIterator& operator += (ptrdiff_t n) + { + return *advance(n); + } + + SwigPyIterator& operator -= (ptrdiff_t n) + { + return *advance(-n); + } + + SwigPyIterator* operator + (ptrdiff_t n) const + { + return copy()->advance(n); + } + + SwigPyIterator* operator - (ptrdiff_t n) const + { + return copy()->advance(-n); + } + + ptrdiff_t operator - (const SwigPyIterator& x) const + { + return x.distance(*this); + } + + static swig_type_info* descriptor() { + static int init = 0; + static swig_type_info* desc = 0; + if (!init) { + desc = SWIG_TypeQuery("swig::SwigPyIterator *"); + init = 1; + } + return desc; + } + }; + +%#if defined(SWIGPYTHON_BUILTIN) + inline PyObject* make_output_iterator_builtin (PyObject *pyself) + { + Py_INCREF(pyself); + return pyself; + } +%#endif +} +} + +%fragment("SwigPyIterator_T","header",fragment="<stddef.h>",fragment="SwigPyIterator",fragment="StdTraits",fragment="StdIteratorTraits") { +namespace swig { + template<typename OutIterator> + class SwigPyIterator_T : public SwigPyIterator + { + public: + typedef OutIterator out_iterator; + typedef typename std::iterator_traits<out_iterator>::value_type value_type; + typedef SwigPyIterator_T<out_iterator> self_type; + + SwigPyIterator_T(out_iterator curr, PyObject *seq) + : SwigPyIterator(seq), current(curr) + { + } + + const out_iterator& get_current() const + { + return current; + } + + + bool equal (const SwigPyIterator &iter) const + { + const self_type *iters = dynamic_cast<const self_type *>(&iter); + if (iters) { + return (current == iters->get_current()); + } else { + throw std::invalid_argument("bad iterator type"); + } + } + + ptrdiff_t distance(const SwigPyIterator &iter) const + { + const self_type *iters = dynamic_cast<const self_type *>(&iter); + if (iters) { + return std::distance(current, iters->get_current()); + } else { + throw std::invalid_argument("bad iterator type"); + } + } + + protected: + out_iterator current; + }; + + template <class ValueType> + struct from_oper + { + typedef const ValueType& argument_type; + typedef PyObject *result_type; + result_type operator()(argument_type v) const + { + return swig::from(v); + } + }; + + template<typename OutIterator, + typename ValueType = typename std::iterator_traits<OutIterator>::value_type, + typename FromOper = from_oper<ValueType> > + class SwigPyForwardIteratorOpen_T : public SwigPyIterator_T<OutIterator> + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T<out_iterator> base; + typedef SwigPyForwardIteratorOpen_T<OutIterator, ValueType, FromOper> self_type; + + SwigPyForwardIteratorOpen_T(out_iterator curr, PyObject *seq) + : SwigPyIterator_T<OutIterator>(curr, seq) + { + } + + PyObject *value() const { + return from(static_cast<const value_type&>(*(base::current))); + } + + SwigPyIterator *copy() const + { + return new self_type(*this); + } + + SwigPyIterator *incr(size_t n = 1) + { + while (n--) { + ++base::current; + } + return this; + } + + }; + + template<typename OutIterator, + typename ValueType = typename std::iterator_traits<OutIterator>::value_type, + typename FromOper = from_oper<ValueType> > + class SwigPyIteratorOpen_T : public SwigPyForwardIteratorOpen_T<OutIterator, ValueType, FromOper> + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T<out_iterator> base; + typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type; + + SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq) + : SwigPyForwardIteratorOpen_T<OutIterator>(curr, seq) + { + } + + SwigPyIterator *decr(size_t n = 1) + { + while (n--) { + --base::current; + } + return this; + } + }; + + template<typename OutIterator, + typename ValueType = typename std::iterator_traits<OutIterator>::value_type, + typename FromOper = from_oper<ValueType> > + class SwigPyForwardIteratorClosed_T : public SwigPyIterator_T<OutIterator> + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T<out_iterator> base; + typedef SwigPyForwardIteratorClosed_T<OutIterator, ValueType, FromOper> self_type; + + SwigPyForwardIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + : SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last) + { + } + + PyObject *value() const { + if (base::current == end) { + throw stop_iteration(); + } else { + return from(static_cast<const value_type&>(*(base::current))); + } + } + + SwigPyIterator *copy() const + { + return new self_type(*this); + } + + SwigPyIterator *incr(size_t n = 1) + { + while (n--) { + if (base::current == end) { + throw stop_iteration(); + } else { + ++base::current; + } + } + return this; + } + + protected: + out_iterator begin; + out_iterator end; + }; + + template<typename OutIterator, + typename ValueType = typename std::iterator_traits<OutIterator>::value_type, + typename FromOper = from_oper<ValueType> > + class SwigPyIteratorClosed_T : public SwigPyForwardIteratorClosed_T<OutIterator,ValueType,FromOper> + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T<out_iterator> base; + typedef SwigPyForwardIteratorClosed_T<OutIterator, ValueType, FromOper> base0; + typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type; + + SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + : SwigPyForwardIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq) + { + } + + SwigPyIterator *decr(size_t n = 1) + { + while (n--) { + if (base::current == base0::begin) { + throw stop_iteration(); + } else { + --base::current; + } + } + return this; + } + }; + + + template<typename OutIter> + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) + { + return new SwigPyForwardIteratorClosed_T<OutIter>(current, begin, end, seq); + } + + template<typename OutIter> + inline SwigPyIterator* + make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) + { + return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq); + } + + template<typename OutIter> + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, PyObject *seq = 0) + { + return new SwigPyForwardIteratorOpen_T<OutIter>(current, seq); + } + + template<typename OutIter> + inline SwigPyIterator* + make_output_iterator(const OutIter& current, PyObject *seq = 0) + { + return new SwigPyIteratorOpen_T<OutIter>(current, seq); + } + +} +} + + +%fragment("SwigPyIterator"); +namespace swig +{ + /* + Throw a StopIteration exception + */ + %ignore stop_iteration; + struct stop_iteration {}; + + %typemap(throws) stop_iteration { + (void)$1; + SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + SWIG_fail; + } + + /* + Mark methods that return new objects + */ + %newobject SwigPyIterator::copy; + %newobject SwigPyIterator::operator + (ptrdiff_t n) const; + %newobject SwigPyIterator::operator - (ptrdiff_t n) const; + + %nodirector SwigPyIterator; + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:tp_iter") SwigPyIterator "&swig::make_output_iterator_builtin"; + %feature("python:slot", "tp_iternext", functype="iternextfunc") SwigPyIterator::__next__; +#else + %extend SwigPyIterator { + %pythoncode %{def __iter__(self): + return self%} + } +#endif + + %catches(swig::stop_iteration) SwigPyIterator::value() const; + %catches(swig::stop_iteration) SwigPyIterator::incr(size_t n = 1); + %catches(swig::stop_iteration) SwigPyIterator::decr(size_t n = 1); + %catches(std::invalid_argument) SwigPyIterator::distance(const SwigPyIterator &x) const; + %catches(std::invalid_argument) SwigPyIterator::equal (const SwigPyIterator &x) const; + %catches(swig::stop_iteration) SwigPyIterator::__next__(); + %catches(swig::stop_iteration) SwigPyIterator::next(); + %catches(swig::stop_iteration) SwigPyIterator::previous(); + %catches(swig::stop_iteration) SwigPyIterator::advance(ptrdiff_t n); + %catches(swig::stop_iteration) SwigPyIterator::operator += (ptrdiff_t n); + %catches(swig::stop_iteration) SwigPyIterator::operator -= (ptrdiff_t n); + %catches(swig::stop_iteration) SwigPyIterator::operator + (ptrdiff_t n) const; + %catches(swig::stop_iteration) SwigPyIterator::operator - (ptrdiff_t n) const; + + struct SwigPyIterator + { + protected: + SwigPyIterator(PyObject *seq); + + public: + virtual ~SwigPyIterator(); + + // Access iterator method, required by Python + virtual PyObject *value() const = 0; + + // Forward iterator method, required by Python + virtual SwigPyIterator *incr(size_t n = 1) = 0; + + // Backward iterator method, very common in C++, but not required in Python + virtual SwigPyIterator *decr(size_t n = 1); + + // Random access iterator methods, but not required in Python + virtual ptrdiff_t distance(const SwigPyIterator &x) const; + + virtual bool equal (const SwigPyIterator &x) const; + + // C++ common/needed methods + virtual SwigPyIterator *copy() const = 0; + + PyObject *next(); + PyObject *__next__(); + PyObject *previous(); + SwigPyIterator *advance(ptrdiff_t n); + + bool operator == (const SwigPyIterator& x) const; + bool operator != (const SwigPyIterator& x) const; + SwigPyIterator& operator += (ptrdiff_t n); + SwigPyIterator& operator -= (ptrdiff_t n); + SwigPyIterator* operator + (ptrdiff_t n) const; + SwigPyIterator* operator - (ptrdiff_t n) const; + ptrdiff_t operator - (const SwigPyIterator& x) const; + }; +} + diff --git a/contrib/tools/swig/Lib/python/pystdcommon.swg b/contrib/tools/swig/Lib/python/pystdcommon.swg new file mode 100644 index 00000000000..afa71350a91 --- /dev/null +++ b/contrib/tools/swig/Lib/python/pystdcommon.swg @@ -0,0 +1,265 @@ +%fragment("StdTraits","header",fragment="StdTraitsCommon") +{ +namespace swig { + /* + Traits that provides the from method + */ + template <class Type> struct traits_from_ptr { + static PyObject *from(Type *val, int owner = 0) { + return SWIG_InternalNewPointerObj(val, type_info<Type>(), owner); + } + }; + + template <class Type> struct traits_from { + static PyObject *from(const Type& val) { + return traits_from_ptr<Type>::from(new Type(val), 1); + } + }; + + template <class Type> struct traits_from<Type *> { + static PyObject *from(Type* val) { + return traits_from_ptr<Type>::from(val, 0); + } + }; + + template <class Type> struct traits_from<const Type *> { + static PyObject *from(const Type* val) { + return traits_from_ptr<Type>::from(const_cast<Type*>(val), 0); + } + }; + + + template <class Type> + inline PyObject *from(const Type& val) { + return traits_from<Type>::from(val); + } + + template <class Type> + inline PyObject *from_ptr(Type* val, int owner) { + return traits_from_ptr<Type>::from(val, owner); + } + + /* + Traits that provides the asval/as/check method + */ + template <class Type> + struct traits_asptr { + static int asptr(PyObject *obj, Type **val) { + int res = SWIG_ERROR; + swig_type_info *descriptor = type_info<Type>(); + if (val) { + Type *p = 0; + int newmem = 0; + res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR; + if (SWIG_IsOK(res)) { + if (newmem & SWIG_CAST_NEW_MEMORY) { + res |= SWIG_NEWOBJMASK; + } + *val = p; + } + } else { + res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR; + } + return res; + } + }; + + template <class Type> + inline int asptr(PyObject *obj, Type **vptr) { + return traits_asptr<Type>::asptr(obj, vptr); + } + + template <class Type> + struct traits_asval { + static int asval(PyObject *obj, Type *val) { + if (val) { + Type *p = 0; + int res = traits_asptr<Type>::asptr(obj, &p); + if (!SWIG_IsOK(res)) return res; + if (p) { + typedef typename noconst_traits<Type>::noconst_type noconst_type; + *(const_cast<noconst_type*>(val)) = *p; + if (SWIG_IsNewObj(res)){ + %delete(p); + res = SWIG_DelNewMask(res); + } + return res; + } else { + return SWIG_ERROR; + } + } else { + return traits_asptr<Type>::asptr(obj, (Type **)(0)); + } + } + }; + + template <class Type> struct traits_asval<Type*> { + static int asval(PyObject *obj, Type **val) { + if (val) { + typedef typename noconst_traits<Type>::noconst_type noconst_type; + noconst_type *p = 0; + int res = traits_asptr<noconst_type>::asptr(obj, &p); + if (SWIG_IsOK(res)) { + *(const_cast<noconst_type**>(val)) = p; + } + return res; + } else { + return traits_asptr<Type>::asptr(obj, (Type **)(0)); + } + } + }; + + template <class Type> + inline int asval(PyObject *obj, Type *val) { + return traits_asval<Type>::asval(obj, val); + } + + template <class Type> + struct traits_as<Type, value_category> { + static Type as(PyObject *obj) { + Type v; + int res = asval(obj, &v); + if (!obj || !SWIG_IsOK(res)) { + if (!PyErr_Occurred()) { + ::%type_error(swig::type_name<Type>()); + } + throw std::invalid_argument("bad type"); + } + return v; + } + }; + + template <class Type> + struct traits_as<Type, pointer_category> { + static Type as(PyObject *obj) { + Type *v = 0; + int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res) && v) { + if (SWIG_IsNewObj(res)) { + Type r(*v); + %delete(v); + return r; + } else { + return *v; + } + } else { + if (!PyErr_Occurred()) { + %type_error(swig::type_name<Type>()); + } + throw std::invalid_argument("bad type"); + } + } + }; + + template <class Type> + struct traits_as<Type*, pointer_category> { + static Type* as(PyObject *obj) { + Type *v = 0; + int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res)) { + return v; + } else { + if (!PyErr_Occurred()) { + %type_error(swig::type_name<Type>()); + } + throw std::invalid_argument("bad type"); + } + } + }; + + template <class Type> + inline Type as(PyObject *obj) { + return traits_as<Type, typename traits<Type>::category>::as(obj); + } + + template <class Type> + struct traits_check<Type, value_category> { + static bool check(PyObject *obj) { + int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template <class Type> + struct traits_check<Type, pointer_category> { + static bool check(PyObject *obj) { + int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template <class Type> + inline bool check(PyObject *obj) { + return traits_check<Type, typename traits<Type>::category>::check(obj); + } +} +} + +// +// Backward compatibility +// + +#ifdef SWIG_PYTHON_BACKWARD_COMP +%fragment("<string>"); +%{ +PyObject* SwigInt_FromBool(bool b) { + return PyInt_FromLong(b ? 1L : 0L); +} +double SwigNumber_Check(PyObject* o) { + return PyFloat_Check(o) || PyInt_Check(o) || PyLong_Check(o); +} +double SwigNumber_AsDouble(PyObject* o) { + return PyFloat_Check(o) ? PyFloat_AsDouble(o) + : (PyInt_Check(o) ? double(PyInt_AsLong(o)) + : double(PyLong_AsLong(o))); +} +PyObject* SwigString_FromString(const std::string& s) { + return PyString_FromStringAndSize(s.data(),s.size()); +} +std::string SwigString_AsString(PyObject* o) { + return std::string(PyString_AsString(o)); +} +%} + +#endif + + +%define %specialize_std_container(Type,Check,As,From) +%{ +namespace swig { + template <> struct traits_asval<Type > { + typedef Type value_type; + static int asval(PyObject *obj, value_type *val) { + if (Check(obj)) { + if (val) *val = As(obj); + return SWIG_OK; + } + return SWIG_ERROR; + } + }; + template <> struct traits_from<Type > { + typedef Type value_type; + static PyObject *from(const value_type& val) { + return From(val); + } + }; + + template <> + struct traits_check<Type, value_category> { + static int check(PyObject *obj) { + int res = Check(obj); + return obj && res ? res : 0; + } + }; +} +%} +%enddef + + +#define specialize_std_vector(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_list(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_deque(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_set(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_multiset(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_unordered_set(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_unordered_multiset(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) diff --git a/contrib/tools/swig/Lib/python/pywstrings.swg b/contrib/tools/swig/Lib/python/pywstrings.swg new file mode 100644 index 00000000000..0e5a78df5ee --- /dev/null +++ b/contrib/tools/swig/Lib/python/pywstrings.swg @@ -0,0 +1,85 @@ +/* ------------------------------------------------------------ + * utility methods for wchar_t strings + * ------------------------------------------------------------ */ + +%{ +#if PY_VERSION_HEX >= 0x03020000 +# define SWIGPY_UNICODE_ARG(obj) ((PyObject*) (obj)) +#else +# define SWIGPY_UNICODE_ARG(obj) ((PyUnicodeObject*) (obj)) +#endif +%} + +%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor") { +SWIGINTERN int +SWIG_AsWCharPtrAndSize(PyObject *obj, wchar_t **cptr, size_t *psize, int *alloc) +{ + PyObject *tmp = 0; + int isunicode = PyUnicode_Check(obj); +%#if PY_VERSION_HEX < 0x03000000 && !defined(SWIG_PYTHON_STRICT_UNICODE_WCHAR) + if (!isunicode && PyString_Check(obj)) { + tmp = PyUnicode_FromObject(obj); + if (tmp) { + isunicode = 1; + obj = tmp; + } else { + PyErr_Clear(); + return SWIG_TypeError; + } + } +%#endif + if (isunicode) { +%#if PY_VERSION_HEX >= 0x03030000 + Py_ssize_t len = PyUnicode_GetLength(obj); +%#else + Py_ssize_t len = PyUnicode_GetSize(obj); +%#endif + if (cptr) { + Py_ssize_t length; + *cptr = %new_array(len + 1, wchar_t); + length = PyUnicode_AsWideChar(SWIGPY_UNICODE_ARG(obj), *cptr, len); + if (length == -1) { + PyErr_Clear(); + Py_XDECREF(tmp); + return SWIG_TypeError; + } + (*cptr)[length] = 0; + } + if (psize) *psize = (size_t) len + 1; + if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; + Py_XDECREF(tmp); + return SWIG_OK; + } else { + swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); + if (pwchar_descriptor) { + void * vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pwchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (wchar_t *)vptr; + if (psize) *psize = vptr ? (wcslen((wchar_t *)vptr) + 1) : 0; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} +} + +%fragment("SWIG_FromWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor") { +SWIGINTERNINLINE PyObject * +SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); + return pwchar_descriptor ? + SWIG_InternalNewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyUnicode_FromWideChar(carray, %numeric_cast(size, Py_ssize_t)); + } + } else { + return SWIG_Py_Void(); + } +} +} + + diff --git a/contrib/tools/swig/Lib/python/std_alloc.i b/contrib/tools/swig/Lib/python/std_alloc.i new file mode 100644 index 00000000000..35dc051beab --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_alloc.i @@ -0,0 +1 @@ +%include <std/std_alloc.i> diff --git a/contrib/tools/swig/Lib/python/std_char_traits.i b/contrib/tools/swig/Lib/python/std_char_traits.i new file mode 100644 index 00000000000..bf4e6c47dd4 --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_char_traits.i @@ -0,0 +1 @@ +%include <std/std_char_traits.i> diff --git a/contrib/tools/swig/Lib/python/std_common.i b/contrib/tools/swig/Lib/python/std_common.i new file mode 100644 index 00000000000..605766238bb --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_common.i @@ -0,0 +1,74 @@ +%include <std/std_except.i> +%include <pystdcommon.swg> + + +/* + Generate the traits for a 'primitive' type, such as 'double', + for which the SWIG_AsVal and SWIG_From methods are already defined. +*/ + +%define %traits_ptypen(Type...) + %fragment(SWIG_Traits_frag(Type),"header", + fragment=SWIG_AsVal_frag(Type), + fragment=SWIG_From_frag(Type), + fragment="StdTraits") { +namespace swig { + template <> struct traits< Type > { + typedef value_category category; + static const char* type_name() { return #Type; } + }; + template <> struct traits_asval< Type > { + typedef Type value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal(Type)(obj, val); + } + }; + template <> struct traits_from< Type > { + typedef Type value_type; + static PyObject *from(const value_type& val) { + return SWIG_From(Type)(val); + } + }; +} +} +%enddef + +/* Traits for enums. This is bit of a sneaky trick needed because a generic template specialization of enums + is not possible (unless using template meta-programming which SWIG doesn't support because of the explicit + instantiations required using %template). The STL containers define the 'front' method and the typemap + below is used whenever the front method is wrapped returning an enum. This typemap simply picks up the + standard enum typemap, but additionally drags in a fragment containing the traits_asval and traits_from + required in the generated code for enums. */ + +%define %traits_enum(Type...) + %fragment("SWIG_Traits_enum_"{Type},"header", + fragment=SWIG_AsVal_frag(int), + fragment=SWIG_From_frag(int), + fragment="StdTraits") { +namespace swig { + template <> struct traits_asval< Type > { + typedef Type value_type; + static int asval(PyObject *obj, value_type *val) { + return SWIG_AsVal(int)(obj, (int *)val); + } + }; + template <> struct traits_from< Type > { + typedef Type value_type; + static PyObject *from(const value_type& val) { + return SWIG_From(int)((int)val); + } + }; +} +} +%typemap(out, fragment="SWIG_Traits_enum_"{Type}) const enum SWIGTYPE& front %{$typemap(out, const enum SWIGTYPE&)%} +%enddef + + +%include <std/std_common.i> + +// +// Generates the traits for all the known primitive +// C++ types (int, double, ...) +// +%apply_cpptypes(%traits_ptypen); + diff --git a/contrib/tools/swig/Lib/python/std_container.i b/contrib/tools/swig/Lib/python/std_container.i new file mode 100644 index 00000000000..d24c1570f1d --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_container.i @@ -0,0 +1,2 @@ +%include <pycontainer.swg> +%include <std/std_container.i> diff --git a/contrib/tools/swig/Lib/python/std_except.i b/contrib/tools/swig/Lib/python/std_except.i new file mode 100644 index 00000000000..af98428f65d --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_except.i @@ -0,0 +1 @@ +%include <typemaps/std_except.swg> diff --git a/contrib/tools/swig/Lib/python/std_string.i b/contrib/tools/swig/Lib/python/std_string.i new file mode 100644 index 00000000000..dc1378ae6de --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_string.i @@ -0,0 +1 @@ +%include <typemaps/std_string.swg> diff --git a/contrib/tools/swig/Lib/python/std_vector.i b/contrib/tools/swig/Lib/python/std_vector.i new file mode 100644 index 00000000000..2ac41a54d7d --- /dev/null +++ b/contrib/tools/swig/Lib/python/std_vector.i @@ -0,0 +1,34 @@ +/* + Vectors +*/ + +%fragment("StdVectorTraits","header",fragment="StdSequenceTraits") +%{ + namespace swig { + template <class T> + struct traits_reserve<std::vector<T> > { + static void reserve(std::vector<T> &seq, typename std::vector<T>::size_type n) { + seq.reserve(n); + } + }; + + template <class T> + struct traits_asptr<std::vector<T> > { + static int asptr(PyObject *obj, std::vector<T> **vec) { + return traits_asptr_stdseq<std::vector<T> >::asptr(obj, vec); + } + }; + + template <class T> + struct traits_from<std::vector<T> > { + static PyObject *from(const std::vector<T>& vec) { + return traits_from_stdseq<std::vector<T> >::from(vec); + } + }; + } +%} + +#define %swig_vector_methods(Type...) %swig_sequence_methods(Type) +#define %swig_vector_methods_val(Type...) %swig_sequence_methods_val(Type); + +%include <std/std_vector.i> diff --git a/contrib/tools/swig/Lib/python/wchar.i b/contrib/tools/swig/Lib/python/wchar.i new file mode 100644 index 00000000000..308139a3ab7 --- /dev/null +++ b/contrib/tools/swig/Lib/python/wchar.i @@ -0,0 +1,21 @@ +#ifdef __cplusplus + +%{ +#include <cwchar> +%} + +#else + +%{ +#include <wchar.h> +%} + +#endif + +%types(wchar_t *); +%include <pywstrings.swg> + +/* + Enable swig wchar support. +*/ +#define SWIG_WCHAR diff --git a/contrib/tools/swig/Lib/std/std_alloc.i b/contrib/tools/swig/Lib/std/std_alloc.i new file mode 100644 index 00000000000..e460dc3eaf8 --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_alloc.i @@ -0,0 +1,77 @@ +namespace std +{ + /** + * @brief The "standard" allocator, as per [20.4]. + * + * The private _Alloc is "SGI" style. (See comments at the top + * of stl_alloc.h.) + * + * The underlying allocator behaves as follows. + * - __default_alloc_template is used via two typedefs + * - "__single_client_alloc" typedef does no locking for threads + * - "__alloc" typedef is threadsafe via the locks + * - __new_alloc is used for memory requests + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp> + class allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind; + + allocator() throw(); + + allocator(const allocator& other) throw(); + template<typename _Tp1> + allocator(const allocator<_Tp1>& other) throw(); + ~allocator() throw(); + + + pointer + address(reference __x) const; + + + const_pointer + address(const_reference __x) const; + + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + _Tp* + allocate(size_type __n, const void* = 0); + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __n); + + size_type + max_size() const throw(); + + void construct(pointer __p, const _Tp& __val); + void destroy(pointer __p); + }; + + template<> + class allocator<void> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template<typename _Tp1> + struct rebind; + }; +} // namespace std diff --git a/contrib/tools/swig/Lib/std/std_basic_string.i b/contrib/tools/swig/Lib/std/std_basic_string.i new file mode 100644 index 00000000000..e95cb476538 --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_basic_string.i @@ -0,0 +1,276 @@ +%include <exception.i> +%include <std_container.i> +%include <std_alloc.i> +%include <std_char_traits.i> + +%fragment("<string>"); + +namespace std +{ + %naturalvar basic_string; +} + + +namespace std { + + template <class _CharT, class _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > + class basic_string + { +#if !defined(SWIG_STD_MODERN_STL) || defined(SWIG_STD_NOMODERN_STL) + %ignore push_back; + %ignore clear; + %ignore compare; + %ignore append; +#endif + + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _CharT value_type; + typedef value_type reference; + typedef value_type const_reference; + typedef _Alloc allocator_type; + + static const size_type npos; + +#ifdef SWIG_EXPORT_ITERATOR_METHODS + class iterator; + class reverse_iterator; + class const_iterator; + class const_reverse_iterator; +#endif + + + %traits_swigtype(_CharT); + %fragment(SWIG_Traits_frag(_CharT)); + + + basic_string(const _CharT* __s, size_type __n); + + // Capacity: + + size_type length() const; + + size_type max_size() const; + + size_type capacity() const; + + void reserve(size_type __res_arg); + %extend { + void shrink_to_fit() { + %#if __cplusplus >= 202002L + self->shrink_to_fit(); + %#else + self->reserve(); + %#endif + } + } + + + // Modifiers: + + 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); + + 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& + 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); + + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + // String operations: + const _CharT* c_str() const; + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + size_type + find(const basic_string& __str, size_type __pos = 0) const; + + size_type + find(_CharT __c, size_type __pos = 0) const; + + size_type + rfind(const basic_string& __str, size_type __pos = npos) const; + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const; + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const; + + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const; + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + size_type + find_last_of(_CharT __c, size_type __pos = npos) const; + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const; + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const; + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + basic_string + substr(size_type __pos = 0, size_type __n = npos) const; + + int + compare(const basic_string& __str) const; + + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + + %ignore pop_back(); + %ignore front() const; + %ignore back() const; + %ignore basic_string(size_type n); + %std_sequence_methods_val(basic_string); + + + %ignore pop(); + + +#ifdef %swig_basic_string + // Add swig/language extra methods + %swig_basic_string(std::basic_string< _CharT, _Traits, _Alloc >); +#endif + +#ifdef SWIG_EXPORT_ITERATOR_METHODS + + + class iterator; + class reverse_iterator; + class const_iterator; + class const_reverse_iterator; + + + 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, size_type __n, _CharT __c); + + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2); + + basic_string& + replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2); +#endif + + basic_string& operator +=(const basic_string& v); + + %newobject __add__; + %newobject __radd__; + %extend { + + std::basic_string< _CharT,_Traits,_Alloc >* __add__(const basic_string& v) { + std::basic_string< _CharT,_Traits,_Alloc >* res = new std::basic_string< _CharT,_Traits,_Alloc >(*self); + *res += v; + return res; + } + + std::basic_string< _CharT,_Traits,_Alloc >* __radd__(const basic_string& v) { + std::basic_string< _CharT,_Traits,_Alloc >* res = new std::basic_string< _CharT,_Traits,_Alloc >(v); + *res += *self; + return res; + } + + std::basic_string< _CharT,_Traits,_Alloc > __str__() { + return *self; + } + + std::basic_ostream<_CharT, std::char_traits<_CharT> >& + __rlshift__(std::basic_ostream<_CharT, std::char_traits<_CharT> >& out) { + out << *self; + return out; + } + } + + }; +} + + diff --git a/contrib/tools/swig/Lib/std/std_char_traits.i b/contrib/tools/swig/Lib/std/std_char_traits.i new file mode 100644 index 00000000000..b9b4def32fd --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_char_traits.i @@ -0,0 +1,140 @@ +%include <std_common.i> +#if defined(SWIG_WCHAR) +%include <wchar.i> +#endif + +namespace std +{ + + /// 21.1.2 Basis for explicit _Traits specialization + /// NB: That for any given actual character type this definition is + /// probably wrong. + template<class _CharT> + struct char_traits + { + }; + + + /// 21.1.4 char_traits specializations + template<> + struct char_traits<char> { + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n); + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c); + + // To keep both the byte 0xff and the eof symbol 0xffffffff + // from ending up as 0xffffffff. + static int_type + to_int_type(const char_type& __c); + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof() ; + + static int_type + not_eof(const int_type& __c); + }; + + +#if defined(SWIG_WCHAR) + template<> + struct char_traits<wchar_t> + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2); + + static bool + eq(const char_type& __c1, const char_type& __c2); + + static bool + lt(const char_type& __c1, const char_type& __c2); + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n); + + static size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, int_type __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n); + + static char_type* + assign(char_type* __s, size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c) ; + + static int_type + to_int_type(const char_type& __c) ; + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2); + + static int_type + eof() ; + + static int_type + not_eof(const int_type& __c); + }; +#endif +} + +namespace std { +#ifndef SWIG_STL_WRAP_TRAITS +%template() char_traits<char>; +#if defined(SWIG_WCHAR) +%template() char_traits<wchar_t>; +#endif +#else +%template(char_traits_c) char_traits<char>; +#if defined(SWIG_WCHAR) +%template(char_traits_w) char_traits<wchar_t>; +#endif +#endif +} diff --git a/contrib/tools/swig/Lib/std/std_common.i b/contrib/tools/swig/Lib/std/std_common.i new file mode 100644 index 00000000000..708f3ceedf9 --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_common.i @@ -0,0 +1,250 @@ +%include <std/std_except.i> + +// +// Use the following macro with modern STL implementations +// +//#define SWIG_STD_MODERN_STL +// +// Use this to deactivate the previous definition, when using gcc-2.95 +// or similar old compilers. +// +//#define SWIG_STD_NOMODERN_STL + +// Here, we identify compilers we know have problems with STL. +%{ +#if defined(__GNUC__) +# if __GNUC__ == 2 && __GNUC_MINOR <= 96 +# define SWIG_STD_NOMODERN_STL +# endif +#endif +%} + +// +// Common code for supporting the C++ std namespace +// + +%fragment("<string>"); +%fragment("<stdexcept>"); +%fragment("<stddef.h>"); + + +%fragment("StdIteratorTraits","header",fragment="<stddef.h>") %{ +#if defined(__SUNPRO_CC) && defined(_RWSTD_VER) +# if !defined(SWIG_NO_STD_NOITERATOR_TRAITS_STL) +# define SWIG_STD_NOITERATOR_TRAITS_STL +# endif +#endif + +#if !defined(SWIG_STD_NOITERATOR_TRAITS_STL) +#include <iterator> +#else +namespace std { + template <class Iterator> + struct iterator_traits { + typedef ptrdiff_t difference_type; + typedef typename Iterator::value_type value_type; + }; + + template <class Iterator, class Category,class T, class Reference, class Pointer, class Distance> + struct iterator_traits<__reverse_bi_iterator<Iterator,Category,T,Reference,Pointer,Distance> > { + typedef Distance difference_type; + typedef T value_type; + }; + + template <class T> + struct iterator_traits<T*> { + typedef T value_type; + typedef ptrdiff_t difference_type; + }; + + template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; + } + return __n; + } +} +#endif +%} + +%fragment("StdTraitsCommon","header",fragment="<string>") %{ +namespace swig { + template <class Type> + struct noconst_traits { + typedef Type noconst_type; + }; + + template <class Type> + struct noconst_traits<const Type> { + typedef Type noconst_type; + }; + + /* + type categories + */ + struct pointer_category { }; + struct value_category { }; + + /* + General traits that provides type_name and type_info + */ + template <class Type> struct traits { }; + + template <class Type> + inline const char* type_name() { + return traits<typename noconst_traits<Type >::noconst_type >::type_name(); + } + + template <class Type> struct traits_info { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name<Type>()); + return info; + } + }; + + /* + Partial specialization for pointers (traits_info) + */ + template <class Type> struct traits_info<Type *> { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name<Type>()); + return info; + } + }; + + template <class Type> + inline swig_type_info *type_info() { + return traits_info<Type>::type_info(); + } + + /* + Partial specialization for pointers (traits) + */ + template <class Type> struct traits <Type *> { + typedef pointer_category category; + static std::string make_ptr_name(const char* name) { + std::string ptrname = name; + ptrname += " *"; + return ptrname; + } + static const char* type_name() { + static std::string name = make_ptr_name(swig::type_name<Type>()); + return name.c_str(); + } + }; + + template <class Type, class Category> + struct traits_as { }; + + template <class Type, class Category> + struct traits_check { }; + +} +%} + +/* + Generate the traits for a swigtype +*/ + +%define %traits_swigtype(Type...) +%fragment(SWIG_Traits_frag(Type),"header",fragment="StdTraits") { + namespace swig { + template <> struct traits< Type > { + typedef pointer_category category; + static const char* type_name() { return #Type; } + }; + } +} +%enddef + + + +/* + Generate the typemaps for a class that has 'value' traits +*/ + +%define %typemap_traits(Code,Type...) + %typemaps_asvalfrom(%arg(Code), + %arg(swig::asval< Type >), + %arg(swig::from), + %arg(SWIG_Traits_frag(Type)), + %arg(SWIG_Traits_frag(Type)), + Type); +%enddef + +/* + Generate the typemaps for a class that behaves more like a 'pointer' or + plain wrapped Swigtype. +*/ + +%define %typemap_traits_ptr(Code,Type...) + %typemaps_asptrfrom(%arg(Code), + %arg(swig::asptr), + %arg(swig::from), + %arg(SWIG_Traits_frag(Type)), + %arg(SWIG_Traits_frag(Type)), + Type); +%enddef + + +/* + Equality methods +*/ +%define %std_equal_methods(Type...) +%extend Type { + bool operator == (const Type& v) { + return *self == v; + } + + bool operator != (const Type& v) { + return *self != v; + } +} + +%enddef + +/* + Order methods +*/ + +%define %std_order_methods(Type...) +%extend Type { + bool operator > (const Type& v) { + return *self > v; + } + + bool operator < (const Type& v) { + return *self < v; + } + + bool operator >= (const Type& v) { + return *self >= v; + } + + bool operator <= (const Type& v) { + return *self <= v; + } +} +%enddef + +/* + Comparison methods +*/ + +%define %std_comp_methods(Type...) +%std_equal_methods(Type ) +%std_order_methods(Type ) +%enddef + diff --git a/contrib/tools/swig/Lib/std/std_container.i b/contrib/tools/swig/Lib/std/std_container.i new file mode 100644 index 00000000000..570dfde484e --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_container.i @@ -0,0 +1,169 @@ +%include <std_common.i> +%include <exception.i> +%include <std_alloc.i> + +%{ +#include <algorithm> +%} + +// Common non-resizable container methods + +%define %std_container_methods_non_resizable(container...) + + container(); + container(const container& other); + + bool empty() const; + size_type size() const; + void swap(container& v); + +%enddef + +%define %std_container_methods_forward_iterators(container...) + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + class iterator; + class const_iterator; + iterator begin(); + iterator end(); + #endif + +%enddef + +%define %std_container_methods_reverse_iterators(container...) + + #ifdef SWIG_EXPORT_ITERATOR_METHODS + class reverse_iterator; + class const_reverse_iterator; + reverse_iterator rbegin(); + reverse_iterator rend(); + #endif + +%enddef + +// Common container methods + +%define %std_container_methods(container...) + + %std_container_methods_non_resizable(%arg(container)) + %std_container_methods_forward_iterators(%arg(container)) + %std_container_methods_reverse_iterators(%arg(container)) + + void clear(); + allocator_type get_allocator() const; + +%enddef + +%define %std_container_methods_without_reverse_iterators(container...) + + %std_container_methods_non_resizable(%arg(container)) + %std_container_methods_forward_iterators(%arg(container)) + + void clear(); + allocator_type get_allocator() const; + +%enddef + +// Common sequence + +%define %std_sequence_methods_common(sequence) + + %std_container_methods(%arg(sequence)); + + sequence(size_type size); + void pop_back(); + + void resize(size_type new_size); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS +%extend { + // %extend wrapper used for differing definitions of these methods introduced in C++11 + iterator erase(iterator pos) { return $self->erase(pos); } + iterator erase(iterator first, iterator last) { return $self->erase(first, last); } +} + #endif + +%enddef + +%define %std_sequence_methods_non_resizable(sequence) + + %std_container_methods_non_resizable(%arg(sequence)) + %std_container_methods_forward_iterators(%arg(container)) + %std_container_methods_reverse_iterators(%arg(container)) + + const value_type& front() const; + const value_type& back() const; + +%enddef + +%define %std_sequence_methods(sequence) + + %std_sequence_methods_common(%arg(sequence)); + + sequence(size_type size, const value_type& value); + void push_back(const value_type& x); + + const value_type& front() const; + const value_type& back() const; + + void assign(size_type n, const value_type& x); + void resize(size_type new_size, const value_type& x); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS +%extend { + // %extend wrapper used for differing definitions of these methods introduced in C++11 + iterator insert(iterator pos, const value_type& x) { return $self->insert(pos, x); } + void insert(iterator pos, size_type n, const value_type& x) { $self->insert(pos, n, x); } +} + #endif + +%enddef + +%define %std_sequence_methods_non_resizable_val(sequence...) + + %std_container_methods_non_resizable(%arg(sequence)) + %std_container_methods_forward_iterators(%arg(container)) + %std_container_methods_reverse_iterators(%arg(container)) + + value_type front() const; + value_type back() const; + +#endif + +%enddef + +%define %std_sequence_methods_val(sequence...) + + %std_sequence_methods_common(%arg(sequence)); + + sequence(size_type size, value_type value); + void push_back(value_type x); + + value_type front() const; + value_type back() const; + + void assign(size_type n, value_type x); + void resize(size_type new_size, value_type x); + + #ifdef SWIG_EXPORT_ITERATOR_METHODS +%extend { + // %extend wrapper used for differing definitions of these methods introduced in C++11 + iterator insert(iterator pos, value_type x) { return $self->insert(pos, x); } + void insert(iterator pos, size_type n, value_type x) { $self->insert(pos, n, x); } +} + #endif + +%enddef + + +// +// Ignore member methods for Type with no default constructor +// +%define %std_nodefconst_type(Type...) +%feature("ignore") std::vector< Type >::vector(size_type size); +%feature("ignore") std::vector< Type >::resize(size_type size); +%feature("ignore") std::deque< Type >::deque(size_type size); +%feature("ignore") std::deque< Type >::resize(size_type size); +%feature("ignore") std::list< Type >::list(size_type size); +%feature("ignore") std::list< Type >::resize(size_type size); +%enddef diff --git a/contrib/tools/swig/Lib/std/std_except.i b/contrib/tools/swig/Lib/std/std_except.i new file mode 100644 index 00000000000..728b9c8b529 --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_except.i @@ -0,0 +1,73 @@ +#if defined(SWIGJAVA) || defined(SWIGCSHARP) +#error "do not use this version of std_except.i" +#endif + +%{ +#include <typeinfo> +#include <stdexcept> +%} + +#if defined(SWIG_STD_EXCEPTIONS_AS_CLASSES) + +namespace std { + struct exception + { + virtual ~exception() throw(); + virtual const char* what() const throw(); + }; + + struct bad_cast : exception + { + }; + + struct bad_exception : exception + { + }; + + struct logic_error : exception + { + logic_error(const string& msg); + }; + + struct domain_error : logic_error + { + domain_error(const string& msg); + }; + + struct invalid_argument : logic_error + { + invalid_argument(const string& msg); + }; + + struct length_error : logic_error + { + length_error(const string& msg); + }; + + struct out_of_range : logic_error + { + out_of_range(const string& msg); + }; + + struct runtime_error : exception + { + runtime_error(const string& msg); + }; + + struct range_error : runtime_error + { + range_error(const string& msg); + }; + + struct overflow_error : runtime_error + { + overflow_error(const string& msg); + }; + + struct underflow_error : runtime_error + { + underflow_error(const string& msg); + }; +} + +#endif diff --git a/contrib/tools/swig/Lib/std/std_string.i b/contrib/tools/swig/Lib/std/std_string.i new file mode 100644 index 00000000000..35fcdd16c6b --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_string.i @@ -0,0 +1,13 @@ +%include <std/std_basic_string.i> + +/* plain strings */ + +namespace std +{ + %std_comp_methods(basic_string<char>); + %naturalvar string; + typedef basic_string<char> string; +} + + +%template(string) std::basic_string<char>; diff --git a/contrib/tools/swig/Lib/std/std_vector.i b/contrib/tools/swig/Lib/std/std_vector.i new file mode 100644 index 00000000000..b35f03bea20 --- /dev/null +++ b/contrib/tools/swig/Lib/std/std_vector.i @@ -0,0 +1,225 @@ +// +// std::vector +// + +%include <std_container.i> + +// Vector + +%define %std_vector_methods(vector...) + %std_sequence_methods(vector) + + void reserve(size_type n); + size_type capacity() const; +%enddef + + +%define %std_vector_methods_val(vector...) + %std_sequence_methods_val(vector) + + void reserve(size_type n); + size_type capacity() const; +%enddef + + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// as much as possible, namely, to allow the user to pass and +// be returned tuples or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector<T>), f(const std::vector<T>&): +// the parameter being read-only, either a sequence or a +// previously wrapped std::vector<T> can be passed. +// -- f(std::vector<T>&), f(std::vector<T>*): +// the parameter may be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector<T> f(), const std::vector<T>& f(): +// the vector is returned by copy; therefore, a sequence of T:s +// is returned which is most easily used in other functions +// -- std::vector<T>& f(), std::vector<T>* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// -- const std::vector<T>* f(), f(const std::vector<T>*): +// for consistency, they expect and return a plain vector pointer. +// ------------------------------------------------------------------------ + +%{ +#include <vector> +%} + +// exported classes + + +namespace std { + + template<class _Tp, class _Alloc = allocator< _Tp > > + class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Alloc allocator_type; + + %traits_swigtype(_Tp); + %traits_enum(_Tp); + + %fragment(SWIG_Traits_frag(std::vector< _Tp, _Alloc >), "header", + fragment=SWIG_Traits_frag(_Tp), + fragment="StdVectorTraits") { + namespace swig { + template <> struct traits<std::vector< _Tp, _Alloc > > { + typedef pointer_category category; + static const char* type_name() { + return "std::vector<" #_Tp "," #_Alloc " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector< _Tp, _Alloc >); + +#ifdef %swig_vector_methods + // Add swig/language extra methods + %swig_vector_methods(std::vector< _Tp, _Alloc >); +#endif + + %std_vector_methods(vector); + }; + + // *** + // This specialization should disappear or get simplified when + // a 'const SWIGTYPE*&' can be defined + // *** + template<class _Tp, class _Alloc > + class vector< _Tp*, _Alloc > { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Alloc allocator_type; + + %traits_swigtype(_Tp); + + %fragment(SWIG_Traits_frag(std::vector< _Tp*, _Alloc >), "header", + fragment=SWIG_Traits_frag(_Tp), + fragment="StdVectorTraits") { + namespace swig { + template <> struct traits<std::vector< _Tp*, _Alloc > > { + typedef value_category category; + static const char* type_name() { + return "std::vector<" #_Tp " *," #_Alloc " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector< _Tp*, _Alloc >); + +#ifdef %swig_vector_methods_val + // Add swig/language extra methods + %swig_vector_methods_val(std::vector< _Tp*, _Alloc >); +#endif + + %std_vector_methods_val(vector); + }; + + // *** + // const pointer specialization + // *** + template<class _Tp, class _Alloc > + class vector< _Tp const *, _Alloc > { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp const * value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Alloc allocator_type; + + %traits_swigtype(_Tp); + + %fragment(SWIG_Traits_frag(std::vector< _Tp const*, _Alloc >), "header", + fragment=SWIG_Traits_frag(_Tp), + fragment="StdVectorTraits") { + namespace swig { + template <> struct traits<std::vector< _Tp const*, _Alloc > > { + typedef value_category category; + static const char* type_name() { + return "std::vector<" #_Tp " const*," #_Alloc " >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector< _Tp const*, _Alloc >); + +#ifdef %swig_vector_methods_val + // Add swig/language extra methods + %swig_vector_methods_val(std::vector< _Tp const*, _Alloc >); +#endif + + %std_vector_methods_val(vector); + }; + + // *** + // bool specialization + // *** + + template<class _Alloc > + class vector<bool,_Alloc > { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef bool value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef bool const_reference; + typedef _Alloc allocator_type; + + %traits_swigtype(bool); + + %fragment(SWIG_Traits_frag(std::vector<bool, _Alloc >), "header", + fragment=SWIG_Traits_frag(bool), + fragment="StdVectorTraits") { + namespace swig { + template <> struct traits<std::vector<bool, _Alloc > > { + typedef value_category category; + static const char* type_name() { + return "std::vector<bool, _Alloc >"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<bool, _Alloc >); + + +#ifdef %swig_vector_methods_val + // Add swig/language extra methods + %swig_vector_methods_val(std::vector<bool, _Alloc >); +#endif + + %std_vector_methods_val(vector); + +#if defined(SWIG_STD_MODERN_STL) && !defined(SWIG_STD_NOMODERN_STL) + void flip(); +#endif + + }; + +} diff --git a/contrib/tools/swig/Lib/typemaps/std_except.swg b/contrib/tools/swig/Lib/typemaps/std_except.swg new file mode 100644 index 00000000000..75d066490fd --- /dev/null +++ b/contrib/tools/swig/Lib/typemaps/std_except.swg @@ -0,0 +1,37 @@ +%include <typemaps/exception.swg> + +/* + Mark all of std exception classes as "exception classes" via + the "exceptionclass" feature. + + If needed, you can disable it by using %noexceptionclass. +*/ + +%define %std_exception_map(Exception, Code) + %exceptionclass Exception; +#if !defined(SWIG_STD_EXCEPTIONS_AS_CLASSES) + %typemap(throws,noblock=1) Exception { + SWIG_exception_fail(Code, $1.what()); + } + %ignore Exception; + struct Exception { + }; +#endif +%enddef + +namespace std { + %std_exception_map(bad_cast, SWIG_TypeError); + %std_exception_map(bad_exception, SWIG_SystemError); + %std_exception_map(domain_error, SWIG_ValueError); + %std_exception_map(exception, SWIG_SystemError); + %std_exception_map(invalid_argument, SWIG_ValueError); + %std_exception_map(length_error, SWIG_IndexError); + %std_exception_map(logic_error, SWIG_RuntimeError); + %std_exception_map(out_of_range, SWIG_IndexError); + %std_exception_map(overflow_error, SWIG_OverflowError); + %std_exception_map(range_error, SWIG_OverflowError); + %std_exception_map(runtime_error, SWIG_RuntimeError); + %std_exception_map(underflow_error, SWIG_OverflowError); +} + +%include <std/std_except.i> diff --git a/contrib/tools/swig/Lib/typemaps/std_string.swg b/contrib/tools/swig/Lib/typemaps/std_string.swg new file mode 100644 index 00000000000..5b57beab560 --- /dev/null +++ b/contrib/tools/swig/Lib/typemaps/std_string.swg @@ -0,0 +1,25 @@ +// +// String +// + + +#ifndef SWIG_STD_BASIC_STRING +#define SWIG_STD_STRING + +%include <typemaps/std_strings.swg> + +%fragment("<string>"); + +namespace std +{ + %naturalvar string; + class string; +} + +%typemaps_std_string(std::string, char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, %checkcode(STDSTRING)); + +#else + +%include <std/std_string.i> + +#endif diff --git a/contrib/tools/swig/Lib/typemaps/std_strings.swg b/contrib/tools/swig/Lib/typemaps/std_strings.swg new file mode 100644 index 00000000000..e9c23ba9158 --- /dev/null +++ b/contrib/tools/swig/Lib/typemaps/std_strings.swg @@ -0,0 +1,78 @@ + +/* defining the String asptr/from methods */ + +%define %std_string_asptr(String, Char, SWIG_AsCharPtrAndSize, Frag) +%fragment(SWIG_AsPtr_frag(String),"header",fragment=Frag) { +SWIGINTERN int +SWIG_AsPtr_dec(String)(SWIG_Object obj, String **val) +{ + Char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ; + if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) { + if (buf) { + if (val) *val = new String(buf, size - 1); + if (alloc == SWIG_NEWOBJ) %delete_array(buf); + return SWIG_NEWOBJ; + } else { + if (val) *val = 0; + return SWIG_OLDOBJ; + } + } else { + static int init = 0; + static swig_type_info* descriptor = 0; + if (!init) { + descriptor = SWIG_TypeQuery(#String " *"); + init = 1; + } + if (descriptor) { + String *vptr; + int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0); + if (SWIG_IsOK(res) && val) *val = vptr; + return res; + } + } + return SWIG_ERROR; +} +} +%enddef + +%define %std_string_from(String, SWIG_FromCharPtrAndSize, Frag) +%fragment(SWIG_From_frag(String),"header",fragment=Frag) { +SWIGINTERNINLINE SWIG_Object +SWIG_From_dec(String)(const String& s) +{ + return SWIG_FromCharPtrAndSize(s.data(), s.size()); +} +} +%enddef + +%define %std_string_asval(String) +%fragment(SWIG_AsVal_frag(String),"header", fragment=SWIG_AsPtr_frag(String)) { +SWIGINTERN int +SWIG_AsVal_dec(String)(SWIG_Object obj, String *val) +{ + String* v = (String *) 0; + int res = SWIG_AsPtr(String)(obj, &v); + if (!SWIG_IsOK(res)) return res; + if (v) { + if (val) *val = *v; + if (SWIG_IsNewObj(res)) { + %delete(v); + res = SWIG_DelNewMask(res); + } + return res; + } + return SWIG_ERROR; +} +} +%enddef + + +%define %typemaps_std_string(String, Char, AsPtrMethod, FromMethod, CheckCode) + +%std_string_asptr(String, Char, AsPtrMethod, #AsPtrMethod) +%std_string_asval(String) +%std_string_from(String, FromMethod, #FromMethod) + +%typemaps_asptrfromn(%arg(CheckCode), String); + +%enddef diff --git a/contrib/tools/swig/Lib/wchar.i b/contrib/tools/swig/Lib/wchar.i new file mode 100644 index 00000000000..14de346346d --- /dev/null +++ b/contrib/tools/swig/Lib/wchar.i @@ -0,0 +1,11 @@ +/* ----------------------------------------------------------------------------- + * wchar.i + * ----------------------------------------------------------------------------- */ + +/* + wchar_t not supported, unless otherwise specified in the target language. +*/ + +#if defined(SWIG_WCHAR) +#undef SWIG_WCHAR +#endif |