comparison libinterp/interp-core/mex.cc @ 15355:a291f850743c draft

modernize mxArray class hierarchy * mxarray.in.h: Move mxArray_base class definition here from mex.cc. Don't derive mxArray_base from mxArray. Move all virtual tags from mxArray functions to the corresponding mxArray_base functions. (mxArray_base::as_mxArray): New virtual function. (mxArray::dup): Attempt as_mxArray conversion first. If that succeeds, set name of copy. Othewise, duplicate the rep object. (struct xmxArray): Delete. (mxArray_base::octave_value as_octave_value): Now public. (mxArray_octave_value::octave_value as_octave_value): Now public. (mxArray_number::octave_value as_octave_value): Now public. (mxArray_sparse::octave_value as_octave_value): Now public. (mxArray_struct::octave_value as_octave_value): Now public. (mxArray_cell::octave_value as_octave_value): Now public. (mxArray::mxArray (const xmxArray&)): Delete. (mxArray::mxArray (mxArray_base*, const char*)): Arg is now mxArray_base*, not mxArray*. (mxArray::rep): Now mxArray_base*, not mxArray*. * mex.cc (mxArray_octave_value::dup): Return mxArray_base*, not mxArray*. Don't attempt conversion from octave_value to mxArray here. (mxArray_octave_value::as_mxArray): New function. (mxArray_number::dup): Return mxArray_base*, not mxArray_number*. (mxArray_sparse::dup): Return mxArray_base*, not mxArray_sparse*. (mxArray_struct::dup): Return mxArray_base*, not mxArray_struct*. (mxArray_cell::dup): Return mxArray_base*, not mxArray_dup*.
author John W. Eaton <jwe@octave.org>
date Tue, 11 Sep 2012 13:38:44 -0400
parents 61822c866ba1
children 5f3a69a309a7
comparison
equal deleted inserted replaced
15354:6a0c0d3d60b6 15355:a291f850743c
102 return retval; 102 return retval;
103 } 103 }
104 104
105 // ------------------------------------------------------------------ 105 // ------------------------------------------------------------------
106 106
107 // A class to provide the default implemenation of some of the virtual 107 void
108 // functions declared in the mxArray class. 108 mxArray_base::error (const char *msg) const
109 109 {
110 class mxArray_base : public mxArray 110 // FIXME
111 { 111 ::error ("%s", msg);
112 protected: 112 }
113
114 mxArray_base (void) : mxArray (xmxArray ()) { }
115
116 public:
117
118 mxArray *dup (void) const = 0;
119
120 ~mxArray_base (void) { }
121
122 bool is_octave_value (void) const { return false; }
123
124 int is_cell (void) const = 0;
125
126 int is_char (void) const = 0;
127
128 int is_class (const char *name_arg) const
129 {
130 int retval = 0;
131
132 const char *cname = get_class_name ();
133
134 if (cname && name_arg)
135 retval = ! strcmp (cname, name_arg);
136
137 return retval;
138 }
139
140 int is_complex (void) const = 0;
141
142 int is_double (void) const = 0;
143
144 int is_function_handle (void) const = 0;
145
146 int is_int16 (void) const = 0;
147
148 int is_int32 (void) const = 0;
149
150 int is_int64 (void) const = 0;
151
152 int is_int8 (void) const = 0;
153
154 int is_logical (void) const = 0;
155
156 int is_numeric (void) const = 0;
157
158 int is_single (void) const = 0;
159
160 int is_sparse (void) const = 0;
161
162 int is_struct (void) const = 0;
163
164 int is_uint16 (void) const = 0;
165
166 int is_uint32 (void) const = 0;
167
168 int is_uint64 (void) const = 0;
169
170 int is_uint8 (void) const = 0;
171
172 int is_logical_scalar (void) const
173 {
174 return is_logical () && get_number_of_elements () == 1;
175 }
176
177 int is_logical_scalar_true (void) const = 0;
178
179 mwSize get_m (void) const = 0;
180
181 mwSize get_n (void) const = 0;
182
183 mwSize *get_dimensions (void) const = 0;
184
185 mwSize get_number_of_dimensions (void) const = 0;
186
187 void set_m (mwSize m) = 0;
188
189 void set_n (mwSize n) = 0;
190
191 void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0;
192
193 mwSize get_number_of_elements (void) const = 0;
194
195 int is_empty (void) const = 0;
196
197 mxClassID get_class_id (void) const = 0;
198
199 const char *get_class_name (void) const = 0;
200
201 void set_class_name (const char *name_arg) = 0;
202
203 mxArray *get_cell (mwIndex /*idx*/) const
204 {
205 invalid_type_error ();
206 return 0;
207 }
208
209 void set_cell (mwIndex idx, mxArray *val) = 0;
210
211 double get_scalar (void) const = 0;
212
213 void *get_data (void) const = 0;
214
215 void *get_imag_data (void) const = 0;
216
217 void set_data (void *pr) = 0;
218
219 void set_imag_data (void *pi) = 0;
220
221 mwIndex *get_ir (void) const = 0;
222
223 mwIndex *get_jc (void) const = 0;
224
225 mwSize get_nzmax (void) const = 0;
226
227 void set_ir (mwIndex *ir) = 0;
228
229 void set_jc (mwIndex *jc) = 0;
230
231 void set_nzmax (mwSize nzmax) = 0;
232
233 int add_field (const char *key) = 0;
234
235 void remove_field (int key_num) = 0;
236
237 mxArray *get_field_by_number (mwIndex index, int key_num) const = 0;
238
239 void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0;
240
241 int get_number_of_fields (void) const = 0;
242
243 const char *get_field_name_by_number (int key_num) const = 0;
244
245 int get_field_number (const char *key) const = 0;
246
247 int get_string (char *buf, mwSize buflen) const = 0;
248
249 char *array_to_string (void) const = 0;
250
251 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0;
252
253 size_t get_element_size (void) const = 0;
254
255 bool mutation_needed (void) const { return false; }
256
257 mxArray *mutate (void) const { return 0; }
258
259 protected:
260
261 octave_value as_octave_value (void) const = 0;
262
263 mxArray_base (const mxArray_base&) : mxArray (xmxArray ()) { }
264
265 void invalid_type_error (void) const
266 {
267 error ("invalid type for operation");
268 }
269
270 void error (const char *msg) const
271 {
272 // FIXME
273 ::error ("%s", msg);
274 }
275 };
276 113
277 static mwIndex 114 static mwIndex
278 calc_single_subscript_internal (mwSize ndims, const mwSize *dims, 115 calc_single_subscript_internal (mwSize ndims, const mwSize *dims,
279 mwSize nsubs, const mwIndex *subs) 116 mwSize nsubs, const mwIndex *subs)
280 { 117 {
325 162
326 mxArray_octave_value (const octave_value& ov) 163 mxArray_octave_value (const octave_value& ov)
327 : mxArray_base (), val (ov), mutate_flag (false), 164 : mxArray_base (), val (ov), mutate_flag (false),
328 id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { } 165 id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { }
329 166
330 mxArray *dup (void) const 167 mxArray_base *dup (void) const { return new mxArray_octave_value (*this); }
331 { 168
332 mxArray *retval = val.as_mxArray (); 169 mxArray *as_mxArray (void) const
333 170 {
334 if (! retval) 171 return val.as_mxArray ();
335 retval = new mxArray_octave_value (*this);
336
337 return retval;
338 } 172 }
339 173
340 ~mxArray_octave_value (void) 174 ~mxArray_octave_value (void)
341 { 175 {
342 mxFree (class_name); 176 mxFree (class_name);
691 mutate_flag = true; 525 mutate_flag = true;
692 } 526 }
693 527
694 mxArray *mutate (void) const { return val.as_mxArray (); } 528 mxArray *mutate (void) const { return val.as_mxArray (); }
695 529
530 octave_value as_octave_value (void) const { return val; }
531
696 protected: 532 protected:
697
698 octave_value as_octave_value (void) const { return val; }
699 533
700 mxArray_octave_value (const mxArray_octave_value& arg) 534 mxArray_octave_value (const mxArray_octave_value& arg)
701 : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag), 535 : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag),
702 id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims), 536 id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims),
703 dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0) 537 dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0)
1191 for (size_t i = tmp_len; i < static_cast<size_t>(nc); i++) 1025 for (size_t i = tmp_len; i < static_cast<size_t>(nc); i++)
1192 cpr[m*i+j] = static_cast<mxChar> (' '); 1026 cpr[m*i+j] = static_cast<mxChar> (' ');
1193 } 1027 }
1194 } 1028 }
1195 1029
1196 mxArray_number *dup (void) const { return new mxArray_number (*this); } 1030 mxArray_base *dup (void) const { return new mxArray_number (*this); }
1197 1031
1198 ~mxArray_number (void) 1032 ~mxArray_number (void)
1199 { 1033 {
1200 mxFree (pr); 1034 mxFree (pr);
1201 mxFree (pi); 1035 mxFree (pi);
1318 } 1152 }
1319 1153
1320 return buf; 1154 return buf;
1321 } 1155 }
1322 1156
1157 octave_value as_octave_value (void) const
1158 {
1159 octave_value retval;
1160
1161 dim_vector dv = dims_to_dim_vector ();
1162
1163 switch (get_class_id ())
1164 {
1165 case mxLOGICAL_CLASS:
1166 retval = int_to_ov<bool, boolNDArray, bool> (dv);
1167 break;
1168
1169 case mxCHAR_CLASS:
1170 {
1171 mwSize nel = get_number_of_elements ();
1172
1173 mxChar *ppr = static_cast<mxChar *> (pr);
1174
1175 charNDArray val (dv);
1176
1177 char *ptr = val.fortran_vec ();
1178
1179 for (mwIndex i = 0; i < nel; i++)
1180 ptr[i] = static_cast<char> (ppr[i]);
1181
1182 retval = val;
1183 }
1184 break;
1185
1186 case mxSINGLE_CLASS:
1187 {
1188 mwSize nel = get_number_of_elements ();
1189
1190 float *ppr = static_cast<float *> (pr);
1191
1192 if (pi)
1193 {
1194 FloatComplexNDArray val (dv);
1195
1196 FloatComplex *ptr = val.fortran_vec ();
1197
1198 float *ppi = static_cast<float *> (pi);
1199
1200 for (mwIndex i = 0; i < nel; i++)
1201 ptr[i] = FloatComplex (ppr[i], ppi[i]);
1202
1203 retval = val;
1204 }
1205 else
1206 {
1207 FloatNDArray val (dv);
1208
1209 float *ptr = val.fortran_vec ();
1210
1211 for (mwIndex i = 0; i < nel; i++)
1212 ptr[i] = ppr[i];
1213
1214 retval = val;
1215 }
1216 }
1217 break;
1218
1219 case mxDOUBLE_CLASS:
1220 {
1221 mwSize nel = get_number_of_elements ();
1222
1223 double *ppr = static_cast<double *> (pr);
1224
1225 if (pi)
1226 {
1227 ComplexNDArray val (dv);
1228
1229 Complex *ptr = val.fortran_vec ();
1230
1231 double *ppi = static_cast<double *> (pi);
1232
1233 for (mwIndex i = 0; i < nel; i++)
1234 ptr[i] = Complex (ppr[i], ppi[i]);
1235
1236 retval = val;
1237 }
1238 else
1239 {
1240 NDArray val (dv);
1241
1242 double *ptr = val.fortran_vec ();
1243
1244 for (mwIndex i = 0; i < nel; i++)
1245 ptr[i] = ppr[i];
1246
1247 retval = val;
1248 }
1249 }
1250 break;
1251
1252 case mxINT8_CLASS:
1253 retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
1254 break;
1255
1256 case mxUINT8_CLASS:
1257 retval = int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
1258 break;
1259
1260 case mxINT16_CLASS:
1261 retval = int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
1262 break;
1263
1264 case mxUINT16_CLASS:
1265 retval = int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
1266 break;
1267
1268 case mxINT32_CLASS:
1269 retval = int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
1270 break;
1271
1272 case mxUINT32_CLASS:
1273 retval = int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
1274 break;
1275
1276 case mxINT64_CLASS:
1277 retval = int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
1278 break;
1279
1280 case mxUINT64_CLASS:
1281 retval = int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
1282 break;
1283
1284 default:
1285 panic_impossible ();
1286 }
1287
1288 return retval;
1289 }
1290
1323 protected: 1291 protected:
1324 1292
1325 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> 1293 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T>
1326 octave_value 1294 octave_value
1327 int_to_ov (const dim_vector& dv) const 1295 int_to_ov (const dim_vector& dv) const
1342 1310
1343 for (mwIndex i = 0; i < nel; i++) 1311 for (mwIndex i = 0; i < nel; i++)
1344 ptr[i] = ppr[i]; 1312 ptr[i] = ppr[i];
1345 1313
1346 retval = val; 1314 retval = val;
1347 }
1348
1349 return retval;
1350 }
1351
1352 octave_value as_octave_value (void) const
1353 {
1354 octave_value retval;
1355
1356 dim_vector dv = dims_to_dim_vector ();
1357
1358 switch (get_class_id ())
1359 {
1360 case mxLOGICAL_CLASS:
1361 retval = int_to_ov<bool, boolNDArray, bool> (dv);
1362 break;
1363
1364 case mxCHAR_CLASS:
1365 {
1366 mwSize nel = get_number_of_elements ();
1367
1368 mxChar *ppr = static_cast<mxChar *> (pr);
1369
1370 charNDArray val (dv);
1371
1372 char *ptr = val.fortran_vec ();
1373
1374 for (mwIndex i = 0; i < nel; i++)
1375 ptr[i] = static_cast<char> (ppr[i]);
1376
1377 retval = val;
1378 }
1379 break;
1380
1381 case mxSINGLE_CLASS:
1382 {
1383 mwSize nel = get_number_of_elements ();
1384
1385 float *ppr = static_cast<float *> (pr);
1386
1387 if (pi)
1388 {
1389 FloatComplexNDArray val (dv);
1390
1391 FloatComplex *ptr = val.fortran_vec ();
1392
1393 float *ppi = static_cast<float *> (pi);
1394
1395 for (mwIndex i = 0; i < nel; i++)
1396 ptr[i] = FloatComplex (ppr[i], ppi[i]);
1397
1398 retval = val;
1399 }
1400 else
1401 {
1402 FloatNDArray val (dv);
1403
1404 float *ptr = val.fortran_vec ();
1405
1406 for (mwIndex i = 0; i < nel; i++)
1407 ptr[i] = ppr[i];
1408
1409 retval = val;
1410 }
1411 }
1412 break;
1413
1414 case mxDOUBLE_CLASS:
1415 {
1416 mwSize nel = get_number_of_elements ();
1417
1418 double *ppr = static_cast<double *> (pr);
1419
1420 if (pi)
1421 {
1422 ComplexNDArray val (dv);
1423
1424 Complex *ptr = val.fortran_vec ();
1425
1426 double *ppi = static_cast<double *> (pi);
1427
1428 for (mwIndex i = 0; i < nel; i++)
1429 ptr[i] = Complex (ppr[i], ppi[i]);
1430
1431 retval = val;
1432 }
1433 else
1434 {
1435 NDArray val (dv);
1436
1437 double *ptr = val.fortran_vec ();
1438
1439 for (mwIndex i = 0; i < nel; i++)
1440 ptr[i] = ppr[i];
1441
1442 retval = val;
1443 }
1444 }
1445 break;
1446
1447 case mxINT8_CLASS:
1448 retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
1449 break;
1450
1451 case mxUINT8_CLASS:
1452 retval = int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
1453 break;
1454
1455 case mxINT16_CLASS:
1456 retval = int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
1457 break;
1458
1459 case mxUINT16_CLASS:
1460 retval = int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
1461 break;
1462
1463 case mxINT32_CLASS:
1464 retval = int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
1465 break;
1466
1467 case mxUINT32_CLASS:
1468 retval = int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
1469 break;
1470
1471 case mxINT64_CLASS:
1472 retval = int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
1473 break;
1474
1475 case mxUINT64_CLASS:
1476 retval = int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
1477 break;
1478
1479 default:
1480 panic_impossible ();
1481 } 1315 }
1482 1316
1483 return retval; 1317 return retval;
1484 } 1318 }
1485 1319
1521 pi (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0), 1355 pi (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0),
1522 ir (static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex)))), 1356 ir (static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex)))),
1523 jc (static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex)))) 1357 jc (static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex))))
1524 { } 1358 { }
1525 1359
1526 mxArray_sparse *dup (void) const { return new mxArray_sparse (*this); } 1360 mxArray_base *dup (void) const { return new mxArray_sparse (*this); }
1527 1361
1528 ~mxArray_sparse (void) 1362 ~mxArray_sparse (void)
1529 { 1363 {
1530 mxFree (pr); 1364 mxFree (pr);
1531 mxFree (pi); 1365 mxFree (pi);
1554 void set_ir (mwIndex *ir_arg) { ir = ir_arg; } 1388 void set_ir (mwIndex *ir_arg) { ir = ir_arg; }
1555 1389
1556 void set_jc (mwIndex *jc_arg) { jc = jc_arg; } 1390 void set_jc (mwIndex *jc_arg) { jc = jc_arg; }
1557 1391
1558 void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; } 1392 void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; }
1559
1560 protected:
1561 1393
1562 octave_value as_octave_value (void) const 1394 octave_value as_octave_value (void) const
1563 { 1395 {
1564 octave_value retval; 1396 octave_value retval;
1565 1397
1712 { 1544 {
1713 for (int i = 0; i < nfields; i++) 1545 for (int i = 0; i < nfields; i++)
1714 fields[i] = strsave (keys[i]); 1546 fields[i] = strsave (keys[i]);
1715 } 1547 }
1716 1548
1717 mxArray_struct *dup (void) const { return new mxArray_struct (*this); } 1549 mxArray_base *dup (void) const { return new mxArray_struct (*this); }
1718 1550
1719 ~mxArray_struct (void) 1551 ~mxArray_struct (void)
1720 { 1552 {
1721 for (int i = 0; i < nfields; i++) 1553 for (int i = 0; i < nfields; i++)
1722 mxFree (fields[i]); 1554 mxFree (fields[i]);
1861 1693
1862 void *get_data (void) const { return data; } 1694 void *get_data (void) const { return data; }
1863 1695
1864 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } 1696 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
1865 1697
1866 protected:
1867
1868 octave_value as_octave_value (void) const 1698 octave_value as_octave_value (void) const
1869 { 1699 {
1870 dim_vector dv = dims_to_dim_vector (); 1700 dim_vector dv = dims_to_dim_vector ();
1871 1701
1872 string_vector keys (fields, nfields); 1702 string_vector keys (fields, nfields);
1938 1768
1939 mxArray_cell (mwSize m, mwSize n) 1769 mxArray_cell (mwSize m, mwSize n)
1940 : mxArray_matlab (mxCELL_CLASS, m, n), 1770 : mxArray_matlab (mxCELL_CLASS, m, n),
1941 data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } 1771 data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { }
1942 1772
1943 mxArray_cell *dup (void) const { return new mxArray_cell (*this); } 1773 mxArray_base *dup (void) const { return new mxArray_cell (*this); }
1944 1774
1945 ~mxArray_cell (void) 1775 ~mxArray_cell (void)
1946 { 1776 {
1947 mwSize nel = get_number_of_elements (); 1777 mwSize nel = get_number_of_elements ();
1948 1778
1960 void set_cell (mwIndex idx, mxArray *val); 1790 void set_cell (mwIndex idx, mxArray *val);
1961 1791
1962 void *get_data (void) const { return data; } 1792 void *get_data (void) const { return data; }
1963 1793
1964 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } 1794 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); }
1965
1966 protected:
1967 1795
1968 octave_value as_octave_value (void) const 1796 octave_value as_octave_value (void) const
1969 { 1797 {
1970 dim_vector dv = dims_to_dim_vector (); 1798 dim_vector dv = dims_to_dim_vector ();
1971 1799