1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_ov_typeinfo_h)
27 #define octave_ov_typeinfo_h 1
28 
29 #include "octave-config.h"
30 
31 #include <string>
32 
33 #include "Array.h"
34 
35 #include "oct-map.h"
36 #include "ov.h"
37 
38 class string_vector;
39 
40 namespace octave
41 {
42   class type_info
43   {
44   public:
45 
46     typedef octave_value (*unary_class_op_fcn) (const octave_value&);
47 
48     typedef octave_value (*unary_op_fcn) (const octave_base_value&);
49 
50     typedef void (*non_const_unary_op_fcn) (octave_base_value&);
51 
52     typedef octave_value (*binary_class_op_fcn)
53       (const octave_value&, const octave_value&);
54 
55     typedef octave_value (*binary_op_fcn)
56       (const octave_base_value&, const octave_base_value&);
57 
58     typedef octave_value (*cat_op_fcn)
59       (octave_base_value&, const octave_base_value&,
60      const Array<octave_idx_type>& ra_idx);
61 
62     typedef octave_value (*assign_op_fcn)
63       (octave_base_value&, const octave_value_list&, const octave_base_value&);
64 
65     typedef octave_value (*assignany_op_fcn)
66       (octave_base_value&, const octave_value_list&, const octave_value&);
67 
68     explicit type_info (int init_tab_sz = 16);
69 
70     // No copying!
71 
72     type_info (const type_info&) = delete;
73 
74     type_info& operator = (const type_info&) = delete;
75 
76     ~type_info (void) = default;
77 
78     // It is intentional that there is no install_type function.
79 
install_unary_class_op(octave_value::unary_op op,unary_class_op_fcn f)80     bool install_unary_class_op (octave_value::unary_op op,
81                                  unary_class_op_fcn f)
82     {
83       return register_unary_class_op (op, f, true);
84     }
85 
install_unary_op(octave_value::unary_op op,int t,unary_op_fcn f)86     bool install_unary_op (octave_value::unary_op op, int t, unary_op_fcn f)
87     {
88       return register_unary_op (op, t, f, true);
89     }
90 
install_non_const_unary_op(octave_value::unary_op op,int t,non_const_unary_op_fcn f)91     bool install_non_const_unary_op (octave_value::unary_op op, int t,
92                                      non_const_unary_op_fcn f)
93     {
94       return register_non_const_unary_op (op, t, f, true);
95     }
96 
install_binary_class_op(octave_value::binary_op op,binary_class_op_fcn f)97     bool install_binary_class_op (octave_value::binary_op op,
98                                   binary_class_op_fcn f)
99     {
100       return register_binary_class_op (op, f, true);
101     }
102 
install_binary_op(octave_value::binary_op op,int t1,int t2,binary_op_fcn f)103     bool install_binary_op (octave_value::binary_op op, int t1, int t2,
104                             binary_op_fcn f)
105     {
106       return register_binary_op (op, t1, t2, f, true);
107     }
108 
install_binary_class_op(octave_value::compound_binary_op op,binary_class_op_fcn f)109     bool install_binary_class_op (octave_value::compound_binary_op op,
110                                   binary_class_op_fcn f)
111     {
112       return register_binary_class_op (op, f, true);
113     }
114 
install_binary_op(octave_value::compound_binary_op op,int t_lhs,int t_rhs,binary_op_fcn f)115     bool install_binary_op (octave_value::compound_binary_op op,
116                             int t_lhs, int t_rhs, binary_op_fcn f)
117     {
118       return register_binary_op (op, t_lhs, t_rhs, f, true);
119     }
120 
install_cat_op(int t1,int t2,cat_op_fcn f)121     bool install_cat_op (int t1, int t2, cat_op_fcn f)
122     {
123       return register_cat_op (t1, t2, f, true);
124     }
125 
install_assign_op(octave_value::assign_op op,int t_lhs,int t_rhs,assign_op_fcn f)126     bool install_assign_op (octave_value::assign_op op,
127                             int t_lhs, int t_rhs, assign_op_fcn f)
128     {
129       return register_assign_op (op, t_lhs, t_rhs, f, true);
130     }
131 
install_assignany_op(octave_value::assign_op op,int t_lhs,assignany_op_fcn f)132     bool install_assignany_op (octave_value::assign_op op, int t_lhs,
133                                assignany_op_fcn f)
134     {
135       return register_assignany_op (op, t_lhs, f, true);
136     }
137 
install_pref_assign_conv(int t_lhs,int t_rhs,int t_result)138     bool install_pref_assign_conv (int t_lhs, int t_rhs, int t_result)
139     {
140       return register_pref_assign_conv (t_lhs, t_rhs, t_result, true);
141     }
142 
install_widening_op(int t,int t_result,octave_base_value::type_conv_fcn f)143     bool install_widening_op (int t, int t_result,
144                               octave_base_value::type_conv_fcn f)
145     {
146       return register_widening_op (t, t_result, f, true);
147     }
148 
149     int register_type (const std::string&, const std::string&,
150                        const octave_value&, bool abort_on_duplicate = false);
151 
152     bool register_unary_class_op (octave_value::unary_op, unary_class_op_fcn,
153                                   bool abort_on_duplicate = false);
154 
155     bool register_unary_op (octave_value::unary_op, int, unary_op_fcn,
156                             bool abort_on_duplicate = false);
157 
158     bool register_non_const_unary_op (octave_value::unary_op, int,
159                                       non_const_unary_op_fcn,
160                                       bool abort_on_duplicate = false);
161 
162     bool register_binary_class_op (octave_value::binary_op,
163                                    binary_class_op_fcn,
164                                    bool abort_on_duplicate = false);
165 
166     bool register_binary_op (octave_value::binary_op, int, int,
167                              binary_op_fcn, bool abort_on_duplicate = false);
168 
169     bool register_binary_class_op (octave_value::compound_binary_op,
170                                    binary_class_op_fcn,
171                                    bool abort_on_duplicate = false);
172 
173     bool register_binary_op (octave_value::compound_binary_op, int, int,
174                              binary_op_fcn, bool abort_on_duplicate = false);
175 
176     bool register_cat_op (int, int, cat_op_fcn,
177                           bool abort_on_duplicate = false);
178 
179     bool register_assign_op (octave_value::assign_op, int, int, assign_op_fcn,
180                              bool abort_on_duplicate = false);
181 
182     bool register_assignany_op (octave_value::assign_op, int, assignany_op_fcn,
183                                 bool abort_on_duplicate = false);
184 
185     bool register_pref_assign_conv (int, int, int,
186                                     bool abort_on_duplicate = false);
187 
188     bool register_widening_op (int, int, octave_base_value::type_conv_fcn,
189                                bool abort_on_duplicate = false);
190 
191     octave_value lookup_type (const std::string& nm);
192 
193     unary_class_op_fcn lookup_unary_class_op (octave_value::unary_op);
194 
195     unary_op_fcn lookup_unary_op (octave_value::unary_op, int);
196 
197     non_const_unary_op_fcn
198     lookup_non_const_unary_op (octave_value::unary_op, int);
199 
200     binary_class_op_fcn lookup_binary_class_op (octave_value::binary_op);
201 
202     binary_op_fcn lookup_binary_op (octave_value::binary_op, int, int);
203 
204     binary_class_op_fcn
205     lookup_binary_class_op (octave_value::compound_binary_op);
206 
207     binary_op_fcn
208     lookup_binary_op (octave_value::compound_binary_op, int, int);
209 
210     cat_op_fcn lookup_cat_op (int, int);
211 
212     assign_op_fcn lookup_assign_op (octave_value::assign_op, int, int);
213 
214     assignany_op_fcn lookup_assignany_op (octave_value::assign_op, int);
215 
216     int lookup_pref_assign_conv (int, int);
217 
218     octave_base_value::type_conv_fcn lookup_widening_op (int, int);
219 
220     string_vector installed_type_names (void) const;
221 
222     octave_scalar_map installed_type_info (void) const;
223 
224     octave_scalar_map unary_ops_map (void) const;
225 
226     octave_scalar_map non_const_unary_ops_map (void) const;
227 
228     octave_scalar_map binary_ops_map (void) const;
229 
230     octave_scalar_map compound_binary_ops_map (void) const;
231 
232     octave_scalar_map assign_ops_map (void) const;
233 
234     octave_scalar_map assignany_ops_map (void) const;
235 
236   private:
237 
238     int num_types;
239 
240     Array<std::string> types;
241 
242     Array<octave_value *> vals;
243 
244     Array<void *> unary_class_ops;
245 
246     Array<void *> unary_ops;
247 
248     Array<void *> non_const_unary_ops;
249 
250     Array<void *> binary_class_ops;
251 
252     Array<void *> binary_ops;
253 
254     Array<void *> compound_binary_class_ops;
255 
256     Array<void *> compound_binary_ops;
257 
258     Array<void *> cat_ops;
259 
260     Array<void *> assign_ops;
261 
262     Array<void *> assignany_ops;
263 
264     Array<int> pref_assign_conv;
265 
266     Array<void *> widening_ops;
267   };
268 }
269 
270 namespace octave_value_typeinfo
271 {
272   typedef octave::type_info::unary_class_op_fcn unary_class_op_fcn;
273 
274   typedef octave::type_info::unary_op_fcn unary_op_fcn;
275 
276   typedef octave::type_info::non_const_unary_op_fcn non_const_unary_op_fcn;
277 
278   typedef octave::type_info::binary_class_op_fcn binary_class_op_fcn;
279 
280   typedef octave::type_info::binary_op_fcn binary_op_fcn;
281 
282   typedef octave::type_info::cat_op_fcn cat_op_fcn;
283 
284   typedef octave::type_info::assign_op_fcn assign_op_fcn;
285 
286   typedef octave::type_info::assignany_op_fcn assignany_op_fcn;
287 
288   extern int register_type (const std::string& t_name,
289                             const std::string& c_name,
290                             const octave_value& val);
291 
292   extern octave_value lookup_type (const std::string& nm);
293 
294   extern unary_class_op_fcn lookup_unary_class_op (octave_value::unary_op op);
295 
296   extern unary_op_fcn lookup_unary_op (octave_value::unary_op op, int t);
297 
298   extern non_const_unary_op_fcn
299   lookup_non_const_unary_op (octave_value::unary_op op, int t);
300 
301   extern binary_class_op_fcn
302   lookup_binary_class_op (octave_value::binary_op op);
303 
304   extern binary_op_fcn
305   lookup_binary_op (octave_value::binary_op op, int t1, int t2);
306 
307   extern binary_class_op_fcn
308   lookup_binary_class_op (octave_value::compound_binary_op op);
309 
310   extern binary_op_fcn
311   lookup_binary_op (octave_value::compound_binary_op op, int t1, int t2);
312 
313   extern cat_op_fcn lookup_cat_op (int t1, int t2);
314 
315   extern assign_op_fcn
316   lookup_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs);
317 
318   extern assignany_op_fcn
319   lookup_assignany_op (octave_value::assign_op op, int t_lhs);
320 
321   extern int lookup_pref_assign_conv (int t_lhs, int t_rhs);
322 
323   extern octave_base_value::type_conv_fcn
324   lookup_widening_op (int t, int t_result);
325 
326   extern string_vector installed_type_names (void);
327 
328   extern octave_scalar_map installed_type_info (void);
329 }
330 
331 #endif
332