GNU Octave
4.4.1
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-2018 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
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
12
13
Octave is distributed in the hope that it will be useful, but
14
WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License 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
<https://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
namespace
octave
32
{
33
class
type_info;
34
}
35
36
// Concatenation macros that enforce argument prescan
37
#define CONCAT2X(x, y) x ## y
38
#define CONCAT2(x, y) CONCAT2X (x, y)
39
40
#define CONCAT3X(x, y, z) x ## y ## z
41
#define CONCAT3(x, y, z) CONCAT3X (x, y, z)
42
43
extern
void
install_ops
(
octave::type_info
&);
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
// The following INSTALL_* macros are obsolete.
80
81
#define INSTALL_UNOP(op, t, f) \
82
octave_value_typeinfo::register_unary_op \
83
(octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
84
85
#define INSTALL_NCUNOP(op, t, f) \
86
octave_value_typeinfo::register_non_const_unary_op \
87
(octave_value::op, t::static_type_id (), CONCAT2 (oct_unop_, f));
88
89
#define INSTALL_BINOP(op, t1, t2, f) \
90
octave_value_typeinfo::register_binary_op \
91
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
92
CONCAT2 (oct_binop_, f));
93
94
#define INSTALL_CATOP(t1, t2, f) \
95
octave_value_typeinfo::register_cat_op \
96
(t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_catop_, f));
97
98
#define INSTALL_ASSIGNOP(op, t1, t2, f) \
99
octave_value_typeinfo::register_assign_op \
100
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
101
CONCAT2 (oct_assignop_, f));
102
103
#define INSTALL_ASSIGNANYOP(op, t1, f) \
104
octave_value_typeinfo::register_assignany_op \
105
(octave_value::op, t1::static_type_id (), CONCAT2 (oct_assignop_, f));
106
107
#define INSTALL_ASSIGNCONV(t1, t2, tr) \
108
octave_value_typeinfo::register_pref_assign_conv \
109
(t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
110
111
#define INSTALL_WIDENOP(t1, t2, f) \
112
octave_value_typeinfo::register_widening_op \
113
(t1::static_type_id (), t2::static_type_id (), CONCAT2 (oct_conv_, f));
114
115
#define DEFASSIGNOP(name, t1, t2) \
116
static octave_value \
117
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
118
const octave_value_list& idx, \
119
const octave_base_value& a2)
120
121
#define DEFASSIGNOP_FN(name, t1, t2, f) \
122
static octave_value \
123
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
124
const octave_value_list& idx, \
125
const octave_base_value& a2) \
126
{ \
127
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
128
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
129
\
130
v1.f (idx, v2.CONCAT2 (t1, _value) ()); \
131
return octave_value (); \
132
}
133
134
#define DEFNULLASSIGNOP_FN(name, t, f) \
135
static octave_value \
136
CONCAT2 (oct_assignop_, name) (octave_base_value& a, \
137
const octave_value_list& idx, \
138
const octave_base_value&) \
139
{ \
140
CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
141
\
142
v.f (idx); \
143
return octave_value (); \
144
}
145
146
#define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
147
static octave_value \
148
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
149
const octave_value_list& idx, \
150
const octave_base_value& a2) \
151
{ \
152
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
153
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
154
\
155
v1.f (idx, v2.CONCAT2 (e, _value) ()); \
156
return octave_value (); \
157
}
158
159
// FIXME: the following currently don't handle index.
160
#define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
161
static octave_value \
162
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
163
const octave_value_list& idx, \
164
const octave_base_value& a2) \
165
{ \
166
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
167
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
168
\
169
assert (idx.empty ()); \
170
v1.matrix_ref () op v2.CONCAT2 (f, _value) (); \
171
\
172
return octave_value (); \
173
}
174
175
#define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
176
static octave_value \
177
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
178
const octave_value_list& idx, \
179
const octave_base_value& a2) \
180
{ \
181
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
182
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
183
\
184
assert (idx.empty ()); \
185
fnop (v1.matrix_ref (), v2.CONCAT2 (f, _value) ()); \
186
\
187
return octave_value (); \
188
}
189
190
#define DEFASSIGNANYOP_FN(name, t1, f) \
191
static octave_value \
192
CONCAT2 (oct_assignop_, name) (octave_base_value& a1, \
193
const octave_value_list& idx, \
194
const octave_value& a2) \
195
{ \
196
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
197
\
198
v1.f (idx, a2); \
199
return octave_value (); \
200
}
201
202
#define CONVDECL(name) \
203
static octave_base_value * \
204
CONCAT2 (oct_conv_, name) (const octave_base_value& a)
205
206
#define DEFCONV(name, a_dummy, b_dummy) \
207
CONVDECL (name)
208
209
#define DEFUNOPX(name, t) \
210
static octave_value \
211
CONCAT2 (oct_unop_, name) (const octave_base_value&)
212
213
#define DEFUNOP(name, t) \
214
static octave_value \
215
CONCAT2 (oct_unop_, name) (const octave_base_value& a)
216
217
#define DEFUNOP_OP(name, t, op) \
218
static octave_value \
219
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
220
{ \
221
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
222
return octave_value (op v.CONCAT2 (t, _value) ()); \
223
}
224
225
#define DEFNDUNOP_OP(name, t, e, op) \
226
static octave_value \
227
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
228
{ \
229
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
230
return octave_value (op v.CONCAT2 (e, _value) ()); \
231
}
232
233
// FIXME: in some cases, the constructor isn't necessary.
234
235
#define DEFUNOP_FN(name, t, f) \
236
static octave_value \
237
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
238
{ \
239
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
240
return octave_value (f (v.CONCAT2 (t, _value) ())); \
241
}
242
243
#define DEFNDUNOP_FN(name, t, e, f) \
244
static octave_value \
245
CONCAT2 (oct_unop_, name) (const octave_base_value& a) \
246
{ \
247
const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
248
return octave_value (f (v.CONCAT2 (e, _value) ())); \
249
}
250
251
#define DEFNCUNOP_METHOD(name, t, method) \
252
static void \
253
CONCAT2 (oct_unop_, name) (octave_base_value& a) \
254
{ \
255
CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a); \
256
v.method (); \
257
}
258
259
#define DEFBINOPX(name, t1, t2) \
260
static octave_value \
261
CONCAT2 (oct_binop_, name) (const octave_base_value&, \
262
const octave_base_value&)
263
264
#define DEFBINOP(name, t1, t2) \
265
static octave_value \
266
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
267
const octave_base_value& a2)
268
269
#define DEFBINOP_OP(name, t1, t2, 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 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
279
}
280
281
#define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
282
static octave_value \
283
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
284
const octave_base_value& a2) \
285
{ \
286
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
287
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
288
\
289
warn_complex_cmp (); \
290
\
291
return octave_value \
292
(v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
293
}
294
295
#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
296
static octave_value \
297
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
298
const octave_base_value& a2) \
299
{ \
300
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
301
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
302
\
303
if (octave::math::isnan (v1.CONCAT2 (t1, _value) ()) || octave::math::isnan (v2.CONCAT2 (t2, _value) ())) \
304
octave::err_nan_to_logical_conversion (); \
305
\
306
return octave_value \
307
(v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ()); \
308
}
309
310
#define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
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 \
319
(v1.CONCAT2 (e1, _value) () op v2.CONCAT2 (e2, _value) ()); \
320
}
321
322
// FIXME: in some cases, the constructor isn't necessary.
323
324
#define DEFBINOP_FN(name, t1, t2, f) \
325
static octave_value \
326
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
327
const octave_base_value& a2) \
328
{ \
329
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
330
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
331
\
332
return octave_value (f (v1.CONCAT2 (t1, _value) (), v2.CONCAT2 (t2, _value) ())); \
333
}
334
335
#define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
336
static octave_value \
337
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
338
const octave_base_value& a2) \
339
{ \
340
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
341
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
342
\
343
return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
344
}
345
346
#define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
347
static octave_value \
348
CONCAT2 (oct_binop_, name) (const octave_base_value& a1, \
349
const octave_base_value& a2) \
350
{ \
351
const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
352
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
353
\
354
return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
355
}
356
357
#define DEFCATOPX(name, t1, t2) \
358
static octave_value \
359
CONCAT2 (oct_catop_, name) (octave_base_value&, const octave_base_value&, \
360
const Array<octave_idx_type>& ra_idx)
361
362
#define DEFCATOP(name, t1, t2) \
363
static octave_value \
364
CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
365
const octave_base_value& a2, \
366
const Array<octave_idx_type>& ra_idx)
367
368
// FIXME: in some cases, the constructor isn't necessary.
369
370
#define DEFCATOP_FN(name, t1, t2, 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 (v1.CONCAT2 (t1, _value) () . f (v2.CONCAT2 (t2, _value) (), ra_idx)); \
380
}
381
382
#define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
383
static octave_value \
384
CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
385
const octave_base_value& a2, \
386
const Array<octave_idx_type>& ra_idx) \
387
{ \
388
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
389
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
390
\
391
return octave_value (v1.CONCAT2 (e1, _value) () . f (v2.CONCAT2 (e2, _value) (), ra_idx)); \
392
}
393
394
#define DEFNDCHARCATOP_FN(name, t1, t2, f) \
395
static octave_value \
396
CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
397
const octave_base_value& a2, \
398
const Array<octave_idx_type>& ra_idx) \
399
{ \
400
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
401
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
402
\
403
return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
404
((a1.is_sq_string () || a2.is_sq_string ()) \
405
? '\'' : '"')); \
406
}
407
408
// For compatibility, the second arg is always converted to the type
409
// of the first. Hmm.
410
411
#define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
412
static octave_value \
413
CONCAT2 (oct_catop_, name) (octave_base_value& a1, \
414
const octave_base_value& a2, \
415
const Array<octave_idx_type>& ra_idx) \
416
{ \
417
CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
418
const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
419
\
420
return octave_value (tc1 (v1.CONCAT2 (e1, _value) ()) . f (tc2 (v2.CONCAT2 (e2, _value) ()), ra_idx)); \
421
}
422
423
#endif
octave
Definition:
aepbalance.cc:44
install_ops
void install_ops(octave::type_info &)
Array-util.h
octave::type_info
Definition:
ov-typeinfo.h:39
libinterp
operators
ops.h
Generated on Sat Sep 1 2018 14:01:42 for GNU Octave by
1.8.14