This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
# File : Makefile.swig
# Makefile for a SWIG module. Use this file if you are
# producing a Ruby extension for general use or distribution.
#
# 1. Prepare extconf.rb.
# 2. Modify this file as appropriate.
# 3. Type 'make -f Makefile.swig' to generate wrapper code and Makefile.
# 4. Type 'make' to build your extension.
# 5. Type 'make install' to install your extension.
#
MODULE = yourmodule
FEATURE = $(MODULE)
INTERFACE = $(MODULE).i
RUBY = ruby
SWIG = swig
# for C extension
SWIGOPT = -ruby
WRAPPER = $(MODULE)_wrap.c
## for C++ extension
#SWIGOPT = -ruby -c++
#WRAPPER = $(MODULE)_wrap.cc
swigall: $(WRAPPER) Makefile
$(WRAPPER): $(INTERFACE)
$(SWIG) $(SWIGOPT) -o $@ $(INTERFACE)
Makefile: extconf.rb
$(RUBY) extconf.rb
@if [ -f Makefile ] ; then\
echo "include Makefile.swig" >> Makefile;\
fi
swigclean:
@if [ -f Makefile ] ; then\
make -f Makefile clean;\
fi
rm -f Makefile $(WRAPPER)

View File

@@ -0,0 +1,48 @@
/* ------------------------------------------------------------
* --- Argc & Argv ---
* ------------------------------------------------------------ */
/* ------------------------------------------------------------
Use it as follow:
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
%inline %{
int mainApp(size_t argc, const char **argv)
{
return argc;
}
then in the ruby side:
args = ["asdf", "asdf2"]
mainApp(args);
* ------------------------------------------------------------ */
%typemap(in) (int ARGC, char **ARGV) {
if (rb_obj_is_kind_of($input,rb_cArray)) {
int i;
int size = RARRAY_LEN($input);
$1 = ($1_ltype) size;
$2 = (char **) malloc((size+1)*sizeof(char *));
VALUE *ptr = RARRAY_PTR($input);
for (i=0; i < size; i++, ptr++) {
$2[i]= STR2CSTR(*ptr);
}
$2[i]=NULL;
} else {
$1 = 0; $2 = 0;
%argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum);
}
}
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
$1 = rb_obj_is_kind_of($input,rb_cArray);
}
%typemap(freearg) (int ARGC, char **ARGV) {
free((char *) $2);
}

View File

@@ -0,0 +1 @@
%include <typemaps/attribute.swg>

View File

@@ -0,0 +1,6 @@
%define %array_class(TYPE,NAME)
%array_class_wrap(TYPE,NAME,__getitem__,__setitem__)
%enddef
%include <typemaps/carrays.swg>

View File

@@ -0,0 +1 @@
%include <typemaps/cdata.swg>

View File

@@ -0,0 +1 @@
%include <typemaps/cmalloc.swg>

View File

@@ -0,0 +1,2 @@
%include <gcj/cni.i>
%include <jstring.i>

View File

@@ -0,0 +1 @@
%include <typemaps/cpointer.swg>

View File

@@ -0,0 +1 @@
%include <typemaps/cstring.swg>

View File

@@ -0,0 +1,382 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* director.swg
*
* This file contains support for director classes that proxy
* method calls from C++ to Ruby extensions.
* ----------------------------------------------------------------------------- */
/*
Use -DSWIG_DIRECTOR_NOUEH if you prefer to avoid the use of the
Undefined Exception Handler provided by swift
*/
#ifndef SWIG_DIRECTOR_NOUEH
#ifndef SWIG_DIRECTOR_UEH
#define SWIG_DIRECTOR_UEH
#endif
#endif
#ifdef __cplusplus
#include <string>
#include <iostream>
#include <map>
namespace Swig {
/* memory handler */
struct GCItem
{
virtual ~GCItem()
{
}
virtual ruby_owntype get_own() const
{
return 0;
}
};
struct GCItem_var
{
GCItem_var(GCItem *item = 0) : _item(item)
{
}
GCItem_var& operator=(GCItem *item)
{
GCItem *tmp = _item;
_item = item;
delete tmp;
return *this;
}
~GCItem_var()
{
delete _item;
}
GCItem * operator->() const
{
return _item;
}
private:
GCItem *_item;
};
template <typename Type>
struct GCItem_T : GCItem
{
GCItem_T(Type *ptr) : _ptr(ptr)
{
}
virtual ~GCItem_T()
{
delete _ptr;
}
private:
Type *_ptr;
};
struct GCItem_Object : GCItem
{
GCItem_Object(ruby_owntype own) : _own(own)
{
}
virtual ~GCItem_Object()
{
}
ruby_owntype get_own() const
{
return _own;
}
private:
ruby_owntype _own;
};
template <typename Type>
struct GCArray_T : GCItem
{
GCArray_T(Type *ptr) : _ptr(ptr)
{
}
virtual ~GCArray_T()
{
delete[] _ptr;
}
private:
Type *_ptr;
};
/* body args */
struct body_args {
VALUE recv;
ID id;
int argc;
VALUE *argv;
};
/* Base class for director exceptions */
class DirectorException {
protected:
VALUE swig_error;
std::string swig_msg;
protected:
DirectorException(VALUE error)
: swig_error(error)
{
}
DirectorException(VALUE error, const char* hdr, const char* msg ="")
: swig_error(error), swig_msg(hdr) {
if (strlen(msg)) {
swig_msg += " ";
swig_msg += msg;
}
if (swig_msg.size()) {
VALUE str = rb_str_new(swig_msg.data(), swig_msg.size());
swig_error = rb_exc_new3(error, str);
} else {
swig_error = error;
}
}
public:
VALUE getType() const {
return CLASS_OF(swig_error);
}
VALUE getError() const {
return swig_error;
}
const std::string& getMessage() const
{
return swig_msg;
}
virtual ~DirectorException() {}
};
/* unknown exception handler */
class UnknownExceptionHandler
{
#ifdef SWIG_DIRECTOR_UEH
static void handler() {
try {
throw;
} catch (DirectorException& e) {
std::cerr << "Swig Director exception caught:" << std::endl
<< e.getMessage() << std::endl;
} catch (std::exception& e) {
std::cerr << "std::exception caught: "<< e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown exception caught." << std::endl;
}
std::cerr << std::endl
<< "Ruby interpreter traceback:" << std::endl;
std::cerr << std::endl;
std::cerr << "This exception was caught by the SWIG unexpected exception handler." << std::endl
<< "Try using %feature(\"director:except\") to avoid reaching this point." << std::endl
<< std::endl
<< "Exception is being re-thrown, program will like abort/terminate." << std::endl;
throw;
}
public:
std::unexpected_handler old;
UnknownExceptionHandler(std::unexpected_handler nh = handler)
{
old = std::set_unexpected(nh);
}
~UnknownExceptionHandler()
{
std::set_unexpected(old);
}
#endif
};
/* Type mismatch in the return value from a Ruby method call */
class DirectorTypeMismatchException : public Swig::DirectorException {
public:
DirectorTypeMismatchException(VALUE error, const char *msg="")
: Swig::DirectorException(error, "Swig director type mismatch", msg)
{
}
DirectorTypeMismatchException(const char *msg="")
: Swig::DirectorException(rb_eTypeError, "Swig director type mismatch", msg)
{
}
static void raise(VALUE error, const char *msg) {
throw DirectorTypeMismatchException(error, msg);
}
static void raise(const char *msg) {
throw DirectorTypeMismatchException(msg);
}
};
/* Any Ruby exception that occurs during a director method call */
class DirectorMethodException : public Swig::DirectorException {
public:
DirectorMethodException(VALUE error)
: Swig::DirectorException(error) {
}
DirectorMethodException(const char* msg = "")
: Swig::DirectorException(rb_eRuntimeError, "Swig director method error.", msg) {
}
static void raise(VALUE error)
{
throw DirectorMethodException(error);
}
};
/* Attempted to call a pure virtual method via a director method */
class DirectorPureVirtualException : public Swig::DirectorException
{
public:
DirectorPureVirtualException(const char* msg = "")
: DirectorException(rb_eRuntimeError, "Swig director pure virtual method called", msg)
{
}
static void raise(const char *msg)
{
throw DirectorPureVirtualException(msg);
}
};
/* Simple thread abstraction for pthreads on win32 */
#ifdef __THREAD__
# define __PTHREAD__
# if defined(_WIN32) || defined(__WIN32__)
# define pthread_mutex_lock EnterCriticalSection
# define pthread_mutex_unlock LeaveCriticalSection
# define pthread_mutex_t CRITICAL_SECTION
# define SWIG_MUTEX_INIT(var) var
# else
# include <pthread.h>
# define SWIG_MUTEX_INIT(var) var = PTHREAD_MUTEX_INITIALIZER
# endif
#endif
#ifdef __PTHREAD__
struct Guard
{
pthread_mutex_t *_mutex;
Guard(pthread_mutex_t &mutex) : _mutex(&mutex)
{
pthread_mutex_lock(_mutex);
}
~Guard()
{
pthread_mutex_unlock(_mutex);
}
};
# define SWIG_GUARD(mutex) Guard _guard(mutex)
#else
# define SWIG_GUARD(mutex)
#endif
/* director base class */
class Director {
private:
/* pointer to the wrapped Ruby object */
VALUE swig_self;
/* flag indicating whether the object is owned by Ruby or c++ */
mutable bool swig_disown_flag;
public:
/* wrap a Ruby object, optionally taking ownership */
Director(VALUE self) : swig_self(self), swig_disown_flag(false) {
}
/* discard our reference at destruction */
virtual ~Director() {
}
/* return a pointer to the wrapped Ruby object */
VALUE swig_get_self() const {
return swig_self;
}
/* acquire ownership of the wrapped Ruby object (the sense of "disown"
* is from Ruby) */
void swig_disown() const {
if (!swig_disown_flag) {
swig_disown_flag = true;
}
}
/* ownership management */
private:
typedef std::map<void*, GCItem_var> ownership_map;
mutable ownership_map owner;
#ifdef __PTHREAD__
static pthread_mutex_t swig_mutex_own;
#endif
public:
template <typename Type>
void swig_acquire_ownership_array(Type *vptr) const
{
if (vptr) {
SWIG_GUARD(swig_mutex_own);
owner[vptr] = new GCArray_T<Type>(vptr);
}
}
template <typename Type>
void swig_acquire_ownership(Type *vptr) const
{
if (vptr) {
SWIG_GUARD(swig_mutex_own);
owner[vptr] = new GCItem_T<Type>(vptr);
}
}
void swig_acquire_ownership_obj(void *vptr, ruby_owntype own) const
{
if (vptr && own) {
SWIG_GUARD(swig_mutex_own);
owner[vptr] = new GCItem_Object(own);
}
}
ruby_owntype swig_release_ownership(void *vptr) const
{
ruby_owntype own = 0;
if (vptr) {
SWIG_GUARD(swig_mutex_own);
ownership_map::iterator iter = owner.find(vptr);
if (iter != owner.end()) {
own = iter->second->get_own();
owner.erase(iter);
}
}
return own;
}
};
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,16 @@
%wrapper %{
#include "ruby.h"
int
main(argc, argv)
int argc;
char **argv;
{
ruby_init();
ruby_options(argc, argv);
ruby_run();
return 0;
}
%}

View File

@@ -0,0 +1,5 @@
%include <typemaps/exception.swg>
%insert("runtime") {
%define_as(SWIG_exception(code, msg), %block(%error(code, msg);))
}

View File

@@ -0,0 +1,9 @@
require 'mkmf'
dir_config('yourlib')
if have_header('yourlib.h') and have_library('yourlib', 'yourlib_init')
# If you use swig -c option, you may have to link libswigrb.
# have_library('swigrb')
create_makefile('yourlib')
end

View File

@@ -0,0 +1,3 @@
# see top-level Makefile.in
Makefile.swig
extconf.rb

View File

@@ -0,0 +1 @@
%include <typemaps/factory.swg>

View File

@@ -0,0 +1,32 @@
// FILE *
%{
#ifdef __cplusplus
extern "C" {
#endif
#include "rubyio.h"
#ifdef __cplusplus
}
#endif
%}
%typemap(in) FILE *READ {
OpenFile *of;
GetOpenFile($input, of);
rb_io_check_readable(of);
$1 = GetReadFile(of);
rb_read_check($1);
}
%typemap(in) FILE *READ_NOCHECK {
OpenFile *of;
GetOpenFile($input, of);
rb_io_check_readable(of);
$1 = GetReadFile(of);
}
%typemap(in) FILE *WRITE {
OpenFile *of;
GetOpenFile($input, of);
rb_io_check_writable(of);
$1 = GetWriteFile(of);
}

View File

@@ -0,0 +1,44 @@
%include <typemaps/valtypes.swg>
%fragment(SWIG_AsVal_frag(jstring),"header") {
SWIGINTERN int
SWIG_AsVal(jstring)(VALUE obj, jstring *val)
{
if (NIL_P(obj)){
if (val) *val = 0;
return SWIG_OK;
}
if (TYPE(obj) == T_STRING) {
if (val) {
char *cstr = rb_string_value_ptr(&(obj));
jsize len = RSTRING_LEN(obj);
*val = JvNewStringLatin1(cstr, len);
}
return SWIG_NEWOBJ;
}
return SWIG_TypeError;
}
}
%fragment(SWIG_From_frag(jstring),"header") {
SWIGINTERNINLINE VALUE
SWIG_From(jstring)(jstring val)
{
if (!val) {
return Qnil;
} else {
jint len = JvGetStringUTFLength(val);
char buf[len];
JvGetStringUTFRegion(val, 0, len, buf);
return rb_str_new(buf,len);
}
}
}
%typemaps_asvalfrom(%checkcode(STRING),
%arg(SWIG_AsVal(jstring)),
%arg(SWIG_From(jstring)),
%arg(SWIG_AsVal_frag(jstring)),
%arg(SWIG_From_frag(jstring)),
java::lang::String *);

View File

@@ -0,0 +1,34 @@
/*
int PROG_ARGC
char **PROG_ARGV
Some C function receive argc and argv from C main function.
This typemap provides ignore typemap which pass Ruby ARGV contents
as argc and argv to C function.
*/
// argc and argv
%typemap(in,numinputs=0) int PROG_ARGC {
$1 = RARRAY_LEN(rb_argv) + 1;
}
%typemap(in,numinputs=0) char **PROG_ARGV {
int i, n;
VALUE ary = rb_eval_string("[$0] + ARGV");
n = RARRAY_LEN(ary);
$1 = (char **)malloc(n + 1);
for (i = 0; i < n; i++) {
VALUE v = rb_obj_as_string(RARRAY_PTR(ary)[i]);
$1[i] = (char *)malloc(RSTRING_LEN(v) + 1);
strcpy($1[i], RSTRING_PTR(v));
}
}
%typemap(freearg) char **PROG_ARGV {
int i, n = RARRAY_LEN(rb_argv) + 1;
for (i = 0; i < n; i++) free($1[i]);
free($1);
}

View File

@@ -0,0 +1,72 @@
/* ------------------------------------------------------------
* ruby.swg
*
* Ruby configuration module.
* ------------------------------------------------------------ */
/* ------------------------------------------------------------
* The Ruby auto rename rules
* ------------------------------------------------------------ */
#if defined(SWIG_RUBY_AUTORENAME)
/* Class names are CamelCase */
%rename("%(camelcase)s", %$isclass) "";
/* Constants created by %constant or #define are UPPER_CASE */
%rename("%(uppercase)s", %$isconstant) "";
/* SWIG only considers static class members with inline intializers
to be constants. For examples of what is and isn't considered
a constant by SWIG see naming.i in the Ruby test suite. */
%rename("%(uppercase)s", %$ismember, %$isvariable,%$isimmutable,%$isstatic,%$hasvalue,%$hasconsttype) "";
/* Enums are mapped to constants but all we do is make sure the
first letter is uppercase */
%rename("%(firstuppercase)s", %$isenumitem) "";
/* Method names should be lower_case_with_underscores */
%rename("%(undercase)s", %$isfunction, %$not %$ismemberget, %$not %$ismemberset) "";
#endif
/* ------------------------------------------------------------
* Inner macros
* ------------------------------------------------------------ */
%include <rubymacros.swg>
/* ------------------------------------------------------------
* The runtime part
* ------------------------------------------------------------ */
%include <rubyruntime.swg>
/* ------------------------------------------------------------
* Special user directives
* ------------------------------------------------------------ */
%include <rubyuserdir.swg>
/* ------------------------------------------------------------
* Typemap specializations
* ------------------------------------------------------------ */
%include <rubytypemaps.swg>
/* ------------------------------------------------------------
* Overloaded operator support
* ------------------------------------------------------------ */
%include <rubyopers.swg>
/* ------------------------------------------------------------
* Warnings for Ruby keywords
* ------------------------------------------------------------ */
%include <rubykw.swg>
/* ------------------------------------------------------------
* Documentation for common Ruby methods
* ------------------------------------------------------------ */
%include <rubyautodoc.swg>
/* ------------------------------------------------------------
* The Ruby initialization function
* ------------------------------------------------------------ */
%include <rubyinit.swg>

View File

@@ -0,0 +1,36 @@
/* -----------------------------------------------------------------------------
* Ruby API portion that goes into the runtime
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
SWIGINTERN VALUE
SWIG_Ruby_AppendOutput(VALUE target, VALUE o) {
if (NIL_P(target)) {
target = o;
} else {
if (TYPE(target) != T_ARRAY) {
VALUE o2 = target;
target = rb_ary_new();
rb_ary_push(target, o2);
}
rb_ary_push(target, o);
}
return target;
}
/* For ruby1.8.4 and earlier. */
#ifndef RUBY_INIT_STACK
RUBY_EXTERN void Init_stack(VALUE* addr);
# define RUBY_INIT_STACK \
VALUE variable_in_this_stack_frame; \
Init_stack(&variable_in_this_stack_frame);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,110 @@
/**
* @file rubyautodoc.swg
* @author gga
* @date Wed May 2 16:41:59 2007
*
* @brief This file implements autodoc typemaps for some common
* ruby methods.
*
*
*/
%define AUTODOC(func, str)
%feature("autodoc", str) func;
%enddef
AUTODOC(to_i, "Convert $class to an Integer");
AUTODOC(to_f, "Convert $class to a Float");
AUTODOC(coerce, "Coerce class to a number");
AUTODOC(to_a, "Convert $class to an Array");
AUTODOC(to_s, "Convert class to a String representation");
AUTODOC(inspect, "Inspect class and its contents");
AUTODOC(at, "Return element at a certain index");
AUTODOC(__getitem__, "Element accessor/slicing");
AUTODOC(__setitem__, "Element setter/slicing");
AUTODOC(slice, "Return a slice (portion of) the $class");
AUTODOC(push, "Add an element at the end of the $class");
AUTODOC(pop, "Remove and return element at the end of the $class");
AUTODOC(shift, "Remove and return element at the beginning of the $class");
AUTODOC(unshift, "Add one or more elements at the beginning of the $class");
AUTODOC(first, "Return the first element in $class");
AUTODOC(last, "Return the last element in $class");
//
// Common Object methods
//
AUTODOC(hash, "Hashing function for class");
AUTODOC(dup, "Create a duplicate of the class and unfreeze it if needed");
AUTODOC(clone, "Create a duplicate of the class");
//
// Container methods
//
AUTODOC(empty, "Check if $class is empty");
AUTODOC(size, "Size or Length of the $class");
AUTODOC(insert, "Insert one or more new elements in the $class");
//
// Iterator methods (block)
//
AUTODOC(each, "Iterate thru each element in the $class. A block must be provided");
AUTODOC(find, "Find an element in the class");
AUTODOC(each_key, "Iterate thru each key element in the $class. A block must be provided");
AUTODOC(each_value, "Iterate thru each key element in the $class. A block must be provided");
AUTODOC(reject, "Iterate thru each element in the $class and reject those that fail a condition returning a new $class. A block must be provided");
AUTODOC(reject_bang, "Iterate thru each element in the $class and reject those that fail a condition. A block must be provided. $class is modified in place");
AUTODOC(select, "Iterate thru each element in the $class and select those that match a condition. A block must be provided");
AUTODOC(delete_at, "Delete an element at a certain index");
AUTODOC(__delete__, "Delete a matching element");
//
// Hash methods
//
AUTODOC(keys, "Return an Array of key elements");
AUTODOC(values, "Return an Array of value elements");
AUTODOC(values_at, "Return an Array of value elements matching the conditions");
//
// Operators
//
#ifdef __cplusplus
AUTODOC(operator==, "Equality comparison operator");
AUTODOC(operator<=, "Lower or equal comparison operator");
AUTODOC(operator>=, "Higher or equal comparison operator");
AUTODOC(operator<, "Lower than comparison operator");
AUTODOC(operator>, "Higher than comparison operator");
AUTODOC(operator<<, "Left shifting or appending operator");
AUTODOC(operator>>, "Right shifting operator or extracting operator");
AUTODOC(operator+, "Add operator");
AUTODOC(operator-, "Substraction operator");
AUTODOC(operator+(), "Positive operator");
AUTODOC(operator-(), "Negation operator");
AUTODOC(operator&, "AND operator");
AUTODOC(operator|, "OR operator");
AUTODOC(operator^, "XOR operator");
AUTODOC(operator~, "Invert operator");
#endif
AUTODOC(__eq__, "Equality comparison operator");
AUTODOC(__le__, "Lower or equal comparison operator");
AUTODOC(__ge__, "Higher or equal comparison operator");
AUTODOC(__lt__, "Lower than comparison operator");
AUTODOC(__gt__, "Higher than comparison operator");
AUTODOC(__lshift__, "Left shifting or appending operator");
AUTODOC(__rshift__, "Right shifting operator or extracting operator");
AUTODOC(__add___, "Add operator");
AUTODOC(__sub__, "Substraction operator");
AUTODOC(__pos__, "Positive operator");
AUTODOC(__neg__, "Negation operator");
AUTODOC(__and__, "AND operator");
AUTODOC(__or__, "OR operator");
AUTODOC(__xor__, "XOR operator");
AUTODOC(__negate__, "Invert operator");
AUTODOC(__pow__, "Exponential operator");
AUTODOC(__divmod__, "Modulo of division");
AUTODOC(__cmp__, "Comparison operator. Returns < 0 for less than, 0 for equal or > 1 for higher than.");

View File

@@ -0,0 +1,395 @@
#ifdef __cplusplus
/*
GC_VALUE is used as a replacement of Ruby's VALUE.
GC_VALUE automatically handles registering and unregistering
of the underlying Ruby object with the GC.
It can be used if you want to create STL containers of VALUEs, such as:
std::vector< GC_VALUE >;
or as a member variable:
struct A {
GC_VALUE _obj;
A(VALUE o) : _obj(o) {
}
};
or as a input/output value (not much use for this, as VALUE works just as
well here, thou):
GC_VALUE func(GC_VALUE obj) {
GC_VALUE out = rb_obj_classname(obj);
return out;
}
GC_VALUE is 'visible' at the wrapped side, so you can do:
%template(RubyVector) std::vector<swig::GC_VALUE>;
and all the proper typemaps will be used.
*/
namespace swig {
%nodirector GC_VALUE;
// We ignore the constructor so that user can never create a GC_VALUE
// manually
%ignore GC_VALUE::GC_VALUE;
struct GC_VALUE {
VALUE inspect() const;
VALUE to_s() const;
GC_VALUE();
protected:
GC_VALUE( const GC_VALUE& );
~GC_VALUE();
};
%exception GC_VALUE {};
%apply VALUE {GC_VALUE};
// Make sure this is the last typecheck done
%typecheck(999999,noblock=1) GC_VALUE, GC_VALUE&,
const GC_VALUE& { $1 = 1; };
/* For input */
%typemap(in,noblock=1) GC_VALUE* (GC_VALUE r), GC_VALUE& (GC_VALUE r) {
r = $input; $1 = &r;
}
/* For output */
%typemap(out,noblock=1) GC_VALUE {
$result = (VALUE)$1;
}
%typemap(out,noblock=1) GC_VALUE*, GC_VALUE const & {
$result = (VALUE)*$1;
}
%ignore LANGUAGE_OBJ;
typedef GC_VALUE LANGUAGE_OBJ;
}
%{
namespace swig {
class GC_VALUE {
protected:
// Hash of all GC_VALUE's currently in use
static VALUE _hash;
VALUE _obj;
static ID hash_id;
static ID lt_id;
static ID gt_id;
static ID eq_id;
static ID le_id;
static ID ge_id;
static ID pos_id;
static ID neg_id;
static ID inv_id;
static ID add_id;
static ID sub_id;
static ID mul_id;
static ID div_id;
static ID mod_id;
static ID and_id;
static ID or_id;
static ID xor_id;
static ID lshift_id;
static ID rshift_id;
struct OpArgs
{
VALUE src;
ID id;
int nargs;
VALUE target;
};
public:
static void initialize()
{
if ( _hash == Qnil )
{
_hash = rb_hash_new();
rb_gc_register_address( &_hash );
}
}
// this function is never called. Provided for symmetry only.
static void cleanup()
{
rb_gc_unregister_address( &_hash );
}
GC_VALUE() : _obj( Qnil )
{
}
GC_VALUE(const GC_VALUE& item) : _obj(item._obj)
{
GC_register();
}
GC_VALUE(VALUE obj) :_obj(obj)
{
GC_register();
}
~GC_VALUE()
{
GC_unregister();
}
GC_VALUE & operator=(const GC_VALUE& item)
{
GC_unregister();
_obj = item._obj;
GC_register();
return *this;
}
void GC_register()
{
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) )
return;
VALUE val = rb_hash_aref( _hash, _obj );
unsigned n = FIXNUM_P(val) ? NUM2UINT(val) : 0;
++n;
rb_hash_aset( _hash, _obj, INT2NUM(n) );
}
void GC_unregister()
{
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) )
return;
// this test should not be needed but I've noticed some very erratic
// behavior of none being unregistered in some very rare situations.
if ( BUILTIN_TYPE(_obj) == T_NONE ) return;
VALUE val = rb_hash_aref( _hash, _obj );
unsigned n = FIXNUM_P(val) ? NUM2UINT(val) : 1;
--n;
if ( n )
rb_hash_aset( _hash, _obj, INT2NUM(n) );
else
rb_hash_delete( _hash, _obj );
}
operator VALUE() const
{
return _obj;
}
VALUE inspect() const
{
return rb_inspect(_obj);
}
VALUE to_s() const
{
return rb_inspect(_obj);
}
static VALUE swig_protect_funcall( VALUE p )
{
OpArgs* args = (OpArgs*) p;
return rb_funcall( args->src, args->id, args->nargs, args->target );
}
#define GC_VALUE_CMP( op_id, op, cmp, cmpval ) \
bool op( const GC_VALUE& other ) const \
{ \
if ( FIXNUM_P(_obj) && FIXNUM_P(other._obj) ) \
{ \
return _obj cmp other._obj; \
} \
bool res = false; \
VALUE ret = Qnil; \
SWIG_RUBY_THREAD_BEGIN_BLOCK; \
if ( rb_respond_to( _obj, op_id ) == Qtrue ) \
{ \
int status; \
OpArgs args; \
args.src = _obj; \
args.id = op_id; \
args.nargs = 1; \
args.target = VALUE(other); \
ret = rb_protect( PROTECTFUNC(swig_protect_funcall), \
VALUE(&args), &status ); \
} \
if ( ret == Qnil ) { \
VALUE a = rb_funcall( _obj, hash_id, 0 ); \
VALUE b = rb_funcall( VALUE(other), hash_id, 0 ); \
res = a cmp b; \
} \
else \
{ \
res = RTEST( ret ); \
} \
SWIG_RUBY_THREAD_END_BLOCK; \
return res; \
}
GC_VALUE_CMP( eq_id, operator==, ==, == 0 )
GC_VALUE_CMP( lt_id, operator<, < , < 0 )
GC_VALUE_CMP( le_id, operator<=, <=, <= 0 )
GC_VALUE_CMP( gt_id, operator>, > , > 0 )
GC_VALUE_CMP( ge_id, operator>=, >=, >= 0 )
#undef GC_VALUE_CMP
bool operator!=( const GC_VALUE& other )
{
return !(this->operator==(other));
}
#define GC_VALUE_UNARY( proc_id, op ) \
GC_VALUE op() const \
{ \
VALUE ret = Qnil; \
SWIG_RUBY_THREAD_BEGIN_BLOCK; \
int status; \
OpArgs args; \
args.src = _obj; \
args.id = proc_id; \
args.nargs = 0; \
args.target = Qnil; \
ret = rb_protect( PROTECTFUNC(swig_protect_funcall), VALUE(&args), \
&status ); \
SWIG_RUBY_THREAD_END_BLOCK; \
return ret; \
}
GC_VALUE_UNARY( pos_id, operator+ )
GC_VALUE_UNARY( neg_id, operator- )
GC_VALUE_UNARY( inv_id, operator~ )
#undef GC_VALUE_BINARY
#define GC_VALUE_BINARY( proc_id, op ) \
GC_VALUE op( const GC_VALUE& other ) const \
{ \
VALUE ret = Qnil; \
SWIG_RUBY_THREAD_BEGIN_BLOCK; \
int status; \
OpArgs args; \
args.src = _obj; \
args.id = proc_id; \
args.nargs = 1; \
args.target = VALUE(other); \
ret = rb_protect( PROTECTFUNC(swig_protect_funcall), VALUE(&args), \
&status ); \
SWIG_RUBY_THREAD_END_BLOCK; \
return GC_VALUE(ret); \
}
GC_VALUE_BINARY( add_id, operator+ );
GC_VALUE_BINARY( sub_id, operator- );
GC_VALUE_BINARY( mul_id, operator* );
GC_VALUE_BINARY( div_id, operator/ );
GC_VALUE_BINARY( mod_id, operator% );
GC_VALUE_BINARY( and_id, operator& );
GC_VALUE_BINARY( xor_id, operator^ );
GC_VALUE_BINARY( or_id, operator| );
GC_VALUE_BINARY( lshift_id, operator<< );
GC_VALUE_BINARY( rshift_id, operator>> );
#undef GC_VALUE_BINARY
};
ID GC_VALUE::hash_id = rb_intern("hash");
ID GC_VALUE::lt_id = rb_intern("<");
ID GC_VALUE::gt_id = rb_intern(">");
ID GC_VALUE::eq_id = rb_intern("==");
ID GC_VALUE::le_id = rb_intern("<=");
ID GC_VALUE::ge_id = rb_intern(">=");
ID GC_VALUE::pos_id = rb_intern("+@");
ID GC_VALUE::neg_id = rb_intern("-@");
ID GC_VALUE::inv_id = rb_intern("~");
ID GC_VALUE::add_id = rb_intern("+");
ID GC_VALUE::sub_id = rb_intern("-");
ID GC_VALUE::mul_id = rb_intern("*");
ID GC_VALUE::div_id = rb_intern("/");
ID GC_VALUE::mod_id = rb_intern("%");
ID GC_VALUE::and_id = rb_intern("&");
ID GC_VALUE::or_id = rb_intern("|");
ID GC_VALUE::xor_id = rb_intern("^");
ID GC_VALUE::lshift_id = rb_intern("<<");
ID GC_VALUE::rshift_id = rb_intern(">>");
VALUE GC_VALUE::_hash = Qnil;
typedef GC_VALUE LANGUAGE_OBJ;
} // namespace swig
%}
%init {
swig::GC_VALUE::initialize();
}
//
// Fragment that contains traits to properly deal with GC_VALUE.
// These functions may be invoked as a need of the from(), asval(),
// asptr() and as() template functors, usually used in %typemaps.
//
%fragment(SWIG_Traits_frag(swig::GC_VALUE),"header",fragment="StdTraits") {
namespace swig {
template <> struct traits<GC_VALUE > {
typedef value_category category;
static const char* type_name() { return "GC_VALUE"; }
};
template <> struct traits_from<GC_VALUE> {
typedef GC_VALUE value_type;
static VALUE from(const value_type& val) {
return static_cast<VALUE>(val);
}
};
template <>
struct traits_check<GC_VALUE, value_category> {
static bool check(GC_VALUE) {
return true;
}
};
template <> struct traits_asval<GC_VALUE > {
typedef GC_VALUE value_type;
static int asval(VALUE obj, value_type *val) {
if (val) *val = obj;
return SWIG_OK;
}
};
} // swig
} // %fragment(traits for swig::GC_VALUE)
#endif // __cplusplus

View File

@@ -0,0 +1,129 @@
/*
Defines the As/From conversors for double/float complex, you need to
provide complex Type, the Name you want to use in the conversors,
the complex Constructor method, and the Real and Imag complex
accesor methods.
See the std_complex.i and ccomplex.i for concrete examples.
*/
/*
Ruby does not have native complex numbers. They are an extension in the
STD library.
*/
%{
static VALUE swig_rb_cComplex = Qnil;
static ID swig_real_id = 0;
static ID swig_imag_id = 0;
int Ruby_Is_Complex( VALUE obj )
{
return ( (rb_respond_to( obj, swig_real_id ) == Qtrue) &&
(rb_respond_to( obj, swig_imag_id ) == Qtrue) );
}
%}
%init {
rb_require("complex");
swig_rb_cComplex = rb_const_get( rb_cObject, rb_intern("Complex") );
if( swig_rb_cComplex == Qnil )
rb_warn("Ruby's complex.so not found");
swig_real_id = rb_intern("real");
swig_imag_id = rb_intern("imag");
}
/* the common from conversor */
%define %swig_fromcplx_conv(Type, Real, Imag)
%fragment(SWIG_From_frag(Type),"header")
{
SWIGINTERNINLINE VALUE
SWIG_From(Type)(%ifcplusplus(const Type&, Type) c)
{
VALUE args[] = {
rb_float_new(Real(c)),
rb_float_new(Imag(c))
};
return rb_class_new_instance(2, args, swig_rb_cComplex);
}
}
%enddef
/* the double case */
%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag)
%fragment(SWIG_AsVal_frag(Type),"header",
fragment=SWIG_AsVal_frag(double))
{
SWIGINTERN int
SWIG_AsVal(Type) (VALUE o, Type* val)
{
if ( Ruby_Is_Complex( o ) ) {
if (val) {
VALUE real = rb_funcall(o, swig_real_id, 0 );
VALUE imag = rb_funcall(o, swig_imag_id, 0 );
double re = 0;
SWIG_AsVal_double( real, &re );
double im = 0;
SWIG_AsVal_double( imag, &im );
*val = Constructor(re, im);
}
return SWIG_OK;
} else {
double d;
int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d));
if (SWIG_IsOK(res)) {
if (val) *val = Constructor(d, 0.0);
return res;
}
}
return SWIG_TypeError;
}
}
%swig_fromcplx_conv(Type, Real, Imag);
%enddef
/* the float case */
%define %swig_cplxflt_conv(Type, Constructor, Real, Imag)
%fragment(SWIG_AsVal_frag(Type),"header",
fragment=SWIG_AsVal_frag(float),
fragment=SWIG_AsVal_frag(double)) {
SWIGINTERN int
SWIG_AsVal(Type)(VALUE o, Type *val)
{
if ( Ruby_Is_Complex( o ) ) {
VALUE real = rb_funcall(o, swig_real_id, 0 );
VALUE imag = rb_funcall(o, swig_imag_id, 0 );
double re = 0;
SWIG_AsVal_double( real, &re );
double im = 0;
SWIG_AsVal_double( imag, &im );
if ((-FLT_MAX <= re && re <= FLT_MAX) &&
(-FLT_MAX <= im && im <= FLT_MAX)) {
if (val) *val = Constructor(%numeric_cast(re, float),
%numeric_cast(im, float));
return SWIG_OK;
} else {
return SWIG_OverflowError;
}
} else {
float re;
int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re));
if (SWIG_IsOK(res)) {
if (val) *val = Constructor(re, 0.0);
return res;
}
}
return SWIG_TypeError;
}
}
%swig_fromcplx_conv(Type, Real, Imag);
%enddef
#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \
%swig_cplxflt_conv(Type, Constructor, Real, Imag)
#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \
%swig_cplxdbl_conv(Type, Constructor, Real, Imag)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,139 @@
/**
* @file rubycontainer_extended.swg
* @author gga
* @date Sat May 5 05:36:01 2007
*
* @brief This file contains additional functions that make containers
* behave closer to ruby primitive types.
* However, some of these functions place some restrictions on
* the underlying object inside of the container and the iterator
* (that it has to have an == comparison function, that it has to have
* an = assignment operator, etc).
*
*/
/**
* Macro used to add extend functions that require operator== in object.
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_with_equal_operator( Container, Type )
VALUE __delete__( const Type& val ) {
VALUE r = Qnil;
Container<Type >::iterator e = $self->end();
Container<Type >::iterator i = std::remove( $self->begin(), e, val );
// remove dangling elements now
$self->erase( i, e );
if ( i != e )
r = swig::from< Type >( val );
else if ( rb_block_given_p() )
r = rb_yield(Qnil);
return r;
}
%enddef // end of %swig_container_with_equal_operator
/**
* Macro used to add extend functions that require the assignment
* operator (ie. = ) of contained class
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_with_assignment( Container, Type )
//
// map! -- the equivalent of std::transform
//
Container< Type >* map_bang() {
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "No block given" );
VALUE r = Qnil;
Container< Type >::iterator i = $self->begin();
Container< Type >::iterator e = $self->end();
try {
for ( ; i != e; ++i )
{
r = swig::from< Type >( *i );
r = rb_yield( r );
*i = swig::as< Type >( r );
}
}
catch ( const std::invalid_argument& )
{
rb_raise(rb_eTypeError,
"Yield block did not return a valid element for " #Container);
}
return $self;
}
%enddef // end of %swig_container_with_assignment
/**
* Macro used to add all extended functions to a container
*
* @param Container STL container
* @param Type class inside container
*
*/
%define %swig_container_extend( Container, Type )
%extend Container< Type > {
%swig_container_with_assignment( %arg(Container), Type );
%swig_container_with_equal_operator( %arg(Container), Type );
}
%enddef
/**
* Private macro used to add all extended functions to C/C++
* primitive types
*
* @param Container an STL container, like std::vector (with no class template)
*
*/
%define %__swig_container_extend_primtypes( Container )
%swig_container_extend( %arg( Container ), bool );
%swig_container_extend( %arg( Container ), char );
%swig_container_extend( %arg( Container ), short );
%swig_container_extend( %arg( Container ), int );
%swig_container_extend( %arg( Container ), unsigned short );
%swig_container_extend( %arg( Container ), unsigned int );
%swig_container_extend( %arg( Container ), float );
%swig_container_extend( %arg( Container ), double );
%swig_container_extend( %arg( Container ), std::complex );
%swig_container_extend( %arg( Container ), std::string );
%swig_container_extend( %arg( Container ), swig::GC_VALUE );
%swig_container_extend( %arg( Container ), swig::GC_VALUE );
%enddef
%__swig_container_extend_primtypes( std::vector );
%__swig_container_extend_primtypes( std::deque );
%__swig_container_extend_primtypes( std::list );

View File

@@ -0,0 +1 @@
/* empty file added for backward comp. */

View File

@@ -0,0 +1,154 @@
/* -----------------------------------------------------------------------------
* error manipulation
* ----------------------------------------------------------------------------- */
/* Define some additional error types */
#define SWIG_ObjectPreviouslyDeletedError -100
/* Define custom exceptions for errors that do not map to existing Ruby
exceptions. Note this only works for C++ since a global cannot be
initialized by a funtion in C. For C, fallback to rb_eRuntimeError.*/
SWIGINTERN VALUE
getNullReferenceError(void) {
static int init = 0;
static VALUE rb_eNullReferenceError ;
if (!init) {
init = 1;
rb_eNullReferenceError = rb_define_class("NullReferenceError", rb_eRuntimeError);
}
return rb_eNullReferenceError;
}
SWIGINTERN VALUE
getObjectPreviouslyDeletedError(void) {
static int init = 0;
static VALUE rb_eObjectPreviouslyDeleted ;
if (!init) {
init = 1;
rb_eObjectPreviouslyDeleted = rb_define_class("ObjectPreviouslyDeleted", rb_eRuntimeError);
}
return rb_eObjectPreviouslyDeleted;
}
SWIGINTERN VALUE
SWIG_Ruby_ErrorType(int SWIG_code) {
VALUE type;
switch (SWIG_code) {
case SWIG_MemoryError:
type = rb_eNoMemError;
break;
case SWIG_IOError:
type = rb_eIOError;
break;
case SWIG_RuntimeError:
type = rb_eRuntimeError;
break;
case SWIG_IndexError:
type = rb_eIndexError;
break;
case SWIG_TypeError:
type = rb_eTypeError;
break;
case SWIG_DivisionByZero:
type = rb_eZeroDivError;
break;
case SWIG_OverflowError:
type = rb_eRangeError;
break;
case SWIG_SyntaxError:
type = rb_eSyntaxError;
break;
case SWIG_ValueError:
type = rb_eArgError;
break;
case SWIG_SystemError:
type = rb_eFatal;
break;
case SWIG_AttributeError:
type = rb_eRuntimeError;
break;
case SWIG_NullReferenceError:
type = getNullReferenceError();
break;
case SWIG_ObjectPreviouslyDeletedError:
type = getObjectPreviouslyDeletedError();
break;
case SWIG_UnknownError:
type = rb_eRuntimeError;
break;
default:
type = rb_eRuntimeError;
}
return type;
}
/* This function is called when a user inputs a wrong argument to
a method.
*/
SWIGINTERN
const char* Ruby_Format_TypeError( const char* msg,
const char* type,
const char* name,
const int argn,
VALUE input )
{
char buf[128];
VALUE str;
VALUE asStr;
if ( msg && *msg )
{
str = rb_str_new2(msg);
}
else
{
str = rb_str_new(NULL, 0);
}
str = rb_str_cat2( str, "Expected argument " );
sprintf( buf, "%d of type ", argn-1 );
str = rb_str_cat2( str, buf );
str = rb_str_cat2( str, type );
str = rb_str_cat2( str, ", but got " );
str = rb_str_cat2( str, rb_obj_classname(input) );
str = rb_str_cat2( str, " " );
asStr = rb_inspect(input);
if ( RSTRING_LEN(asStr) > 30 )
{
str = rb_str_cat( str, StringValuePtr(asStr), 30 );
str = rb_str_cat2( str, "..." );
}
else
{
str = rb_str_append( str, asStr );
}
if ( name )
{
str = rb_str_cat2( str, "\n\tin SWIG method '" );
str = rb_str_cat2( str, name );
str = rb_str_cat2( str, "'" );
}
return StringValuePtr( str );
}
/* This function is called when an overloaded method fails */
SWIGINTERN
void Ruby_Format_OverloadedError(
const int argc,
const int maxargs,
const char* method,
const char* prototypes
)
{
const char* msg = "Wrong # of arguments";
if ( argc <= maxargs ) msg = "Wrong arguments";
rb_raise(rb_eArgError,"%s for overloaded method '%s'.\n"
"Possible C/C++ prototypes are:\n%s",
msg, method, prototypes);
}

View File

@@ -0,0 +1,23 @@
/*
Create a file with this name, 'rubyfragments.swg', in your working
directory and add all the %fragments you want to take precedence
over the ones defined by default by swig.
For example, if you add:
%fragment(SWIG_AsVal_frag(int),"header") {
SWIGINTERNINLINE int
SWIG_AsVal(int)(VALUE obj, int *val)
{
<your code here>;
}
}
this will replace the code used to retrieve an integer value for all
the typemaps that need it, including:
int, std::vector<int>, std::list<std::pair<int,int> >, etc.
*/

View File

@@ -0,0 +1,139 @@
#include <ruby.h>
/* Remove global macros defined in Ruby's win32.h */
#ifdef write
# undef write
#endif
#ifdef read
# undef read
#endif
/* Ruby 1.7 defines NUM2LL(), LL2NUM() and ULL2NUM() macros */
#ifndef NUM2LL
#define NUM2LL(x) NUM2LONG((x))
#endif
#ifndef LL2NUM
#define LL2NUM(x) INT2NUM((long) (x))
#endif
#ifndef ULL2NUM
#define ULL2NUM(x) UINT2NUM((unsigned long) (x))
#endif
/* Ruby 1.7 doesn't (yet) define NUM2ULL() */
#ifndef NUM2ULL
#ifdef HAVE_LONG_LONG
#define NUM2ULL(x) rb_num2ull((x))
#else
#define NUM2ULL(x) NUM2ULONG(x)
#endif
#endif
/* RSTRING_LEN, etc are new in Ruby 1.9, but ->ptr and ->len no longer work */
/* Define these for older versions so we can just write code the new way */
#ifndef RSTRING_LEN
# define RSTRING_LEN(x) RSTRING(x)->len
#endif
#ifndef RSTRING_PTR
# define RSTRING_PTR(x) RSTRING(x)->ptr
#endif
#ifndef RSTRING_END
# define RSTRING_END(x) (RSTRING_PTR(x) + RSTRING_LEN(x))
#endif
#ifndef RARRAY_LEN
# define RARRAY_LEN(x) RARRAY(x)->len
#endif
#ifndef RARRAY_PTR
# define RARRAY_PTR(x) RARRAY(x)->ptr
#endif
#ifndef RFLOAT_VALUE
# define RFLOAT_VALUE(x) RFLOAT(x)->value
#endif
#ifndef DOUBLE2NUM
# define DOUBLE2NUM(x) rb_float_new(x)
#endif
#ifndef RHASH_TBL
# define RHASH_TBL(x) (RHASH(x)->tbl)
#endif
#ifndef RHASH_ITER_LEV
# define RHASH_ITER_LEV(x) (RHASH(x)->iter_lev)
#endif
#ifndef RHASH_IFNONE
# define RHASH_IFNONE(x) (RHASH(x)->ifnone)
#endif
#ifndef RHASH_SIZE
# define RHASH_SIZE(x) (RHASH(x)->tbl->num_entries)
#endif
#ifndef RHASH_EMPTY_P
# define RHASH_EMPTY_P(x) (RHASH_SIZE(x) == 0)
#endif
#ifndef RSTRUCT_LEN
# define RSTRUCT_LEN(x) RSTRUCT(x)->len
#endif
#ifndef RSTRUCT_PTR
# define RSTRUCT_PTR(x) RSTRUCT(x)->ptr
#endif
/*
* Need to be very careful about how these macros are defined, especially
* when compiling C++ code or C code with an ANSI C compiler.
*
* VALUEFUNC(f) is a macro used to typecast a C function that implements
* a Ruby method so that it can be passed as an argument to API functions
* like rb_define_method() and rb_define_singleton_method().
*
* VOIDFUNC(f) is a macro used to typecast a C function that implements
* either the "mark" or "free" stuff for a Ruby Data object, so that it
* can be passed as an argument to API functions like Data_Wrap_Struct()
* and Data_Make_Struct().
*/
#ifdef __cplusplus
# ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
# define PROTECTFUNC(f) ((VALUE (*)()) f)
# define VALUEFUNC(f) ((VALUE (*)()) f)
# define VOIDFUNC(f) ((void (*)()) f)
# else
# ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
# define PROTECTFUNC(f) ((VALUE (*)()) f)
# define VALUEFUNC(f) ((VALUE (*)()) f)
# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
# else /* These definitions should work for Ruby 1.7+ */
# define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
# endif
# endif
#else
# define VALUEFUNC(f) (f)
# define VOIDFUNC(f) (f)
#endif
/* Don't use for expressions have side effect */
#ifndef RB_STRING_VALUE
#define RB_STRING_VALUE(s) (TYPE(s) == T_STRING ? (s) : (*(volatile VALUE *)&(s) = rb_str_to_str(s)))
#endif
#ifndef StringValue
#define StringValue(s) RB_STRING_VALUE(s)
#endif
#ifndef StringValuePtr
#define StringValuePtr(s) RSTRING_PTR(RB_STRING_VALUE(s))
#endif
#ifndef StringValueLen
#define StringValueLen(s) RSTRING_LEN(RB_STRING_VALUE(s))
#endif
#ifndef SafeStringValue
#define SafeStringValue(v) do {\
StringValue(v);\
rb_check_safe_str(v);\
} while (0)
#endif
#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
#define rb_define_alloc_func(klass, func) rb_define_singleton_method((klass), "new", VALUEFUNC((func)), -1)
#define rb_undef_alloc_func(klass) rb_undef_method(CLASS_OF((klass)), "new")
#endif
static VALUE _mSWIG = Qnil;

View File

@@ -0,0 +1 @@
%insert(initbeforefunc) "swiginit.swg"

View File

@@ -0,0 +1,935 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* rubyiterators.swg
*
* Implement a C++ 'output' iterator for Ruby.
*
* Users can derive form the Iterator to implemet their
* own iterators. As an example (real one since we use it for STL/STD
* containers), the template Iterator_T does the
* implementation for generic C++ iterators.
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%fragment("ConstIterator","header") {
namespace swig {
struct stop_iteration {
};
/**
* Abstract base class used to represent all iterators of STL containers.
*/
struct ConstIterator {
public:
typedef ConstIterator self_type;
protected:
GC_VALUE _seq;
protected:
ConstIterator(VALUE seq) : _seq(seq)
{
}
// Random access iterator methods, but not required in Ruby
virtual ptrdiff_t distance(const ConstIterator &x) const
{
throw std::invalid_argument("distance not supported");
}
virtual bool equal (const ConstIterator &x) const
{
throw std::invalid_argument("equal not supported");
}
virtual self_type* advance(ptrdiff_t n)
{
throw std::invalid_argument("advance not supported");
}
public:
virtual ~ConstIterator() {}
// Access iterator method, required by Ruby
virtual VALUE value() const {
throw std::invalid_argument("value not supported");
return Qnil;
};
virtual VALUE setValue( const VALUE& v ) {
throw std::invalid_argument("value= not supported");
return Qnil;
}
virtual self_type* next( size_t n = 1 )
{
return this->advance( n );
}
virtual self_type* previous( size_t n = 1 )
{
ptrdiff_t nn = n;
return this->advance( -nn );
}
virtual VALUE to_s() const {
throw std::invalid_argument("to_s not supported");
return Qnil;
}
virtual VALUE inspect() const {
throw std::invalid_argument("inspect not supported");
return Qnil;
}
virtual ConstIterator *dup() const
{
throw std::invalid_argument("dup not supported");
return NULL;
}
//
// C++ common/needed methods. We emulate a bidirectional
// operator, to be compatible with all the STL.
// The iterator traits will then tell the STL what type of
// iterator we really are.
//
ConstIterator() : _seq( Qnil )
{
}
ConstIterator( const self_type& b ) : _seq( b._seq )
{
}
self_type& operator=( const self_type& b )
{
_seq = b._seq;
return *this;
}
bool operator == (const ConstIterator& x) const
{
return equal(x);
}
bool operator != (const ConstIterator& x) const
{
return ! operator==(x);
}
// Pre-decrement operator
self_type& operator--()
{
return *previous();
}
// Pre-increment operator
self_type& operator++()
{
return *next();
}
// Post-decrement operator
self_type operator--(int)
{
self_type r = *this;
previous();
return r;
}
// Post-increment operator
self_type operator++(int)
{
self_type r = *this;
next();
return r;
}
ConstIterator& operator += (ptrdiff_t n)
{
return *advance(n);
}
ConstIterator& operator -= (ptrdiff_t n)
{
return *advance(-n);
}
ConstIterator* operator + (ptrdiff_t n) const
{
return dup()->advance(n);
}
ConstIterator* operator - (ptrdiff_t n) const
{
return dup()->advance(-n);
}
ptrdiff_t operator - (const ConstIterator& 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::ConstIterator *");
init = 1;
}
return desc;
}
};
/**
* Abstract base class used to represent all non-const iterators of STL containers.
*
*/
struct Iterator : public ConstIterator {
public:
typedef Iterator self_type;
protected:
Iterator(VALUE seq) : ConstIterator(seq)
{
}
virtual self_type* advance(ptrdiff_t n)
{
throw std::invalid_argument("operation not supported");
}
public:
static swig_type_info* descriptor() {
static int init = 0;
static swig_type_info* desc = 0;
if (!init) {
desc = SWIG_TypeQuery("swig::Iterator *");
init = 1;
}
return desc;
}
virtual Iterator *dup() const
{
throw std::invalid_argument("dup not supported");
return NULL;
}
virtual self_type* next( size_t n = 1 )
{
return this->advance( n );
}
virtual self_type* previous( size_t n = 1 )
{
ptrdiff_t nn = n;
return this->advance( -nn );
}
bool operator == (const ConstIterator& x) const
{
return equal(x);
}
bool operator != (const Iterator& x) const
{
return ! operator==(x);
}
Iterator& operator += (ptrdiff_t n)
{
return *advance(n);
}
Iterator& operator -= (ptrdiff_t n)
{
return *advance(-n);
}
Iterator* operator + (ptrdiff_t n) const
{
return dup()->advance(n);
}
Iterator* operator - (ptrdiff_t n) const
{
return dup()->advance(-n);
}
ptrdiff_t operator - (const Iterator& x) const
{
return x.distance(*this);
}
};
}
}
%fragment("ConstIterator_T","header",fragment="ConstIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
namespace swig {
/**
* Templated base classes for all custom const_iterators.
*
*/
template<typename OutConstIterator>
class ConstIterator_T : public ConstIterator
{
public:
typedef OutConstIterator const_iter;
typedef typename std::iterator_traits<const_iter>::value_type value_type;
typedef ConstIterator_T<const_iter> self_type;
protected:
virtual bool equal (const ConstIterator &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");
}
}
virtual ptrdiff_t distance(const ConstIterator &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");
}
}
virtual ConstIterator* advance(ptrdiff_t n)
{
std::advance( current, n );
return this;
}
public:
ConstIterator_T() : ConstIterator(Qnil)
{
}
ConstIterator_T(const_iter curr, VALUE seq = Qnil)
: ConstIterator(seq), current(curr)
{
}
const const_iter& get_current() const
{
return current;
}
const value_type& operator*() const
{
return *current;
}
virtual VALUE inspect() const
{
VALUE ret = rb_str_new2("#<");
ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
ret = rb_str_cat2( ret, "::const_iterator " );
VALUE cur = value();
ret = rb_str_concat( ret, rb_inspect(cur) );
ret = rb_str_cat2( ret, ">" );
return ret;
}
virtual VALUE to_s() const
{
VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
ret = rb_str_cat2( ret, "::const_iterator " );
VALUE cur = value();
ret = rb_str_concat( ret, rb_obj_as_string(cur) );
return ret;
}
protected:
const_iter current;
};
/**
* Templated base classes for all custom non-const iterators.
*
*/
template<typename InOutIterator>
class Iterator_T : public Iterator
{
public:
typedef InOutIterator nonconst_iter;
// Make this class iterator STL compatible, by using iterator_traits
typedef typename std::iterator_traits<nonconst_iter >::iterator_category iterator_category;
typedef typename std::iterator_traits<nonconst_iter >::value_type value_type;
typedef typename std::iterator_traits<nonconst_iter >::difference_type difference_type;
typedef typename std::iterator_traits<nonconst_iter >::pointer pointer;
typedef typename std::iterator_traits<nonconst_iter >::reference reference;
typedef Iterator base;
typedef Iterator_T< nonconst_iter > self_type;
protected:
virtual bool equal (const ConstIterator &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");
}
}
virtual ptrdiff_t distance(const ConstIterator &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");
}
}
virtual Iterator* advance(ptrdiff_t n)
{
std::advance( current, n );
return this;
}
public:
Iterator_T(nonconst_iter curr, VALUE seq = Qnil)
: Iterator(seq), current(curr)
{
}
const nonconst_iter& get_current() const
{
return current;
}
self_type& operator=( const self_type& b )
{
base::operator=( b );
return *this;
}
self_type& operator=( const value_type& b )
{
*current = b;
return *this;
}
const value_type& operator*() const
{
return *current;
}
value_type& operator*()
{
return *current;
}
virtual VALUE inspect() const
{
VALUE ret = rb_str_new2("#<");
ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
ret = rb_str_cat2( ret, "::iterator " );
VALUE cur = value();
ret = rb_str_concat( ret, rb_inspect(cur) );
ret = rb_str_cat2( ret, ">" );
return ret;
}
virtual VALUE to_s() const
{
VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
ret = rb_str_cat2( ret, "::iterator " );
VALUE cur = value();
ret = rb_str_concat( ret, rb_obj_as_string(cur) );
return ret;
}
protected:
nonconst_iter current;
};
/**
* Auxiliary functor to store the value of a ruby object inside
* a reference of a compatible C++ type. ie: Ruby -> C++
*
*/
template <class ValueType>
struct asval_oper
{
typedef ValueType value_type;
typedef bool result_type;
bool operator()(VALUE obj, value_type& v) const
{
return ( swig::asval< value_type >(obj, &v) == SWIG_OK );
}
};
/**
* Auxiliary functor to return a ruby object from a C++ type.
* ie: C++ -> Ruby
*
*/
template <class ValueType>
struct from_oper
{
typedef const ValueType& argument_type;
typedef VALUE result_type;
result_type operator()(argument_type v) const
{
return swig::from(v);
}
};
/**
* ConstIterator class for a const_iterator with no end() boundaries.
*
*/
template<typename OutConstIterator,
typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
typename FromOper = from_oper<ValueType> >
class ConstIteratorOpen_T : public ConstIterator_T<OutConstIterator>
{
public:
FromOper from;
typedef OutConstIterator const_iter;
typedef ValueType value_type;
typedef ConstIterator_T<const_iter> base;
typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type;
ConstIteratorOpen_T(const_iter curr, VALUE seq = Qnil)
: ConstIterator_T<OutConstIterator>(curr, seq)
{
}
virtual VALUE value() const {
return from(static_cast<const value_type&>(*(base::current)));
}
ConstIterator *dup() const
{
return new self_type(*this);
}
};
/**
* Iterator class for an iterator with no end() boundaries.
*
*/
template<typename InOutIterator,
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
typename FromOper = from_oper<ValueType>,
typename AsvalOper = asval_oper<ValueType> >
class IteratorOpen_T : public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef ValueType value_type;
typedef Iterator_T<nonconst_iter> base;
typedef IteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
public:
IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq)
{
}
virtual VALUE value() const {
return from(static_cast<const value_type&>(*(base::current)));
}
virtual VALUE setValue( const VALUE& v )
{
value_type& dst = *base::current;
if ( asval(v, dst) ) return v;
return Qnil;
}
Iterator *dup() const
{
return new self_type(*this);
}
};
/**
* ConstIterator class for a const_iterator where begin() and end() boundaries are known.
*
*/
template<typename OutConstIterator,
typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
typename FromOper = from_oper<ValueType> >
class ConstIteratorClosed_T : public ConstIterator_T<OutConstIterator>
{
public:
FromOper from;
typedef OutConstIterator const_iter;
typedef ValueType value_type;
typedef ConstIterator_T<const_iter> base;
typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type;
protected:
virtual ConstIterator* advance(ptrdiff_t n)
{
std::advance( base::current, n );
if ( base::current == end )
throw stop_iteration();
return this;
}
public:
ConstIteratorClosed_T(const_iter curr, const_iter first,
const_iter last, VALUE seq = Qnil)
: ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last)
{
}
virtual VALUE value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
ConstIterator *dup() const
{
return new self_type(*this);
}
private:
const_iter begin;
const_iter end;
};
/**
* Iterator class for a iterator where begin() and end() boundaries are known.
*
*/
template<typename InOutIterator,
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
typename FromOper = from_oper<ValueType>,
typename AsvalOper = asval_oper<ValueType> >
class IteratorClosed_T : public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef ValueType value_type;
typedef Iterator_T<nonconst_iter> base;
typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
protected:
virtual Iterator* advance(ptrdiff_t n)
{
std::advance( base::current, n );
if ( base::current == end )
throw stop_iteration();
return this;
}
public:
IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
nonconst_iter last, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
{
}
virtual VALUE value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
// Iterator setter method, required by Ruby
virtual VALUE setValue( const VALUE& v )
{
if (base::current == end)
throw stop_iteration();
value_type& dst = *base::current;
if ( asval( v, dst ) ) return v;
return Qnil;
}
Iterator *dup() const
{
return new self_type(*this);
}
private:
nonconst_iter begin;
nonconst_iter end;
};
/* Partial specialization for bools which don't allow de-referencing */
template< typename InOutIterator, typename FromOper, typename AsvalOper >
class IteratorOpen_T< InOutIterator, bool, FromOper, AsvalOper > :
public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef bool value_type;
typedef Iterator_T<nonconst_iter> base;
typedef IteratorOpen_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq)
{
}
virtual VALUE value() const {
return from(static_cast<const value_type&>(*(base::current)));
}
virtual VALUE setValue( const VALUE& v )
{
bool tmp = *base::current;
if ( asval( v, tmp ) )
{
*base::current = tmp;
return v;
}
return Qnil;
}
Iterator *dup() const
{
return new self_type(*this);
}
};
/* Partial specialization for bools which don't allow de-referencing */
template< typename InOutIterator, typename FromOper, typename AsvalOper >
class IteratorClosed_T< InOutIterator, bool, FromOper, AsvalOper > :
public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef bool value_type;
typedef Iterator_T<nonconst_iter> base;
typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
protected:
virtual Iterator* advance(ptrdiff_t n)
{
std::advance( base::current, n );
if ( base::current == end )
throw stop_iteration();
return this;
}
public:
IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
nonconst_iter last, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
{
}
virtual VALUE value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
virtual VALUE setValue( const VALUE& v )
{
if (base::current == end)
throw stop_iteration();
bool tmp = *base::current;
if ( asval( v, tmp ) )
{
*base::current = tmp;
return v;
}
return Qnil;
}
Iterator *dup() const
{
return new self_type(*this);
}
private:
nonconst_iter begin;
nonconst_iter end;
};
/**
* Helper function used to wrap a bounded const_iterator. This is to be used in
* a %typemap(out), for example.
*
*/
template<typename InOutIter>
inline Iterator*
make_nonconst_iterator(const InOutIter& current, const InOutIter& begin,
const InOutIter& end, VALUE seq = Qnil)
{
return new IteratorClosed_T<InOutIter>(current, begin, end, seq);
}
/**
* Helper function used to wrap an unbounded const_iterator. This is to be used in
* a %typemap(out), for example.
*
*/
template<typename InOutIter>
inline Iterator*
make_nonconst_iterator(const InOutIter& current, VALUE seq = Qnil)
{
return new IteratorOpen_T<InOutIter>(current, seq);
}
/**
* Helper function used to wrap a bounded const_iterator. This is to be used in
* a %typemap(out), for example.
*
*/
template<typename OutIter>
inline ConstIterator*
make_const_iterator(const OutIter& current, const OutIter& begin,
const OutIter& end, VALUE seq = Qnil)
{
return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq);
}
/**
* Helper function used to wrap an unbounded const_iterator. This is to be used in
* a %typemap(out), for example.
*
*/
template<typename OutIter>
inline ConstIterator*
make_const_iterator(const OutIter& current, VALUE seq = Qnil)
{
return new ConstIteratorOpen_T<OutIter>(current, seq);
}
}
}
%fragment("ConstIterator");
//
// This part is just so SWIG is aware of the base abstract iterator class.
//
namespace swig
{
/*
Throw a StopIteration exception
*/
%ignore stop_iteration;
struct stop_iteration {};
%typemap(throws) stop_iteration {
(void)$1;
SWIG_Ruby_ExceptionType(NULL, Qnil);
SWIG_fail;
}
/*
Mark methods that return new objects
*/
%newobject ConstIterator::dup;
%newobject ConstIterator::operator + (ptrdiff_t n) const;
%newobject ConstIterator::operator - (ptrdiff_t n) const;
%nodirector ConstIterator;
%catches(swig::stop_iteration) ConstIterator::value() const;
%catches(swig::stop_iteration) ConstIterator::incr(size_t n = 1);
%catches(swig::stop_iteration) ConstIterator::decr(size_t n = 1);
%catches(std::invalid_argument) ConstIterator::distance(const ConstIterator &x) const;
%catches(std::invalid_argument) ConstIterator::equal (const ConstIterator &x) const;
%catches(swig::stop_iteration) ConstIterator::next();
%catches(swig::stop_iteration) ConstIterator::previous();
%catches(swig::stop_iteration) ConstIterator::advance(ptrdiff_t n);
%catches(swig::stop_iteration) ConstIterator::operator += (ptrdiff_t n);
%catches(swig::stop_iteration) ConstIterator::operator -= (ptrdiff_t n);
%catches(swig::stop_iteration) ConstIterator::operator + (ptrdiff_t n) const;
%catches(swig::stop_iteration) ConstIterator::operator - (ptrdiff_t n) const;
struct ConstIterator
{
protected:
ConstIterator(VALUE seq);
public:
virtual ~ConstIterator();
// Access iterator method, required by Ruby
virtual VALUE value() const;
// C++ common/needed methods
virtual ConstIterator *dup() const;
virtual VALUE inspect() const;
virtual VALUE to_s() const;
virtual ConstIterator* next(size_t n = 1);
virtual ConstIterator* previous(size_t n = 1);
bool operator == (const ConstIterator& x) const;
ConstIterator* operator + (ptrdiff_t n) const;
ConstIterator* operator - (ptrdiff_t n) const;
ptrdiff_t operator - (const ConstIterator& x) const;
};
struct Iterator : public ConstIterator
{
%rename("value=") setValue( const VALUE& v );
virtual VALUE setValue( const VALUE& v );
virtual Iterator *dup() const;
virtual Iterator* next(size_t n = 1);
virtual Iterator* previous(size_t n = 1);
virtual VALUE inspect() const;
virtual VALUE to_s() const;
bool operator == (const Iterator& x) const;
Iterator* operator + (ptrdiff_t n) const;
Iterator* operator - (ptrdiff_t n) const;
ptrdiff_t operator - (const Iterator& x) const;
};
}

View File

@@ -0,0 +1,72 @@
#ifndef RUBY_RUBYKW_SWG_
#define RUBY_RUBYKW_SWG_
/* Warnings for Ruby keywords */
#define RUBYKW(x) %keywordwarn("'" `x` "' is a ruby keyword, and it will renamed as 'C_"`x`"'",rename="C_%s",fullname=1) `x`
/*
from http://www.rubycentral.com/book/language.html
*/
RUBYKW(BEGIN);
RUBYKW(END);
RUBYKW(alias);
RUBYKW(and);
RUBYKW(begin);
RUBYKW(break);
RUBYKW(case);
RUBYKW(class);
RUBYKW(def);
RUBYKW("defined");
RUBYKW(do);
RUBYKW(else);
RUBYKW(elsif);
RUBYKW(end);
RUBYKW(ensure);
RUBYKW(false);
RUBYKW(fatal);
RUBYKW(for);
RUBYKW(if);
RUBYKW(in);
RUBYKW(module);
RUBYKW(next);
RUBYKW(nil);
RUBYKW(not);
RUBYKW(or);
RUBYKW(redo);
RUBYKW(rescue);
RUBYKW(retry);
RUBYKW(return);
RUBYKW(self);
RUBYKW(super);
RUBYKW(then);
RUBYKW(true);
RUBYKW(undef);
RUBYKW(unless);
RUBYKW(until);
RUBYKW(when);
RUBYKW(while);
RUBYKW(yield);
// RUBYKW(FalseClass);
// RUBYKW(TrueClass);
// RUBYKW(Numeric);
// RUBYKW(Integer);
// RUBYKW(Fixnum);
// RUBYKW(Float);
// RUBYKW(Range);
// RUBYKW(Array);
// RUBYKW(String);
// RUBYKW(IO);
// RUBYKW(File);
// RUBYKW(FileUtils);
// RUBYKW(Find);
// RUBYKW(Struct);
// RUBYKW(OpenStruct);
// RUBYKW(Regexp);
#undef RUBYKW
#endif //RUBY_RUBYKW_SWG_

View File

@@ -0,0 +1,13 @@
// Redefine these macros so argument index for ruby is done properly,
// ignoring self and we get some more info about the input.
#define %argfail_fmt(_type,_name,_argn) Ruby_Format_TypeError( "", _type, #_name, _argn, $input )
#define %argnullref_fmt(_type,_name,_argn) Ruby_Format_TypeError(%nullref_fmt(), _type, #_name, _argn, $input)
%{
#define SWIG_RUBY_THREAD_BEGIN_BLOCK
#define SWIG_RUBY_THREAD_END_BLOCK
%}
%include <typemaps/swigmacros.swg>

View File

@@ -0,0 +1,55 @@
/* ------------------------------------------------------------
* Overloaded operator support
* ------------------------------------------------------------ */
#ifdef __cplusplus
%rename(__add__) *::operator+;
%rename(__pos__) *::operator+();
%rename(__pos__) *::operator+() const;
%rename(__sub__) *::operator-;
%rename(__neg__) *::operator-();
%rename(__neg__) *::operator-() const;
%rename(__mul__) *::operator*;
%rename(__div__) *::operator/;
%rename(__mod__) *::operator%;
%rename(__lshift__) *::operator<<;
%rename(__rshift__) *::operator>>;
%rename(__and__) *::operator&;
%rename(__or__) *::operator|;
%rename(__xor__) *::operator^;
%rename(__invert__) *::operator~;
%rename(__lt__) *::operator<;
%rename(__le__) *::operator<=;
%rename(__gt__) *::operator>;
%rename(__ge__) *::operator>=;
%rename(__eq__) *::operator==;
/* Special cases */
%rename(__call__) *::operator();
/* Ignored inplace operators */
%ignoreoperator(NOTEQUAL) operator!=;
%ignoreoperator(PLUSEQ) operator+=;
%ignoreoperator(MINUSEQ) operator-=;
%ignoreoperator(MULEQ) operator*=;
%ignoreoperator(DIVEQ) operator/=;
%ignoreoperator(MODEQ) operator%=;
%ignoreoperator(LSHIFTEQ) operator<<=;
%ignoreoperator(RSHIFTEQ) operator>>=;
%ignoreoperator(ANDEQ) operator&=;
%ignoreoperator(OREQ) operator|=;
%ignoreoperator(XOREQ) operator^=;
/* Ignored operators */
%ignoreoperator(LNOT) operator!;
%ignoreoperator(LAND) operator&&;
%ignoreoperator(LOR) operator||;
%ignoreoperator(EQ) operator=;
%ignoreoperator(PLUSPLUS) operator++;
%ignoreoperator(MINUSMINUS) operator--;
%ignoreoperator(ARROWSTAR) operator->*;
%ignoreoperator(INDEX) operator[];
#endif /* __cplusplus */

View File

@@ -0,0 +1,220 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* rubyprimtypes.swg
*
* ----------------------------------------------------------------------------- */
/* ------------------------------------------------------------
* Primitive Types
* ------------------------------------------------------------ */
/* auxiliary ruby fail method */
%fragment("SWIG_ruby_failed","header")
{
SWIGINTERN VALUE
SWIG_ruby_failed(void)
{
return Qnil;
}
}
%define %ruby_aux_method(Type, Method, Action)
SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE *args)
{
VALUE obj = args[0];
VALUE type = TYPE(obj);
Type *res = (Type *)(args[1]);
*res = Action;
return obj;
}
%enddef
/* boolean */
%fragment(SWIG_From_frag(bool),"header") {
SWIGINTERNINLINE VALUE
SWIG_From_dec(bool)(bool value)
{
return value ? Qtrue : Qfalse;
}
}
%fragment(SWIG_AsVal_frag(bool),"header",
fragment=SWIG_AsVal_frag(int)) {
SWIGINTERN int
SWIG_AsVal_dec(bool)(VALUE obj, bool *val)
{
if (obj == Qtrue) {
if (val) *val = true;
return SWIG_OK;
} else if (obj == Qfalse) {
if (val) *val = false;
return SWIG_OK;
} else {
int res = 0;
if (SWIG_AsVal(int)(obj, &res) == SWIG_OK) {
if (val) *val = res ? true : false;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}
/* long */
%fragment(SWIG_From_frag(long),"header",
fragment="<limits.h>") {
%define_as(SWIG_From_dec(long), LONG2NUM)
}
%fragment(SWIG_AsVal_frag(long),"header",fragment="SWIG_ruby_failed") {
%ruby_aux_method(long, NUM2LONG, type == T_FIXNUM ? NUM2LONG(obj) : rb_big2long(obj))
SWIGINTERN int
SWIG_AsVal_dec(long)(VALUE obj, long* val)
{
VALUE type = TYPE(obj);
if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
long v;
VALUE a[2];
a[0] = obj;
a[1] = (VALUE)(&v);
if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
if (val) *val = v;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}
/* unsigned long */
%fragment(SWIG_From_frag(unsigned long),"header",
fragment=SWIG_From_frag(long)) {
SWIGINTERNINLINE VALUE
SWIG_From_dec(unsigned long)(unsigned long value)
{
return ULONG2NUM(value);
}
}
%fragment(SWIG_AsVal_frag(unsigned long),"header",fragment="SWIG_ruby_failed") {
%ruby_aux_method(unsigned long, NUM2ULONG, type == T_FIXNUM ? NUM2ULONG(obj) : rb_big2ulong(obj))
SWIGINTERN int
SWIG_AsVal_dec(unsigned long)(VALUE obj, unsigned long *val)
{
VALUE type = TYPE(obj);
if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
unsigned long v;
VALUE a[2];
a[0] = obj;
a[1] = (VALUE)(&v);
if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
if (val) *val = v;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}
/* long long */
%fragment(SWIG_From_frag(long long),"header",
fragment=SWIG_From_frag(long),
fragment="<limits.h>") {
SWIGINTERNINLINE VALUE
SWIG_From_dec(long long)(long long value)
{
return LL2NUM(value);
}
}
%fragment(SWIG_AsVal_frag(long long),"header",fragment="SWIG_ruby_failed") {
%ruby_aux_method(long long, NUM2LL, type == T_FIXNUM ? NUM2LL(obj) : rb_big2ll(obj))
SWIGINTERN int
SWIG_AsVal_dec(long long)(VALUE obj, long long *val)
{
VALUE type = TYPE(obj);
if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
long long v;
VALUE a[2];
a[0] = obj;
a[1] = (VALUE)(&v);
if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
if (val) *val = v;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}
/* unsigned long long */
%fragment(SWIG_From_frag(unsigned long long),"header",
fragment=SWIG_From_frag(long long),
fragment="<limits.h>") {
SWIGINTERNINLINE VALUE
SWIG_From_dec(unsigned long long)(unsigned long long value)
{
return ULL2NUM(value);
}
}
%fragment(SWIG_AsVal_frag(unsigned long long),"header",fragment="SWIG_ruby_failed") {
%ruby_aux_method(long long, NUM2ULL, type == T_FIXNUM ? NUM2ULL(obj) : rb_big2ull(obj))
SWIGINTERN int
SWIG_AsVal_dec(unsigned long long)(VALUE obj, unsigned long long *val)
{
VALUE type = TYPE(obj);
if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
unsigned long long v;
VALUE a[2];
a[0] = obj;
a[1] = (VALUE)(&v);
if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
if (val) *val = v;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}
/* double */
%fragment(SWIG_From_frag(double),"header") {
%define_as(SWIG_From_dec(double), rb_float_new)
}
%fragment(SWIG_AsVal_frag(double),"header",fragment="SWIG_ruby_failed") {
%ruby_aux_method(double, NUM2DBL, (type == T_FLOAT ? NUM2DBL(obj) : (type == T_FIXNUM ? (double) FIX2INT(obj) : rb_big2dbl(obj))))
SWIGINTERN int
SWIG_AsVal_dec(double)(VALUE obj, double *val)
{
VALUE type = TYPE(obj);
if ((type == T_FLOAT) || (type == T_FIXNUM) || (type == T_BIGNUM)) {
double v;
VALUE a[2];
a[0] = obj;
a[1] = (VALUE)(&v);
if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2DBL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
if (val) *val = v;
return SWIG_OK;
}
}
return SWIG_TypeError;
}
}

View File

@@ -0,0 +1,444 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* rubyrun.swg
*
* This file contains the runtime support for Ruby modules
* and includes code for managing global variables and pointer
* type checking.
* ----------------------------------------------------------------------------- */
/* For backward compatibility only */
#define SWIG_POINTER_EXCEPTION 0
/* for raw pointers */
#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, own)
#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Ruby_NewPointerObj(ptr, type, flags)
#define SWIG_AcquirePtr(ptr, own) SWIG_Ruby_AcquirePtr(ptr, own)
#define swig_owntype ruby_owntype
/* for raw packed data */
#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty, flags)
#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Ruby_NewPackedObj(ptr, sz, type)
/* for class or struct pointers */
#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
/* for C or C++ function pointers */
#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_ConvertPtr(obj, pptr, type, 0)
#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_NewPointerObj(ptr, type, 0)
/* for C++ member pointers, ie, member methods */
#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty)
#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Ruby_NewPackedObj(ptr, sz, type)
/* Runtime API */
#define SWIG_GetModule(clientdata) SWIG_Ruby_GetModule()
#define SWIG_SetModule(clientdata, pointer) SWIG_Ruby_SetModule(pointer)
/* Error manipulation */
#define SWIG_ErrorType(code) SWIG_Ruby_ErrorType(code)
#define SWIG_Error(code, msg) rb_raise(SWIG_Ruby_ErrorType(code), msg)
#define SWIG_fail goto fail
/* Ruby-specific SWIG API */
#define SWIG_InitRuntime() SWIG_Ruby_InitRuntime()
#define SWIG_define_class(ty) SWIG_Ruby_define_class(ty)
#define SWIG_NewClassInstance(value, ty) SWIG_Ruby_NewClassInstance(value, ty)
#define SWIG_MangleStr(value) SWIG_Ruby_MangleStr(value)
#define SWIG_CheckConvert(value, ty) SWIG_Ruby_CheckConvert(value, ty)
#include "assert.h"
/* -----------------------------------------------------------------------------
* pointers/data manipulation
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
VALUE klass;
VALUE mImpl;
void (*mark)(void *);
void (*destroy)(void *);
int trackObjects;
} swig_class;
/* Global pointer used to keep some internal SWIG stuff */
static VALUE _cSWIG_Pointer = Qnil;
static VALUE swig_runtime_data_type_pointer = Qnil;
/* Global IDs used to keep some internal SWIG stuff */
static ID swig_arity_id = 0;
static ID swig_call_id = 0;
/*
If your swig extension is to be run within an embedded ruby and has
director callbacks, you should set -DRUBY_EMBEDDED during compilation.
This will reset ruby's stack frame on each entry point from the main
program the first time a virtual director function is invoked (in a
non-recursive way).
If this is not done, you run the risk of Ruby trashing the stack.
*/
#ifdef RUBY_EMBEDDED
# define SWIG_INIT_STACK \
if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
++swig_virtual_calls;
# define SWIG_RELEASE_STACK --swig_virtual_calls;
# define Ruby_DirectorTypeMismatchException(x) \
rb_raise( rb_eTypeError, x ); return c_result;
static unsigned int swig_virtual_calls = 0;
#else /* normal non-embedded extension */
# define SWIG_INIT_STACK
# define SWIG_RELEASE_STACK
# define Ruby_DirectorTypeMismatchException(x) \
throw Swig::DirectorTypeMismatchException( x );
#endif /* RUBY_EMBEDDED */
SWIGRUNTIME VALUE
getExceptionClass(void) {
static int init = 0;
static VALUE rubyExceptionClass ;
if (!init) {
init = 1;
rubyExceptionClass = rb_const_get(_mSWIG, rb_intern("Exception"));
}
return rubyExceptionClass;
}
/* This code checks to see if the Ruby object being raised as part
of an exception inherits from the Ruby class Exception. If so,
the object is simply returned. If not, then a new Ruby exception
object is created and that will be returned to Ruby.*/
SWIGRUNTIME VALUE
SWIG_Ruby_ExceptionType(swig_type_info *desc, VALUE obj) {
VALUE exceptionClass = getExceptionClass();
if (rb_obj_is_kind_of(obj, exceptionClass)) {
return obj;
} else {
return rb_exc_new3(rb_eRuntimeError, rb_obj_as_string(obj));
}
}
/* Initialize Ruby runtime support */
SWIGRUNTIME void
SWIG_Ruby_InitRuntime(void)
{
if (_mSWIG == Qnil) {
_mSWIG = rb_define_module("SWIG");
swig_call_id = rb_intern("call");
swig_arity_id = rb_intern("arity");
}
}
/* Define Ruby class for C type */
SWIGRUNTIME void
SWIG_Ruby_define_class(swig_type_info *type)
{
VALUE klass;
char *klass_name = (char *) malloc(4 + strlen(type->name) + 1);
sprintf(klass_name, "TYPE%s", type->name);
if (NIL_P(_cSWIG_Pointer)) {
_cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject);
rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new");
}
klass = rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer);
free((void *) klass_name);
}
/* Create a new pointer object */
SWIGRUNTIME VALUE
SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
{
int own = flags & SWIG_POINTER_OWN;
int track;
char *klass_name;
swig_class *sklass;
VALUE klass;
VALUE obj;
if (!ptr)
return Qnil;
if (type->clientdata) {
sklass = (swig_class *) type->clientdata;
/* Are we tracking this class and have we already returned this Ruby object? */
track = sklass->trackObjects;
if (track) {
obj = SWIG_RubyInstanceFor(ptr);
/* Check the object's type and make sure it has the correct type.
It might not in cases where methods do things like
downcast methods. */
if (obj != Qnil) {
VALUE value = rb_iv_get(obj, "@__swigtype__");
char* type_name = RSTRING_PTR(value);
if (strcmp(type->name, type_name) == 0) {
return obj;
}
}
}
/* Create a new Ruby object */
obj = Data_Wrap_Struct(sklass->klass, VOIDFUNC(sklass->mark),
( own ? VOIDFUNC(sklass->destroy) :
(track ? VOIDFUNC(SWIG_RubyRemoveTracking) : 0 )
), ptr);
/* If tracking is on for this class then track this object. */
if (track) {
SWIG_RubyAddTracking(ptr, obj);
}
} else {
klass_name = (char *) malloc(4 + strlen(type->name) + 1);
sprintf(klass_name, "TYPE%s", type->name);
klass = rb_const_get(_mSWIG, rb_intern(klass_name));
free((void *) klass_name);
obj = Data_Wrap_Struct(klass, 0, 0, ptr);
}
rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
return obj;
}
/* Create a new class instance (always owned) */
SWIGRUNTIME VALUE
SWIG_Ruby_NewClassInstance(VALUE klass, swig_type_info *type)
{
VALUE obj;
swig_class *sklass = (swig_class *) type->clientdata;
obj = Data_Wrap_Struct(klass, VOIDFUNC(sklass->mark), VOIDFUNC(sklass->destroy), 0);
rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
return obj;
}
/* Get type mangle from class name */
SWIGRUNTIMEINLINE char *
SWIG_Ruby_MangleStr(VALUE obj)
{
VALUE stype = rb_iv_get(obj, "@__swigtype__");
return StringValuePtr(stype);
}
/* Acquire a pointer value */
typedef void (*ruby_owntype)(void*);
SWIGRUNTIME ruby_owntype
SWIG_Ruby_AcquirePtr(VALUE obj, ruby_owntype own) {
if (obj) {
ruby_owntype oldown = RDATA(obj)->dfree;
RDATA(obj)->dfree = own;
return oldown;
} else {
return 0;
}
}
/* Convert a pointer value */
SWIGRUNTIME int
SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags, ruby_owntype *own)
{
char *c;
swig_cast_info *tc;
void *vptr = 0;
/* Grab the pointer */
if (NIL_P(obj)) {
*ptr = 0;
return SWIG_OK;
} else {
if (TYPE(obj) != T_DATA) {
return SWIG_ERROR;
}
Data_Get_Struct(obj, void, vptr);
}
if (own) *own = RDATA(obj)->dfree;
/* Check to see if the input object is giving up ownership
of the underlying C struct or C++ object. If so then we
need to reset the destructor since the Ruby object no
longer owns the underlying C++ object.*/
if (flags & SWIG_POINTER_DISOWN) {
/* Is tracking on for this class? */
int track = 0;
if (ty && ty->clientdata) {
swig_class *sklass = (swig_class *) ty->clientdata;
track = sklass->trackObjects;
}
if (track) {
/* We are tracking objects for this class. Thus we change the destructor
* to SWIG_RubyRemoveTracking. This allows us to
* remove the mapping from the C++ to Ruby object
* when the Ruby object is garbage collected. If we don't
* do this, then it is possible we will return a reference
* to a Ruby object that no longer exists thereby crashing Ruby. */
RDATA(obj)->dfree = SWIG_RubyRemoveTracking;
} else {
RDATA(obj)->dfree = 0;
}
}
/* Do type-checking if type info was provided */
if (ty) {
if (ty->clientdata) {
if (rb_obj_is_kind_of(obj, ((swig_class *) (ty->clientdata))->klass)) {
if (vptr == 0) {
/* The object has already been deleted */
return SWIG_ObjectPreviouslyDeletedError;
}
*ptr = vptr;
return SWIG_OK;
}
}
if ((c = SWIG_MangleStr(obj)) == NULL) {
return SWIG_ERROR;
}
tc = SWIG_TypeCheck(c, ty);
if (!tc) {
return SWIG_ERROR;
} else {
int newmemory = 0;
*ptr = SWIG_TypeCast(tc, vptr, &newmemory);
assert(!newmemory); /* newmemory handling not yet implemented */
}
} else {
*ptr = vptr;
}
return SWIG_OK;
}
/* Check convert */
SWIGRUNTIMEINLINE int
SWIG_Ruby_CheckConvert(VALUE obj, swig_type_info *ty)
{
char *c = SWIG_MangleStr(obj);
if (!c) return 0;
return SWIG_TypeCheck(c,ty) != 0;
}
SWIGRUNTIME VALUE
SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type) {
char result[1024];
char *r = result;
if ((2*sz + 1 + strlen(type->name)) > 1000) return 0;
*(r++) = '_';
r = SWIG_PackData(r, ptr, sz);
strcpy(r, type->name);
return rb_str_new2(result);
}
/* Convert a packed value value */
SWIGRUNTIME int
SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty) {
swig_cast_info *tc;
const char *c;
if (TYPE(obj) != T_STRING) goto type_error;
c = StringValuePtr(obj);
/* Pointer values must start with leading underscore */
if (*c != '_') goto type_error;
c++;
c = SWIG_UnpackData(c, ptr, sz);
if (ty) {
tc = SWIG_TypeCheck(c, ty);
if (!tc) goto type_error;
}
return SWIG_OK;
type_error:
return SWIG_ERROR;
}
SWIGRUNTIME swig_module_info *
SWIG_Ruby_GetModule(void)
{
VALUE pointer;
swig_module_info *ret = 0;
VALUE verbose = rb_gv_get("VERBOSE");
/* temporarily disable warnings, since the pointer check causes warnings with 'ruby -w' */
rb_gv_set("VERBOSE", Qfalse);
/* first check if pointer already created */
pointer = rb_gv_get("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
if (pointer != Qnil) {
Data_Get_Struct(pointer, swig_module_info, ret);
}
/* reinstate warnings */
rb_gv_set("VERBOSE", verbose);
return ret;
}
SWIGRUNTIME void
SWIG_Ruby_SetModule(swig_module_info *pointer)
{
/* register a new class */
VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
/* create and store the structure pointer to a global variable */
swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
}
/* This function can be used to check whether a proc or method or similarly
callable function has been passed. Usually used in a %typecheck, like:
%typecheck(c_callback_t, precedence=SWIG_TYPECHECK_POINTER) {
$result = SWIG_Ruby_isCallable( $input );
}
*/
SWIGINTERN
int SWIG_Ruby_isCallable( VALUE proc )
{
if ( rb_respond_to( proc, swig_call_id ) == Qtrue )
return 1;
return 0;
}
/* This function can be used to check the arity (number of arguments)
a proc or method can take. Usually used in a %typecheck.
Valid arities will be that equal to minimal or those < 0
which indicate a variable number of parameters at the end.
*/
SWIGINTERN
int SWIG_Ruby_arity( VALUE proc, int minimal )
{
if ( rb_respond_to( proc, swig_arity_id ) == Qtrue )
{
VALUE num = rb_funcall( proc, swig_arity_id, 0 );
int arity = NUM2INT(num);
if ( arity < 0 && (arity+1) < -minimal ) return 1;
if ( arity == minimal ) return 1;
return 1;
}
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,9 @@
%runtime "swiglabels.swg" /* Common C API type-checking code */
%runtime "swigrun.swg" /* Common C API type-checking code */
%runtime "swigerrors.swg" /* SWIG errors */
%runtime "rubyhead.swg" /* Ruby includes and fixes */
%runtime "rubyerrors.swg" /* Ruby errors */
%runtime "rubytracking.swg" /* API for tracking C++ classes to Ruby objects */
%runtime "rubyapi.swg"
%runtime "rubyrun.swg"

View File

@@ -0,0 +1,37 @@
/**
* @file rubystdautodoc.swg
* @author gga
* @date Wed May 2 17:20:39 2007
*
* @brief This file contains autodocs for standard STL functions.
*
*
*/
//
// For STL autodocumentation
//
AUTODOC(c_str, "Convert class to a String representation");
AUTODOC(begin, "Return an iterator to the beginning of the $class");
AUTODOC(end, "Return an iterator to past the end of the $class");
AUTODOC(rbegin, "Return a reverse iterator to the beginning (the end) of the $class");
AUTODOC(rend, "Return a reverse iterator to past the end (past the beginning) of the $class");
AUTODOC(length, "Size or Length of the $class");
AUTODOC(replace, "Replace all or a portion of the $class");
AUTODOC(resize, "Resize the size of the $class");
AUTODOC(capacity, "Reserved capacity of the $class");
AUTODOC(reserve, "Reserve memory in the $class for a number of elements");
AUTODOC(erase, "Delete a portion of the $class");
AUTODOC(max_size, "Maximum size of elements allowed in the $class");
AUTODOC(iterator, "Return an iterator to the $class");
AUTODOC(empty, "Check if the $class is empty or not");
AUTODOC(rfind, "Find an element in reverse usually starting from the end of the $class");
AUTODOC(assign, "Assign a new $class or portion of it");
AUTODOC(front, "Return the first element in $class");
AUTODOC(back, "Return the last element in $class");
AUTODOC(second, "Return the second element in $class");
AUTODOC(push_front, "Add an element at the beginning of the $class");
AUTODOC(push_back, "Add an element at the end of the $class");
AUTODOC(pop_front, "Remove and return element at the beginning of the $class");
AUTODOC(pop_back, "Remove and return an element at the end of the $class");
AUTODOC(clear, "Clear $class contents");

View File

@@ -0,0 +1,265 @@
/* ------------------------------------------------------------
* The Ruby classes, for C++
* ------------------------------------------------------------ */
%include <rubyclasses.swg>
%fragment("StdTraits","header",fragment="StdTraitsCommon")
{
namespace swig {
/*
Traits that provides the from method
*/
template <class Type> struct traits_from_ptr {
static VALUE from(Type *val, int owner = 0) {
return SWIG_NewPointerObj(val, type_info<Type>(), owner);
}
};
template <class Type> struct traits_from {
static VALUE from(const Type& val) {
return traits_from_ptr<Type>::from(new Type(val), 1);
}
};
template <class Type> struct traits_from<Type *> {
static VALUE from(Type* val) {
return traits_from_ptr<Type>::from(val, 0);
}
};
template <class Type> struct traits_from<const Type *> {
static VALUE from(const Type* val) {
return traits_from_ptr<Type>::from(const_cast<Type*>(val), 0);
}
};
template <class Type>
inline VALUE from(const Type& val) {
return traits_from<Type>::from(val);
}
template <class Type>
inline VALUE 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(VALUE obj, Type **val) {
Type *p;
int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
return res;
}
};
template <class Type>
inline int asptr(VALUE obj, Type **vptr) {
return traits_asptr<Type>::asptr(obj, vptr);
}
template <class Type>
struct traits_asval {
static int asval(VALUE 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(VALUE 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(VALUE obj, Type *val) {
return traits_asval<Type>::asval(obj, val);
}
template <class Type>
struct traits_as<Type, value_category> {
static Type as(VALUE obj, bool throw_error) {
Type v;
int res = asval(obj, &v);
if (!obj || !SWIG_IsOK(res)) {
if (throw_error) throw std::invalid_argument("bad type");
VALUE lastErr = rb_gv_get("$!");
if (lastErr == Qnil) {
%type_error(swig::type_name<Type>());
}
}
return v;
}
};
template <class Type>
struct traits_as<Type, pointer_category> {
static Type as(VALUE obj, bool throw_error) {
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 {
// Uninitialized return value, no Type() constructor required.
if (throw_error) throw std::invalid_argument("bad type");
VALUE lastErr = rb_gv_get("$!");
if (lastErr == Qnil) {
%type_error(swig::type_name<Type>());
}
static Type *v_def = (Type*) malloc(sizeof(Type));
memset(v_def,0,sizeof(Type));
return *v_def;
}
}
};
template <class Type>
struct traits_as<Type*, pointer_category> {
static Type* as(VALUE obj, bool throw_error) {
Type *v = 0;
int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
if (SWIG_IsOK(res)) {
return v;
} else {
if (throw_error) throw std::invalid_argument("bad type");
VALUE lastErr = rb_gv_get("$!");
if (lastErr == Qnil) {
%type_error(swig::type_name<Type>());
}
return 0;
}
}
};
template <class Type>
inline Type as(VALUE obj, bool te = false) {
return traits_as< Type, typename traits< Type >::category >::as(obj, te);
}
template <class Type>
struct traits_check<Type, value_category> {
static bool check(VALUE 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(VALUE obj) {
int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR;
return SWIG_IsOK(res) ? true : false;
}
};
template <class Type>
inline bool check(VALUE obj) {
return traits_check<Type, typename traits<Type>::category>::check(obj);
}
}
}
// Define GC marking template traits for a container type
%define %create_mark_traits(Type)
%{
namespace swig {
template <class T>
struct mark_traits {
typedef typename Type<T >::const_iterator const_iterator;
inline void operator()(const Type<T >& c ) const
{
const_iterator i = c.begin();
const_iterator e = c.end();
for ( ; i != e; ++i )
{
rb_gc_mark( swig::from( &(*i) ) );
}
}
};
// Partial specializations for classes that requires no GC marking
// or a special GC marking algorithm.
template< >
struct mark_traits<bool> {
inline void operator()(const Type<bool >& c ) const {}
};
template< >
struct mark_traits<char> {
inline void operator()(const Type<char >& c ) const {}
};
template< >
struct mark_traits<int> {
inline void operator()(const Type<int >& c ) const {}
};
template< >
struct mark_traits<unsigned> {
inline void operator()(const Type<unsigned >& c ) const {}
};
template< >
struct mark_traits<GC_VALUE> {
typedef Type<GC_VALUE >::const_iterator const_iterator;
inline void operator()(const Type<GC_VALUE >& c ) const {
const_iterator i = c.begin();
const_iterator e = c.end();
for ( ; i != e; ++i )
{
VALUE v = *i;
if ( FIXNUM_P(v) || SPECIAL_CONST_P(v) || SYMBOL_P(v) ||
( BUILTIN_TYPE(v) == T_NONE ) ) continue;
rb_gc_mark( v );
}
}
};
}
%}
%enddef

View File

@@ -0,0 +1,162 @@
/**
* @file rubystdfunctors.swg
* @date Sun May 6 00:44:33 2007
*
* @brief This file provides unary and binary functors for STL
* containers, that will invoke a Ruby proc or method to do
* their operation.
*
* You can use them in a swig file like:
*
* %include <std_set.i>
* %include <std_functors.i>
*
* %template< IntSet > std::set< int, swig::BinaryPredicate<> >;
*
*
* which will then allow calling them from Ruby either like:
*
* # order of set is defined by C++ default
* a = IntSet.new
*
* # sort order defined by Ruby proc
* b = IntSet.new( proc { |a,b| a > b } )
*
*/
%include rubyclasses.swg
namespace swig {
%apply GC_VALUE { UnaryPredicate, BinaryPredicate, UnaryFunction,
BinaryFunction };
%typecheck(SWIG_TYPECHECK_POINTER,noblock=1)
UnaryPredicate, UnaryPredicate&, UnaryFunction, UnaryFunction&
{
$1 = SWIG_Ruby_isCallable($input) && SWIG_Ruby_arity($input, 1);
}
%typecheck(SWIG_TYPECHECK_POINTER,noblock=1)
BinaryPredicate, BinaryPredicate&, BinaryFunction, BinaryFunction& {
$1 = SWIG_Ruby_isCallable($input) && SWIG_Ruby_arity($input, 2);
}
%typemap(in,noblock=1) BinaryFunction&, BinaryFunction {
$1 = new swig::BinaryFunction< >($input);
}
%typemap(in,noblock=1) UnaryFunction&, UnaryFunction {
$1 = new swig::UnaryFunction< >($input);
}
%typemap(in,noblock=1) BinaryPredicate&, BinaryPredicate {
$1 = new swig::BinaryPredicate<>($input);
}
%typemap(in,noblock=1) UnaryPredicate&, UnaryPredicate {
$1 = new swig::UnaryPredicate< >($input);
}
%ignore BinaryFunction;
template< class _T = GC_VALUE >
struct BinaryFunction {
};
%ignore UnaryFunction;
template< class _T = GC_VALUE >
struct UnaryFunction {
};
%ignore BinaryPredicate;
template< class _T = GC_VALUE >
struct BinaryPredicate {
};
%ignore UnaryPredicate;
template< class _T = GC_VALUE >
struct UnaryPredicate {
};
}
%fragment("StdFunctors","header",fragment="StdTraits")
{
namespace swig {
static ID call_id = rb_intern("call");
template <class _T = GC_VALUE, class _DefaultFunc = std::less<GC_VALUE> >
struct BinaryPredicate : GC_VALUE, std::binary_function< _T, _T, bool >
{
BinaryPredicate(VALUE obj = Qnil) : GC_VALUE(obj) { }
bool operator()(_T a, _T b) const
{
if (_obj != Qnil) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
VALUE arg1 = swig::from(a);
VALUE arg2 = swig::from(b);
VALUE res = rb_funcall( _obj, swig::call_id, 2, arg1, arg2);
SWIG_RUBY_THREAD_END_BLOCK;
return RTEST(res);
} else {
return _DefaultFunc()(a, b);
}
}
};
template <class _T = GC_VALUE, class _DefaultFunc = std::less< _T > >
struct BinaryFunction : GC_VALUE, std::binary_function< _T, _T, _T >
{
BinaryFunction(VALUE obj = Qnil) : GC_VALUE(obj) { }
_T operator()(_T a, _T b) const
{
if (_obj != Qnil) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
VALUE arg1 = swig::from(a);
VALUE arg2 = swig::from(b);
VALUE res = rb_funcall( _obj, swig::call_id, 2, arg1, arg2);
SWIG_RUBY_THREAD_END_BLOCK;
return swig::as<_T >(res);
} else {
return _DefaultFunc()(a, b);
}
}
};
template< class _T = GC_VALUE >
struct UnaryPredicate : GC_VALUE, std::unary_function< _T, bool >
{
UnaryPredicate(VALUE obj = Qnil) : GC_VALUE(obj) { }
bool operator()(_T a) const
{
SWIG_RUBY_THREAD_BEGIN_BLOCK;
VALUE arg1 = swig::from<_T >(a);
VALUE res = rb_funcall( _obj, swig::call_id, 1, arg1);
SWIG_RUBY_THREAD_END_BLOCK;
return RTEST(res);
}
};
template< class _T = GC_VALUE >
struct UnaryFunction : GC_VALUE, std::unary_function< _T, _T >
{
UnaryFunction(VALUE obj = Qnil) : GC_VALUE(obj) { }
_T operator()(_T a) const
{
SWIG_RUBY_THREAD_BEGIN_BLOCK;
VALUE arg1 = swig::from(a);
VALUE res = rb_funcall( _obj, swig::call_id, 1, VALUE(arg1));
SWIG_RUBY_THREAD_END_BLOCK;
return swig::as< _T >(res);
}
};
} // namespace swig
}

View File

@@ -0,0 +1,61 @@
/* ------------------------------------------------------------
* utility methods for char strings
* ------------------------------------------------------------ */
%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
SWIGINTERN int
SWIG_AsCharPtrAndSize(VALUE obj, char** cptr, size_t* psize, int *alloc)
{
if (TYPE(obj) == T_STRING) {
%#if defined(StringValuePtr)
char *cstr = StringValuePtr(obj);
%#else
char *cstr = STR2CSTR(obj);
%#endif
size_t size = RSTRING_LEN(obj) + 1;
if (cptr) {
if (alloc) {
if (*alloc == SWIG_NEWOBJ) {
*cptr = %new_copy_array(cstr, size, char);
} else {
*cptr = cstr;
*alloc = SWIG_OLDOBJ;
}
}
}
if (psize) *psize = size;
return SWIG_OK;
} else {
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
if (pchar_descriptor) {
void* vptr = 0;
if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
if (cptr) *cptr = (char *)vptr;
if (psize) *psize = vptr ? (strlen((char*)vptr) + 1) : 0;
if (alloc) *alloc = SWIG_OLDOBJ;
return SWIG_OK;
}
}
}
return SWIG_TypeError;
}
}
%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
SWIGINTERNINLINE VALUE
SWIG_FromCharPtrAndSize(const char* carray, size_t size)
{
if (carray) {
if (size > LONG_MAX) {
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
return pchar_descriptor ?
SWIG_NewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : Qnil;
} else {
return rb_str_new(carray, %numeric_cast(size,long));
}
} else {
return Qnil;
}
}
}

View File

@@ -0,0 +1,160 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* rubytracking.swg
*
* This file contains support for tracking mappings from
* Ruby objects to C++ objects. This functionality is needed
* to implement mark functions for Ruby's mark and sweep
* garbage collector.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
/* Ruby 1.8 actually assumes the first case. */
#if SIZEOF_VOIDP == SIZEOF_LONG
# define SWIG2NUM(v) LONG2NUM((unsigned long)v)
# define NUM2SWIG(x) (unsigned long)NUM2LONG(x)
#elif SIZEOF_VOIDP == SIZEOF_LONG_LONG
# define SWIG2NUM(v) LL2NUM((unsigned long long)v)
# define NUM2SWIG(x) (unsigned long long)NUM2LL(x)
#else
# error sizeof(void*) is not the same as long or long long
#endif
/* Global Ruby hash table to store Trackings from C/C++
structs to Ruby Objects.
*/
static VALUE swig_ruby_trackings = Qnil;
/* Global variable that stores a reference to the ruby
hash table delete function. */
static ID swig_ruby_hash_delete;
/* Setup a Ruby hash table to store Trackings */
SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
/* Create a ruby hash table to store Trackings from C++
objects to Ruby objects. */
/* Try to see if some other .so has already created a
tracking hash table, which we keep hidden in an instance var
in the SWIG module.
This is done to allow multiple DSOs to share the same
tracking table.
*/
ID trackings_id = rb_intern( "@__trackings__" );
VALUE verbose = rb_gv_get("VERBOSE");
rb_gv_set("VERBOSE", Qfalse);
swig_ruby_trackings = rb_ivar_get( _mSWIG, trackings_id );
rb_gv_set("VERBOSE", verbose);
/* No, it hasn't. Create one ourselves */
if ( swig_ruby_trackings == Qnil )
{
swig_ruby_trackings = rb_hash_new();
rb_ivar_set( _mSWIG, trackings_id, swig_ruby_trackings );
}
/* Now store a reference to the hash table delete function
so that we only have to look it up once.*/
swig_ruby_hash_delete = rb_intern("delete");
}
/* Get a Ruby number to reference a pointer */
SWIGRUNTIME VALUE SWIG_RubyPtrToReference(void* ptr) {
/* We cast the pointer to an unsigned long
and then store a reference to it using
a Ruby number object. */
/* Convert the pointer to a Ruby number */
return SWIG2NUM(ptr);
}
/* Get a Ruby number to reference an object */
SWIGRUNTIME VALUE SWIG_RubyObjectToReference(VALUE object) {
/* We cast the object to an unsigned long
and then store a reference to it using
a Ruby number object. */
/* Convert the Object to a Ruby number */
return SWIG2NUM(object);
}
/* Get a Ruby object from a previously stored reference */
SWIGRUNTIME VALUE SWIG_RubyReferenceToObject(VALUE reference) {
/* The provided Ruby number object is a reference
to the Ruby object we want.*/
/* Convert the Ruby number to a Ruby object */
return NUM2SWIG(reference);
}
/* Add a Tracking from a C/C++ struct to a Ruby object */
SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
/* In a Ruby hash table we store the pointer and
the associated Ruby object. The trick here is
that we cannot store the Ruby object directly - if
we do then it cannot be garbage collected. So
instead we typecast it as a unsigned long and
convert it to a Ruby number object.*/
/* Get a reference to the pointer as a Ruby number */
VALUE key = SWIG_RubyPtrToReference(ptr);
/* Get a reference to the Ruby object as a Ruby number */
VALUE value = SWIG_RubyObjectToReference(object);
/* Store the mapping to the global hash table. */
rb_hash_aset(swig_ruby_trackings, key, value);
}
/* Get the Ruby object that owns the specified C/C++ struct */
SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
/* Get a reference to the pointer as a Ruby number */
VALUE key = SWIG_RubyPtrToReference(ptr);
/* Now lookup the value stored in the global hash table */
VALUE value = rb_hash_aref(swig_ruby_trackings, key);
if (value == Qnil) {
/* No object exists - return nil. */
return Qnil;
}
else {
/* Convert this value to Ruby object */
return SWIG_RubyReferenceToObject(value);
}
}
/* Remove a Tracking from a C/C++ struct to a Ruby object. It
is very important to remove objects once they are destroyed
since the same memory address may be reused later to create
a new object. */
SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
/* Get a reference to the pointer as a Ruby number */
VALUE key = SWIG_RubyPtrToReference(ptr);
/* Delete the object from the hash table by calling Ruby's
do this we need to call the Hash.delete method.*/
rb_funcall(swig_ruby_trackings, swig_ruby_hash_delete, 1, key);
}
/* This is a helper method that unlinks a Ruby object from its
underlying C++ object. This is needed if the lifetime of the
Ruby object is longer than the C++ object */
SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
VALUE object = SWIG_RubyInstanceFor(ptr);
if (object != Qnil) {
DATA_PTR(object) = 0;
}
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,62 @@
/* ------------------------------------------------------------
* Typemap specializations for Ruby
* ------------------------------------------------------------ */
/* ------------------------------------------------------------
* Fragment section
* ------------------------------------------------------------ */
/* bool is dangerous in Ruby, change precedence */
#undef SWIG_TYPECHECK_BOOL
%define SWIG_TYPECHECK_BOOL 10000 %enddef
/* Include fundamental fragemt definitions */
%include <typemaps/fragments.swg>
/* Look for user fragments file. */
%include <rubyfragments.swg>
/* Ruby fragments for primitive types */
%include <rubyprimtypes.swg>
/* Ruby fragments for char* strings */
%include <rubystrings.swg>
/* Backward compatibility output helper */
%fragment("output_helper","header") %{
#define output_helper SWIG_Ruby_AppendOutput
%}
/* ------------------------------------------------------------
* Unified typemap section
* ------------------------------------------------------------ */
/* Directors are supported in Ruby */
#ifndef SWIG_DIRECTOR_TYPEMAPS
#define SWIG_DIRECTOR_TYPEMAPS
#endif
/* Ruby types */
#define SWIG_Object VALUE
#define VOID_Object Qnil
/* Overload of the output/constant/exception handling */
/* append output */
#define SWIG_AppendOutput(result,obj) SWIG_Ruby_AppendOutput(result, obj)
/* set constant */
#define SWIG_SetConstant(name, obj) rb_define_const($module, name, obj)
/* raise */
#define SWIG_Raise(obj, type, desc) rb_exc_raise(SWIG_Ruby_ExceptionType(desc, obj))
/* Get the address of the 'Ruby self' object */
%typemap(in,numinputs=0,noblock=1) VALUE* RUBY_SELF {
$1 = &self;
}
/* Include the unified typemap library */
%include <typemaps/swigtypemaps.swg>

View File

@@ -0,0 +1,10 @@
#define %alias %feature("alias")
#define %freefunc %feature("freefunc")
#define %markfunc %feature("markfunc")
#define %mixin %feature("mixin")
#define %predicate %feature("predicate", "1")
#define %bang %feature("bang", "1")
#define %trackobjects %feature("trackobjects")
#define %nooutput %feature("outputs","0")
#define %initstack %feature("initstack", "1")
#define %ignorestack %feature("initstack", "0")

View File

@@ -0,0 +1,76 @@
/**
* @file rubywstrings.swg
* @author
* @date Fri May 4 17:49:40 2007
*
* @brief Currently, Ruby does not support Unicode or WChar properly, so these
* are still treated as char arrays for now.
* There are other libraries available that add support to this in
* ruby including WString, FXString, etc.
*
*
*/
/* ------------------------------------------------------------
* utility methods for wchar_t strings
* ------------------------------------------------------------ */
%fragment("SWIG_AsWCharPtrAndSize","header",fragment="<wchar.h>",fragment="SWIG_pwchar_descriptor") {
SWIGINTERN int
SWIG_AsWCharPtrAndSize(VALUE obj, wchar_t **cptr, size_t *psize, int *alloc)
{
return SWIG_AsCharPtrAndSize( obj, (char**)cptr, psize, alloc);
// VALUE tmp = 0;
// bool ok = false;
// if ( TYPE(obj) == T_STRING ) {
// if (cptr) {
// obj = tmp = SWIG_Unicode_FromObject(obj);
// ok = true;
// }
// }
// if (ok) {
// int len = PyUnicode_GetSize(obj);
// rb_notimplement();
// if (cptr) {
// *cptr = %new_array(len + 1, wchar_t);
// SWIG_Unicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len);
// (*cptr)[len] = 0;
// }
// if (psize) *psize = (size_t) len + 1;
// if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0;
// 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 VALUE
SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size)
{
return SWIG_FromCharPtrAndSize( (const char*)carray, size);
// if (carray) {
// if (size > INT_MAX) {
// swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor();
// return pwchar_descriptor ?
// SWIG_NewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : Qnil;
// } else {
// return SWIG_Unicode_FromWideChar(carray, %numeric_cast(size,int));
// }
// } else {
// return Qnil;
// }
}
}

View File

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

View File

@@ -0,0 +1,97 @@
#if !defined(SWIG_STD_STRING)
#define SWIG_STD_BASIC_STRING
%include <rubycontainer.swg>
#define %swig_basic_string(Type...) %swig_sequence_methods_val(Type)
%traits_swigtype(std::basic_string<char>);
%fragment(SWIG_Traits_frag(std::basic_string<char>));
%fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
fragment="SWIG_AsCharPtrAndSize") {
SWIGINTERN int
SWIG_AsPtr(std::basic_string<char>)(VALUE obj, std::string **val)
{
static swig_type_info* string_info =
SWIG_TypeQuery("std::basic_string<char> *");
std::string *vptr;
if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
if (val) *val = vptr;
return SWIG_OLDOBJ;
} else {
char* buf = 0 ; size_t size = 0; int alloc = 0;
if (SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
if (buf) {
if (val) *val = new std::string(buf, size - 1);
if (alloc == SWIG_NEWOBJ) %delete_array(buf);
return SWIG_NEWOBJ;
}
}
if (val) {
rb_raise( rb_eTypeError, "a string is expected");
}
return 0;
}
}
}
%fragment(SWIG_From_frag(std::basic_string<char>),"header",
fragment="SWIG_FromCharPtrAndSize") {
SWIGINTERNINLINE VALUE
SWIG_From(std::basic_string<char>)(const std::string& s)
{
return SWIG_FromCharPtrAndSize(s.data(), s.size());
}
}
%include <std/std_basic_string.i>
%typemaps_asptrfromn(%checkcode(STRING), std::basic_string<char>);
#endif
#if !defined(SWIG_STD_WSTRING)
%fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
fragment="SWIG_AsWCharPtrAndSize") {
SWIGINTERN int
SWIG_AsPtr(std::basic_string<wchar_t>)(VALUE obj, std::wstring **val)
{
static swig_type_info* string_info =
SWIG_TypeQuery("std::basic_string<wchar_t> *");
std::wstring *vptr;
if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
if (val) *val = vptr;
return SWIG_OLDOBJ;
} else {
wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
if (SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
if (buf) {
if (val) *val = new std::wstring(buf, size - 1);
if (alloc == SWIG_NEWOBJ) %delete_array(buf);
return SWIG_NEWOBJ;
}
}
if (val) {
rb_raise( rb_eTypeError, "a string is expected");
}
return 0;
}
}
}
%fragment(SWIG_From_frag(std::basic_string<wchar_t>),"header",
fragment="SWIG_FromWCharPtrAndSize") {
SWIGINTERNINLINE VALUE
SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s)
{
return SWIG_FromWCharPtrAndSize(s.data(), s.size());
}
}
%typemaps_asptrfromn(%checkcode(UNISTRING), std::basic_string<wchar_t>);
#endif

View File

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

View File

@@ -0,0 +1,44 @@
%include <std/std_except.i>
%include <rubystdcommon.swg>
%include <rubystdautodoc.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(VALUE obj, value_type *val) {
return SWIG_AsVal(Type)(obj, val);
}
};
template <> struct traits_from<Type > {
typedef Type value_type;
static VALUE from(const value_type& val) {
return SWIG_From(Type)(val);
}
};
}
}
%enddef
%include <std/std_common.i>
//
// Generates the traits for all the known primitive
// C++ types (int, double, ...)
//
%apply_cpptypes(%traits_ptypen);

View File

@@ -0,0 +1,22 @@
/*
* STD C++ complex typemaps
*/
%include <rubycomplex.swg>
%{
#include <complex>
%}
/* defining the complex as/from converters */
%swig_cplxdbl_convn(std::complex<double>, std::complex<double>, std::real, std::imag)
%swig_cplxflt_convn(std::complex<float>, std::complex<float>, std::real, std::imag)
/* defining the typemaps */
%typemaps_primitive(%checkcode(CPLXDBL), std::complex<double>);
%typemaps_primitive(%checkcode(CPLXFLT), std::complex<float>);

View File

@@ -0,0 +1,2 @@
%include <rubycontainer.swg>
%include <std/std_container.i>

View File

@@ -0,0 +1,30 @@
/*
Deques
*/
%fragment("StdDequeTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T>
struct traits_asptr<std::deque<T> > {
static int asptr(VALUE obj, std::deque<T> **vec) {
return traits_asptr_stdseq<std::deque<T> >::asptr(obj, vec);
}
};
template <class T>
struct traits_from<std::deque<T> > {
static VALUE from(const std::deque<T> & vec) {
return traits_from_stdseq<std::deque<T> >::from(vec);
}
};
}
%}
%ignore std::deque::push_back;
%ignore std::deque::pop_back;
#define %swig_deque_methods(Type...) %swig_sequence_methods(Type)
#define %swig_deque_methods_val(Type...) %swig_sequence_methods_val(Type);
%include <std/std_deque.i>

View File

@@ -0,0 +1 @@
%include <typemaps/std_except.swg>

View File

@@ -0,0 +1,29 @@
/**
* @file std_functors.i
* @date Sun May 6 00:44:33 2007
*
* @brief This file provides unary and binary functors for STL
* containers, that will invoke a Ruby proc or method to do
* their operation.
*
* You can use them in a swig file like:
*
* %include <std_set.i>
* %include <std_functors.i>
*
* %template< IntSet > std::set< int, swig::BinaryPredicate<int> >;
*
*
* which will then allow calling them from Ruby either like:
*
* # order of set is defined by C++ default
* a = IntSet.new
*
* # sort order defined by Ruby proc
* b = IntSet.new( proc { |a,b| a > b } )
*
*/
%include <rubystdfunctors.swg>
%fragment("StdFunctors");

View File

@@ -0,0 +1,14 @@
#pragma SWIG nowarn=801
%rename(ios_base_in) std::ios_base::in;
AUTODOC(cerr, "Standard C++ error stream");
AUTODOC(cout, "Standard C++ output stream");
AUTODOC(cin, "Standard C++ input stream");
AUTODOC(clog, "Standard C++ logging stream");
AUTODOC(endl, "Add an end line to stream");
AUTODOC(ends, "Ends stream");
AUTODOC(flush, "Flush stream");
%include <std/std_ios.i>

View File

@@ -0,0 +1,12 @@
namespace std
{
%callback("%s") endl;
%callback("%s") ends;
%callback("%s") flush;
}
%warnfilter(365) operator+=;
%warnfilter(802) std::basic_iostream; // turn off multiple inheritance warning
%include <std/std_iostream.i>

View File

@@ -0,0 +1,41 @@
/*
Lists
*/
%fragment("StdListTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T >
struct traits_asptr<std::list<T> > {
static int asptr(VALUE obj, std::list<T> **lis) {
return traits_asptr_stdseq<std::list<T> >::asptr(obj, lis);
}
};
template <class T>
struct traits_from<std::list<T> > {
static VALUE from(const std::list<T> & vec) {
return traits_from_stdseq<std::list<T> >::from(vec);
}
};
}
%}
%ignore std::list::push_back;
%ignore std::list::pop_back;
#define %swig_list_methods(Type...) %swig_sequence_methods(Type)
#define %swig_list_methods_val(Type...) %swig_sequence_methods_val(Type);
%rename("delete") std::list::__delete__;
%rename("reject!") std::list::reject_bang;
%rename("map!") std::list::map_bang;
%rename("empty?") std::list::empty;
%rename("include?" ) std::list::__contains__ const;
%rename("has_key?" ) std::list::has_key const;
%alias std::list::push "<<";
%include <std/std_list.i>

View File

@@ -0,0 +1,417 @@
//
// Maps
//
%fragment("StdMapTraits","header",fragment="StdSequenceTraits")
{
namespace swig {
template <class RubySeq, class K, class T >
inline void
assign(const RubySeq& rubyseq, std::map<K,T > *map) {
typedef typename std::map<K,T>::value_type value_type;
typename RubySeq::const_iterator it = rubyseq.begin();
for (;it != rubyseq.end(); ++it) {
map->insert(value_type(it->first, it->second));
}
}
template <class K, class T>
struct traits_asptr<std::map<K,T> > {
typedef std::map<K,T> map_type;
static int asptr(VALUE obj, map_type **val) {
int res = SWIG_ERROR;
if ( TYPE(obj) == T_HASH ) {
static ID id_to_a = rb_intern("to_a");
VALUE items = rb_funcall(obj, id_to_a, 0);
res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val);
} else {
map_type *p;
res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<map_type>(),0);
if (SWIG_IsOK(res) && val) *val = p;
}
return res;
}
};
template <class K, class T >
struct traits_from<std::map<K,T> > {
typedef std::map<K,T> map_type;
typedef typename map_type::const_iterator const_iterator;
typedef typename map_type::size_type size_type;
static VALUE from(const map_type& map) {
swig_type_info *desc = swig::type_info<map_type>();
if (desc && desc->clientdata) {
return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN);
} else {
size_type size = map.size();
int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
if (rubysize < 0) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
rb_raise( rb_eRuntimeError, "map size not valid in Ruby");
SWIG_RUBY_THREAD_END_BLOCK;
return Qnil;
}
VALUE obj = rb_hash_new();
for (const_iterator i= map.begin(); i!= map.end(); ++i) {
VALUE key = swig::from(i->first);
VALUE val = swig::from(i->second);
rb_hash_aset(obj, key, val);
}
return obj;
}
}
};
template <class ValueType>
struct from_key_oper
{
typedef const ValueType& argument_type;
typedef VALUE result_type;
result_type operator()(argument_type v) const
{
return swig::from(v.first);
}
};
template <class ValueType>
struct from_value_oper
{
typedef const ValueType& argument_type;
typedef VALUE result_type;
result_type operator()(argument_type v) const
{
return swig::from(v.second);
}
};
template<class OutIterator, class FromOper,
class ValueType = typename OutIterator::value_type>
struct MapIterator_T : ConstIteratorClosed_T<OutIterator, ValueType, FromOper>
{
MapIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
: ConstIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
{
}
};
template<class OutIterator,
class FromOper = from_key_oper<typename OutIterator::value_type> >
struct MapKeyIterator_T : MapIterator_T<OutIterator, FromOper>
{
MapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
: MapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
{
}
};
template<typename OutIter>
inline ConstIterator*
make_output_key_iterator(const OutIter& current, const OutIter& begin,
const OutIter& end, VALUE seq = 0)
{
return new MapKeyIterator_T<OutIter>(current, begin, end, seq);
}
template<class OutIterator,
class FromOper = from_value_oper<typename OutIterator::value_type> >
struct MapValueIterator_T : MapIterator_T<OutIterator, FromOper>
{
MapValueIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
: MapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
{
}
};
template<typename OutIter>
inline ConstIterator*
make_output_value_iterator(const OutIter& current, const OutIter& begin,
const OutIter& end, VALUE seq = 0)
{
return new MapValueIterator_T<OutIter>(current, begin, end, seq);
}
}
}
%define %swig_map_common(Map...)
%swig_container_methods(%arg(Map));
// %swig_sequence_iterator(%arg(Map));
%extend {
VALUE __delete__(const key_type& key) {
Map::iterator i = self->find(key);
if (i != self->end()) {
self->erase(i);
return swig::from( key );
}
else {
return Qnil;
}
}
bool has_key(const key_type& key) const {
Map::const_iterator i = self->find(key);
return i != self->end();
}
VALUE keys() {
Map::size_type size = self->size();
int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
if (rubysize < 0) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
SWIG_RUBY_THREAD_END_BLOCK;
return Qnil;
}
VALUE ary = rb_ary_new2(rubysize);
Map::const_iterator i = self->begin();
Map::const_iterator e = self->end();
for ( ; i != e; ++i ) {
rb_ary_push( ary, swig::from(i->first) );
}
return ary;
}
Map* each()
{
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "no block given");
VALUE k, v;
Map::iterator i = self->begin();
Map::iterator e = self->end();
for ( ; i != e; ++i )
{
const Map::key_type& key = i->first;
const Map::mapped_type& val = i->second;
k = swig::from<Map::key_type>(key);
v = swig::from<Map::mapped_type>(val);
rb_yield_values(2, k, v);
}
return self;
}
%newobject select;
Map* select() {
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "no block given" );
Map* r = new Map;
Map::iterator i = $self->begin();
Map::iterator e = $self->end();
for ( ; i != e; ++i )
{
VALUE k = swig::from<Map::key_type>(i->first);
VALUE v = swig::from<Map::mapped_type>(i->second);
if ( RTEST( rb_yield_values(2, k, v) ) )
$self->insert(r->end(), *i);
}
return r;
}
%typemap(in) (int argc, VALUE* argv) {
$1 = argc;
$2 = argv;
}
VALUE values_at(int argc, VALUE* argv, ...) {
VALUE r = rb_ary_new();
ID id = rb_intern("[]");
swig_type_info* type = swig::type_info< Map >();
VALUE me = SWIG_NewPointerObj( $self, type, 0 );
for ( int i = 0; i < argc; ++i )
{
VALUE key = argv[i];
VALUE tmp = rb_funcall( me, id, 1, key );
rb_ary_push( r, tmp );
}
return r;
}
Map* each_key()
{
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "no block given");
VALUE r;
Map::iterator i = self->begin();
Map::iterator e = self->end();
for ( ; i != e; ++i )
{
r = swig::from( i->first );
rb_yield(r);
}
return self;
}
VALUE values() {
Map::size_type size = self->size();
int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
if (rubysize < 0) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
SWIG_RUBY_THREAD_END_BLOCK;
return Qnil;
}
VALUE ary = rb_ary_new2(rubysize);
Map::const_iterator i = self->begin();
Map::const_iterator e = self->end();
for ( ; i != e; ++i ) {
rb_ary_push( ary, swig::from(i->second) );
}
return ary;
}
Map* each_value()
{
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "no block given");
VALUE r;
Map::iterator i = self->begin();
Map::iterator e = self->end();
for ( ; i != e; ++i )
{
r = swig::from( i->second );
rb_yield(r);
}
return self;
}
VALUE entries() {
Map::size_type size = self->size();
int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
if (rubysize < 0) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
SWIG_RUBY_THREAD_END_BLOCK;
return Qnil;
}
VALUE ary = rb_ary_new2(rubysize);
Map::const_iterator i = self->begin();
Map::const_iterator e = self->end();
for ( ; i != e; ++i ) {
rb_ary_push( ary, swig::from<std::pair<Map::key_type,
Map::mapped_type> >(*i) );
}
return ary;
}
bool __contains__(const key_type& key) {
return self->find(key) != self->end();
}
%newobject key_iterator(VALUE *RUBY_SELF);
swig::ConstIterator* key_iterator(VALUE *RUBY_SELF) {
return swig::make_output_key_iterator($self->begin(), $self->begin(),
$self->end(), *RUBY_SELF);
}
%newobject value_iterator(VALUE *RUBY_SELF);
swig::ConstIterator* value_iterator(VALUE *RUBY_SELF) {
return swig::make_output_value_iterator($self->begin(), $self->begin(),
$self->end(), *RUBY_SELF);
}
}
%enddef
%define %swig_map_methods(Map...)
%swig_map_common(Map)
%extend {
VALUE __getitem__(const key_type& key) const {
Map::const_iterator i = self->find(key);
if ( i != self->end() )
return swig::from<Map::mapped_type>( i->second );
else
return Qnil;
}
void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
(*self)[key] = x;
}
VALUE inspect()
{
Map::const_iterator i = $self->begin();
Map::const_iterator e = $self->end();
VALUE str = rb_str_new2( swig::type_name< Map >() );
str = rb_str_cat2( str, " {" );
bool comma = false;
VALUE tmp;
for ( ; i != e; ++i, comma = true )
{
if (comma) str = rb_str_cat2( str, "," );
tmp = swig::from< Map::key_type >( i->first );
tmp = rb_inspect( tmp );
str = rb_str_buf_append( str, tmp );
str = rb_str_cat2( str, "=>" );
tmp = swig::from< Map::mapped_type >( i->second );
tmp = rb_inspect( tmp );
str = rb_str_buf_append( str, tmp );
}
str = rb_str_cat2( str, "}" );
return str;
}
VALUE to_a()
{
Map::const_iterator i = $self->begin();
Map::const_iterator e = $self->end();
VALUE ary = rb_ary_new2( std::distance( i, e ) );
VALUE tmp;
for ( ; i != e; ++i )
{
// @todo: improve -- this should just be swig::from(*i)
tmp = swig::from< std::pair<Map::key_type,
Map::mapped_type> >( *i );
rb_ary_push( ary, tmp );
}
return ary;
}
VALUE to_s()
{
Map::iterator i = $self->begin();
Map::iterator e = $self->end();
VALUE str = rb_str_new2( "" );
VALUE tmp;
for ( ; i != e; ++i )
{
// @todo: improve -- this should just be swig::from(*i)
tmp = swig::from< std::pair<Map::key_type,
Map::mapped_type> >( *i );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
}
return str;
}
}
%enddef
%mixin std::map "Enumerable";
%rename("delete") std::map::__delete__;
%rename("reject!") std::map::reject_bang;
%rename("map!") std::map::map_bang;
%rename("empty?") std::map::empty;
%rename("include?" ) std::map::__contains__ const;
%rename("has_key?" ) std::map::has_key const;
%alias std::map::push "<<";
%include <std/std_map.i>

View File

@@ -0,0 +1,226 @@
/*
Multimaps
*/
%include <std_map.i>
%fragment("StdMultimapTraits","header",fragment="StdSequenceTraits")
{
namespace swig {
template <class RubySeq, class K, class T >
inline void
assign(const RubySeq& rubyseq, std::multimap<K,T > *multimap) {
typedef typename std::multimap<K,T>::value_type value_type;
typename RubySeq::const_iterator it = rubyseq.begin();
for (;it != rubyseq.end(); ++it) {
multimap->insert(value_type(it->first, it->second));
}
}
template <class K, class T>
struct traits_asptr<std::multimap<K,T> > {
typedef std::multimap<K,T> multimap_type;
static int asptr(VALUE obj, std::multimap<K,T> **val) {
int res = SWIG_ERROR;
if ( TYPE(obj) == T_HASH ) {
static ID id_to_a = rb_intern("to_a");
VALUE items = rb_funcall(obj, id_to_a, 0);
return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
} else {
multimap_type *p;
res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<multimap_type>(),0);
if (SWIG_IsOK(res) && val) *val = p;
}
return res;
}
};
template <class K, class T >
struct traits_from<std::multimap<K,T> > {
typedef std::multimap<K,T> multimap_type;
typedef typename multimap_type::const_iterator const_iterator;
typedef typename multimap_type::size_type size_type;
static VALUE from(const multimap_type& multimap) {
swig_type_info *desc = swig::type_info<multimap_type>();
if (desc && desc->clientdata) {
return SWIG_NewPointerObj(new multimap_type(multimap), desc, SWIG_POINTER_OWN);
} else {
size_type size = multimap.size();
int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
if (rubysize < 0) {
SWIG_RUBY_THREAD_BEGIN_BLOCK;
rb_raise(rb_eRuntimeError,
"multimap size not valid in Ruby");
SWIG_RUBY_THREAD_END_BLOCK;
return Qnil;
}
VALUE obj = rb_hash_new();
for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) {
VALUE key = swig::from(i->first);
VALUE val = swig::from(i->second);
VALUE oldval = rb_hash_aref( obj, key );
if ( oldval == Qnil )
rb_hash_aset(obj, key, val);
else {
// Multiple values for this key, create array if needed
// and add a new element to it.
VALUE ary;
if ( TYPE(oldval) == T_ARRAY )
ary = oldval;
else
{
ary = rb_ary_new2(2);
rb_ary_push( ary, oldval );
rb_hash_aset( obj, key, ary );
}
rb_ary_push( ary, val );
}
}
return obj;
}
}
};
}
}
%define %swig_multimap_methods(MultiMap...)
%swig_map_common(%arg(MultiMap));
%extend {
VALUE __getitem__(const key_type& key) const {
MultiMap::const_iterator i = self->find(key);
if ( i != self->end() )
{
MultiMap::const_iterator e = $self->upper_bound(key);
VALUE ary = rb_ary_new();
for ( ; i != e; ++i )
{
rb_ary_push( ary, swig::from<MultiMap::mapped_type>( i->second ) );
}
if ( RARRAY_LEN(ary) == 1 )
return RARRAY_PTR(ary)[0];
return ary;
}
else
return Qnil;
}
void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
self->insert(MultiMap::value_type(key,x));
}
VALUE inspect()
{
MultiMap::iterator i = $self->begin();
MultiMap::iterator e = $self->end();
VALUE str = rb_str_new2( swig::type_name< MultiMap >() );
str = rb_str_cat2( str, " {" );
VALUE tmp;
while ( i != e )
{
const MultiMap::key_type& key = i->first;
const MultiMap::key_type& oldkey = key;
tmp = swig::from( key );
str = rb_str_buf_append( str, rb_inspect(tmp) );
str = rb_str_cat2( str, "=>" );
VALUE vals = rb_ary_new();
for ( ; i != e && key == oldkey; ++i )
{
const MultiMap::mapped_type& val = i->second;
tmp = swig::from( val );
rb_ary_push( vals, tmp );
}
if ( RARRAY_LEN(vals) == 1 )
{
str = rb_str_buf_append( str, rb_inspect(tmp) );
}
else
{
str = rb_str_buf_append( str, rb_inspect(vals) );
}
}
str = rb_str_cat2( str, "}" );
return str;
}
VALUE to_a()
{
MultiMap::const_iterator i = $self->begin();
MultiMap::const_iterator e = $self->end();
VALUE ary = rb_ary_new2( std::distance( i, e ) );
VALUE tmp;
while ( i != e )
{
const MultiMap::key_type& key = i->first;
const MultiMap::key_type& oldkey = key;
tmp = swig::from( key );
rb_ary_push( ary, tmp );
VALUE vals = rb_ary_new();
for ( ; i != e && key == oldkey; ++i )
{
const MultiMap::mapped_type& val = i->second;
tmp = swig::from( val );
rb_ary_push( vals, tmp );
}
if ( RARRAY_LEN(vals) == 1 )
{
rb_ary_push( ary, tmp );
}
else
{
rb_ary_push( ary, vals );
}
}
return ary;
}
VALUE to_s()
{
MultiMap::iterator i = $self->begin();
MultiMap::iterator e = $self->end();
VALUE str = rb_str_new2( "" );
VALUE tmp;
while ( i != e )
{
const MultiMap::key_type& key = i->first;
const MultiMap::key_type& oldkey = key;
tmp = swig::from( key );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
VALUE vals = rb_ary_new();
for ( ; i != e && key == oldkey; ++i )
{
const MultiMap::mapped_type& val = i->second;
tmp = swig::from( val );
rb_ary_push( vals, tmp );
}
tmp = rb_obj_as_string( vals );
str = rb_str_buf_append( str, tmp );
}
return str;
}
}
%enddef
%mixin std::multimap "Enumerable";
%rename("delete") std::multimap::__delete__;
%rename("reject!") std::multimap::reject_bang;
%rename("map!") std::multimap::map_bang;
%rename("empty?") std::multimap::empty;
%rename("include?" ) std::multimap::__contains__ const;
%rename("has_key?" ) std::multimap::has_key const;
%alias std::multimap::push "<<";
%include <std/std_multimap.i>

View File

@@ -0,0 +1,53 @@
/*
Multisets
*/
%include <std_set.i>
%fragment("StdMultisetTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class RubySeq, class T>
inline void
assign(const RubySeq& rubyseq, std::multiset<T>* seq) {
#ifdef SWIG_STD_NOINSERT_TEMPLATE_STL
typedef typename RubySeq::value_type value_type;
typename RubySeq::const_iterator it = rubyseq.begin();
for (;it != rubyseq.end(); ++it) {
seq->insert(seq->end(),(value_type)(*it));
}
#else
seq->insert(rubyseq.begin(), rubyseq.end());
#endif
}
template <class T>
struct traits_asptr<std::multiset<T> > {
static int asptr(VALUE obj, std::multiset<T> **m) {
return traits_asptr_stdseq<std::multiset<T> >::asptr(obj, m);
}
};
template <class T>
struct traits_from<std::multiset<T> > {
static VALUE from(const std::multiset<T>& vec) {
return traits_from_stdseq<std::multiset<T> >::from(vec);
}
};
}
%}
#define %swig_multiset_methods(Set...) %swig_set_methods(Set)
%rename("delete") std::multiset::__delete__;
%rename("reject!") std::multiset::reject_bang;
%rename("map!") std::multiset::map_bang;
%rename("empty?") std::multiset::empty;
%rename("include?" ) std::multiset::__contains__ const;
%rename("has_key?" ) std::multiset::has_key const;
%alias std::multiset::push "<<";
%include <std/std_multiset.i>

View File

@@ -0,0 +1,207 @@
/*
Pairs
*/
%include <rubystdcommon.swg>
//#define SWIG_STD_PAIR_ASVAL
%fragment("StdPairTraits","header",fragment="StdTraits") {
namespace swig {
template <class T, class U >
struct traits_asval<std::pair<T,U> > {
typedef std::pair<T,U> value_type;
static int get_pair(VALUE first, VALUE second,
std::pair<T,U> *val)
{
if (val) {
T *pfirst = &(val->first);
int res1 = swig::asval((VALUE)first, pfirst);
if (!SWIG_IsOK(res1)) return res1;
U *psecond = &(val->second);
int res2 = swig::asval((VALUE)second, psecond);
if (!SWIG_IsOK(res2)) return res2;
return res1 > res2 ? res1 : res2;
} else {
T *pfirst = 0;
int res1 = swig::asval((VALUE)first, pfirst);
if (!SWIG_IsOK(res1)) return res1;
U *psecond = 0;
int res2 = swig::asval((VALUE)second, psecond);
if (!SWIG_IsOK(res2)) return res2;
return res1 > res2 ? res1 : res2;
}
}
static int asval(VALUE obj, std::pair<T,U> *val) {
int res = SWIG_ERROR;
if ( TYPE(obj) == T_ARRAY ) {
if (RARRAY_LEN(obj) == 2) {
VALUE first = rb_ary_entry(obj,0);
VALUE second = rb_ary_entry(obj,1);
res = get_pair(first, second, val);
}
} else {
value_type *p;
res = SWIG_ConvertPtr(obj,(void**)&p,
swig::type_info<value_type>(),0);
if (SWIG_IsOK(res) && val) *val = *p;
}
return res;
}
};
template <class T, class U >
struct traits_asptr<std::pair<T,U> > {
typedef std::pair<T,U> value_type;
static int get_pair(VALUE first, VALUE second,
std::pair<T,U> **val)
{
if (val) {
value_type *vp = %new_instance(std::pair<T,U>);
T *pfirst = &(vp->first);
int res1 = swig::asval((VALUE)first, pfirst);
if (!SWIG_IsOK(res1)) return res1;
U *psecond = &(vp->second);
int res2 = swig::asval((VALUE)second, psecond);
if (!SWIG_IsOK(res2)) return res2;
*val = vp;
return SWIG_AddNewMask(res1 > res2 ? res1 : res2);
} else {
T *pfirst = 0;
int res1 = swig::asval((VALUE)first, pfirst);
if (!SWIG_IsOK(res1)) return res1;
U *psecond = 0;
int res2 = swig::asval((VALUE)second, psecond);
if (!SWIG_IsOK(res2)) return res2;
return res1 > res2 ? res1 : res2;
}
}
static int asptr(VALUE obj, std::pair<T,U> **val) {
int res = SWIG_ERROR;
if ( TYPE(obj) == T_ARRAY ) {
if ( RARRAY_LEN(obj) == 2) {
VALUE first = rb_ary_entry(obj,0);
VALUE second = rb_ary_entry(obj,1);
res = get_pair(first, second, val);
}
} else {
value_type *p;
res = SWIG_ConvertPtr(obj,(void**)&p,
swig::type_info<value_type>(),0);
if (SWIG_IsOK(res) && val) *val = p;
}
return res;
}
};
template <class T, class U >
struct traits_from<std::pair<T,U> > {
static VALUE _wrap_pair_second( VALUE self )
{
std::pair< typename swig::noconst_traits<T >::noconst_type,U>* p = NULL;
swig::asptr( self, &p );
return swig::from( p->second );
}
static VALUE _wrap_pair_second_eq( VALUE self, VALUE arg )
{
std::pair< typename swig::noconst_traits<T >::noconst_type,U>* p = NULL;
swig::asptr( self, &p );
return swig::from( p->second );
}
static VALUE from(const std::pair<T,U>& val) {
VALUE obj = rb_ary_new2(2);
RARRAY_PTR(obj)[0] = swig::from<
typename swig::noconst_traits<T >::noconst_type>(val.first);
RARRAY_PTR(obj)[1] = swig::from(val.second);
RARRAY_LEN(obj) = 2;
rb_define_singleton_method(obj, "second",
VALUEFUNC(_wrap_pair_second), 0 );
rb_define_singleton_method(obj, "second=",
VALUEFUNC(_wrap_pair_second_eq), 1 );
rb_obj_freeze(obj); // treat as immutable tuple
return obj;
}
};
}
}
// Missing typemap
%typemap(in) std::pair* (int res) {
res = swig::asptr( $input, &$1 );
if (!SWIG_IsOK(res))
%argument_fail(res, "$1_type", $symname, $argnum);
}
%define %swig_pair_methods(pair...)
%extend {
VALUE inspect() const
{
VALUE tmp;
VALUE str = rb_str_new2( swig::type_name< pair >() );
str = rb_str_cat2( str, " (" );
tmp = swig::from( $self->first );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
str = rb_str_cat2( str, "," );
tmp = swig::from( $self->second );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
str = rb_str_cat2( str, ")" );
return str;
}
VALUE to_s() const
{
VALUE tmp;
VALUE str = rb_str_new2( "(" );
tmp = swig::from( $self->first );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
str = rb_str_cat2( str, "," );
tmp = swig::from( $self->second );
tmp = rb_obj_as_string( tmp );
str = rb_str_buf_append( str, tmp );
str = rb_str_cat2( str, ")" );
return str;
}
VALUE __getitem__( int index )
{
if (( index % 2 ) == 0 )
return swig::from( $self->first );
else
return swig::from( $self->second );
}
VALUE __setitem__( int index, VALUE obj )
{
int res;
if (( index % 2 ) == 0 )
{
res = swig::asval( obj, &($self->first) );
}
else
{
res = swig::asval(obj, &($self->second) );
}
if (!SWIG_IsOK(res))
rb_raise( rb_eArgError, "invalid item for " #pair );
return obj;
}
} // extend
%enddef
%include <std/std_pair.i>

View File

@@ -0,0 +1,33 @@
/*
Queues
*/
%fragment("StdQueueTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T>
struct traits_asptr<std::queue<T> > {
static int asptr(VALUE obj, std::queue<T> **vec) {
return traits_asptr_stdseq<std::queue<T> >::asptr(obj, vec);
}
};
template <class T>
struct traits_from<std::queue<T> > {
static VALUE from(const std::queue<T> & vec) {
return traits_from_stdseq<std::queue<T> >::from(vec);
}
};
}
%}
%rename("delete") std::queue::__delete__;
%rename("reject!") std::queue::reject_bang;
%rename("map!") std::queue::map_bang;
%rename("empty?") std::queue::empty;
%rename("include?" ) std::queue::__contains__ const;
%rename("has_key?" ) std::queue::has_key const;
%alias std::queue::push "<<";
%include <std/std_queue.i>

View File

@@ -0,0 +1,216 @@
/*
Sets
*/
%fragment("StdSetTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class RubySeq, class T>
inline void
assign(const RubySeq& rubyseq, std::set<T>* seq) {
#ifdef SWIG_STD_NOINSERT_TEMPLATE_STL
typedef typename RubySeq::value_type value_type;
typename RubySeq::const_iterator it = rubyseq.begin();
for (;it != rubyseq.end(); ++it) {
seq->insert(seq->end(),(value_type)(*it));
}
#else
seq->insert(rubyseq.begin(), rubyseq.end());
#endif
}
template <class T>
struct traits_asptr<std::set<T> > {
static int asptr(VALUE obj, std::set<T> **s) {
return traits_asptr_stdseq<std::set<T> >::asptr(obj, s);
}
};
template <class T>
struct traits_from<std::set<T> > {
static VALUE from(const std::set<T>& vec) {
return traits_from_stdseq<std::set<T> >::from(vec);
}
};
/**
* Set Iterator class for an iterator with no end() boundaries.
*
*/
template<typename InOutIterator,
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
typename FromOper = from_oper<ValueType>,
typename AsvalOper = asval_oper<ValueType> >
class SetIteratorOpen_T : public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef ValueType value_type;
typedef Iterator_T<nonconst_iter> base;
typedef SetIteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
public:
SetIteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq)
{
}
virtual VALUE value() const {
return from(static_cast<const value_type&>(*(base::current)));
}
// no setValue allowed
Iterator *dup() const
{
return new self_type(*this);
}
};
/**
* Set Iterator class for a iterator where begin() and end() boundaries
are known.
*
*/
template<typename InOutIterator,
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
typename FromOper = from_oper<ValueType>,
typename AsvalOper = asval_oper<ValueType> >
class SetIteratorClosed_T : public Iterator_T<InOutIterator>
{
public:
FromOper from;
AsvalOper asval;
typedef InOutIterator nonconst_iter;
typedef ValueType value_type;
typedef Iterator_T<nonconst_iter> base;
typedef SetIteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
protected:
virtual Iterator* advance(ptrdiff_t n)
{
std::advance( base::current, n );
if ( base::current == end )
throw stop_iteration();
return this;
}
public:
SetIteratorClosed_T(nonconst_iter curr, nonconst_iter first,
nonconst_iter last, VALUE seq = Qnil)
: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
{
}
virtual VALUE value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
// no setValue allowed
Iterator *dup() const
{
return new self_type(*this);
}
private:
nonconst_iter begin;
nonconst_iter end;
};
// Template specialization to construct a closed iterator for sets
// this turns a nonconst iterator into a const one for ruby to avoid
// allowing the user to change the value
template< typename InOutIter >
inline Iterator*
make_set_nonconst_iterator(const InOutIter& current,
const InOutIter& begin,
const InOutIter& end,
VALUE seq = Qnil)
{
return new SetIteratorClosed_T< InOutIter >(current,
begin, end, seq);
}
// Template specialization to construct an open iterator for sets
// this turns a nonconst iterator into a const one for ruby to avoid
// allowing the user to change the value
template< typename InOutIter >
inline Iterator*
make_set_nonconst_iterator(const InOutIter& current,
VALUE seq = Qnil)
{
return new SetIteratorOpen_T< InOutIter >(current, seq);
}
}
%}
%define %swig_set_methods(set...)
%swig_sequence_methods_common(%arg(set));
%fragment("RubyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="RubySequence_Cont") {}
// Redefine std::set iterator/reverse_iterator typemap
%typemap(out,noblock=1) iterator, reverse_iterator {
$result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
self),
swig::Iterator::descriptor(),SWIG_POINTER_OWN);
}
// Redefine std::set std::pair<iterator, bool> typemap
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
std::pair<iterator, bool> {
$result = rb_ary_new2(2);
RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
swig::Iterator::descriptor(),SWIG_POINTER_OWN);
RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second);
RARRAY_LEN($result) = 2;
}
%extend {
%alias push "<<";
value_type push(const value_type& x) {
self->insert(x);
return x;
}
bool __contains__(const value_type& x) {
return self->find(x) != self->end();
}
value_type __getitem__(difference_type i) const throw (std::out_of_range) {
return *(swig::cgetpos(self, i));
}
};
%enddef
%mixin std::set "Enumerable";
%rename("delete") std::set::__delete__;
%rename("reject!") std::set::reject_bang;
%rename("map!") std::set::map_bang;
%rename("empty?") std::set::empty;
%rename("include?" ) std::set::__contains__ const;
%rename("has_key?" ) std::set::has_key const;
%alias std::set::push "<<";
%include <std/std_set.i>

View File

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

View File

@@ -0,0 +1,35 @@
/*
Stacks
*/
%fragment("StdStackTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T>
struct traits_asptr<std::stack<T> > {
static int asptr(VALUE obj, std::stack<T> **vec) {
return traits_asptr_stdseq<std::stack<T> >::asptr(obj, vec);
}
};
template <class T>
struct traits_from<std::stack<T> > {
static VALUE from(const std::stack<T> & vec) {
return traits_from_stdseq<std::stack<T> >::from(vec);
}
};
}
%}
%rename("delete") std::stack::__delete__;
%rename("reject!") std::stack::reject_bang;
%rename("map!") std::stack::map_bang;
%rename("empty?") std::stack::empty;
%rename("include?" ) std::stack::__contains__ const;
%rename("has_key?" ) std::stack::has_key const;
%alias std::stack::push "<<";
%include <std/std_stack.i>

View File

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

View File

@@ -0,0 +1,9 @@
%warnfilter(801) std::string; // wrong class name
%warnfilter(378) std::basic_string::operator!=;
AUTODOC(substr, "Return a portion of the String");
%include <typemaps/std_string.swg>

View File

@@ -0,0 +1,52 @@
/*
Vectors
*/
%fragment("StdVectorTraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T>
struct traits_asptr<std::vector<T> > {
static int asptr(VALUE 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 VALUE from(const std::vector<T>& vec) {
return traits_from_stdseq<std::vector<T> >::from(vec);
}
};
}
%}
%define %swig_vector_methods(Type...)
%swig_sequence_methods(Type)
%swig_sequence_front_inserters(Type);
%enddef
%define %swig_vector_methods_val(Type...)
%swig_sequence_methods_val(Type);
%swig_sequence_front_inserters(Type);
%enddef
%mixin std::vector "Enumerable";
%ignore std::vector::push_back;
%ignore std::vector::pop_back;
%rename("delete") std::vector::__delete__;
%rename("reject!") std::vector::reject_bang;
%rename("map!") std::vector::map_bang;
%rename("empty?") std::vector::empty;
%rename("include?" ) std::vector::__contains__ const;
%rename("has_key?" ) std::vector::has_key const;
%alias std::vector::push "<<";
%include <std/std_vector.i>

View File

@@ -0,0 +1,36 @@
/*
Vectors + allocators
*/
%fragment("StdVectorATraits","header",fragment="StdSequenceTraits")
%{
namespace swig {
template <class T, class A>
struct traits_asptr<std::vector<T,A> > {
typedef std::vector<T,A> vector_type;
typedef T value_type;
static int asptr(VALUE obj, vector_type **vec) {
return traits_asptr_stdseq<vector_type>::asptr(obj, vec);
}
};
template <class T, class A>
struct traits_from<std::vector<T,A> > {
typedef std::vector<T,A> vector_type;
static VALUE from(const vector_type& vec) {
return traits_from_stdseq<vector_type>::from(vec);
}
};
}
%}
#define %swig_vector_methods(Type...) %swig_sequence_methods(Type)
#define %swig_vector_methods_val(Type...) %swig_sequence_methods_val(Type);
%mixin std::vector "Enumerable";
%ignore std::vector::push_back;
%ignore std::vector::pop_back;
%alias std::vector::push "<<";
%include <std/std_vectora.i>

View File

@@ -0,0 +1,3 @@
%include <rubywstrings.swg>
%include <typemaps/std_wstring.swg>

View File

@@ -0,0 +1,15 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* stl.i
*
* Initial STL definition. extended as needed in each language
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%include <std_string.i>
%include <std_vector.i>
%include <std_map.i>
%include <std_pair.i>

View File

@@ -0,0 +1,64 @@
/*
struct timeval *
time_t
Ruby has builtin class Time. INPUT/OUTPUT typemap for timeval and
time_t is provided.
*/
%{
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
struct timeval rb_time_timeval(VALUE);
#endif
#ifdef __cplusplus
}
#endif
%}
%typemap(in) struct timeval *INPUT (struct timeval temp)
{
if (NIL_P($input))
$1 = NULL;
else {
temp = rb_time_timeval($input);
$1 = &temp;
}
}
%typemap(in,numinputs=0) struct timeval *OUTPUT(struct timeval temp)
{
$1 = &temp;
}
%typemap(argout) struct timeval *OUTPUT
{
$result = rb_time_new($1->tv_sec, $1->tv_usec);
}
%typemap(out) struct timeval *
{
$result = rb_time_new($1->tv_sec, $1->tv_usec);
}
%typemap(out) struct timespec *
{
$result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000);
}
// time_t
%typemap(in) time_t
{
if (NIL_P($input))
$1 = (time_t)-1;
else
$1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0));
}
%typemap(out) time_t
{
$result = rb_time_new($1, 0);
}

View File

@@ -0,0 +1,317 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* typemaps.i
*
* Pointer handling
*
* These mappings provide support for input/output arguments and
* common uses for C/C++ pointers. INOUT mappings allow for C/C++
* pointer variables in addition to input/output arguments.
* ----------------------------------------------------------------------------- */
#if !defined(SWIG_USE_OLD_TYPEMAPS)
%include <typemaps/typemaps.swg>
#else
/*
The SWIG typemap library provides a language independent mechanism for
supporting output arguments, input values, and other C function
calling mechanisms. The primary use of the library is to provide a
better interface to certain C function--especially those involving
pointers.
*/
// ------------------------------------------------------------------------
// Pointer handling
//
// These mappings provide support for input/output arguments and common
// uses for C/C++ pointers.
// ------------------------------------------------------------------------
// INPUT typemaps.
// These remap a C pointer to be an "INPUT" value which is passed by value
// instead of reference.
/*
The following methods can be applied to turn a pointer into a simple
"input" value. That is, instead of passing a pointer to an object,
you would use a real value instead.
int *INPUT
short *INPUT
long *INPUT
long long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
unsigned long long *INPUT
unsigned char *INPUT
bool *INPUT
float *INPUT
double *INPUT
To use these, suppose you had a C function like this :
double fadd(double *a, double *b) {
return *a+*b;
}
You could wrap it with SWIG as follows :
%include typemaps.i
double fadd(double *INPUT, double *INPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INPUT { double *a, double *b };
double fadd(double *a, double *b);
*/
%define INPUT_TYPEMAP(type, converter)
%typemap(in) type *INPUT($*1_ltype temp), type &INPUT($*1_ltype temp)
{
temp = ($*1_ltype) converter($input);
$1 = &temp;
}
%typemap(typecheck) type *INPUT = type;
%typemap(typecheck) type &INPUT = type;
%enddef
INPUT_TYPEMAP(float, NUM2DBL);
INPUT_TYPEMAP(double, NUM2DBL);
INPUT_TYPEMAP(int, NUM2INT);
INPUT_TYPEMAP(short, NUM2SHRT);
INPUT_TYPEMAP(long, NUM2LONG);
INPUT_TYPEMAP(long long, NUM2LL);
INPUT_TYPEMAP(unsigned int, NUM2UINT);
INPUT_TYPEMAP(unsigned short, NUM2USHRT);
INPUT_TYPEMAP(unsigned long, NUM2ULONG);
INPUT_TYPEMAP(unsigned long long, NUM2ULL);
INPUT_TYPEMAP(unsigned char, NUM2UINT);
INPUT_TYPEMAP(signed char, NUM2INT);
INPUT_TYPEMAP(bool, RTEST);
#undef INPUT_TYPEMAP
// OUTPUT typemaps. These typemaps are used for parameters that
// are output only. The output value is appended to the result as
// a array element.
/*
The following methods can be applied to turn a pointer into an "output"
value. When calling a function, no input value would be given for
a parameter, but an output value would be returned. In the case of
multiple output values, they are returned in the form of a Ruby Array.
int *OUTPUT
short *OUTPUT
long *OUTPUT
long long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
unsigned long long *OUTPUT
unsigned char *OUTPUT
bool *OUTPUT
float *OUTPUT
double *OUTPUT
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters).K:
double modf(double x, double *ip);
You could wrap it with SWIG as follows :
%include typemaps.i
double modf(double x, double *OUTPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
The Ruby output of the function would be a Array containing both
output values.
*/
%define OUTPUT_TYPEMAP(type, converter, convtype)
%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;";
%typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT {
VALUE o = converter(convtype (*$1));
$result = output_helper($result, o);
}
%enddef
OUTPUT_TYPEMAP(int, INT2NUM, (int));
OUTPUT_TYPEMAP(short, INT2NUM, (int));
OUTPUT_TYPEMAP(long, INT2NUM, (long));
OUTPUT_TYPEMAP(long long, LL2NUM, (long long));
OUTPUT_TYPEMAP(unsigned int, UINT2NUM, (unsigned int));
OUTPUT_TYPEMAP(unsigned short, UINT2NUM, (unsigned int));
OUTPUT_TYPEMAP(unsigned long, UINT2NUM, (unsigned long));
OUTPUT_TYPEMAP(unsigned long long, ULL2NUM, (unsigned long long));
OUTPUT_TYPEMAP(unsigned char, UINT2NUM, (unsigned int));
OUTPUT_TYPEMAP(signed char, INT2NUM, (int));
OUTPUT_TYPEMAP(float, rb_float_new, (double));
OUTPUT_TYPEMAP(double, rb_float_new, (double));
#undef OUTPUT_TYPEMAP
%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;";
%typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT {
VALUE o = (*$1) ? Qtrue : Qfalse;
$result = output_helper($result, o);
}
// INOUT
// Mappings for an argument that is both an input and output
// parameter
/*
The following methods can be applied to make a function parameter both
an input and output value. This combines the behavior of both the
"INPUT" and "OUTPUT" methods described earlier. Output values are
returned in the form of a Ruby array.
int *INOUT
short *INOUT
long *INOUT
long long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
unsigned long long *INOUT
unsigned char *INOUT
bool *INOUT
float *INOUT
double *INOUT
For example, suppose you were trying to wrap the following function :
void neg(double *x) {
*x = -(*x);
}
You could wrap it with SWIG as follows :
%include typemaps.i
void neg(double *INOUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INOUT { double *x };
void neg(double *x);
Unlike C, this mapping does not directly modify the input value (since
this makes no sense in Ruby). Rather, the modified input value shows
up as the return value of the function. Thus, to apply this function
to a Ruby variable you might do this :
x = neg(x)
Note : previous versions of SWIG used the symbol 'BOTH' to mark
input/output arguments. This is still supported, but will be slowly
phased out in future releases.
*/
%typemap(in) int *INOUT = int *INPUT;
%typemap(in) short *INOUT = short *INPUT;
%typemap(in) long *INOUT = long *INPUT;
%typemap(in) long long *INOUT = long long *INPUT;
%typemap(in) unsigned *INOUT = unsigned *INPUT;
%typemap(in) unsigned short *INOUT = unsigned short *INPUT;
%typemap(in) unsigned long *INOUT = unsigned long *INPUT;
%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT;
%typemap(in) unsigned char *INOUT = unsigned char *INPUT;
%typemap(in) signed char *INOUT = signed char *INPUT;
%typemap(in) bool *INOUT = bool *INPUT;
%typemap(in) float *INOUT = float *INPUT;
%typemap(in) double *INOUT = double *INPUT;
%typemap(in) int &INOUT = int &INPUT;
%typemap(in) short &INOUT = short &INPUT;
%typemap(in) long &INOUT = long &INPUT;
%typemap(in) long long &INOUT = long long &INPUT;
%typemap(in) unsigned &INOUT = unsigned &INPUT;
%typemap(in) unsigned short &INOUT = unsigned short &INPUT;
%typemap(in) unsigned long &INOUT = unsigned long &INPUT;
%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT;
%typemap(in) unsigned char &INOUT = unsigned char &INPUT;
%typemap(in) signed char &INOUT = signed char &INPUT;
%typemap(in) bool &INOUT = bool &INPUT;
%typemap(in) float &INOUT = float &INPUT;
%typemap(in) double &INOUT = double &INPUT;
%typemap(argout) int *INOUT = int *OUTPUT;
%typemap(argout) short *INOUT = short *OUTPUT;
%typemap(argout) long *INOUT = long *OUTPUT;
%typemap(argout) long long *INOUT = long long *OUTPUT;
%typemap(argout) unsigned *INOUT = unsigned *OUTPUT;
%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT;
%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT;
%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT;
%typemap(argout) signed char *INOUT = signed char *OUTPUT;
%typemap(argout) bool *INOUT = bool *OUTPUT;
%typemap(argout) float *INOUT = float *OUTPUT;
%typemap(argout) double *INOUT = double *OUTPUT;
%typemap(argout) int &INOUT = int &OUTPUT;
%typemap(argout) short &INOUT = short &OUTPUT;
%typemap(argout) long &INOUT = long &OUTPUT;
%typemap(argout) long long &INOUT = long long &OUTPUT;
%typemap(argout) unsigned &INOUT = unsigned &OUTPUT;
%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT;
%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT;
%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;
%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT;
%typemap(argout) signed char &INOUT = signed char &OUTPUT;
%typemap(argout) bool &INOUT = bool &OUTPUT;
%typemap(argout) float &INOUT = float &OUTPUT;
%typemap(argout) double &INOUT = double &OUTPUT;
/* Overloading information */
%typemap(typecheck) double *INOUT = double;
%typemap(typecheck) signed char *INOUT = signed char;
%typemap(typecheck) unsigned char *INOUT = unsigned char;
%typemap(typecheck) unsigned long *INOUT = unsigned long;
%typemap(typecheck) unsigned long long *INOUT = unsigned long long;
%typemap(typecheck) unsigned short *INOUT = unsigned short;
%typemap(typecheck) unsigned int *INOUT = unsigned int;
%typemap(typecheck) long *INOUT = long;
%typemap(typecheck) long long *INOUT = long long;
%typemap(typecheck) short *INOUT = short;
%typemap(typecheck) int *INOUT = int;
%typemap(typecheck) float *INOUT = float;
%typemap(typecheck) double &INOUT = double;
%typemap(typecheck) signed char &INOUT = signed char;
%typemap(typecheck) unsigned char &INOUT = unsigned char;
%typemap(typecheck) unsigned long &INOUT = unsigned long;
%typemap(typecheck) unsigned long long &INOUT = unsigned long long;
%typemap(typecheck) unsigned short &INOUT = unsigned short;
%typemap(typecheck) unsigned int &INOUT = unsigned int;
%typemap(typecheck) long &INOUT = long;
%typemap(typecheck) long long &INOUT = long long;
%typemap(typecheck) short &INOUT = short;
%typemap(typecheck) int &INOUT = int;
%typemap(typecheck) float &INOUT = float;
#endif
// --------------------------------------------------------------------
// Special types
// --------------------------------------------------------------------
%include <progargcargv.i>
%include <file.i>
%include <timeval.i>