00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if !defined (octave_ops_h)
00026 #define octave_ops_h 1
00027
00028 #include "Array-util.h"
00029
00030
00031 #define CONCAT2X(x,y) x ## y
00032 #define CONCAT2(x,y) CONCAT2X(x,y)
00033
00034 #define CONCAT3X(x,y,z) x ## y ## z
00035 #define CONCAT3(x,y,z) CONCAT3X(x,y,z)
00036
00037 extern void install_ops (void);
00038
00039 #define INSTALL_UNOP(op, t, f) \
00040 octave_value_typeinfo::register_unary_op \
00041 (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
00042
00043 #define INSTALL_NCUNOP(op, t, f) \
00044 octave_value_typeinfo::register_non_const_unary_op \
00045 (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
00046
00047 #define INSTALL_BINOP(op, t1, t2, f) \
00048 octave_value_typeinfo::register_binary_op \
00049 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
00050 CONCAT2(oct_binop_, f));
00051
00052 #define INSTALL_CATOP(t1, t2, f) \
00053 octave_value_typeinfo::register_cat_op \
00054 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_catop_, f));
00055
00056 #define INSTALL_ASSIGNOP(op, t1, t2, f) \
00057 octave_value_typeinfo::register_assign_op \
00058 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
00059 CONCAT2(oct_assignop_, f));
00060
00061 #define INSTALL_ASSIGNANYOP(op, t1, f) \
00062 octave_value_typeinfo::register_assignany_op \
00063 (octave_value::op, t1::static_type_id (), CONCAT2(oct_assignop_, f));
00064
00065 #define INSTALL_ASSIGNCONV(t1, t2, tr) \
00066 octave_value_typeinfo::register_pref_assign_conv \
00067 (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
00068
00069 #define INSTALL_CONVOP(t1, t2, f) \
00070 octave_value_typeinfo::register_type_conv_op \
00071 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
00072
00073 #define INSTALL_WIDENOP(t1, t2, f) \
00074 octave_value_typeinfo::register_widening_op \
00075 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
00076
00077 #define CAST_UNOP_ARG(t) \
00078 t v = dynamic_cast<t> (a)
00079
00080 #define CAST_BINOP_ARGS(t1, t2) \
00081 t1 v1 = dynamic_cast<t1> (a1); \
00082 t2 v2 = dynamic_cast<t2> (a2)
00083
00084 #define CAST_CONV_ARG(t) \
00085 t v = dynamic_cast<t> (a)
00086
00087 #define ASSIGNOPDECL(name) \
00088 static octave_value \
00089 CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
00090 const octave_value_list& idx, \
00091 const octave_base_value& a2)
00092
00093 #define NULLASSIGNOPDECL(name) \
00094 static octave_value \
00095 CONCAT2(oct_assignop_, name) (octave_base_value& a, \
00096 const octave_value_list& idx, \
00097 const octave_base_value&)
00098
00099 #define ASSIGNANYOPDECL(name) \
00100 static octave_value \
00101 CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
00102 const octave_value_list& idx, \
00103 const octave_value& a2)
00104
00105 #define DEFASSIGNOP(name, t1, t2) \
00106 ASSIGNOPDECL (name)
00107
00108 #define DEFASSIGNOP_FN(name, t1, t2, f) \
00109 ASSIGNOPDECL (name) \
00110 { \
00111 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00112 \
00113 v1.f (idx, v2.CONCAT2(t1, _value) ()); \
00114 return octave_value (); \
00115 }
00116
00117 #define DEFNULLASSIGNOP_FN(name, t, f) \
00118 NULLASSIGNOPDECL (name) \
00119 { \
00120 CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
00121 \
00122 v.f (idx); \
00123 return octave_value (); \
00124 }
00125
00126 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
00127 ASSIGNOPDECL (name) \
00128 { \
00129 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00130 \
00131 v1.f (idx, v2.CONCAT2(e, _value) ()); \
00132 return octave_value (); \
00133 }
00134
00135
00136 #define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
00137 ASSIGNOPDECL (name) \
00138 { \
00139 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00140 \
00141 assert (idx.empty ()); \
00142 v1.matrix_ref () op v2.CONCAT2(f, _value) (); \
00143 \
00144 return octave_value (); \
00145 }
00146
00147 #define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
00148 ASSIGNOPDECL (name) \
00149 { \
00150 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00151 \
00152 assert (idx.empty ()); \
00153 fnop (v1.matrix_ref (), v2.CONCAT2(f, _value) ()); \
00154 \
00155 return octave_value (); \
00156 }
00157
00158 #define DEFASSIGNANYOP_FN(name, t1, f) \
00159 ASSIGNANYOPDECL (name) \
00160 { \
00161 CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
00162 \
00163 v1.f (idx, a2); \
00164 return octave_value (); \
00165 }
00166
00167 #define CONVDECL(name) \
00168 static octave_base_value * \
00169 CONCAT2(oct_conv_, name) (const octave_base_value& a)
00170
00171 #define CONVDECLX(name) \
00172 static octave_base_value * \
00173 CONCAT2(oct_conv_, name) (const octave_base_value&)
00174
00175 #define DEFCONV(name, a_dummy, b_dummy) \
00176 CONVDECL (name)
00177
00178 #define DEFCONVFNX(name, tfrom, ovtto, tto, e) \
00179 CONVDECL (name) \
00180 { \
00181 CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
00182 \
00183 return new CONCAT2(octave_, ovtto) (CONCAT2(tto, NDArray) (v.CONCAT2(e, array_value) ())); \
00184 }
00185
00186 #define DEFCONVFNX2(name, tfrom, ovtto, e) \
00187 CONVDECL (name) \
00188 { \
00189 CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
00190 \
00191 return new CONCAT2(octave_, ovtto) (v.CONCAT2(e, array_value) ()); \
00192 }
00193
00194 #define DEFDBLCONVFN(name, ovtfrom, e) \
00195 CONVDECL (name) \
00196 { \
00197 CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
00198 \
00199 return new octave_matrix (NDArray (v.CONCAT2(e, _value) ())); \
00200 }
00201
00202 #define DEFFLTCONVFN(name, ovtfrom, e) \
00203 CONVDECL (name) \
00204 { \
00205 CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
00206 \
00207 return new octave_float_matrix (FloatNDArray (v.CONCAT2(e, _value) ())); \
00208 }
00209
00210 #define DEFSTRINTCONVFN(name, tto) \
00211 DEFCONVFNX(name, char_matrix_str, CONCAT2(tto, _matrix), tto, char_)
00212
00213 #define DEFSTRDBLCONVFN(name, tfrom) \
00214 DEFCONVFNX(name, tfrom, matrix, , char_)
00215
00216 #define DEFSTRFLTCONVFN(name, tfrom) \
00217 DEFCONVFNX(name, tfrom, float_matrix, Float, char_)
00218
00219 #define DEFCONVFN(name, tfrom, tto) \
00220 DEFCONVFNX2 (name, tfrom, CONCAT2(tto, _matrix), CONCAT2(tto, _))
00221
00222 #define DEFCONVFN2(name, tfrom, sm, tto) \
00223 DEFCONVFNX2 (name, CONCAT3(tfrom, _, sm), CONCAT2(tto, _matrix), CONCAT2(tto, _))
00224
00225 #define UNOPDECL(name, a) \
00226 static octave_value \
00227 CONCAT2(oct_unop_, name) (const octave_base_value& a)
00228
00229 #define DEFUNOPX(name, t) \
00230 UNOPDECL (name, , )
00231
00232 #define DEFUNOP(name, t) \
00233 UNOPDECL (name, a)
00234
00235 #define DEFUNOP_OP(name, t, op) \
00236 UNOPDECL (name, a) \
00237 { \
00238 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
00239 return octave_value (op v.CONCAT2(t, _value) ()); \
00240 }
00241
00242 #define DEFNDUNOP_OP(name, t, e, op) \
00243 UNOPDECL (name, a) \
00244 { \
00245 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
00246 return octave_value (op v.CONCAT2(e, _value) ()); \
00247 }
00248
00249
00250
00251 #define DEFUNOP_FN(name, t, f) \
00252 UNOPDECL (name, a) \
00253 { \
00254 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
00255 return octave_value (f (v.CONCAT2(t, _value) ())); \
00256 }
00257
00258 #define DEFNDUNOP_FN(name, t, e, f) \
00259 UNOPDECL (name, a) \
00260 { \
00261 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
00262 return octave_value (f (v.CONCAT2(e, _value) ())); \
00263 }
00264
00265 #define DEFNCUNOP_METHOD(name, t, method) \
00266 static void \
00267 CONCAT2(oct_unop_, name) (octave_base_value& a) \
00268 { \
00269 CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
00270 v.method (); \
00271 }
00272
00273 #define BINOPDECL(name, a1, a2) \
00274 static octave_value \
00275 CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2)
00276
00277 #define DEFBINOPX(name, t1, t2) \
00278 BINOPDECL (name, , )
00279
00280 #define DEFBINOP(name, t1, t2) \
00281 BINOPDECL (name, a1, a2)
00282
00283 #define DEFBINOP_OP(name, t1, t2, op) \
00284 BINOPDECL (name, a1, a2) \
00285 { \
00286 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00287 return octave_value \
00288 (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
00289 }
00290
00291 #define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
00292 BINOPDECL (name, a1, a2) \
00293 { \
00294 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00295 gripe_warn_complex_cmp (); \
00296 return octave_value \
00297 (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
00298 }
00299
00300 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
00301 BINOPDECL (name, a1, a2) \
00302 { \
00303 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00304 if (xisnan (v1.CONCAT2(t1, _value) ()) || xisnan (v2.CONCAT2(t2, _value) ())) \
00305 { \
00306 error ("invalid conversion from NaN to logical"); \
00307 return octave_value (); \
00308 } \
00309 else \
00310 return octave_value \
00311 (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
00312 }
00313
00314 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
00315 BINOPDECL (name, a1, a2) \
00316 { \
00317 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00318 return octave_value \
00319 (v1.CONCAT2(e1, _value) () op v2.CONCAT2(e2, _value) ()); \
00320 }
00321
00322
00323
00324 #define DEFBINOP_FN(name, t1, t2, f) \
00325 BINOPDECL (name, a1, a2) \
00326 { \
00327 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00328 return octave_value (f (v1.CONCAT2(t1, _value) (), v2.CONCAT2(t2, _value) ())); \
00329 }
00330
00331 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
00332 BINOPDECL (name, a1, a2) \
00333 { \
00334 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00335 return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
00336 }
00337
00338 #define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
00339 BINOPDECL (name, a1, a2) \
00340 { \
00341 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00342 return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
00343 }
00344
00345 #define BINOP_NONCONFORMANT(msg) \
00346 gripe_nonconformant (msg, \
00347 a1.rows (), a1.columns (), \
00348 a2.rows (), a2.columns ()); \
00349 return octave_value ()
00350
00351 #define CATOPDECL(name, a1, a2) \
00352 static octave_value \
00353 CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
00354 const Array<octave_idx_type>& ra_idx)
00355
00356 #define DEFCATOPX(name, t1, t2) \
00357 CATOPDECL (name, , )
00358
00359 #define DEFCATOP(name, t1, t2) \
00360 CATOPDECL (name, a1, a2)
00361
00362
00363
00364 #define DEFCATOP_FN(name, t1, t2, f) \
00365 CATOPDECL (name, a1, a2) \
00366 { \
00367 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00368 return octave_value (v1.CONCAT2(t1, _value) () . f (v2.CONCAT2(t2, _value) (), ra_idx)); \
00369 }
00370
00371 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
00372 CATOPDECL (name, a1, a2) \
00373 { \
00374 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00375 return octave_value (v1.CONCAT2(e1, _value) () . f (v2.CONCAT2(e2, _value) (), ra_idx)); \
00376 }
00377
00378 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \
00379 CATOPDECL (name, a1, a2) \
00380 { \
00381 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00382 \
00383 return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
00384 ((a1.is_sq_string () || a2.is_sq_string ()) \
00385 ? '\'' : '"')); \
00386 }
00387
00388
00389
00390
00391 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
00392 CATOPDECL (name, a1, a2) \
00393 { \
00394 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
00395 return octave_value (tc1 (v1.CONCAT2(e1, _value) ()) . f (tc2 (v2.CONCAT2(e2, _value) ()), ra_idx)); \
00396 }
00397
00398 #define CATOP_NONCONFORMANT(msg) \
00399 gripe_nonconformant (msg, \
00400 a1.rows (), a1.columns (), \
00401 a2.rows (), a2.columns ()); \
00402 return octave_value ()
00403
00404 #endif
00405
00406
00407
00408
00409
00410