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