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