Mercurial > hg > octave-nkf
annotate src/ops.h @ 7948:af10baa63915 ss-3-1-50
3.1.50 snapshot
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 18 Jul 2008 17:42:48 -0400 |
parents | 935be827eaf8 |
children | 2b8952e133c9 |
rev | line source |
---|---|
2376 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 2003, 2004, 2005, 2006, 2007 |
4 John W. Eaton | |
2376 | 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 | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2376 | 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 | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2376 | 21 |
22 */ | |
23 | |
24 #if !defined (octave_ops_h) | |
25 #define octave_ops_h 1 | |
26 | |
4669 | 27 #include "Array-util.h" |
28 | |
2376 | 29 extern void install_ops (void); |
30 | |
3203 | 31 #define INSTALL_UNOP(op, t, f) \ |
32 octave_value_typeinfo::register_unary_op \ | |
33 (octave_value::op, t::static_type_id (), oct_unop_ ## f); | |
34 | |
35 #define INSTALL_NCUNOP(op, t, f) \ | |
36 octave_value_typeinfo::register_non_const_unary_op \ | |
37 (octave_value::op, t::static_type_id (), oct_unop_ ## f); | |
38 | |
2376 | 39 #define INSTALL_BINOP(op, t1, t2, f) \ |
40 octave_value_typeinfo::register_binary_op \ | |
3203 | 41 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ |
42 oct_binop_ ## f); | |
2376 | 43 |
4915 | 44 #define INSTALL_CATOP(t1, t2, f) \ |
45 octave_value_typeinfo::register_cat_op \ | |
46 (t1::static_type_id (), t2::static_type_id (), oct_catop_ ## f); | |
47 | |
2879 | 48 #define INSTALL_ASSIGNOP(op, t1, t2, f) \ |
2376 | 49 octave_value_typeinfo::register_assign_op \ |
3203 | 50 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ |
51 oct_assignop_ ## f); | |
2376 | 52 |
3195 | 53 #define INSTALL_ASSIGNANYOP(op, t1, f) \ |
54 octave_value_typeinfo::register_assignany_op \ | |
3203 | 55 (octave_value::op, t1::static_type_id (), oct_assignop_ ## f); |
3195 | 56 |
2376 | 57 #define INSTALL_ASSIGNCONV(t1, t2, tr) \ |
58 octave_value_typeinfo::register_pref_assign_conv \ | |
59 (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ()); | |
60 | |
4901 | 61 #define INSTALL_CONVOP(t1, t2, f) \ |
62 octave_value_typeinfo::register_type_conv_op \ | |
63 (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f); | |
64 | |
2376 | 65 #define INSTALL_WIDENOP(t1, t2, f) \ |
66 octave_value_typeinfo::register_widening_op \ | |
3203 | 67 (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f); |
2376 | 68 |
69 #define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \ | |
70 xt xn = get_x; \ | |
71 yt yn = get_y; | |
72 | |
73 #define BOOL_OP2(x) \ | |
5275 | 74 octave_idx_type nr = x.rows (); \ |
75 octave_idx_type nc = x.columns (); | |
2376 | 76 |
77 #define BOOL_OP3(test) \ | |
2825 | 78 boolMatrix retval (nr, nc); \ |
5275 | 79 for (octave_idx_type j = 0; j < nc; j++) \ |
80 for (octave_idx_type i = 0; i < nr; i++) \ | |
2376 | 81 retval (i, j) = test; \ |
82 return retval; | |
83 | |
2601 | 84 #define SC_MX_BOOL_OP(st, sn, get_s, mt, mn, get_m, test, empty_result) \ |
2376 | 85 do \ |
86 { \ | |
87 BOOL_OP1 (st, sn, get_s, mt, mn, get_m) \ | |
88 BOOL_OP2 (mn) \ | |
2612 | 89 if (nr == 0 || nc == 0) \ |
2601 | 90 return empty_result; \ |
2376 | 91 BOOL_OP3 (test) \ |
92 } \ | |
93 while (0) | |
94 | |
2601 | 95 #define MX_SC_BOOL_OP(mt, mn, get_m, st, sn, get_s, test, empty_result) \ |
2376 | 96 do \ |
97 { \ | |
98 BOOL_OP1 (mt, mn, get_m, st, sn, get_s) \ | |
99 BOOL_OP2 (mn) \ | |
2612 | 100 if (nr == 0 || nc == 0) \ |
2601 | 101 return empty_result; \ |
2376 | 102 BOOL_OP3 (test) \ |
103 } \ | |
104 while (0) | |
105 | |
106 #define MX_MX_BOOL_OP(m1t, m1n, get_m1, m2t, m2n, get_m2, test, op, \ | |
2613 | 107 one_empty_result, two_empty_result) \ |
2376 | 108 do \ |
109 { \ | |
110 BOOL_OP1 (m1t, m1n, get_m1, m2t, m2n, get_m2) \ | |
5275 | 111 octave_idx_type m1_nr = m1n.rows (); \ |
112 octave_idx_type m1_nc = m1n.cols (); \ | |
113 octave_idx_type m2_nr = m2n.rows (); \ | |
114 octave_idx_type m2_nc = m2n.cols (); \ | |
2613 | 115 if (m1_nr == m2_nr && m1_nc == m2_nc) \ |
2376 | 116 { \ |
2613 | 117 if (m1_nr == 0 && m1_nc == 0) \ |
118 return two_empty_result; \ | |
119 else \ | |
120 { \ | |
121 BOOL_OP2 (m1n) \ | |
122 BOOL_OP3 (test) \ | |
123 } \ | |
2376 | 124 } \ |
2613 | 125 else \ |
126 { \ | |
127 if ((m1_nr == 0 && m1_nc == 0) || (m2_nr == 0 && m2_nc == 0)) \ | |
128 return one_empty_result; \ | |
129 else \ | |
130 { \ | |
131 gripe_nonconformant ("operator " op, m1_nr, m1_nc, \ | |
132 m2_nr, m2_nc); \ | |
2825 | 133 return boolMatrix (); \ |
2613 | 134 } \ |
135 } \ | |
2376 | 136 } \ |
137 while (0) | |
138 | |
3203 | 139 #define CAST_UNOP_ARG(t) \ |
5760 | 140 t v = dynamic_cast<t> (a) |
3203 | 141 |
2376 | 142 #define CAST_BINOP_ARGS(t1, t2) \ |
5760 | 143 t1 v1 = dynamic_cast<t1> (a1); \ |
144 t2 v2 = dynamic_cast<t2> (a2) | |
2376 | 145 |
146 #define CAST_CONV_ARG(t) \ | |
5760 | 147 t v = dynamic_cast<t> (a) |
2376 | 148 |
2914 | 149 #define ASSIGNOPDECL(name) \ |
150 static octave_value \ | |
5759 | 151 oct_assignop_ ## name (octave_base_value& a1, \ |
152 const octave_value_list& idx, \ | |
153 const octave_base_value& a2) | |
154 | |
155 #define ASSIGNANYOPDECL(name) \ | |
156 static octave_value \ | |
157 oct_assignop_ ## name (octave_base_value& a1, \ | |
3203 | 158 const octave_value_list& idx, \ |
159 const octave_value& a2) | |
2914 | 160 |
161 #define DEFASSIGNOP(name, t1, t2) \ | |
162 ASSIGNOPDECL (name) | |
163 | |
164 #define DEFASSIGNOP_FN(name, t1, t2, f) \ | |
165 ASSIGNOPDECL (name) \ | |
166 { \ | |
167 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ | |
168 \ | |
169 v1.f (idx, v2.t1 ## _value ()); \ | |
170 return octave_value (); \ | |
171 } | |
172 | |
4686 | 173 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \ |
174 ASSIGNOPDECL (name) \ | |
175 { \ | |
176 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ | |
177 \ | |
178 v1.f (idx, v2.e ## _value ()); \ | |
179 return octave_value (); \ | |
180 } | |
181 | |
3195 | 182 #define DEFASSIGNANYOP_FN(name, t1, f) \ |
5759 | 183 ASSIGNANYOPDECL (name) \ |
3195 | 184 { \ |
5760 | 185 octave_ ## t1& v1 = dynamic_cast<octave_ ## t1&> (a1); \ |
3195 | 186 \ |
187 v1.f (idx, a2); \ | |
188 return octave_value (); \ | |
189 } | |
190 | |
2914 | 191 #define CONVDECL(name) \ |
5759 | 192 static octave_base_value * \ |
193 oct_conv_ ## name (const octave_base_value& a) | |
3203 | 194 |
195 #define CONVDECLX(name) \ | |
5759 | 196 static octave_base_value * \ |
197 oct_conv_ ## name (const octave_base_value&) | |
2914 | 198 |
4901 | 199 #define DEFCONV(name, a_dummy, b_dummy) \ |
2914 | 200 CONVDECL (name) |
201 | |
4901 | 202 #define DEFCONVFNX(name, tfrom, ovtto, tto, e) \ |
203 CONVDECL (name) \ | |
204 { \ | |
205 CAST_CONV_ARG (const octave_ ## tfrom&); \ | |
206 \ | |
207 return new octave_ ## ovtto (tto ## NDArray (v.e ## array_value ())); \ | |
208 } | |
209 | |
210 #define DEFDBLCONVFN(name, ovtfrom, e) \ | |
211 CONVDECL (name) \ | |
212 { \ | |
213 CAST_CONV_ARG (const octave_ ## ovtfrom&); \ | |
214 \ | |
215 return new octave_matrix (NDArray (v.e ## _value ())); \ | |
216 } | |
217 | |
5032 | 218 #define DEFSTRINTCONVFN(name, tto) \ |
219 DEFCONVFNX(name, char_matrix_str, tto ## _matrix, tto, char_) | |
220 | |
5992 | 221 #define DEFSTRDBLCONVFN(name, tfrom) \ |
222 DEFCONVFNX(name, tfrom, matrix, , char_) | |
5032 | 223 |
4901 | 224 #define DEFCONVFN(name, tfrom, tto) \ |
225 DEFCONVFNX (name, tfrom, tto ## _matrix, tto, ) | |
226 | |
227 #define DEFCONVFN2(name, tfrom, sm, tto) \ | |
228 DEFCONVFNX (name, tfrom ## _ ## sm, tto ## _matrix, tto, tfrom ## _) | |
229 | |
3203 | 230 #define UNOPDECL(name, a) \ |
231 static octave_value \ | |
5759 | 232 oct_unop_ ## name (const octave_base_value& a) |
3203 | 233 |
234 #define DEFUNOPX(name, t) \ | |
235 UNOPDECL (name, , ) | |
236 | |
237 #define DEFUNOP(name, t) \ | |
238 UNOPDECL (name, a) | |
239 | |
240 #define DEFUNOP_OP(name, t, op) \ | |
241 UNOPDECL (name, a) \ | |
242 { \ | |
243 CAST_UNOP_ARG (const octave_ ## t&); \ | |
244 return octave_value (op v.t ## _value ()); \ | |
245 } | |
246 | |
4550 | 247 #define DEFNDUNOP_OP(name, t, e, op) \ |
4543 | 248 UNOPDECL (name, a) \ |
249 { \ | |
250 CAST_UNOP_ARG (const octave_ ## t&); \ | |
4550 | 251 return octave_value (op v.e ## _value ()); \ |
4543 | 252 } |
253 | |
5775 | 254 // FIXME -- in some cases, the constructor isn't necessary. |
3203 | 255 |
256 #define DEFUNOP_FN(name, t, f) \ | |
257 UNOPDECL (name, a) \ | |
258 { \ | |
259 CAST_UNOP_ARG (const octave_ ## t&); \ | |
260 return octave_value (f (v.t ## _value ())); \ | |
261 } | |
262 | |
4550 | 263 #define DEFNDUNOP_FN(name, t, e, f) \ |
4543 | 264 UNOPDECL (name, a) \ |
265 { \ | |
266 CAST_UNOP_ARG (const octave_ ## t&); \ | |
4550 | 267 return octave_value (f (v.e ## _value ())); \ |
4543 | 268 } |
269 | |
3203 | 270 #define DEFNCUNOP_METHOD(name, t, method) \ |
271 static void \ | |
5759 | 272 oct_unop_ ## name (octave_base_value& a) \ |
3203 | 273 { \ |
274 CAST_UNOP_ARG (octave_ ## t&); \ | |
275 v.method (); \ | |
276 } | |
277 | |
2914 | 278 #define BINOPDECL(name, a1, a2) \ |
279 static octave_value \ | |
5759 | 280 oct_binop_ ## name (const octave_base_value& a1, const octave_base_value& a2) |
2914 | 281 |
282 #define DEFBINOPX(name, t1, t2) \ | |
283 BINOPDECL (name, , ) | |
284 | |
285 #define DEFBINOP(name, t1, t2) \ | |
286 BINOPDECL (name, a1, a2) | |
287 | |
288 #define DEFBINOP_OP(name, t1, t2, op) \ | |
289 BINOPDECL (name, a1, a2) \ | |
290 { \ | |
291 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ | |
292 return octave_value \ | |
293 (v1.t1 ## _value () op v2.t2 ## _value ()); \ | |
294 } | |
295 | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
296 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
297 BINOPDECL (name, a1, a2) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
298 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
299 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
300 if (xisnan (v1.t1 ## _value ()) || xisnan (v2.t2 ## _value ())) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
301 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
302 error ("invalid conversion from NaN to logical"); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
303 return octave_value (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
304 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
305 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
306 return octave_value \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
307 (v1.t1 ## _value () op v2.t2 ## _value ()); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
308 } |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
309 |
4543 | 310 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \ |
311 BINOPDECL (name, a1, a2) \ | |
312 { \ | |
313 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ | |
314 return octave_value \ | |
315 (v1.e1 ## _value () op v2.e2 ## _value ()); \ | |
316 } | |
317 | |
5775 | 318 // FIXME -- in some cases, the constructor isn't necessary. |
2914 | 319 |
320 #define DEFBINOP_FN(name, t1, t2, f) \ | |
321 BINOPDECL (name, a1, a2) \ | |
322 { \ | |
323 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ | |
324 return octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \ | |
325 } | |
326 | |
4543 | 327 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \ |
328 BINOPDECL (name, a1, a2) \ | |
329 { \ | |
330 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ | |
331 return octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \ | |
332 } | |
333 | |
2914 | 334 #define BINOP_NONCONFORMANT(msg) \ |
335 gripe_nonconformant (msg, \ | |
336 a1.rows (), a1.columns (), \ | |
337 a2.rows (), a2.columns ()); \ | |
338 return octave_value () | |
339 | |
4915 | 340 #define CATOPDECL(name, a1, a2) \ |
341 static octave_value \ | |
5759 | 342 oct_catop_ ## name (octave_base_value& a1, const octave_base_value& a2, \ |
6871 | 343 const Array<octave_idx_type>& ra_idx) |
4915 | 344 |
345 #define DEFCATOPX(name, t1, t2) \ | |
346 CATOPDECL (name, , ) | |
347 | |
348 #define DEFCATOP(name, t1, t2) \ | |
349 CATOPDECL (name, a1, a2) | |
350 | |
5775 | 351 // FIXME -- in some cases, the constructor isn't necessary. |
4915 | 352 |
353 #define DEFCATOP_FN(name, t1, t2, f) \ | |
5075 | 354 CATOPDECL (name, a1, a2) \ |
4915 | 355 { \ |
5073 | 356 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ |
5533 | 357 return octave_value (v1.t1 ## _value () . f (v2.t2 ## _value (), ra_idx)); \ |
4915 | 358 } |
359 | |
5075 | 360 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \ |
361 CATOPDECL (name, a1, a2) \ | |
4915 | 362 { \ |
5073 | 363 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ |
5533 | 364 return octave_value (v1.e1 ## _value () . f (v2.e2 ## _value (), ra_idx)); \ |
365 } | |
366 | |
367 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \ | |
368 CATOPDECL (name, a1, a2) \ | |
369 { \ | |
370 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ | |
371 \ | |
372 return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \ | |
373 true, ((a1.is_sq_string () || a2.is_sq_string ()) \ | |
374 ? '\'' : '"')); \ | |
4915 | 375 } |
376 | |
5075 | 377 // For compatibility, the second arg is always converted to the type |
378 // of the first. Hmm. | |
379 | |
380 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \ | |
381 CATOPDECL (name, a1, a2) \ | |
382 { \ | |
383 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ | |
384 return octave_value (tc1 (v1.e1 ## _value ()) . f (tc2 (v2.e2 ## _value ()), ra_idx)); \ | |
385 } | |
386 | |
4915 | 387 #define CATOP_NONCONFORMANT(msg) \ |
388 gripe_nonconformant (msg, \ | |
389 a1.rows (), a1.columns (), \ | |
390 a2.rows (), a2.columns ()); \ | |
391 return octave_value () | |
392 | |
2376 | 393 #endif |
394 | |
395 /* | |
396 ;;; Local Variables: *** | |
397 ;;; mode: C++ *** | |
398 ;;; End: *** | |
399 */ |