GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ops.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 John W. Eaton
4 Copyright (C) 2009 VZLU Prague, a.s.
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if ! defined (octave_ops_h)
25 #define octave_ops_h 1
26 
27 #include "octave-config.h"
28 
29 #include "Array-util.h"
30 
31 // Concatenation macros that enforce argument prescan
32 #define CONCAT2X(x, y) x ## y
33 #define CONCAT2(x, y) CONCAT2X (x, y)
34 
35 #define CONCAT3X(x, y, z) x ## y ## z
36 #define CONCAT3(x, y, z) CONCAT3X (x, y, z)
37 
38 extern void install_ops (void);
39 
40 #define INSTALL_UNOP(op, t, f) \
41  octave_value_typeinfo::register_unary_op \
42  (octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
43 
44 #define INSTALL_NCUNOP(op, t, f) \
45  octave_value_typeinfo::register_non_const_unary_op \
46  (octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
47 
48 #define INSTALL_BINOP(op, t1, t2, f) \
49  octave_value_typeinfo::register_binary_op \
50  (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
51  CONCAT2 (oct_binop_, f));
52 
53 #define INSTALL_CATOP(t1, t2, f) \
54  octave_value_typeinfo::register_cat_op \
55  (t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_catop_, f));
56 
57 #define INSTALL_ASSIGNOP(op, t1, t2, f) \
58  octave_value_typeinfo::register_assign_op \
59  (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
60  CONCAT2 (oct_assignop_, f));
61 
62 #define INSTALL_ASSIGNANYOP(op, t1, f) \
63  octave_value_typeinfo::register_assignany_op \
64  (octave_value::op, t1::static_type_id (), CONCAT2 (oct_assignop_, f));
65 
66 #define INSTALL_ASSIGNCONV(t1, t2, tr) \
67  octave_value_typeinfo::register_pref_assign_conv \
68  (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
69 
70 #define INSTALL_WIDENOP(t1, t2, f) \
71  octave_value_typeinfo::register_widening_op \
72  (t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_conv_, f));
73 
74 #define DEFASSIGNOP(name, t1, t2) \
75  static octave_value \
76  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
77  const octave_value_list& idx, \
78  const octave_base_value& a2)
79 
80 #define DEFASSIGNOP_FN(name, t1, t2, f) \
81  static octave_value \
82  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
83  const octave_value_list& idx, \
84  const octave_base_value& a2) \
85  { \
86  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
87  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
88  \
89  v1.f (idx, v2.CONCAT2 (t1, _value) ()); \
90  return octave_value (); \
91  }
92 
93 #define DEFNULLASSIGNOP_FN(name, t, f) \
94  static octave_value \
95  CONCAT2 (oct_assignop_, name) (octave_base_value& a, \
96  const octave_value_list& idx, \
97  const octave_base_value&) \
98  { \
99  CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
100  \
101  v.f (idx); \
102  return octave_value (); \
103  }
104 
105 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
106  static octave_value \
107  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
108  const octave_value_list& idx, \
109  const octave_base_value& a2) \
110  { \
111  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
112  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
113  \
114  v1.f (idx, v2.CONCAT2 (e, _value) ()); \
115  return octave_value (); \
116  }
117 
118 // FIXME: the following currently don't handle index.
119 #define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
120  static octave_value \
121  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
122  const octave_value_list& idx, \
123  const octave_base_value& a2) \
124  { \
125  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
126  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
127  \
128  assert (idx.empty ()); \
129  v1.matrix_ref () op v2.CONCAT2 (f, _value) (); \
130  \
131  return octave_value (); \
132  }
133 
134 #define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
135  static octave_value \
136  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
137  const octave_value_list& idx, \
138  const octave_base_value& a2) \
139  { \
140  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
141  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
142  \
143  assert (idx.empty ()); \
144  fnop (v1.matrix_ref (), v2.CONCAT2 (f, _value) ()); \
145  \
146  return octave_value (); \
147  }
148 
149 #define DEFASSIGNANYOP_FN(name, t1, f) \
150  static octave_value \
151  CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
152  const octave_value_list& idx, \
153  const octave_value& a2) \
154  { \
155  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
156  \
157  v1.f (idx, a2); \
158  return octave_value (); \
159  }
160 
161 #define CONVDECL(name) \
162  static octave_base_value * \
163  CONCAT2 (oct_conv_, name) (const octave_base_value& a)
164 
165 #define DEFCONV(name, a_dummy, b_dummy) \
166  CONVDECL (name)
167 
168 #define DEFUNOPX(name, t) \
169  static octave_value \
170  CONCAT2 (oct_unop_, name) (const octave_base_value&)
171 
172 #define DEFUNOP(name, t) \
173  static octave_value \
174  CONCAT2 (oct_unop_, name) (const octave_base_value& a)
175 
176 #define DEFUNOP_OP(name, t, op) \
177  static octave_value \
178  CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
179  { \
180  const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
181  return octave_value (op v.CONCAT2 (t, _value) ()); \
182  }
183 
184 #define DEFNDUNOP_OP(name, t, e, op) \
185  static octave_value \
186  CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
187  { \
188  const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
189  return octave_value (op v.CONCAT2 (e, _value) ()); \
190  }
191 
192 // FIXME: in some cases, the constructor isn't necessary.
193 
194 #define DEFUNOP_FN(name, t, f) \
195  static octave_value \
196  CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
197  { \
198  const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
199  return octave_value (f (v.CONCAT2 (t, _value) ())); \
200  }
201 
202 #define DEFNDUNOP_FN(name, t, e, f) \
203  static octave_value \
204  CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
205  { \
206  const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
207  return octave_value (f (v.CONCAT2 (e, _value) ())); \
208  }
209 
210 #define DEFNCUNOP_METHOD(name, t, method) \
211  static void \
212  CONCAT2 (oct_unop_, name) (octave_base_value& a) \
213  { \
214  CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
215  v.method (); \
216  }
217 
218 #define DEFBINOPX(name, t1, t2) \
219  static octave_value \
220  CONCAT2 (oct_binop_, name) (const octave_base_value&, \
221  const octave_base_value&)
222 
223 #define DEFBINOP(name, t1, t2) \
224  static octave_value \
225  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
226  const octave_base_value& a2)
227 
228 #define DEFBINOP_OP(name, t1, t2, op) \
229  static octave_value \
230  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
231  const octave_base_value& a2) \
232  { \
233  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
234  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
235  \
236  return octave_value \
237  (v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
238  }
239 
240 #define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
241  static octave_value \
242  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
243  const octave_base_value& a2) \
244  { \
245  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
246  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
247  \
248  warn_complex_cmp (); \
249  \
250  return octave_value \
251  (v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
252  }
253 
254 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
255  static octave_value \
256  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
257  const octave_base_value& a2) \
258  { \
259  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
260  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
261  \
262  if (octave::math::isnan (v1.CONCAT2 (t1, _value) ()) || octave::math::isnan (v2.CONCAT2 (t2, _value) ())) \
263  octave::err_nan_to_logical_conversion (); \
264  \
265  return octave_value \
266  (v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
267  }
268 
269 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
270  static octave_value \
271  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
272  const octave_base_value& a2) \
273  { \
274  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
275  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
276  \
277  return octave_value \
278  (v1.CONCAT2 (e1, _value) () op v2.CONCAT2 (e2, _value) ()); \
279  }
280 
281 // FIXME: in some cases, the constructor isn't necessary.
282 
283 #define DEFBINOP_FN(name, t1, t2, f) \
284  static octave_value \
285  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
286  const octave_base_value& a2) \
287  { \
288  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
289  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
290  \
291  return octave_value (f (v1.CONCAT2 (t1, _value) (), v2.CONCAT2 (t2, _value) ())); \
292  }
293 
294 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
295  static octave_value \
296  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
297  const octave_base_value& a2) \
298  { \
299  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
300  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
301  \
302  return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
303  }
304 
305 #define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
306  static octave_value \
307  CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
308  const octave_base_value& a2) \
309  { \
310  const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
311  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
312  \
313  return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
314  }
315 
316 #define DEFCATOPX(name, t1, t2) \
317  static octave_value \
318  CONCAT2 (oct_catop_, name) (octave_base_value&, const octave_base_value&, \
319  const Array<octave_idx_type>& ra_idx)
320 
321 #define DEFCATOP(name, t1, t2) \
322  static octave_value \
323  CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
324  const octave_base_value& a2, \
325  const Array<octave_idx_type>& ra_idx)
326 
327 // FIXME: in some cases, the constructor isn't necessary.
328 
329 #define DEFCATOP_FN(name, t1, t2, f) \
330  static octave_value \
331  CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
332  const octave_base_value& a2, \
333  const Array<octave_idx_type>& ra_idx) \
334  { \
335  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
336  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
337  \
338  return octave_value (v1.CONCAT2 (t1, _value) () . f (v2.CONCAT2 (t2, _value) (), ra_idx)); \
339  }
340 
341 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
342  static octave_value \
343  CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
344  const octave_base_value& a2, \
345  const Array<octave_idx_type>& ra_idx) \
346  { \
347  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
348  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
349  \
350  return octave_value (v1.CONCAT2 (e1, _value) () . f (v2.CONCAT2 (e2, _value) (), ra_idx)); \
351  }
352 
353 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \
354  static octave_value \
355  CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
356  const octave_base_value& a2, \
357  const Array<octave_idx_type>& ra_idx) \
358  { \
359  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
360  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
361  \
362  return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
363  ((a1.is_sq_string () || a2.is_sq_string ()) \
364  ? '\'' : '"')); \
365  }
366 
367 // For compatibility, the second arg is always converted to the type
368 // of the first. Hmm.
369 
370 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
371  static octave_value \
372  CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
373  const octave_base_value& a2, \
374  const Array<octave_idx_type>& ra_idx) \
375  { \
376  CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
377  const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
378  \
379  return octave_value (tc1 (v1.CONCAT2 (e1, _value) ()) . f (tc2 (v2.CONCAT2 (e2, _value) ()), ra_idx)); \
380  }
381 
382 #endif
void install_ops(void)
Definition: ops.cc:135