summaryrefslogtreecommitdiff
path: root/devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg')
-rw-r--r--devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg395
1 files changed, 395 insertions, 0 deletions
diff --git a/devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg b/devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg
new file mode 100644
index 0000000..db54826
--- /dev/null
+++ b/devtools/swigwin-1.3.34/Lib/ruby/rubyclasses.swg
@@ -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
+