GNU Octave
3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
libinterp
operators
ops.h
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 1996-2013 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 "
Array-util.h
"
28
29
// Concatenation macros that enforce argument prescan
30
#define CONCAT2X(x,y) x ## y
31
#define CONCAT2(x,y) CONCAT2X(x,y)
32
33
#define CONCAT3X(x,y,z) x ## y ## z
34
#define CONCAT3(x,y,z) CONCAT3X(x,y,z)
35
36
extern
void
install_ops
(
void
);
37
38
#define INSTALL_UNOP(op, t, f) \
39
octave_value_typeinfo::register_unary_op \
40
(octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
41
42
#define INSTALL_NCUNOP(op, t, f) \
43
octave_value_typeinfo::register_non_const_unary_op \
44
(octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
45
46
#define INSTALL_BINOP(op, t1, t2, f) \
47
octave_value_typeinfo::register_binary_op \
48
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
49
CONCAT2(oct_binop_, f));
50
51
#define INSTALL_CATOP(t1, t2, f) \
52
octave_value_typeinfo::register_cat_op \
53
(t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_catop_, f));
54
55
#define INSTALL_ASSIGNOP(op, t1, t2, f) \
56
octave_value_typeinfo::register_assign_op \
57
(octave_value::op, t1::static_type_id (), t2::static_type_id (), \
58
CONCAT2(oct_assignop_, f));
59
60
#define INSTALL_ASSIGNANYOP(op, t1, f) \
61
octave_value_typeinfo::register_assignany_op \
62
(octave_value::op, t1::static_type_id (), CONCAT2(oct_assignop_, f));
63
64
#define INSTALL_ASSIGNCONV(t1, t2, tr) \
65
octave_value_typeinfo::register_pref_assign_conv \
66
(t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
67
68
#define INSTALL_CONVOP(t1, t2, f) \
69
octave_value_typeinfo::register_type_conv_op \
70
(t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
71
72
#define INSTALL_WIDENOP(t1, t2, f) \
73
octave_value_typeinfo::register_widening_op \
74
(t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
75
76
#define CAST_UNOP_ARG(t) \
77
t v = dynamic_cast<t> (a)
78
79
#define CAST_BINOP_ARGS(t1, t2) \
80
t1 v1 = dynamic_cast<t1> (a1); \
81
t2 v2 = dynamic_cast<t2> (a2)
82
83
#define CAST_CONV_ARG(t) \
84
t v = dynamic_cast<t> (a)
85
86
#define ASSIGNOPDECL(name) \
87
static octave_value \
88
CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
89
const octave_value_list& idx, \
90
const octave_base_value& a2)
91
92
#define NULLASSIGNOPDECL(name) \
93
static octave_value \
94
CONCAT2(oct_assignop_, name) (octave_base_value& a, \
95
const octave_value_list& idx, \
96
const octave_base_value&)
97
98
#define ASSIGNANYOPDECL(name) \
99
static octave_value \
100
CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
101
const octave_value_list& idx, \
102
const octave_value& a2)
103
104
#define DEFASSIGNOP(name, t1, t2) \
105
ASSIGNOPDECL (name)
106
107
#define DEFASSIGNOP_FN(name, t1, t2, f) \
108
ASSIGNOPDECL (name) \
109
{ \
110
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
111
\
112
v1.f (idx, v2.CONCAT2(t1, _value) ()); \
113
return octave_value (); \
114
}
115
116
#define DEFNULLASSIGNOP_FN(name, t, f) \
117
NULLASSIGNOPDECL (name) \
118
{ \
119
CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
120
\
121
v.f (idx); \
122
return octave_value (); \
123
}
124
125
#define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
126
ASSIGNOPDECL (name) \
127
{ \
128
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
129
\
130
v1.f (idx, v2.CONCAT2(e, _value) ()); \
131
return octave_value (); \
132
}
133
134
// FIXME: the following currently don't handle index.
135
#define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
136
ASSIGNOPDECL (name) \
137
{ \
138
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
139
\
140
assert (idx.empty ()); \
141
v1.matrix_ref () op v2.CONCAT2(f, _value) (); \
142
\
143
return octave_value (); \
144
}
145
146
#define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
147
ASSIGNOPDECL (name) \
148
{ \
149
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
150
\
151
assert (idx.empty ()); \
152
fnop (v1.matrix_ref (), v2.CONCAT2(f, _value) ()); \
153
\
154
return octave_value (); \
155
}
156
157
#define DEFASSIGNANYOP_FN(name, t1, f) \
158
ASSIGNANYOPDECL (name) \
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 CONVDECLX(name) \
171
static octave_base_value * \
172
CONCAT2(oct_conv_, name) (const octave_base_value&)
173
174
#define DEFCONV(name, a_dummy, b_dummy) \
175
CONVDECL (name)
176
177
#define DEFCONVFNX(name, tfrom, ovtto, tto, e) \
178
CONVDECL (name) \
179
{ \
180
CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
181
\
182
return new CONCAT2(octave_, ovtto) (CONCAT2(tto, NDArray) (v.CONCAT2(e, array_value) ())); \
183
}
184
185
#define DEFCONVFNX2(name, tfrom, ovtto, e) \
186
CONVDECL (name) \
187
{ \
188
CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
189
\
190
return new CONCAT2(octave_, ovtto) (v.CONCAT2(e, array_value) ()); \
191
}
192
193
#define DEFDBLCONVFN(name, ovtfrom, e) \
194
CONVDECL (name) \
195
{ \
196
CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
197
\
198
return new octave_matrix (NDArray (v.CONCAT2(e, _value) ())); \
199
}
200
201
#define DEFFLTCONVFN(name, ovtfrom, e) \
202
CONVDECL (name) \
203
{ \
204
CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
205
\
206
return new octave_float_matrix (FloatNDArray (v.CONCAT2(e, _value) ())); \
207
}
208
209
#define DEFSTRINTCONVFN(name, tto) \
210
DEFCONVFNX(name, char_matrix_str, CONCAT2(tto, _matrix), tto, char_)
211
212
#define DEFSTRDBLCONVFN(name, tfrom) \
213
DEFCONVFNX(name, tfrom, matrix, , char_)
214
215
#define DEFSTRFLTCONVFN(name, tfrom) \
216
DEFCONVFNX(name, tfrom, float_matrix, Float, char_)
217
218
#define DEFCONVFN(name, tfrom, tto) \
219
DEFCONVFNX2 (name, tfrom, CONCAT2(tto, _matrix), CONCAT2(tto, _))
220
221
#define DEFCONVFN2(name, tfrom, sm, tto) \
222
DEFCONVFNX2 (name, CONCAT3(tfrom, _, sm), CONCAT2(tto, _matrix), CONCAT2(tto, _))
223
224
#define UNOPDECL(name, a) \
225
static octave_value \
226
CONCAT2(oct_unop_, name) (const octave_base_value& a)
227
228
#define DEFUNOPX(name, t) \
229
UNOPDECL (name, , )
230
231
#define DEFUNOP(name, t) \
232
UNOPDECL (name, a)
233
234
#define DEFUNOP_OP(name, t, op) \
235
UNOPDECL (name, a) \
236
{ \
237
CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
238
return octave_value (op v.CONCAT2(t, _value) ()); \
239
}
240
241
#define DEFNDUNOP_OP(name, t, e, op) \
242
UNOPDECL (name, a) \
243
{ \
244
CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
245
return octave_value (op v.CONCAT2(e, _value) ()); \
246
}
247
248
// FIXME: in some cases, the constructor isn't necessary.
249
250
#define DEFUNOP_FN(name, t, f) \
251
UNOPDECL (name, a) \
252
{ \
253
CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
254
return octave_value (f (v.CONCAT2(t, _value) ())); \
255
}
256
257
#define DEFNDUNOP_FN(name, t, e, f) \
258
UNOPDECL (name, a) \
259
{ \
260
CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
261
return octave_value (f (v.CONCAT2(e, _value) ())); \
262
}
263
264
#define DEFNCUNOP_METHOD(name, t, method) \
265
static void \
266
CONCAT2(oct_unop_, name) (octave_base_value& a) \
267
{ \
268
CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
269
v.method (); \
270
}
271
272
#define BINOPDECL(name, a1, a2) \
273
static octave_value \
274
CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2)
275
276
#define DEFBINOPX(name, t1, t2) \
277
BINOPDECL (name, , )
278
279
#define DEFBINOP(name, t1, t2) \
280
BINOPDECL (name, a1, a2)
281
282
#define DEFBINOP_OP(name, t1, t2, op) \
283
BINOPDECL (name, a1, a2) \
284
{ \
285
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
286
return octave_value \
287
(v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
288
}
289
290
#define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
291
BINOPDECL (name, a1, a2) \
292
{ \
293
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
294
gripe_warn_complex_cmp (); \
295
return octave_value \
296
(v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
297
}
298
299
#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
300
BINOPDECL (name, a1, a2) \
301
{ \
302
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
303
if (xisnan (v1.CONCAT2(t1, _value) ()) || xisnan (v2.CONCAT2(t2, _value) ())) \
304
{ \
305
gripe_nan_to_logical_conversion (); \
306
return octave_value (); \
307
} \
308
else \
309
return octave_value \
310
(v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
311
}
312
313
#define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
314
BINOPDECL (name, a1, a2) \
315
{ \
316
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
317
return octave_value \
318
(v1.CONCAT2(e1, _value) () op v2.CONCAT2(e2, _value) ()); \
319
}
320
321
// FIXME: in some cases, the constructor isn't necessary.
322
323
#define DEFBINOP_FN(name, t1, t2, f) \
324
BINOPDECL (name, a1, a2) \
325
{ \
326
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
327
return octave_value (f (v1.CONCAT2(t1, _value) (), v2.CONCAT2(t2, _value) ())); \
328
}
329
330
#define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
331
BINOPDECL (name, a1, a2) \
332
{ \
333
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
334
return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
335
}
336
337
#define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
338
BINOPDECL (name, a1, a2) \
339
{ \
340
CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
341
return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
342
}
343
344
#define CATOPDECL(name, a1, a2) \
345
static octave_value \
346
CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
347
const Array<octave_idx_type>& ra_idx)
348
349
#define DEFCATOPX(name, t1, t2) \
350
CATOPDECL (name, , )
351
352
#define DEFCATOP(name, t1, t2) \
353
CATOPDECL (name, a1, a2)
354
355
// FIXME: in some cases, the constructor isn't necessary.
356
357
#define DEFCATOP_FN(name, t1, t2, f) \
358
CATOPDECL (name, a1, a2) \
359
{ \
360
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
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
CATOPDECL (name, a1, a2) \
366
{ \
367
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
368
return octave_value (v1.CONCAT2(e1, _value) () . f (v2.CONCAT2(e2, _value) (), ra_idx)); \
369
}
370
371
#define DEFNDCHARCATOP_FN(name, t1, t2, f) \
372
CATOPDECL (name, a1, a2) \
373
{ \
374
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
375
\
376
return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
377
((a1.is_sq_string () || a2.is_sq_string ()) \
378
? '\'' : '"')); \
379
}
380
381
// For compatibility, the second arg is always converted to the type
382
// of the first. Hmm.
383
384
#define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
385
CATOPDECL (name, a1, a2) \
386
{ \
387
CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
388
return octave_value (tc1 (v1.CONCAT2(e1, _value) ()) . f (tc2 (v2.CONCAT2(e2, _value) ()), ra_idx)); \
389
}
390
391
#define CATOP_NONCONFORMANT(msg) \
392
gripe_nonconformant (msg, \
393
a1.rows (), a1.columns (), \
394
a2.rows (), a2.columns ()); \
395
return octave_value ()
396
397
#endif
Generated on Mon Dec 30 2013 03:04:37 for GNU Octave by
1.8.1.2