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