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