GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-typeinfo.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <iostream>
31 
32 #include "Array.h"
33 
34 #include "defun.h"
35 #include "error.h"
36 #include "interpreter.h"
37 #include "interpreter-private.h"
38 #include "ops.h"
39 #include "ov-typeinfo.h"
40 #include "ov.h"
41 
42 namespace octave
43 {
44  // FIXME: we should also store all class names and provide a
45  // way to list them (calling class with nargin == 0?).
46 
47  static NDArray as_nd_array (const Array<int>& x)
48  {
49  NDArray retval (x.dims ());
50 
51  for (int i = 0; i < x.numel (); i++)
52  retval.xelem(i) = x(i);
53 
54  return retval;
55  }
56 
58  {
59  boolNDArray retval (x.dims ());
60 
61  for (octave_idx_type i = 0; i < x.numel (); i++)
62  retval.xelem (i) = x(i);
63 
64  return retval;
65  }
66 
67  type_info::type_info (int init_tab_sz)
68  : num_types (0), types (dim_vector (init_tab_sz, 1), ""),
69  vals (dim_vector (init_tab_sz, 1)),
70  unary_class_ops (dim_vector (octave_value::num_unary_ops, 1), nullptr),
71  unary_ops (dim_vector (octave_value::num_unary_ops, init_tab_sz), nullptr),
72  non_const_unary_ops (dim_vector (octave_value::num_unary_ops, init_tab_sz), nullptr),
73  binary_class_ops (dim_vector (octave_value::num_binary_ops, 1), nullptr),
74  binary_ops (dim_vector (octave_value::num_binary_ops, init_tab_sz, init_tab_sz), nullptr),
75  compound_binary_class_ops (dim_vector (octave_value::num_compound_binary_ops, 1), nullptr),
76  compound_binary_ops (dim_vector (octave_value::num_compound_binary_ops, init_tab_sz, init_tab_sz), nullptr),
77  cat_ops (dim_vector (init_tab_sz, init_tab_sz), nullptr),
78  assign_ops (dim_vector (octave_value::num_assign_ops, init_tab_sz, init_tab_sz), nullptr),
79  assignany_ops (dim_vector (octave_value::num_assign_ops, init_tab_sz), nullptr),
80  pref_assign_conv (dim_vector (init_tab_sz, init_tab_sz), -1),
81  widening_ops (dim_vector (init_tab_sz, init_tab_sz), nullptr)
82  {
83  install_types (*this);
84 
85  install_ops (*this);
86  }
87 
88  int type_info::register_type (const std::string& t_name,
89  const std::string& /* c_name */,
90  const octave_value& val,
91  bool abort_on_duplicate)
92  {
93  int i = 0;
94 
95  for (i = 0; i < num_types; i++)
96  {
97  if (t_name == types (i))
98  {
99  if (abort_on_duplicate)
100  {
101  std::cerr << "duplicate type " << t_name << std::endl;
102  abort ();
103  }
104 
105  warning ("duplicate type %s\n", t_name.c_str ());
106 
107  return i;
108  }
109  }
110 
111  int len = types.numel ();
112 
113  if (i == len)
114  {
115  len *= 2;
116 
117  types.resize (dim_vector (len, 1), "");
118 
119  vals.resize (dim_vector (len, 1), nullptr);
120 
123 
126 
129 
132  nullptr);
133 
134  cat_ops.resize (dim_vector (len, len), nullptr);
135 
138 
141 
143 
144  widening_ops.resize (dim_vector (len, len), nullptr);
145  }
146 
147  types (i) = t_name;
148 
149  // Yes, this object is intentionally not deleted in the destructor
150  // so that we avoid a crash on exit for user-defined data types.
151  // See bug #53156. If that problem is properly fixed, then this
152  // could be stored as an object instead of a pointer to an object
153  // allocated with new.
154 
155  vals(i) = new octave_value (val);
156 
157  num_types++;
158 
159  return i;
160  }
161 
164  bool abort_on_duplicate)
165  {
166  if (lookup_unary_class_op (op))
167  {
168  std::string op_name = octave_value::unary_op_as_string (op);
169 
170  if (abort_on_duplicate)
171  {
172  std::cerr << "duplicate unary operator '" << op_name
173  << "' for class dispatch" << std::endl;
174  abort ();
175  }
176 
177  warning ("duplicate unary operator '%s' for class dispatch",
178  op_name.c_str ());
179  }
180 
181  unary_class_ops.checkelem (static_cast<int> (op))
182  = reinterpret_cast<void *> (f);
183 
184  return false;
185  }
186 
188  unary_op_fcn f, bool abort_on_duplicate)
189  {
190  if (lookup_unary_op (op, t))
191  {
192  std::string op_name = octave_value::unary_op_as_string (op);
193  std::string type_name = types(t);
194 
195  if (abort_on_duplicate)
196  {
197  std::cerr << "duplicate unary operator '" << op_name
198  << "' for type '" << type_name << "'" << std::endl;
199  abort ();
200  }
201 
202  warning ("duplicate unary operator '%s' for type '%s'",
203  op_name.c_str (), type_name.c_str ());
204  }
205 
206  unary_ops.checkelem (static_cast<int> (op), t) = reinterpret_cast<void *> (f);
207 
208  return false;
209  }
210 
211  bool
214  bool abort_on_duplicate)
215  {
216  if (lookup_non_const_unary_op (op, t))
217  {
218  std::string op_name = octave_value::unary_op_as_string (op);
219  std::string type_name = types(t);
220 
221  if (abort_on_duplicate)
222  {
223  std::cerr << "duplicate unary operator '" << op_name
224  << "' for type '" << type_name << "'" << std::endl;
225  abort ();
226  }
227 
228  warning ("duplicate unary operator '%s' for type '%s'",
229  op_name.c_str (), type_name.c_str ());
230  }
231 
232  non_const_unary_ops.checkelem (static_cast<int> (op), t)
233  = reinterpret_cast<void *> (f);
234 
235  return false;
236  }
237 
238  bool
241  bool abort_on_duplicate)
242  {
243  if (lookup_binary_class_op (op))
244  {
245  std::string op_name = octave_value::binary_op_as_string (op);
246 
247  if (abort_on_duplicate)
248  {
249 
250  std::cerr << "duplicate binary operator '" << op_name
251  << "' for class dispatch" << std::endl;
252  abort ();
253  }
254 
255  warning ("duplicate binary operator '%s' for class dispatch",
256  op_name.c_str ());
257  }
258 
259  binary_class_ops.checkelem (static_cast<int> (op))
260  = reinterpret_cast<void *> (f);
261 
262  return false;
263  }
264 
266  int t1, int t2,
268  bool abort_on_duplicate)
269  {
270  if (lookup_binary_op (op, t1, t2))
271  {
272  std::string op_name = octave_value::binary_op_as_string (op);
273  std::string t1_name = types(t1);
274  std::string t2_name = types(t2);
275 
276  if (abort_on_duplicate)
277  {
278  std::cerr << "duplicate binary operator '" << op_name
279  << "' for types '" << t1_name << "' and '"
280  << t2_name << "'" << std::endl;
281  abort ();
282  }
283 
284  warning ("duplicate binary operator '%s' for types '%s' and '%s'",
285  op_name.c_str (), t1_name.c_str (), t1_name.c_str ());
286  }
287 
288  binary_ops.checkelem (static_cast<int> (op), t1, t2)
289  = reinterpret_cast<void *> (f);
290 
291  return false;
292  }
293 
294  bool
297  bool abort_on_duplicate)
298  {
299  if (lookup_binary_class_op (op))
300  {
301  std::string op_name = octave_value::binary_op_fcn_name (op);
302 
303  if (abort_on_duplicate)
304  {
305  std::cerr << "duplicate compound binary operator '"
306  << op_name << "' for class dispatch" << std::endl;
307  abort ();
308  }
309 
310  warning ("duplicate compound binary operator '%s' for class dispatch",
311  op_name.c_str ());
312  }
313 
314  compound_binary_class_ops.checkelem (static_cast<int> (op))
315  = reinterpret_cast<void *> (f);
316 
317  return false;
318  }
319 
321  int t1, int t2,
323  bool abort_on_duplicate)
324  {
325  if (lookup_binary_op (op, t1, t2))
326  {
327  std::string op_name = octave_value::binary_op_fcn_name (op);
328  std::string t1_name = types(t1);
329  std::string t2_name = types(t2);
330 
331  if (abort_on_duplicate)
332  {
333  std::cerr << "duplicate compound binary operator '"
334  << op_name << "' for types '" << t1_name
335  << "' and '" << t2_name << "'" << std::endl;
336  abort ();
337  }
338 
339  warning ("duplicate compound binary operator '%s' for types '%s' and '%s'",
340  op_name.c_str (), t1_name.c_str (), t1_name.c_str ());
341  }
342 
343  compound_binary_ops.checkelem (static_cast<int> (op), t1, t2)
344  = reinterpret_cast<void *> (f);
345 
346  return false;
347  }
348 
350  bool abort_on_duplicate)
351  {
352  if (lookup_cat_op (t1, t2))
353  {
354  std::string t1_name = types(t1);
355  std::string t2_name = types(t2);
356 
357  if (abort_on_duplicate)
358  {
359  std::cerr << "duplicate concatenation operator for types '"
360  << t1_name << "' and '" << t2_name << "'" << std::endl;
361  abort ();
362  }
363 
364  warning ("duplicate concatenation operator for types '%s' and '%s'",
365  t1_name.c_str (), t1_name.c_str ());
366  }
367 
368  cat_ops.checkelem (t1, t2) = reinterpret_cast<void *> (f);
369 
370  return false;
371  }
372 
374  int t_lhs, int t_rhs,
376  bool abort_on_duplicate)
377  {
378  if (lookup_assign_op (op, t_lhs, t_rhs))
379  {
380  std::string op_name = octave_value::assign_op_as_string (op);
381  std::string t_lhs_name = types(t_lhs);
382  std::string t_rhs_name = types(t_rhs);
383 
384  if (abort_on_duplicate)
385  {
386  std::cerr << "duplicate assignment operator '"
387  << op_name << "' for types '" << t_lhs_name
388  << "' and '" << t_rhs_name << "'" << std::endl;
389  abort ();
390  }
391 
392  warning ("duplicate assignment operator '%s' for types '%s' and '%s'",
393  op_name.c_str (), t_lhs_name.c_str (), t_rhs_name.c_str ());
394  }
395 
396  assign_ops.checkelem (static_cast<int> (op), t_lhs, t_rhs)
397  = reinterpret_cast<void *> (f);
398 
399  return false;
400  }
401 
404  bool abort_on_duplicate)
405  {
406  if (lookup_assignany_op (op, t_lhs))
407  {
408  std::string op_name = octave_value::assign_op_as_string (op);
409  std::string t_lhs_name = types(t_lhs);
410 
411  if (abort_on_duplicate)
412  {
413  std::cerr << "duplicate assignment operator '" << op_name
414  << "' for types '" << t_lhs_name << "'" << std::endl;
415  abort ();
416  }
417 
418  warning ("duplicate assignment operator '%s' for types '%s'",
419  op_name.c_str (), t_lhs_name.c_str ());
420  }
421 
422  assignany_ops.checkelem (static_cast<int> (op), t_lhs)
423  = reinterpret_cast<void *> (f);
424 
425  return false;
426  }
427 
428  bool type_info::register_pref_assign_conv (int t_lhs, int t_rhs,
429  int t_result,
430  bool abort_on_duplicate)
431  {
432  if (lookup_pref_assign_conv (t_lhs, t_rhs) >= 0)
433  {
434  std::string t_lhs_name = types(t_lhs);
435  std::string t_rhs_name = types(t_rhs);
436 
437  if (abort_on_duplicate)
438  {
439  std::cerr << "overriding assignment conversion for types '"
440  << t_lhs_name << "' and '" << t_rhs_name << "'"
441  << std::endl;
442  abort ();
443  }
444 
445  warning ("overriding assignment conversion for types '%s' and '%s'",
446  t_lhs_name.c_str (), t_rhs_name.c_str ());
447  }
448 
449  pref_assign_conv.checkelem (t_lhs, t_rhs) = t_result;
450 
451  return false;
452  }
453 
454  bool type_info::register_widening_op (int t, int t_result,
456  bool abort_on_duplicate)
457  {
458  if (lookup_widening_op (t, t_result))
459  {
460  std::string t_name = types(t);
461  std::string t_result_name = types(t_result);
462 
463  if (abort_on_duplicate)
464  {
465  std::cerr << "overriding widening op for '" << t_name
466  << "' to '" << t_result_name << "'" << std::endl;
467  abort ();
468  }
469 
470  warning ("overriding widening op for '%s' to '%s'",
471  t_name.c_str (), t_result_name.c_str ());
472  }
473 
474  widening_ops.checkelem (t, t_result) = reinterpret_cast<void *> (f);
475 
476  return false;
477  }
478 
479  octave_value type_info::lookup_type (const std::string& nm)
480  {
482 
483  for (int i = 0; i < num_types; i++)
484  {
485  if (nm == types(i))
486  {
487  retval = *vals(i);
488  retval.make_unique ();
489  break;
490  }
491  }
492 
493  return retval;
494  }
495 
498  {
499  void *f = unary_class_ops.checkelem (static_cast<int> (op));
500  return reinterpret_cast<type_info::unary_class_op_fcn> (f);
501  }
502 
505  {
506  void *f = unary_ops.checkelem (static_cast<int> (op), t);
507  return reinterpret_cast<type_info::unary_op_fcn> (f);
508  }
509 
512  {
513  void *f = non_const_unary_ops.checkelem (static_cast<int> (op), t);
514  return reinterpret_cast<type_info::non_const_unary_op_fcn> (f);
515  }
516 
519  {
520  void *f = binary_class_ops.checkelem (static_cast<int> (op));
521  return reinterpret_cast<type_info::binary_class_op_fcn> (f);
522  }
523 
526  {
527  void *f = binary_ops.checkelem (static_cast<int> (op), t1, t2);
528  return reinterpret_cast<type_info::binary_op_fcn> (f);
529  }
530 
533  {
534  void *f = compound_binary_class_ops.checkelem (static_cast<int> (op));
535  return reinterpret_cast<type_info::binary_class_op_fcn> (f);
536  }
537 
540  int t1, int t2)
541  {
542  void *f = compound_binary_ops.checkelem (static_cast<int> (op), t1, t2);
543  return reinterpret_cast<type_info::binary_op_fcn> (f);
544  }
545 
547  type_info::lookup_cat_op (int t1, int t2)
548  {
549  void *f = cat_ops.checkelem (t1, t2);
550  return reinterpret_cast<type_info::cat_op_fcn> (f);
551  }
552 
555  int t_lhs, int t_rhs)
556  {
557  void *f = assign_ops.checkelem (static_cast<int> (op), t_lhs, t_rhs);
558  return reinterpret_cast<type_info::assign_op_fcn> (f);
559  }
560 
563  {
564  void *f = assignany_ops.checkelem (static_cast<int> (op), t_lhs);
565  return reinterpret_cast<type_info::assignany_op_fcn> (f);
566  }
567 
568  int
569  type_info::lookup_pref_assign_conv (int t_lhs, int t_rhs)
570  {
571  return pref_assign_conv.checkelem (t_lhs, t_rhs);
572  }
573 
575  type_info::lookup_widening_op (int t, int t_result)
576  {
577  void *f = widening_ops.checkelem (t, t_result);
578  return reinterpret_cast<octave_base_value::type_conv_fcn> (f);
579  }
580 
583  {
585 
586  for (int i = 0; i < num_types; i++)
587  retval(i) = types(i);
588 
589  return retval;
590  }
591 
594  {
596 
597  int len = std::min (static_cast<int> (non_const_unary_ops.columns ()),
598  num_types);
599 
600  dim_vector tab_dims (1, len);
601 
602  for (int j = 0; j < octave_value::num_unary_ops; j++)
603  {
604  boolNDArray tab (tab_dims);
605 
606  for (int i = 0; i < len; i++)
607  tab.xelem (i) = (unary_ops(j,i) != nullptr);
608 
609  octave_value::unary_op op_id = static_cast<octave_value::unary_op> (j);
610 
611  retval.setfield (octave_value::unary_op_as_string (op_id), tab);
612  }
613 
614  return retval;
615  }
616 
619  {
621 
622  int len = std::min (static_cast<int> (non_const_unary_ops.columns ()),
623  num_types);
624 
625  dim_vector tab_dims (1, len);
626 
627  for (int j = 0; j < octave_value::num_unary_ops; j++)
628  {
629  boolNDArray tab (tab_dims);
630 
631  for (int i = 0; i < len; i++)
632  tab.xelem (i) = (non_const_unary_ops(j,i) != nullptr);
633 
634  octave_value::unary_op op_id = static_cast<octave_value::unary_op> (j);
635 
636  retval.setfield (octave_value::unary_op_as_string (op_id), tab);
637  }
638 
639  return retval;
640  }
641 
644  {
646 
647  int len = std::min (static_cast<int> (binary_ops.columns ()), num_types);
648 
649  dim_vector tab_dims (len, len);
650 
651  for (int k = 0; k < octave_value::num_binary_ops; k++)
652  {
653  boolNDArray tab (tab_dims);
654 
655  for (int j = 0; j < len; j++)
656  for (int i = 0; i < len; i++)
657  tab.xelem (j,i) = (binary_ops(k,j,i) != nullptr);
658 
659  octave_value::binary_op op_id = static_cast<octave_value::binary_op> (k);
660 
661  retval.setfield (octave_value::binary_op_as_string (op_id), tab);
662  }
663 
664  return retval;
665  }
666 
669  {
671 
672  int len = std::min (static_cast<int> (compound_binary_ops.columns ()),
673  num_types);
674 
675  dim_vector tab_dims (len, len);
676 
677  for (int k = 0; k < octave_value::num_compound_binary_ops; k++)
678  {
679  boolNDArray tab (tab_dims);
680 
681  for (int j = 0; j < len; j++)
682  for (int i = 0; i < len; i++)
683  tab.xelem (j,i) = (compound_binary_ops(k,j,i) != nullptr);
684 
686  = static_cast<octave_value::compound_binary_op> (k);
687 
688  retval.setfield (octave_value::binary_op_fcn_name (op_id), tab);
689  }
690 
691  return retval;
692  }
693 
696  {
698 
699  int len = std::min (static_cast<int> (assign_ops.columns ()), num_types);
700 
701  dim_vector tab_dims (len, len);
702 
703  for (int k = 0; k < octave_value::num_assign_ops; k++)
704  {
705  boolNDArray tab (tab_dims);
706 
707  for (int j = 0; j < len; j++)
708  for (int i = 0; i < len; i++)
709  tab.xelem (j,i) = (assign_ops(k,j,i) != nullptr);
710 
711  octave_value::assign_op op_id = static_cast<octave_value::assign_op> (k);
712 
713  retval.setfield (octave_value::assign_op_as_string (op_id), tab);
714  }
715 
716  return retval;
717  }
718 
721  {
723 
724  int len = std::min (static_cast<int> (assignany_ops.columns ()), num_types);
725 
726  dim_vector tab_dims (1, len);
727 
728  for (int j = 0; j < octave_value::num_assign_ops; j++)
729  {
730  boolNDArray tab (tab_dims);
731 
732  for (int i = 0; i < len; i++)
733  tab.xelem (i) = (assignany_ops(j,i) != nullptr);
734 
735  octave_value::assign_op op_id = static_cast<octave_value::assign_op> (j);
736 
737  retval.setfield (octave_value::assign_op_as_string (op_id), tab);
738  }
739 
740  return retval;
741  }
742 
745  {
747 
748  retval.setfield ("types", octave_value (Cell (installed_type_names ())));
749  retval.setfield ("unary_ops", unary_ops_map ());
750  retval.setfield ("non_const_unary_ops", non_const_unary_ops_map ());
751  retval.setfield ("binary_ops", binary_ops_map ());
752  retval.setfield ("compound_binary_ops", compound_binary_ops_map ());
753  retval.setfield ("cat_ops", as_bool_nd_array (cat_ops));
754  retval.setfield ("assign_ops", assign_ops_map ());
755  retval.setfield ("assignany_ops", assignany_ops_map ());
756  retval.setfield ("pref_assign_conv", as_nd_array (pref_assign_conv));
757  retval.setfield ("widening_ops", as_bool_nd_array (widening_ops));
758 
759  return retval;
760  }
761 }
762 
764 {
765  int register_type (const std::string& t_name, const std::string& c_name,
766  const octave_value& val)
767  {
768  octave::type_info& type_info
769  = octave::__get_type_info__ ("register_type");
770 
771  return type_info.register_type (t_name, c_name, val);
772  }
773 
774  octave_value lookup_type (const std::string& nm)
775  {
776  octave::type_info& type_info
777  = octave::__get_type_info__ ("lookup_type");
778 
779  return type_info.lookup_type (nm);
780  }
781 
783  {
784  octave::type_info& type_info
785  = octave::__get_type_info__ ("lookup_unary_class_op");
786 
787  return type_info.lookup_unary_class_op (op);
788  }
789 
791  {
792  octave::type_info& type_info
793  = octave::__get_type_info__ ("lookup_unary_op");
794 
795  return type_info.lookup_unary_op (op, t);
796  }
797 
800  {
801  octave::type_info& type_info
802  = octave::__get_type_info__ ("lookup_non_const_unary_op");
803 
804  return type_info.lookup_non_const_unary_op (op, t);
805  }
806 
809  {
810  octave::type_info& type_info
811  = octave::__get_type_info__ ("lookup_binary_class_op");
812 
813  return type_info.lookup_binary_class_op (op);
814  }
815 
818  {
819  octave::type_info& type_info
820  = octave::__get_type_info__ ("lookup_binary_op");
821 
822  return type_info.lookup_binary_op (op, t1, t2);
823  }
824 
827  {
828  octave::type_info& type_info
829  = octave::__get_type_info__ ("lookup_binary_class_op");
830 
831  return type_info.lookup_binary_class_op (op);
832  }
833 
836  {
837  octave::type_info& type_info
838  = octave::__get_type_info__ ("lookup_binary_op");
839 
840  return type_info.lookup_binary_op (op, t1, t2);
841  }
842 
843  cat_op_fcn lookup_cat_op (int t1, int t2)
844  {
845  octave::type_info& type_info
846  = octave::__get_type_info__ ("lookup_cat_op");
847 
848  return type_info.lookup_cat_op (t1, t2);
849  }
850 
852  lookup_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs)
853  {
854  octave::type_info& type_info
855  = octave::__get_type_info__ ("lookup_assign_op");
856 
857  return type_info.lookup_assign_op (op, t_lhs, t_rhs);
858  }
859 
862  {
863  octave::type_info& type_info
864  = octave::__get_type_info__ ("lookup_assignany_op");
865 
866  return type_info.lookup_assignany_op (op, t_lhs);
867  }
868 
869  int lookup_pref_assign_conv (int t_lhs, int t_rhs)
870  {
871  octave::type_info& type_info
872  = octave::__get_type_info__ ("lookup_pref_assign_conv");
873 
874  return type_info.lookup_pref_assign_conv (t_lhs, t_rhs);
875  }
876 
878  lookup_widening_op (int t, int t_result)
879  {
880  octave::type_info& type_info
881  = octave::__get_type_info__ ("lookup_widening_op");
882 
883  return type_info.lookup_widening_op (t, t_result);
884  }
885 
887  {
888  octave::type_info& type_info
889  = octave::__get_type_info__ ("installed_type_names");
890 
891  return type_info.installed_type_names ();
892  }
893 
895  {
896  octave::type_info& type_info
897  = octave::__get_type_info__ ("installed_type_info");
898 
899  return type_info.installed_type_info ();
900  }
901 }
902 
903 DEFMETHOD (typeinfo, interp, args, ,
904  doc: /* -*- texinfo -*-
905 @deftypefn {} {} typeinfo ()
906 @deftypefnx {} {} typeinfo (@var{expr})
907 
908 Return the type of the expression @var{expr}, as a string.
909 
910 If @var{expr} is omitted, return a cell array of strings containing all the
911 currently installed data types.
912 @seealso{class, isa}
913 @end deftypefn */)
914 {
915  int nargin = args.length ();
916 
917  if (nargin > 1)
918  print_usage ();
919 
920  if (nargin == 0)
921  {
922  octave::type_info& type_info = interp.get_type_info ();
923 
924  return ovl (Cell (type_info.installed_type_names ()));
925  }
926  else
927  return ovl (args(0).type_name ());
928 }
929 
930 /*
931 %!assert (iscellstr (typeinfo ()))
932 
933 %!assert (typeinfo ({"cell"}), "cell")
934 
935 %!assert (typeinfo (1), "scalar")
936 %!assert (typeinfo (double (1)), "scalar")
937 %!assert (typeinfo (i), "complex scalar")
938 
939 %!assert (typeinfo ([1, 2]), "matrix")
940 %!assert (typeinfo (double ([1, 2])), "matrix")
941 %!assert (typeinfo (diag ([1, 2])), "diagonal matrix")
942 %!assert (typeinfo ([i, 2]), "complex matrix")
943 %!assert (typeinfo (diag ([i, 2])), "complex diagonal matrix")
944 
945 %!assert (typeinfo (1:2), "range")
946 
947 %!assert (typeinfo (false), "bool")
948 %!assert (typeinfo ([true, false]), "bool matrix")
949 
950 %!assert (typeinfo ("string"), "string")
951 %!assert (typeinfo ('string'), "sq_string")
952 
953 %!assert (typeinfo (int8 (1)), "int8 scalar")
954 %!assert (typeinfo (int16 (1)), "int16 scalar")
955 %!assert (typeinfo (int32 (1)), "int32 scalar")
956 %!assert (typeinfo (int64 (1)), "int64 scalar")
957 %!assert (typeinfo (uint8 (1)), "uint8 scalar")
958 %!assert (typeinfo (uint16 (1)), "uint16 scalar")
959 %!assert (typeinfo (uint32 (1)), "uint32 scalar")
960 %!assert (typeinfo (uint64 (1)), "uint64 scalar")
961 
962 %!assert (typeinfo (int8 ([1,2])), "int8 matrix")
963 %!assert (typeinfo (int16 ([1,2])), "int16 matrix")
964 %!assert (typeinfo (int32 ([1,2])), "int32 matrix")
965 %!assert (typeinfo (int64 ([1,2])), "int64 matrix")
966 %!assert (typeinfo (uint8 ([1,2])), "uint8 matrix")
967 %!assert (typeinfo (uint16 ([1,2])), "uint16 matrix")
968 %!assert (typeinfo (uint32 ([1,2])), "uint32 matrix")
969 %!assert (typeinfo (uint64 ([1,2])), "uint64 matrix")
970 
971 %!assert (typeinfo (sparse ([true, false])), "sparse bool matrix")
972 %!assert (typeinfo (logical (sparse (i * eye (10)))), "sparse bool matrix")
973 %!assert (typeinfo (sparse ([1,2])), "sparse matrix")
974 %!assert (typeinfo (sparse (eye (10))), "sparse matrix")
975 %!assert (typeinfo (sparse ([i,2])), "sparse complex matrix")
976 %!assert (typeinfo (sparse (i * eye (10))), "sparse complex matrix")
977 
978 %!test
979 %! s(2).a = 1;
980 %! assert (typeinfo (s), "struct");
981 
982 %!test
983 %! s.a = 1;
984 %! assert (typeinfo (s), "scalar struct");
985 
986 ## FIXME: This doesn't work as a test for comma-separated list
987 %!#test
988 %! clist = {1, 2, 3};
989 %! assert (typeinfo (clist{:}), "cs-list");
990 
991 %!assert (typeinfo (@sin), "function handle")
992 %!assert (typeinfo (@(x) x), "function handle")
993 
994 %!assert (typeinfo (single (1)), "float scalar")
995 %!assert (typeinfo (single (i)), "float complex scalar")
996 %!assert (typeinfo (single ([1, 2])), "float matrix")
997 
998 %!assert (typeinfo (single (diag ([1, 2]))), "float diagonal matrix")
999 %!assert (typeinfo (diag (single ([1, 2]))), "float diagonal matrix")
1000 %!assert (typeinfo (single (diag ([i, 2]))), "float complex diagonal matrix")
1001 %!assert (typeinfo (diag (single ([i, 2]))), "float complex diagonal matrix")
1002 
1003 %!assert (typeinfo (eye(3)(:,[1 3 2])), "permutation matrix")
1004 %!test
1005 %! [l, u, p] = lu (rand (3));
1006 %! assert (typeinfo (p), "permutation matrix");
1007 
1008 %!assert (typeinfo ([]), "null_matrix")
1009 %!assert (typeinfo (""), "null_string")
1010 %!assert (typeinfo (''), "null_sq_string")
1011 
1012 %!test
1013 %! cvar = onCleanup (@() "");
1014 %! assert (typeinfo (cvar), "onCleanup");
1015 
1016 %!testif HAVE_JAVA; usejava ("jvm")
1017 %! x = javaObject ("java.lang.StringBuffer");
1018 %! assert (typeinfo (x), "octave_java");
1019 
1020 ## Test input validation
1021 %!error typeinfo ("foo", 1)
1022 */
1023 
1024 DEFMETHOD (__dump_typeinfo__, interp, args, ,
1025  doc: /* -*- texinfo -*-
1026 @deftypefn {} {} __dump_typeinfo__ ()
1027 Undocumented internal function.
1028 @end deftypefn */)
1029 {
1030  if (args.length () > 0)
1031  print_usage ();
1032 
1033  octave::type_info& type_info = interp.get_type_info ();
1034 
1035  return ovl (type_info.installed_type_info ());
1036 }
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1011
octave_idx_type columns(void) const
Definition: Array.h:424
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:469
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
void make_unique(void)
Definition: Array.h:188
T & checkelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.cc:192
Definition: Cell.h:43
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
unary_class_op_fcn lookup_unary_class_op(octave_value::unary_op)
Definition: ov-typeinfo.cc:497
octave_value(* assignany_op_fcn)(octave_base_value &, const octave_value_list &, const octave_value &)
Definition: ov-typeinfo.h:66
octave_scalar_map compound_binary_ops_map(void) const
Definition: ov-typeinfo.cc:668
Array< void * > assignany_ops
Definition: ov-typeinfo.h:262
Array< void * > unary_ops
Definition: ov-typeinfo.h:246
octave_value lookup_type(const std::string &nm)
Definition: ov-typeinfo.cc:479
unary_op_fcn lookup_unary_op(octave_value::unary_op, int)
Definition: ov-typeinfo.cc:504
bool register_unary_class_op(octave_value::unary_op, unary_class_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:162
octave_value(* binary_class_op_fcn)(const octave_value &, const octave_value &)
Definition: ov-typeinfo.h:53
Array< octave_value * > vals
Definition: ov-typeinfo.h:242
non_const_unary_op_fcn lookup_non_const_unary_op(octave_value::unary_op, int)
Definition: ov-typeinfo.cc:511
octave_scalar_map non_const_unary_ops_map(void) const
Definition: ov-typeinfo.cc:618
bool register_binary_class_op(octave_value::binary_op, binary_class_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:239
octave_scalar_map binary_ops_map(void) const
Definition: ov-typeinfo.cc:643
Array< int > pref_assign_conv
Definition: ov-typeinfo.h:264
Array< void * > non_const_unary_ops
Definition: ov-typeinfo.h:248
Array< void * > compound_binary_class_ops
Definition: ov-typeinfo.h:254
int lookup_pref_assign_conv(int, int)
Definition: ov-typeinfo.cc:569
assign_op_fcn lookup_assign_op(octave_value::assign_op, int, int)
Definition: ov-typeinfo.cc:554
assignany_op_fcn lookup_assignany_op(octave_value::assign_op, int)
Definition: ov-typeinfo.cc:562
Array< void * > binary_class_ops
Definition: ov-typeinfo.h:250
Array< void * > compound_binary_ops
Definition: ov-typeinfo.h:256
octave_value(* unary_class_op_fcn)(const octave_value &)
Definition: ov-typeinfo.h:46
Array< void * > widening_ops
Definition: ov-typeinfo.h:266
type_info(int init_tab_sz=16)
Definition: ov-typeinfo.cc:67
bool register_binary_op(octave_value::binary_op, int, int, binary_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:265
bool register_cat_op(int, int, cat_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:349
octave_scalar_map unary_ops_map(void) const
Definition: ov-typeinfo.cc:593
bool register_assign_op(octave_value::assign_op, int, int, assign_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:373
octave_value(* assign_op_fcn)(octave_base_value &, const octave_value_list &, const octave_base_value &)
Definition: ov-typeinfo.h:63
Array< void * > assign_ops
Definition: ov-typeinfo.h:260
int register_type(const std::string &, const std::string &, const octave_value &, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:88
octave_value(* binary_op_fcn)(const octave_base_value &, const octave_base_value &)
Definition: ov-typeinfo.h:56
octave_scalar_map installed_type_info(void) const
Definition: ov-typeinfo.cc:744
octave_value(* unary_op_fcn)(const octave_base_value &)
Definition: ov-typeinfo.h:48
bool register_non_const_unary_op(octave_value::unary_op, int, non_const_unary_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:212
octave_value(* cat_op_fcn)(octave_base_value &, const octave_base_value &, const Array< octave_idx_type > &ra_idx)
Definition: ov-typeinfo.h:59
binary_class_op_fcn lookup_binary_class_op(octave_value::binary_op)
Definition: ov-typeinfo.cc:518
Array< void * > binary_ops
Definition: ov-typeinfo.h:252
octave_base_value::type_conv_fcn lookup_widening_op(int, int)
Definition: ov-typeinfo.cc:575
bool register_assignany_op(octave_value::assign_op, int, assignany_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:402
bool register_widening_op(int, int, octave_base_value::type_conv_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:454
Array< void * > cat_ops
Definition: ov-typeinfo.h:258
binary_op_fcn lookup_binary_op(octave_value::binary_op, int, int)
Definition: ov-typeinfo.cc:525
Array< void * > unary_class_ops
Definition: ov-typeinfo.h:244
Array< std::string > types
Definition: ov-typeinfo.h:240
octave_scalar_map assign_ops_map(void) const
Definition: ov-typeinfo.cc:695
cat_op_fcn lookup_cat_op(int, int)
Definition: ov-typeinfo.cc:547
string_vector installed_type_names(void) const
Definition: ov-typeinfo.cc:582
void(* non_const_unary_op_fcn)(octave_base_value &)
Definition: ov-typeinfo.h:50
octave_scalar_map assignany_ops_map(void) const
Definition: ov-typeinfo.cc:720
bool register_pref_assign_conv(int, int, int, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:428
bool register_unary_op(octave_value::unary_op, int, unary_op_fcn, bool abort_on_duplicate=false)
Definition: ov-typeinfo.cc:187
octave_base_value *(* type_conv_fcn)(const octave_base_value &)
Definition: ov-base.h:207
static std::string binary_op_as_string(binary_op)
Definition: ov.cc:178
unary_op
Definition: ov.h:83
@ num_unary_ops
Definition: ov.h:91
static std::string assign_op_as_string(assign_op)
Definition: ov.cc:349
compound_binary_op
Definition: ov.h:121
@ num_compound_binary_ops
Definition: ov.h:133
assign_op
Definition: ov.h:138
@ num_assign_ops
Definition: ov.h:152
static std::string unary_op_as_string(unary_op)
Definition: ov.cc:122
binary_op
Definition: ov.h:96
@ num_binary_ops
Definition: ov.h:116
static std::string binary_op_fcn_name(binary_op)
Definition: ov.cc:245
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
void warning(const char *fmt,...)
Definition: error.cc:1050
F77_RET_T const F77_DBLE * x
binary_class_op_fcn lookup_binary_class_op(octave_value::binary_op op)
Definition: ov-typeinfo.cc:808
octave::type_info::cat_op_fcn cat_op_fcn
Definition: ov-typeinfo.h:282
octave::type_info::assign_op_fcn assign_op_fcn
Definition: ov-typeinfo.h:284
unary_class_op_fcn lookup_unary_class_op(octave_value::unary_op op)
Definition: ov-typeinfo.cc:782
int lookup_pref_assign_conv(int t_lhs, int t_rhs)
Definition: ov-typeinfo.cc:869
unary_op_fcn lookup_unary_op(octave_value::unary_op op, int t)
Definition: ov-typeinfo.cc:790
octave::type_info::unary_class_op_fcn unary_class_op_fcn
Definition: ov-typeinfo.h:272
octave::type_info::assignany_op_fcn assignany_op_fcn
Definition: ov-typeinfo.h:286
string_vector installed_type_names(void)
Definition: ov-typeinfo.cc:886
octave_value lookup_type(const std::string &nm)
Definition: ov-typeinfo.cc:774
assign_op_fcn lookup_assign_op(octave_value::assign_op op, int t_lhs, int t_rhs)
Definition: ov-typeinfo.cc:852
non_const_unary_op_fcn lookup_non_const_unary_op(octave_value::unary_op op, int t)
Definition: ov-typeinfo.cc:799
assignany_op_fcn lookup_assignany_op(octave_value::assign_op op, int t_lhs)
Definition: ov-typeinfo.cc:861
binary_op_fcn lookup_binary_op(octave_value::binary_op op, int t1, int t2)
Definition: ov-typeinfo.cc:817
int register_type(const std::string &t_name, const std::string &c_name, const octave_value &val)
Definition: ov-typeinfo.cc:765
octave_scalar_map installed_type_info(void)
Definition: ov-typeinfo.cc:894
octave::type_info::non_const_unary_op_fcn non_const_unary_op_fcn
Definition: ov-typeinfo.h:276
octave::type_info::unary_op_fcn unary_op_fcn
Definition: ov-typeinfo.h:274
octave::type_info::binary_class_op_fcn binary_class_op_fcn
Definition: ov-typeinfo.h:278
octave::type_info::binary_op_fcn binary_op_fcn
Definition: ov-typeinfo.h:280
octave_base_value::type_conv_fcn lookup_widening_op(int t, int t_result)
Definition: ov-typeinfo.cc:878
cat_op_fcn lookup_cat_op(int t1, int t2)
Definition: ov-typeinfo.cc:843
type_info & __get_type_info__(const std::string &who)
static double f(double k, double l_nu, double c_pm)
Definition: randpoisson.cc:118
static NDArray as_nd_array(const Array< int > &x)
Definition: ov-typeinfo.cc:47
static boolNDArray as_bool_nd_array(const Array< void * > &x)
Definition: ov-typeinfo.cc:57
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
void install_ops(octave::type_info &)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
void install_types(octave::type_info &ti)
Definition: ov.cc:2914
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
F77_RET_T len
Definition: xerbla.cc:61