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