GNU Octave
7.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-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 (octave_ops_h)
27
#define octave_ops_h 1
28
29
#include "octave-config.h"
30
31
#include "
Array-util.h
"
32
33
namespace
octave
34
{
35
class
type_info
;
36
}
37
38
// Concatenation macros that enforce argument prescan
39
#define CONCAT2X(x, y) x ## y
40
#define CONCAT2(x, y) CONCAT2X (x, y)
41
42
#define CONCAT3X(x, y, z) x ## y ## z
43
#define CONCAT3(x, y, z) CONCAT3X (x, y, z)
44
45
#define INSTALL_UNOP_TI(ti, op, t, f) \
46
ti.install_unary_op \
47
(octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
48
49
#define INSTALL_NCUNOP_TI(ti, op, t, f) \
50
ti.install_non_const_unary_op \
51
(octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
52
53
#define INSTALL_BINOP_TI(ti, op, t1, t2, f) \
54
ti.install_binary_op \
55
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
56
CONCAT2 (oct_binop_, f));
57
58
#define INSTALL_CATOP_TI(ti, t1, t2, f) \
59
ti.install_cat_op \
60
(t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_catop_, f));
61
62
#define INSTALL_ASSIGNOP_TI(ti, op, t1, t2, f) \
63
ti.install_assign_op \
64
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
65
CONCAT2 (oct_assignop_, f));
66
67
#define INSTALL_ASSIGNANYOP_TI(ti, op, t1, f) \
68
ti.install_assignany_op \
69
(octave_value::op, t1::static_type_id (), CONCAT2 (oct_assignop_, f));
70
71
#define INSTALL_ASSIGNCONV_TI(ti, t1, t2, tr) \
72
ti.install_pref_assign_conv \
73
(t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
74
75
#define INSTALL_WIDENOP_TI(ti, t1, t2, f) \
76
ti.install_widening_op \
77
(t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_conv_, f));
78
79
#define DEFASSIGNOP(name, t1, t2) \
80
static octave_value \
81
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
82
const octave_value_list& idx, \
83
const octave_base_value& a2)
84
85
#define DEFASSIGNOP_FN(name, t1, t2, f) \
86
static octave_value \
87
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
88
const octave_value_list& idx, \
89
const octave_base_value& a2) \
90
{ \
91
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
92
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
93
\
94
v1.f (idx, v2.CONCAT2 (t1, _value) ()); \
95
return octave_value (); \
96
}
97
98
#define DEFNULLASSIGNOP_FN(name, t, f) \
99
static octave_value \
100
CONCAT2 (oct_assignop_, name) (octave_base_value& a, \
101
const octave_value_list& idx, \
102
const octave_base_value&) \
103
{ \
104
CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
105
\
106
v.f (idx); \
107
return octave_value (); \
108
}
109
110
#define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
111
static octave_value \
112
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
113
const octave_value_list& idx, \
114
const octave_base_value& a2) \
115
{ \
116
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
117
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
118
\
119
v1.f (idx, v2.CONCAT2 (e, _value) ()); \
120
return octave_value (); \
121
}
122
123
// FIXME: the following currently don't handle index.
124
#define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
125
static octave_value \
126
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
127
const octave_value_list& idx, \
128
const octave_base_value& a2) \
129
{ \
130
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
131
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
132
\
133
assert (idx.empty ()); \
134
v1.matrix_ref () op v2.CONCAT2 (f, _value) (); \
135
\
136
return octave_value (); \
137
}
138
139
#define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
140
static octave_value \
141
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
142
const octave_value_list& idx, \
143
const octave_base_value& a2) \
144
{ \
145
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
146
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
147
\
148
assert (idx.empty ()); \
149
fnop (v1.matrix_ref (), v2.CONCAT2 (f, _value) ()); \
150
\
151
return octave_value (); \
152
}
153
154
#define DEFASSIGNANYOP_FN(name, t1, f) \
155
static octave_value \
156
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
157
const octave_value_list& idx, \
158
const octave_value& a2) \
159
{ \
160
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
161
\
162
v1.f (idx, a2); \
163
return octave_value (); \
164
}
165
166
#define CONVDECL(name) \
167
static octave_base_value * \
168
CONCAT2 (oct_conv_, name) (const octave_base_value& a)
169
170
#define DEFCONV(name, a_dummy, b_dummy) \
171
CONVDECL (name)
172
173
#define DEFUNOPX(name, t) \
174
static octave_value \
175
CONCAT2 (oct_unop_, name) (const octave_base_value&)
176
177
#define DEFUNOP(name, t) \
178
static octave_value \
179
CONCAT2 (oct_unop_, name) (const octave_base_value& a)
180
181
#define DEFUNOP_OP(name, t, op) \
182
static octave_value \
183
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
184
{ \
185
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
186
return octave_value (op v.CONCAT2 (t, _value) ()); \
187
}
188
189
#define DEFNDUNOP_OP(name, t, e, op) \
190
static octave_value \
191
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
192
{ \
193
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
194
return octave_value (op v.CONCAT2 (e, _value) ()); \
195
}
196
197
// FIXME: in some cases, the constructor isn't necessary.
198
199
#define DEFUNOP_FN(name, t, f) \
200
static octave_value \
201
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
202
{ \
203
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
204
return octave_value (f (v.CONCAT2 (t, _value) ())); \
205
}
206
207
#define DEFNDUNOP_FN(name, t, e, f) \
208
static octave_value \
209
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
210
{ \
211
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
212
return octave_value (f (v.CONCAT2 (e, _value) ())); \
213
}
214
215
#define DEFNCUNOP_METHOD(name, t, method) \
216
static void \
217
CONCAT2 (oct_unop_, name) (octave_base_value& a) \
218
{ \
219
CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
220
v.method (); \
221
}
222
223
#define DEFBINOPX(name, t1, t2) \
224
static octave_value \
225
CONCAT2 (oct_binop_, name) (const octave_base_value&, \
226
const octave_base_value&)
227
228
#define DEFBINOP(name, t1, t2) \
229
static octave_value \
230
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
231
const octave_base_value& a2)
232
233
#define DEFBINOP_OP(name, t1, t2, op) \
234
static octave_value \
235
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
236
const octave_base_value& a2) \
237
{ \
238
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
239
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
240
\
241
return octave_value \
242
(v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
243
}
244
245
#define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
246
static octave_value \
247
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
248
const octave_base_value& a2) \
249
{ \
250
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
251
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
252
\
253
warn_complex_cmp (); \
254
\
255
return octave_value \
256
(v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
257
}
258
259
#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
260
static octave_value \
261
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
262
const octave_base_value& a2) \
263
{ \
264
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
265
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
266
\
267
if (octave::math::isnan (v1.CONCAT2 (t1, _value) ()) || octave::math::isnan (v2.CONCAT2 (t2, _value) ())) \
268
octave::err_nan_to_logical_conversion (); \
269
\
270
return octave_value \
271
(v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
272
}
273
274
#define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
275
static octave_value \
276
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
277
const octave_base_value& a2) \
278
{ \
279
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
280
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
281
\
282
return octave_value \
283
(v1.CONCAT2 (e1, _value) () op v2.CONCAT2 (e2, _value) ()); \
284
}
285
286
// FIXME: in some cases, the constructor isn't necessary.
287
288
#define DEFBINOP_FN(name, t1, t2, f) \
289
static octave_value \
290
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
291
const octave_base_value& a2) \
292
{ \
293
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
294
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
295
\
296
return octave_value (f (v1.CONCAT2 (t1, _value) (), v2.CONCAT2 (t2, _value) ())); \
297
}
298
299
#define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
300
static octave_value \
301
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
302
const octave_base_value& a2) \
303
{ \
304
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
305
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
306
\
307
return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
308
}
309
310
#define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
311
static octave_value \
312
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
313
const octave_base_value& a2) \
314
{ \
315
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
316
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
317
\
318
return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
319
}
320
321
#define DEFCATOPX(name, t1, t2) \
322
static octave_value \
323
CONCAT2 (oct_catop_, name) (const octave_base_value&, \
324
const octave_base_value&, \
325
const Array<octave_idx_type>& ra_idx)
326
327
#define DEFCATOP(name, t1, t2) \
328
static octave_value \
329
CONCAT2 (oct_catop_, name) (const octave_base_value& a1, \
330
const octave_base_value& a2, \
331
const Array<octave_idx_type>& ra_idx)
332
333
// FIXME: in some cases, the constructor isn't necessary.
334
335
#define DEFCATOP_FN(name, t1, t2, f) \
336
static octave_value \
337
CONCAT2 (oct_catop_, name) (const octave_base_value& a1, \
338
const octave_base_value& a2, \
339
const Array<octave_idx_type>& ra_idx) \
340
{ \
341
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
342
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
343
\
344
return octave_value (v1.CONCAT2 (t1, _value) () . f (v2.CONCAT2 (t2, _value) (), ra_idx)); \
345
}
346
347
#define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
348
static octave_value \
349
CONCAT2 (oct_catop_, name) (const octave_base_value& a1, \
350
const octave_base_value& a2, \
351
const Array<octave_idx_type>& ra_idx) \
352
{ \
353
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
354
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
355
\
356
return octave_value (v1.CONCAT2 (e1, _value) () . f (v2.CONCAT2 (e2, _value) (), ra_idx)); \
357
}
358
359
#define DEFNDCHARCATOP_FN(name, t1, t2, f) \
360
static octave_value \
361
CONCAT2 (oct_catop_, name) (const octave_base_value& a1, \
362
const octave_base_value& a2, \
363
const Array<octave_idx_type>& ra_idx) \
364
{ \
365
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
366
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
367
\
368
return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
369
((a1.is_sq_string () || a2.is_sq_string ()) \
370
? '\'' : '"')); \
371
}
372
373
// For compatibility, the second arg is always converted to the type
374
// of the first. Hmm.
375
376
#define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
377
static octave_value \
378
CONCAT2 (oct_catop_, name) (const octave_base_value& a1, \
379
const octave_base_value& a2, \
380
const Array<octave_idx_type>& ra_idx) \
381
{ \
382
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
383
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
384
\
385
return octave_value (tc1 (v1.CONCAT2 (e1, _value) ()) . f (tc2 (v2.CONCAT2 (e2, _value) ()), ra_idx)); \
386
}
387
388
#endif
Array-util.h
type_info
Definition:
ov-typeinfo.h:45
octave
Definition:
idx-vector.cc:46
libinterp
operators
ops.h
Generated on Sun Jun 26 2022 01:27:49 for GNU Octave by
1.9.4