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