Home | History | Annotate | Download | only in octave
      1 
      2 #include <octave/version.h>
      3 #ifndef OCTAVE_API_VERSION_NUMBER
      4 
      5   // Hack to distinguish between Octave 3.2 and earlier versions before OCTAVE_API_VERSION_NUMBER existed
      6   #define ComplexLU __ignore
      7   #include <octave/CmplxLU.h>
      8   #undef ComplexLU
      9   #ifdef octave_Complex_LU_h
     10   # define OCTAVE_API_VERSION_NUMBER 36
     11   #else
     12   # define OCTAVE_API_VERSION_NUMBER 37
     13   #endif
     14 
     15 #endif
     16 
     17 #if OCTAVE_API_VERSION_NUMBER < 37
     18 #define SWIG_DEFUN(cname, wname, doc) DEFUNX_DLD(#cname, wname, FS ## cname, args, nargout, doc)
     19 #else
     20 #define SWIG_DEFUN(cname, wname, doc) DEFUNX_DLD(#cname, wname, G ## cname, args, nargout, doc)
     21 #endif
     22 
     23 SWIGRUNTIME bool SWIG_check_num_args(const char *func_name, int num_args, int max_args, int min_args, int varargs) {
     24   if (num_args > max_args && !varargs)
     25     error("function %s takes at most %i arguments", func_name, max_args);
     26   else if (num_args < min_args)
     27     error("function %s requires at least %i arguments", func_name, min_args);
     28   else
     29     return true;
     30   return false;
     31 }
     32 
     33 SWIGRUNTIME octave_value_list *SWIG_Octave_AppendOutput(octave_value_list *ovl, const octave_value &ov) {
     34   ovl->append(ov);
     35   return ovl;
     36 }
     37 
     38 SWIGRUNTIME octave_value SWIG_ErrorType(int code) {
     39   switch (code) {
     40   case SWIG_MemoryError:
     41     return "SWIG_MemoryError";
     42   case SWIG_IOError:
     43     return "SWIG_IOError";
     44   case SWIG_RuntimeError:
     45     return "SWIG_RuntimeError";
     46   case SWIG_IndexError:
     47     return "SWIG_IndexError";
     48   case SWIG_TypeError:
     49     return "SWIG_TypeError";
     50   case SWIG_DivisionByZero:
     51     return "SWIG_DivisionByZero";
     52   case SWIG_OverflowError:
     53     return "SWIG_OverflowError";
     54   case SWIG_SyntaxError:
     55     return "SWIG_SyntaxError";
     56   case SWIG_ValueError:
     57     return "SWIG_ValueError";
     58   case SWIG_SystemError:
     59     return "SWIG_SystemError";
     60   case SWIG_AttributeError:
     61     return "SWIG_AttributeError";
     62   }
     63   return "SWIG unknown error";
     64 }
     65 
     66 SWIGRUNTIME octave_value SWIG_Error(int code, const char *msg) {
     67   octave_value type(SWIG_ErrorType(code));
     68   std::string r = msg;
     69   r += " (" + type.string_value() + ")";
     70   error(r.c_str());
     71   return octave_value(r);
     72 }
     73 
     74 #define SWIG_fail                                       goto fail
     75 
     76 #define SWIG_Octave_ConvertPtr(obj, pptr, type, flags)  SWIG_Octave_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
     77 #define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Octave_ConvertPtr(obj, pptr, type, flags)
     78 #define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Octave_ConvertPtrAndOwn(obj, pptr, type, flags, own)
     79 #define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Octave_ConvertPtr(obj, pptr, type, flags)
     80 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Octave_NewPointerObj(ptr, type, flags)
     81 #define swig_owntype                                    int
     82 
     83 #define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Octave_ConvertPacked(obj, ptr, sz, ty)
     84 #define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Octave_NewPackedObj(ptr, sz, type)
     85 
     86 #define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_ConvertPtr(obj, pptr, type, 0)
     87 #define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_NewPointerObj(ptr, type, 0)
     88 
     89 #define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Octave_ConvertPacked(obj, ptr, sz, ty)
     90 #define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Octave_NewPackedObj(ptr, sz, type)
     91 
     92 #define SWIG_GetModule(clientdata) SWIG_Octave_GetModule(clientdata)
     93 #define SWIG_SetModule(clientdata, pointer) SWIG_Octave_SetModule(clientdata,pointer);
     94 #define SWIG_MODULE_CLIENTDATA_TYPE void*
     95 
     96 #define Octave_Error_Occurred() 0
     97 #define SWIG_Octave_AddErrorMsg(msg) {;}
     98 
     99 SWIGRUNTIME swig_module_info *SWIG_Octave_GetModule(void *clientdata);
    100 SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *pointer);
    101 
    102 // For backward compatibility only
    103 #define SWIG_POINTER_EXCEPTION  0
    104 #define SWIG_arg_fail(arg)      0
    105 
    106 // Runtime API implementation
    107 
    108 #include <map>
    109 #include <vector>
    110 #include <string>
    111 
    112 typedef octave_value_list(*octave_func) (const octave_value_list &, int);
    113 class octave_swig_type;
    114 
    115 namespace Swig {
    116 
    117 #ifdef SWIG_DIRECTORS
    118 
    119   class Director;
    120 
    121   typedef std::map < void *, Director * > rtdir_map;
    122   SWIGINTERN rtdir_map* get_rtdir_map();
    123   SWIGINTERNINLINE void set_rtdir(void *vptr, Director *d);
    124   SWIGINTERNINLINE void erase_rtdir(void *vptr);
    125   SWIGINTERNINLINE Director *get_rtdir(void *vptr);
    126 
    127   SWIGRUNTIME void swig_director_destroyed(octave_swig_type *self, Director *d);
    128   SWIGRUNTIME octave_swig_type *swig_director_get_self(Director *d);
    129   SWIGRUNTIME void swig_director_set_self(Director *d, octave_swig_type *self);
    130 
    131 #endif
    132 
    133   SWIGRUNTIME octave_base_value *swig_value_ref(octave_swig_type *ost);
    134   SWIGRUNTIME octave_swig_type *swig_value_deref(octave_value ov);
    135   SWIGRUNTIME octave_swig_type *swig_value_deref(const octave_base_value &ov);
    136 }
    137 
    138 #ifdef SWIG_DIRECTORS
    139 SWIGRUNTIME void swig_acquire_ownership(void *vptr);
    140 SWIGRUNTIME void swig_acquire_ownership_array(void *vptr);
    141 SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
    142 #endif
    143 
    144   struct swig_octave_member {
    145     const char *name;
    146     octave_func method;
    147     octave_func get_method;
    148     octave_func set_method;
    149     int flags;			// 1 static, 2 global
    150     const char *doc;
    151     bool is_static() const {
    152       return flags &1;
    153     } bool is_global() const {
    154       return flags &2;
    155     }
    156   };
    157 
    158   struct swig_octave_class {
    159     const char *name;
    160     swig_type_info **type;
    161     int director;
    162     octave_func constructor;
    163     const char *constructor_doc;
    164     octave_func destructor;
    165     const swig_octave_member *members;
    166     const char **base_names;
    167     const swig_type_info **base;
    168   };
    169 
    170   // octave_swig_type plays the role of both the shadow class and the class 
    171   // representation within Octave, since there is no support for classes.
    172   //
    173   // These should really be decoupled, with the class support added to Octave
    174   // and the shadow class given by an m-file script. That would dramatically 
    175   // reduce the runtime complexity, and be more in line w/ other modules.
    176 
    177   class octave_swig_type:public octave_base_value {
    178     struct cpp_ptr {
    179       void *ptr;
    180       bool destroyed;
    181       cpp_ptr(void *_ptr):ptr(_ptr), destroyed(false) {
    182       }};
    183     typedef std::pair < const swig_type_info *, cpp_ptr > type_ptr_pair;
    184 
    185     mutable swig_module_info *module;
    186 
    187     const swig_type_info *construct_type;	// type of special type object
    188     std::vector < type_ptr_pair > types;	// our c++ base classes
    189     int own;			// whether we call c++ destructors when we die
    190 
    191     typedef std::pair < const swig_octave_member *, octave_value > member_value_pair;
    192     typedef std::map < std::string, member_value_pair > member_map;
    193     member_map members;
    194     bool always_static;
    195 
    196     const swig_octave_member *find_member(const swig_type_info *type, const std::string &name) {
    197       if (!type->clientdata)
    198 	return 0;
    199       swig_octave_class *c = (swig_octave_class *) type->clientdata;
    200       const swig_octave_member *m;
    201       for (m = c->members; m->name; ++m)
    202 	if (m->name == name)
    203 	  return m;
    204       for (int j = 0; c->base_names[j]; ++j) {
    205 	if (!c->base[j]) {
    206 	  if (!module)
    207 	    module = SWIG_GetModule(0);
    208 	  assert(module);
    209 	  c->base[j] = SWIG_MangledTypeQueryModule(module, module, c->base_names[j]);
    210 	}
    211 	if (!c->base[j])
    212 	  return 0;
    213 	if ((m = find_member(c->base[j], name)))
    214 	  return m;
    215       }
    216       return 0;
    217     }
    218 
    219     member_value_pair *find_member(const std::string &name, bool insert_if_not_found) {
    220       member_map::iterator it = members.find(name);
    221       if (it != members.end())
    222 	return &it->second;
    223       const swig_octave_member *m;
    224       for (unsigned int j = 0; j < types.size(); ++j)
    225 	if ((m = find_member(types[j].first, name)))
    226 	  return &members.insert(std::make_pair(name, std::make_pair(m, octave_value()))).first->second;
    227       if (!insert_if_not_found)
    228 	return 0;
    229       return &members[name];
    230     }
    231 
    232     const swig_type_info *find_base(const std::string &name, const swig_type_info *base) {
    233       if (!base) {
    234 	for (unsigned int j = 0; j < types.size(); ++j) {
    235 	  assert(types[j].first->clientdata);
    236 	  swig_octave_class *cj = (swig_octave_class *) types[j].first->clientdata;
    237 	  if (cj->name == name)
    238 	    return types[j].first;
    239 	}
    240 	return 0;
    241       }
    242       assert(base->clientdata);
    243       swig_octave_class *c = (swig_octave_class *) base->clientdata;
    244       for (int j = 0; c->base_names[j]; ++j) {
    245 	if (!c->base[j]) {
    246 	  if (!module)
    247 	    module = SWIG_GetModule(0);
    248 	  assert(module);
    249 	  c->base[j] = SWIG_MangledTypeQueryModule(module, module, c->base_names[j]);
    250 	}
    251 	if (!c->base[j])
    252 	  return 0;
    253 	assert(c->base[j]->clientdata);
    254 	swig_octave_class *cj = (swig_octave_class *) c->base[j]->clientdata;
    255 	if (cj->name == name)
    256 	  return c->base[j];
    257       }
    258       return 0;
    259     }
    260 
    261     void load_members(const swig_octave_class* c,member_map& out) const {
    262       for (const swig_octave_member *m = c->members; m->name; ++m) {
    263 	if (out.find(m->name) == out.end())
    264 	  out.insert(std::make_pair(m->name, std::make_pair(m, octave_value())));
    265       }
    266       for (int j = 0; c->base_names[j]; ++j) {
    267 	if (!c->base[j]) {
    268 	  if (!module)
    269 	    module = SWIG_GetModule(0);
    270 	  assert(module);
    271 	  c->base[j] = SWIG_MangledTypeQueryModule(module, module, c->base_names[j]);
    272 	}
    273 	if (!c->base[j])
    274 	  continue;
    275 	assert(c->base[j]->clientdata);
    276 	const swig_octave_class *cj =
    277 	  (const swig_octave_class *) c->base[j]->clientdata;
    278 	load_members(cj,out);
    279       }
    280     }
    281 
    282     void load_members(member_map& out) const {
    283       out=members;
    284       for (unsigned int j = 0; j < types.size(); ++j)
    285 	if (types[j].first->clientdata)
    286 	  load_members((const swig_octave_class *) types[j].first->clientdata, out);
    287     }
    288 
    289     octave_value_list member_invoke(member_value_pair *m, const octave_value_list &args, int nargout) {
    290       if (m->second.is_defined())
    291 	return m->second.subsref("(", std::list < octave_value_list > (1, args), nargout);
    292       else if (m->first && m->first->method)
    293 	return m->first->method(args, nargout);
    294       error("member not defined or not invocable");
    295       return octave_value_list();
    296     }
    297 
    298     bool dispatch_unary_op(const std::string &symbol, octave_value &ret) {
    299       member_value_pair *m = find_member(symbol, false);
    300       if (!m || m->first->is_static() || m->first->is_global())
    301 	return false;
    302       octave_value_list args;
    303       args.append(as_value());
    304       octave_value_list argout(member_invoke(m, args, 1));
    305       if (argout.length() < 1)
    306 	return false;
    307       ret = argout(0);
    308       return true;
    309     }
    310 
    311     bool dispatch_binary_op(const std::string &symbol, const octave_base_value &rhs, octave_value &ret) {
    312       member_value_pair *m = find_member(symbol, false);
    313       if (!m || m->first->is_static() || m->first->is_global())
    314 	return false;
    315       octave_value_list args;
    316       args.append(as_value());
    317       args.append(make_value_hack(rhs));
    318       octave_value_list argout(member_invoke(m, args, 1));
    319       if (argout.length() < 1)
    320 	return false;
    321       ret = argout(0);
    322       return true;
    323     }
    324 
    325     bool dispatch_index_op(const std::string &symbol, const octave_value_list &rhs, octave_value_list &ret) {
    326       member_value_pair *m = find_member(symbol, false);
    327       if (!m || m->first->is_static() || m->first->is_global())
    328 	return false;
    329       octave_value_list args;
    330       args.append(as_value());
    331       args.append(rhs);
    332       octave_value_list argout(member_invoke(m, args, 1));
    333       if (argout.length() >= 1)
    334 	ret = argout(0);
    335       return true;
    336     }
    337 
    338     octave_value_list member_deref(member_value_pair *m, const octave_value_list &args) {
    339       if (m->second.is_defined())
    340 	return m->second;
    341       else if (m->first) {
    342 	if (m->first->get_method)
    343 	  return m->first->get_method(args, 1);
    344 	else if (m->first->method)
    345 	  return octave_value(new octave_builtin(m->first->method));
    346       }
    347       error("undefined member");
    348       return octave_value_list();
    349     }
    350 
    351     static octave_value make_value_hack(const octave_base_value &x) {
    352       ((octave_swig_type &) x).count++;
    353       return octave_value((octave_base_value *) &x);
    354     }
    355 
    356     octave_swig_type(const octave_swig_type &x);
    357     octave_swig_type &operator=(const octave_swig_type &rhs);
    358   public:
    359 
    360     octave_swig_type(void *_ptr = 0, const swig_type_info *_type = 0, int _own = 0,
    361 		     bool _always_static = false)
    362       :	module(0), construct_type(_ptr ? 0 : _type), own(_own), 
    363       always_static(_always_static) {
    364       if (_type || _ptr)
    365 	types.push_back(std::make_pair(_type, _ptr));
    366 #ifdef SWIG_DIRECTORS
    367       if (_ptr) {
    368 	Swig::Director *d = Swig::get_rtdir(_ptr);
    369 	if (d)
    370 	  Swig::swig_director_set_self(d, this);
    371       }
    372 #endif
    373     }
    374 
    375     ~octave_swig_type() {
    376       if (own) {
    377 	++count;
    378 	for (unsigned int j = 0; j < types.size(); ++j) {
    379 	  if (!types[j].first || !types[j].first->clientdata)
    380 	    continue;
    381 	  swig_octave_class *c = (swig_octave_class *) types[j].first->clientdata;
    382 	  if (c->destructor && !types[j].second.destroyed && types[j].second.ptr) {
    383 	    c->destructor(as_value(), 0);
    384 	  }
    385 	}
    386       }
    387 #ifdef SWIG_DIRECTORS
    388       for (unsigned int j = 0; j < types.size(); ++j)
    389 	Swig::erase_rtdir(types[j].second.ptr);
    390 #endif
    391     }
    392 
    393     dim_vector dims(void) const {
    394       octave_swig_type *nc_this = const_cast < octave_swig_type *>(this);
    395       
    396       // Find the __dims__ method of this object
    397       member_value_pair *m = nc_this->find_member("__dims__", false);
    398 
    399       if (!m) return dim_vector(1,1);
    400       
    401       // Call the __dims__ method of this object
    402       octave_value_list inarg;
    403       inarg.append(nc_this->as_value());
    404       octave_value_list outarg = nc_this->member_invoke(m, inarg, 1);
    405 
    406       // __dims__ should return (at least) one output argument
    407       if (outarg.length() < 1) return dim_vector(1,1);
    408       
    409       octave_value & out = outarg(0);
    410 
    411       // Return value should be cell or matrix of integers
    412       if (out.is_cell()) {
    413         const Cell & c=out.cell_value();
    414         int ndim = c.rows();
    415         if (ndim==1 && c.columns()!=1) ndim = c.columns();
    416 
    417         dim_vector d;
    418         d.resize(ndim < 2 ? 2 : ndim);
    419         d(0) = d(1) = 1;
    420 
    421         // Fill in dim_vector 
    422         for (int k=0;k<ndim;k++) {
    423           const octave_value& obj = c(k);
    424           d.elem(k) = obj.int_value();
    425           
    426           // __dims__ should return a cell filled with integers
    427           if (error_state) return dim_vector(1,1);
    428         }
    429         return d;
    430       } else if (out.is_matrix_type() || out.is_real_nd_array() || out.is_numeric_type() ) {
    431         if (out.rows()==1 || out.columns()==1) {
    432            Array<int> a = out.int_vector_value();
    433            if (error_state) return dim_vector(1,1);
    434            dim_vector d;
    435            d.resize(a.numel() < 2 ? 2 : a.numel());
    436            d(0) = d(1) = 1;
    437            for (int k=0;k<a.numel();k++) {
    438               d.elem(k) = a(k);
    439            }
    440            return d;
    441         } else {
    442           return dim_vector(1,1);
    443         }
    444       } else {
    445         return dim_vector(1,1);
    446       }
    447     }
    448 
    449     octave_value as_value() {
    450       ++count;
    451       return Swig::swig_value_ref(this);
    452     }
    453 
    454     void incref() {
    455       ++count;
    456     }
    457 
    458     void decref() {
    459       if (!--count)
    460 	delete this;
    461     }
    462 
    463     long swig_this() const {
    464       if (!types.size())
    465 	return (long) this;
    466       return (long) types[0].second.ptr;
    467     }
    468     const char* help_text() const {
    469       if (!types.size())
    470 	return 0;
    471       if (!types[0].first->clientdata)
    472 	return 0;
    473       swig_octave_class *c = (swig_octave_class *) types[0].first->clientdata;
    474       return c->constructor_doc;
    475     }
    476 
    477     std::string swig_type_name() const {
    478       // * need some way to manually name subclasses.
    479       // * eg optional first arg to subclass(), or named_subclass()
    480       std::string ret;
    481       for (unsigned int j = 0; j < types.size(); ++j) {
    482 	if (j)
    483 	  ret += "_";
    484 	if (types[j].first->clientdata) {
    485 	  swig_octave_class *c = (swig_octave_class *) types[j].first->clientdata;
    486 	  ret += c->name;
    487 	} else
    488 	  ret += types[j].first->name;
    489       }
    490       return ret;
    491     }
    492 
    493     void merge(octave_swig_type &rhs) {
    494       rhs.own = 0;
    495       for (unsigned int j = 0; j < rhs.types.size(); ++j) {
    496 	assert(!rhs.types[j].second.destroyed);
    497 #ifdef SWIG_DIRECTORS
    498 	Swig::Director *d = Swig::get_rtdir(rhs.types[j].second.ptr);
    499 	if (d)
    500 	  Swig::swig_director_set_self(d, this);
    501 #endif
    502       }
    503       types.insert(types.end(), rhs.types.begin(), rhs.types.end());
    504       members.insert(rhs.members.begin(), rhs.members.end());
    505       rhs.types.clear();
    506       rhs.members.clear();
    507     }
    508 
    509     typedef member_map::const_iterator swig_member_const_iterator;
    510     swig_member_const_iterator swig_members_begin() { return members.begin(); }
    511     swig_member_const_iterator swig_members_end() { return members.end(); }
    512 
    513     void *cast(swig_type_info *type, int *_own, int flags) {
    514       if (_own)
    515 	*_own = own;
    516       if (flags &SWIG_POINTER_DISOWN)
    517 	own = 0;
    518       if (!type && types.size())
    519 	return types[0].second.ptr;
    520       for (unsigned int j = 0; j < types.size(); ++j)
    521 	if (type == types[j].first)
    522 	  return types[j].second.ptr;
    523       for (unsigned int j = 0; j < types.size(); ++j) {
    524 	swig_cast_info *tc = SWIG_TypeCheck(types[j].first->name, type);
    525 	if (!tc)
    526 	  continue;
    527 	int newmemory = 0;
    528 	void *vptr = SWIG_TypeCast(tc, types[j].second.ptr, &newmemory);
    529 	assert(!newmemory);	// newmemory handling not yet implemented
    530 	return vptr;
    531       }
    532       return 0;
    533     }
    534 
    535     bool is_owned() const {
    536       return own;
    537     }
    538 
    539 #ifdef SWIG_DIRECTORS
    540     void director_destroyed(Swig::Director *d) {
    541       bool found = false;
    542       for (unsigned int j = 0; j < types.size(); ++j) {
    543 	Swig::Director *dj = Swig::get_rtdir(types[j].second.ptr);
    544 	if (dj == d) {
    545 	  types[j].second.destroyed = true;
    546 	  found = true;
    547 	}
    548       }
    549       assert(found);
    550     }
    551 #endif
    552 
    553     void assign(const std::string &name, const octave_value &ov) {
    554       members[name] = std::make_pair((const swig_octave_member *) 0, ov);
    555     }
    556 
    557     void assign(const std::string &name, const swig_octave_member *m) {
    558       members[name] = std::make_pair(m, octave_value());
    559     }
    560 
    561     octave_base_value *clone() const {
    562       // pass-by-value is probably not desired, and is harder;
    563       // requires calling copy constructors of contained types etc.
    564       assert(0);
    565       *(int *) 0 = 0;
    566       return 0;
    567     }
    568 
    569     octave_base_value *empty_clone() const {
    570       return new octave_swig_type();
    571     }
    572 
    573     bool is_defined() const {
    574       return true;
    575     }
    576 
    577     virtual bool is_map() const {
    578       return true;
    579     }
    580 
    581     virtual octave_value subsref(const std::string &ops, const std::list < octave_value_list > &idx) {
    582       octave_value_list ovl = subsref(ops, idx, 1);
    583       return ovl.length()? ovl(0) : octave_value();
    584     }
    585 
    586     virtual octave_value_list subsref(const std::string &ops, const std::list < octave_value_list > &idx, int nargout) {
    587       assert(ops.size() > 0);
    588       assert(ops.size() == idx.size());
    589 
    590       std::list < octave_value_list >::const_iterator idx_it = idx.begin();
    591       int skip = 0;
    592       octave_value_list sub_ovl;
    593 
    594       // constructor invocation
    595       if (ops[skip] == '(' && construct_type) {
    596 	assert(construct_type->clientdata);
    597 	swig_octave_class *c = (swig_octave_class *) construct_type->clientdata;
    598 	if (!c->constructor) {
    599 	  error("cannot create instance");
    600 	  return octave_value_list();
    601 	}
    602 	octave_value_list args;
    603 	if (c->director)
    604 	  args.append(Swig::swig_value_ref(new octave_swig_type(this, 0, 0)));
    605 	args.append(*idx_it++);
    606 	++skip;
    607 	sub_ovl = c->constructor(args, nargout);
    608       }
    609       // member dereference or invocation
    610       else if (ops[skip] == '.') {
    611 	std::string subname;
    612 	const swig_type_info *base = 0;	// eg, a.base.base_cpp_mem
    613 	for (;;) {
    614 	  octave_value_list subname_ovl(*idx_it++);
    615 	  ++skip;
    616 	  assert(subname_ovl.length() == 1 && subname_ovl(0).is_string());
    617 	  subname = subname_ovl(0).string_value();
    618 
    619 	  const swig_type_info *next_base = find_base(subname, base);
    620 	  if (!next_base || skip >= (int) ops.size() || ops[skip] != '.')
    621 	    break;
    622 	  base = next_base;
    623 	}
    624 
    625 	member_value_pair tmp, *m = &tmp;
    626 	if (!base || !(m->first = find_member(base, subname)))
    627 	  m = find_member(subname, false);
    628 	if (!m) {
    629 	  error("member not found");
    630 	  return octave_value_list();
    631 	}
    632 
    633 	octave_value_list args;
    634 	if (!always_static &&
    635 	    (!m->first || (!m->first->is_static() && !m->first->is_global())))
    636 	  args.append(as_value());
    637 	if (skip < (int) ops.size() && ops[skip] == '(' && 
    638 	    ((m->first && m->first->method) || m->second.is_function() || 
    639 	     m->second.is_function_handle())) {
    640 	  args.append(*idx_it++);
    641 	  ++skip;
    642 	  sub_ovl = member_invoke(m, args, nargout);
    643 	} else {
    644 	  sub_ovl = member_deref(m, args);
    645 	}
    646       }
    647       // index operator
    648       else {
    649 	if (ops[skip] == '(' || ops[skip] == '{') {
    650 	  const char *op_name = ops[skip] == '(' ? "__paren__" : "__brace__";
    651 	  octave_value_list args;
    652 	  args.append(*idx_it++);
    653 	  ++skip;
    654 	  if (!dispatch_index_op(op_name, args, sub_ovl)) {
    655 	    error("error evaluating index operator");
    656 	    return octave_value_list();
    657 	  }
    658 	} else {
    659 	  error("unsupported subsref");
    660 	  return octave_value_list();
    661 	}
    662       }
    663 
    664       if (skip >= (int) ops.size())
    665 	return sub_ovl;
    666       if (sub_ovl.length() < 1) {
    667 	error("bad subs ref");
    668 	return octave_value_list();
    669       }
    670       return sub_ovl(0).next_subsref(nargout, ops, idx, skip);
    671     }
    672 
    673     octave_value subsasgn(const std::string &ops, const std::list < octave_value_list > &idx, const octave_value &rhs) {
    674       assert(ops.size() > 0);
    675       assert(ops.size() == idx.size());
    676 
    677       std::list < octave_value_list >::const_iterator idx_it = idx.begin();
    678       int skip = 0;
    679 
    680       if (ops.size() > 1) {
    681 	std::list < octave_value_list >::const_iterator last = idx.end();
    682 	--last;
    683 	std::list < octave_value_list > next_idx(idx.begin(), last);
    684 	octave_value next_ov = subsref(ops.substr(0, ops.size() - 1), next_idx);
    685 	next_ov.subsasgn(ops.substr(ops.size() - 1), std::list < octave_value_list > (1, *last), rhs);
    686       }
    687 
    688       else if (ops[skip] == '(' || ops[skip] == '{') {
    689 	const char *op_name = ops[skip] == '(' ? "__paren_asgn__" : "__brace_asgn__";
    690 	member_value_pair *m = find_member(op_name, false);
    691 	if (m) {
    692 	  octave_value_list args;
    693 	  args.append(as_value());
    694 	  args.append(*idx_it);
    695 	  args.append(rhs);
    696 	  member_invoke(m, args, 1);
    697 	} else
    698 	  error("%s member not found", op_name);
    699       }
    700 
    701       else if (ops[skip] == '.') {
    702 	octave_value_list subname_ovl(*idx_it++);
    703 	++skip;
    704 	assert(subname_ovl.length() == 1 &&subname_ovl(0).is_string());
    705 	std::string subname = subname_ovl(0).string_value();
    706 
    707 	member_value_pair *m = find_member(subname, true);
    708 	if (!m->first || !m->first->set_method) {
    709 	  m->first = 0;
    710 	  m->second = rhs;
    711 	} else if (m->first->set_method) {
    712 	  octave_value_list args;
    713 	  if (!m->first->is_static() && !m->first->is_global())
    714 	    args.append(as_value());
    715 	  args.append(rhs);
    716 	  m->first->set_method(args, 1);
    717 	} else
    718 	  error("member not assignable");
    719       } else
    720 	error("unsupported subsasgn");
    721 
    722       return as_value();
    723     }
    724 
    725     virtual bool is_object() const {
    726       return true;
    727     }
    728 
    729     virtual bool is_string() const {
    730       octave_swig_type *nc_this = const_cast < octave_swig_type *>(this);
    731       return !!nc_this->find_member("__str__", false);
    732     }
    733 
    734     virtual std::string string_value(bool force = false) const {
    735       octave_swig_type *nc_this = const_cast < octave_swig_type *>(this);
    736       member_value_pair *m = nc_this->find_member("__str__", false);
    737       if (!m) {
    738 	error("__str__ method not defined");
    739 	return std::string();
    740       }
    741       octave_value_list outarg = nc_this->member_invoke(m, octave_value_list(nc_this->as_value()), 1);
    742       if (outarg.length() < 1 || !outarg(0).is_string()) {
    743 	error("__str__ method did not return a string");
    744 	return std::string();
    745       }
    746       return outarg(0).string_value();
    747     }
    748 
    749 #if OCTAVE_API_VERSION_NUMBER >= 40
    750     virtual octave_map map_value() const {
    751       return octave_map();
    752     }
    753 #else
    754     virtual Octave_map map_value() const {
    755       return Octave_map();
    756     }
    757 #endif
    758 
    759     virtual string_vector map_keys() const {
    760       member_map tmp;
    761       load_members(tmp);
    762 
    763       string_vector keys(tmp.size());
    764       int k = 0;
    765       for (member_map::iterator it = tmp.begin(); it != tmp.end(); ++it)
    766 	keys(k++) = it->first;
    767 
    768       return keys;
    769     }
    770 
    771     virtual bool save_ascii (std::ostream& os) {
    772       return true;
    773     }
    774 
    775     virtual bool load_ascii (std::istream& is) {
    776       return true;
    777     }
    778 
    779     virtual bool save_binary (std::ostream& os, bool& save_as_floats) {
    780       return true;
    781     }
    782 
    783     virtual bool load_binary (std::istream& is, bool swap, 
    784 			      oct_mach_info::float_format fmt) {
    785       return true;
    786     }
    787 
    788 #if defined (HAVE_HDF5)
    789     virtual bool
    790       save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) {
    791       return true;
    792     }
    793 
    794     virtual bool
    795       load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug) {
    796       return true;
    797     }
    798 #endif
    799 
    800     virtual octave_value convert_to_str(bool pad = false, bool force = false, char type = '"') const {
    801       return string_value();
    802     }
    803 
    804     virtual octave_value convert_to_str_internal(bool pad, bool force, char type) const {
    805       return string_value();
    806     }
    807 
    808     static bool dispatch_global_op(const std::string &symbol, const octave_value_list &args, octave_value &ret) {
    809       // we assume that SWIG_op_prefix-prefixed functions are installed in global namespace
    810       // (rather than any module namespace).
    811 
    812       octave_function *fcn = is_valid_function(symbol, std::string(), false);
    813       if (!fcn)
    814 	return false;
    815       ret = fcn->do_multi_index_op(1, args)(0);
    816       return true;
    817     }
    818 
    819     static octave_value dispatch_unary_op(const octave_base_value &x, const char *op_name) {
    820       octave_swig_type *ost = Swig::swig_value_deref(x);
    821       assert(ost);
    822 
    823       octave_value ret;
    824       if (ost->dispatch_unary_op(std::string("__") + op_name + std::string("__"), ret))
    825 	return ret;
    826       std::string symbol = SWIG_op_prefix + ost->swig_type_name() + "_" + op_name;
    827       octave_value_list args;
    828       args.append(make_value_hack(x));
    829       if (dispatch_global_op(symbol, args, ret))
    830 	return ret;
    831 
    832       error("could not dispatch unary operator");
    833       return octave_value();
    834     }
    835 
    836     static octave_value dispatch_binary_op(const octave_base_value &lhs, const octave_base_value &rhs, const char *op_name) {
    837       octave_swig_type *lhs_ost = Swig::swig_value_deref(lhs);
    838       octave_swig_type *rhs_ost = Swig::swig_value_deref(rhs);
    839 
    840       octave_value ret;
    841       if (lhs_ost && lhs_ost->dispatch_binary_op(std::string("__") + op_name + std::string("__"), rhs, ret))
    842 	return ret;
    843       if (rhs_ost) {
    844         if (strlen(op_name) == 2  && (op_name[1] == 't' || op_name[1] == 'e')) {
    845           if (op_name[0] == 'l' && rhs_ost->dispatch_binary_op(std::string("__g") + op_name[1] + std::string("__"), lhs, ret))
    846             return ret;
    847           if (op_name[0] == 'g' && rhs_ost->dispatch_binary_op(std::string("__l") + op_name[1] + std::string("__"), lhs, ret))
    848             return ret;
    849         }
    850         if (rhs_ost->dispatch_binary_op(std::string("__r") + op_name + std::string("__"), lhs, ret))
    851           return ret;
    852       }
    853 
    854       std::string symbol;
    855       octave_value_list args;
    856       args.append(make_value_hack(lhs));
    857       args.append(make_value_hack(rhs));
    858 
    859       symbol = SWIG_op_prefix;
    860       symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name();
    861       symbol += "_";
    862       symbol += op_name;
    863       symbol += "_";
    864       symbol += rhs_ost ? rhs_ost->swig_type_name() : rhs.type_name();
    865       if (dispatch_global_op(symbol, args, ret))
    866 	return ret;
    867 
    868       symbol = SWIG_op_prefix;
    869       symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name();
    870       symbol += "_";
    871       symbol += op_name;
    872       symbol += "_";
    873       symbol += "any";
    874       if (dispatch_global_op(symbol, args, ret))
    875 	return ret;
    876 
    877       symbol = SWIG_op_prefix;
    878       symbol += "any";
    879       symbol += "_";
    880       symbol += op_name;
    881       symbol += "_";
    882       symbol += rhs_ost ? rhs_ost->swig_type_name() : rhs.type_name();
    883       if (dispatch_global_op(symbol, args, ret))
    884 	return ret;
    885 
    886       error("could not dispatch binary operator");
    887       return octave_value();
    888     }
    889 
    890     void print(std::ostream &os, bool pr_as_read_syntax = false) const {
    891       if (is_string()) {
    892 	os << string_value();
    893 	return;
    894       }
    895 
    896       member_map tmp;
    897       load_members(tmp);
    898 
    899       indent(os);
    900       os << "{"; newline(os);
    901       increment_indent_level();
    902       for (unsigned int j = 0; j < types.size(); ++j) {
    903         indent(os);
    904 	if (types[j].first->clientdata) {
    905 	  const swig_octave_class *c = (const swig_octave_class *) types[j].first->clientdata;
    906 	  os << c->name << ", ptr = " << types[j].second.ptr; newline(os);
    907 	} else {
    908 	  os << types[j].first->name << ", ptr = " << types[j].second.ptr; newline(os);
    909 	}
    910       }
    911       for (member_map::const_iterator it = tmp.begin(); it != tmp.end(); ++it) {
    912         indent(os);
    913 	if (it->second.first) {
    914 	  const char *objtype = it->second.first->method ? "method" : "variable";
    915 	  const char *modifier = (it->second.first->flags &1) ? "static " : (it->second.first->flags &2) ? "global " : "";
    916 	  os << it->second.first->name << " (" << modifier << objtype << ")"; newline(os);
    917 	  assert(it->second.first->name == it->first);
    918 	} else {
    919 	  os << it->first; newline(os);
    920 	}
    921       }
    922       decrement_indent_level();
    923       indent(os);
    924       os << "}"; newline(os);
    925     }
    926   };
    927 
    928   // Octave tries hard to preserve pass-by-value semantics. Eg, assignments
    929   // will call clone() via make_unique() if there is more than one outstanding 
    930   // reference to the lhs, and forces the clone's reference count to 1 
    931   // (so you can't just increment your own count and return this).
    932   //
    933   // One way to fix this (without modifying Octave) is to add a level of
    934   // indirection such that clone copies ref-counted pointer and we keep 
    935   // pass-by-ref semantics (which are more natural/expected for C++ bindings).
    936   //
    937   // Supporting both pass-by-{ref,value} and toggling via %feature/option 
    938   // might be nice.
    939 
    940   class octave_swig_ref:public octave_base_value {
    941     octave_swig_type *ptr;
    942   public:
    943     octave_swig_ref(octave_swig_type *_ptr = 0)
    944       :ptr(_ptr) { }
    945 
    946     ~octave_swig_ref()
    947       { if (ptr) ptr->decref(); }
    948 
    949     octave_swig_type *get_ptr() const
    950       { return ptr; }
    951 
    952     octave_base_value *clone() const
    953       { if (ptr) ptr->incref(); return new octave_swig_ref(ptr); }
    954 
    955     octave_base_value *empty_clone() const
    956       { return new octave_swig_ref(0); }
    957 
    958     dim_vector dims(void) const 
    959       { return ptr->dims(); }
    960 
    961     bool is_defined() const
    962       { return ptr->is_defined(); }
    963 
    964     virtual bool is_map() const 
    965       { return ptr->is_map(); }
    966 
    967     virtual octave_value subsref(const std::string &ops, const std::list < octave_value_list > &idx) 
    968       { return ptr->subsref(ops, idx); }
    969 
    970     virtual octave_value_list subsref(const std::string &ops, const std::list < octave_value_list > &idx, int nargout)
    971       { return ptr->subsref(ops, idx, nargout); }
    972 
    973     octave_value subsasgn(const std::string &ops, const std::list < octave_value_list > &idx, const octave_value &rhs)
    974       { return ptr->subsasgn(ops, idx, rhs); }
    975 
    976     virtual bool is_object() const 
    977       { return ptr->is_object(); }
    978 
    979     virtual bool is_string() const 
    980       { return ptr->is_string(); }
    981 
    982     virtual std::string string_value(bool force = false) const 
    983       { return ptr->string_value(force); }
    984 
    985 #if OCTAVE_API_VERSION_NUMBER >= 40
    986     virtual octave_map map_value() const
    987       { return ptr->map_value(); }
    988 #else
    989     virtual Octave_map map_value() const
    990       { return ptr->map_value(); }
    991 #endif
    992 
    993     virtual string_vector map_keys() const
    994       { return ptr->map_keys(); }
    995 
    996     virtual bool save_ascii (std::ostream& os)
    997       { return ptr->save_ascii(os); }
    998 
    999     virtual bool load_ascii (std::istream& is)
   1000       { return ptr->load_ascii(is); }
   1001 
   1002     virtual bool save_binary (std::ostream& os, bool& save_as_floats)
   1003       { return ptr->save_binary(os, save_as_floats); }
   1004 
   1005     virtual bool load_binary (std::istream& is, bool swap, 
   1006 			      oct_mach_info::float_format fmt)
   1007       { return ptr->load_binary(is, swap, fmt); }
   1008 
   1009 #if defined (HAVE_HDF5)
   1010     virtual bool
   1011       save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
   1012       { return ptr->save_hdf5(loc_id, name, save_as_floats); }
   1013 
   1014     virtual bool
   1015       load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug)
   1016       { return ptr->load_hdf5(loc_id, name, have_h5giterate_bug); }
   1017 #endif
   1018 
   1019     virtual octave_value convert_to_str(bool pad = false, bool force = false, char type = '"') const
   1020       { return ptr->convert_to_str(pad, force, type); }
   1021 
   1022     virtual octave_value convert_to_str_internal(bool pad, bool force, char type) const
   1023       { return ptr->convert_to_str_internal(pad, force, type); }
   1024 
   1025     void print(std::ostream &os, bool pr_as_read_syntax = false) const
   1026       { return ptr->print(os, pr_as_read_syntax); }
   1027 
   1028   private:
   1029     DECLARE_OCTAVE_ALLOCATOR;
   1030     DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA;
   1031   };
   1032   DEFINE_OCTAVE_ALLOCATOR(octave_swig_ref);
   1033   DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_ref, "swig_ref", "swig_ref");
   1034 
   1035   class octave_swig_packed:public octave_base_value {
   1036     swig_type_info *type;
   1037     std::vector < char > buf;
   1038   public:
   1039 
   1040     octave_swig_packed(swig_type_info *_type = 0, const void *_buf = 0, size_t _buf_len = 0)
   1041       :	type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) {
   1042     }
   1043 
   1044     bool copy(swig_type_info *outtype, void *ptr, size_t sz) const {
   1045       if (outtype && outtype != type)
   1046 	return false;
   1047       assert(sz <= buf.size());
   1048       std::copy(buf.begin(), buf.begin()+sz, (char*)ptr);
   1049       return true;
   1050     }
   1051 
   1052     octave_base_value *clone() const {
   1053       return new octave_swig_packed(*this);
   1054     }
   1055 
   1056     octave_base_value *empty_clone() const {
   1057       return new octave_swig_packed();
   1058     }
   1059 
   1060     bool is_defined() const {
   1061       return true;
   1062     }
   1063 
   1064     void print(std::ostream &os, bool pr_as_read_syntax = false) const {
   1065       indent(os);
   1066       os << "swig packed type: name = " << (type ? type->name : std::string()) << ", len = " << buf.size(); newline(os);
   1067     }
   1068 
   1069 
   1070     virtual bool save_ascii (std::ostream& os) {
   1071       return true;
   1072     }
   1073 
   1074     virtual bool load_ascii (std::istream& is) {
   1075       return true;
   1076     }
   1077 
   1078     virtual bool save_binary (std::ostream& os, bool& save_as_floats) {
   1079       return true;
   1080     }
   1081 
   1082     virtual bool load_binary (std::istream& is, bool swap, 
   1083 			      oct_mach_info::float_format fmt) {
   1084       return true;
   1085     }
   1086 
   1087 #if defined (HAVE_HDF5)
   1088     virtual bool
   1089       save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) {
   1090       return true;
   1091     }
   1092 
   1093     virtual bool
   1094       load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug) {
   1095       return true;
   1096     }
   1097 #endif
   1098 
   1099   private:
   1100     DECLARE_OCTAVE_ALLOCATOR;
   1101     DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA;
   1102   };
   1103   DEFINE_OCTAVE_ALLOCATOR(octave_swig_packed);
   1104   DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_packed, "swig_packed", "swig_packed");
   1105 
   1106   static octave_value_list octave_set_immutable(const octave_value_list &args, int nargout) {
   1107     error("attempt to set immutable member variable");
   1108     return octave_value_list();
   1109   }
   1110 
   1111   struct octave_value_ref {
   1112     const octave_value_list &ovl;
   1113     int j;
   1114 
   1115     octave_value_ref(const octave_value_list &_ovl, int _j)
   1116       :ovl(_ovl), j(_j) { }
   1117 
   1118     operator  octave_value() const {
   1119       return ovl(j);
   1120     }
   1121 
   1122     octave_value operator*() const {
   1123       return ovl(j);
   1124     }
   1125   };
   1126 
   1127 
   1128 namespace Swig {
   1129 
   1130   SWIGRUNTIME octave_base_value *swig_value_ref(octave_swig_type *ost) {
   1131     return new octave_swig_ref(ost);
   1132   }
   1133 
   1134   SWIGRUNTIME octave_swig_type *swig_value_deref(octave_value ov) {
   1135     if (ov.is_cell() && ov.rows() == 1 && ov.columns() == 1)
   1136       ov = ov.cell_value()(0);
   1137     return swig_value_deref(*ov.internal_rep());
   1138   }
   1139 
   1140   SWIGRUNTIME octave_swig_type *swig_value_deref(const octave_base_value &ov) {
   1141     if (ov.type_id() != octave_swig_ref::static_type_id())
   1142       return 0;
   1143     const octave_swig_ref *osr = static_cast < const octave_swig_ref *>(&ov);
   1144     return osr->get_ptr();
   1145   }
   1146 
   1147 }
   1148 
   1149 
   1150 #define swig_unary_op(name) \
   1151 SWIGRUNTIME octave_value swig_unary_op_##name(const octave_base_value &x) { \
   1152   return octave_swig_type::dispatch_unary_op(x,#name); \
   1153 }
   1154 #define swig_binary_op(name) \
   1155 SWIGRUNTIME octave_value swig_binary_op_##name(const octave_base_value&lhs,const octave_base_value &rhs) { \
   1156   return octave_swig_type::dispatch_binary_op(lhs,rhs,#name); \
   1157 }
   1158 #define swigreg_unary_op(name) \
   1159 if (!octave_value_typeinfo::lookup_unary_op(octave_value::op_##name,tid)) \
   1160 octave_value_typeinfo::register_unary_op(octave_value::op_##name,tid,swig_unary_op_##name);
   1161 #define swigreg_binary_op(name) \
   1162 if (!octave_value_typeinfo::lookup_binary_op(octave_value::op_##name,tid1,tid2)) \
   1163 octave_value_typeinfo::register_binary_op(octave_value::op_##name,tid1,tid2,swig_binary_op_##name);
   1164 
   1165   swig_unary_op(not);
   1166   swig_unary_op(uplus);
   1167   swig_unary_op(uminus);
   1168   swig_unary_op(transpose);
   1169   swig_unary_op(hermitian);
   1170   swig_unary_op(incr);
   1171   swig_unary_op(decr);
   1172 
   1173   swig_binary_op(add);
   1174   swig_binary_op(sub);
   1175   swig_binary_op(mul);
   1176   swig_binary_op(div);
   1177   swig_binary_op(pow);
   1178   swig_binary_op(ldiv);
   1179   swig_binary_op(lshift);
   1180   swig_binary_op(rshift);
   1181   swig_binary_op(lt);
   1182   swig_binary_op(le);
   1183   swig_binary_op(eq);
   1184   swig_binary_op(ge);
   1185   swig_binary_op(gt);
   1186   swig_binary_op(ne);
   1187   swig_binary_op(el_mul);
   1188   swig_binary_op(el_div);
   1189   swig_binary_op(el_pow);
   1190   swig_binary_op(el_ldiv);
   1191   swig_binary_op(el_and);
   1192   swig_binary_op(el_or);
   1193 
   1194   SWIGRUNTIME void SWIG_InstallUnaryOps(int tid) {
   1195     swigreg_unary_op(not);
   1196     swigreg_unary_op(uplus);
   1197     swigreg_unary_op(uminus);
   1198     swigreg_unary_op(transpose);
   1199     swigreg_unary_op(hermitian);
   1200     swigreg_unary_op(incr);
   1201     swigreg_unary_op(decr);
   1202   }
   1203   SWIGRUNTIME void SWIG_InstallBinaryOps(int tid1, int tid2) {
   1204     swigreg_binary_op(add);
   1205     swigreg_binary_op(sub);
   1206     swigreg_binary_op(mul);
   1207     swigreg_binary_op(div);
   1208     swigreg_binary_op(pow);
   1209     swigreg_binary_op(ldiv);
   1210     swigreg_binary_op(lshift);
   1211     swigreg_binary_op(rshift);
   1212     swigreg_binary_op(lt);
   1213     swigreg_binary_op(le);
   1214     swigreg_binary_op(eq);
   1215     swigreg_binary_op(ge);
   1216     swigreg_binary_op(gt);
   1217     swigreg_binary_op(ne);
   1218     swigreg_binary_op(el_mul);
   1219     swigreg_binary_op(el_div);
   1220     swigreg_binary_op(el_pow);
   1221     swigreg_binary_op(el_ldiv);
   1222     swigreg_binary_op(el_and);
   1223     swigreg_binary_op(el_or);
   1224   }
   1225   SWIGRUNTIME void SWIG_InstallOps(int tid) {
   1226     // here we assume that tid are conseq integers increasing from zero, and 
   1227     // that our tid is the last one. might be better to have explicit string 
   1228     // list of types we should bind to, and use lookup_type to resolve their tid.
   1229 
   1230     SWIG_InstallUnaryOps(tid);
   1231     SWIG_InstallBinaryOps(tid, tid);
   1232     for (int j = 0; j < tid; ++j) {
   1233       SWIG_InstallBinaryOps(j, tid);
   1234       SWIG_InstallBinaryOps(tid, j);
   1235     }
   1236   }
   1237 
   1238 SWIGRUNTIME octave_value SWIG_Octave_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
   1239   int own = (flags &SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
   1240 
   1241 #ifdef SWIG_DIRECTORS
   1242   Swig::Director *d = Swig::get_rtdir(ptr);
   1243   if (d && Swig::swig_director_get_self(d))
   1244     return Swig::swig_director_get_self(d)->as_value();
   1245 #endif
   1246   return Swig::swig_value_ref(new octave_swig_type(ptr, type, own));
   1247 }
   1248 
   1249 SWIGRUNTIME int SWIG_Octave_ConvertPtrAndOwn(octave_value ov, void **ptr, swig_type_info *type, int flags, int *own) {
   1250   if (ov.is_cell() && ov.rows() == 1 && ov.columns() == 1)
   1251     ov = ov.cell_value()(0);
   1252   if (!ov.is_defined() ||
   1253       (ov.is_matrix_type() && ov.rows() == 0 && ov.columns() == 0) ) {
   1254     if (ptr)
   1255       *ptr = 0;
   1256     return SWIG_OK;
   1257   }
   1258   if (ov.type_id() != octave_swig_ref::static_type_id())
   1259     return SWIG_ERROR;
   1260   octave_swig_ref *osr = static_cast < octave_swig_ref *>(ov.internal_rep());
   1261   octave_swig_type *ost = osr->get_ptr();
   1262   void *vptr = ost->cast(type, own, flags);
   1263   if (!vptr)
   1264     return SWIG_ERROR;
   1265   if (ptr)
   1266     *ptr = vptr;
   1267   return SWIG_OK;
   1268 }
   1269 
   1270 SWIGRUNTIME octave_value SWIG_Octave_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
   1271   return new octave_swig_packed(type, (char *) ptr, sz);
   1272 }
   1273 
   1274 SWIGRUNTIME int SWIG_Octave_ConvertPacked(const octave_value &ov, void *ptr, size_t sz, swig_type_info *type) {
   1275   if (!ov.is_defined())
   1276     return SWIG_ERROR;
   1277   if (ov.type_id() != octave_swig_packed::static_type_id())
   1278     return SWIG_ERROR;
   1279   octave_swig_packed *ost = static_cast < octave_swig_packed *>(ov.internal_rep());
   1280   return ost->copy(type, (char *) ptr, sz) ? SWIG_OK : SWIG_ERROR;
   1281 }
   1282 
   1283 SWIGRUNTIMEINLINE void SWIG_Octave_SetConstant(octave_swig_type *module_ns, const std::string &name, const octave_value &ov) {
   1284   module_ns->assign(name, ov);
   1285 }
   1286 
   1287 SWIGRUNTIMEINLINE octave_value SWIG_Octave_GetGlobalValue(std::string name) {
   1288   return get_global_value(name, true);
   1289 }
   1290 
   1291 SWIGRUNTIME void SWIG_Octave_SetGlobalValue(std::string name, const octave_value& value) {
   1292   set_global_value(name, value);
   1293 }
   1294 
   1295 SWIGRUNTIME void SWIG_Octave_LinkGlobalValue(std::string name) {
   1296 #if OCTAVE_API_VERSION_NUMBER < 37
   1297   link_to_global_variable(curr_sym_tab->lookup(name, true));
   1298 #else
   1299   symbol_table::varref(name);
   1300   symbol_table::mark_global(name);
   1301 #endif
   1302 }
   1303 
   1304 SWIGRUNTIME swig_module_info *SWIG_Octave_GetModule(void *clientdata) {
   1305   octave_value ov = SWIG_Octave_GetGlobalValue("__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION);
   1306   if (!ov.is_defined() ||
   1307       ov.type_id() != octave_swig_packed::static_type_id())
   1308     return 0;
   1309   const octave_swig_packed* osp = 
   1310     static_cast < const octave_swig_packed *> (ov.internal_rep());
   1311   swig_module_info *pointer = 0;
   1312   osp->copy(0, &pointer, sizeof(swig_module_info *));
   1313   return pointer;
   1314 }
   1315 
   1316 SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *pointer) {
   1317   octave_value ov = new octave_swig_packed(0, &pointer, sizeof(swig_module_info *));
   1318   SWIG_Octave_SetGlobalValue("__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION, ov);
   1319 }
   1320