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