GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
mxarray.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2001-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26/*
27
28Part of this code was originally distributed as part of Octave Forge under
29the following terms:
30
31Author: Paul Kienzle
32I grant this code to the public domain.
332001-03-22
34
35THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45SUCH DAMAGE.
46
47*/
48
49#if ! defined (octave_mxarray_h)
50#define octave_mxarray_h 1
51
52#include "octave-config.h"
53
54#include "mxtypes.h"
55
56#if defined (MXARRAY_TYPEDEFS_ONLY)
57# warning "MXARRAY_TYPEDEFS_ONLY has been deprecated and will be removed in \
58Octave 12. Include "mxtypes.h" instead of "mxarray.h"."
59#endif
60
61#if ! defined (MXARRAY_TYPEDEFS_ONLY)
62
63#include <cstring>
64#include <set>
65
66#include "error.h"
67
68#include "ov-mex-fcn.h"
69
70class octave_value;
71class dim_vector;
72
73#define DO_MUTABLE_METHOD(RET_T, METHOD_CALL) \
74 RET_T retval = m_rep->METHOD_CALL; \
75 \
76 if (m_rep->mutation_needed ()) \
77 { \
78 maybe_mutate (); \
79 retval = m_rep->METHOD_CALL; \
80 } \
81 \
82 return retval
83
84#define DO_VOID_MUTABLE_METHOD(METHOD_CALL) \
85 m_rep->METHOD_CALL; \
86 \
87 if (m_rep->mutation_needed ()) \
88 { \
89 maybe_mutate (); \
90 m_rep->METHOD_CALL; \
91 }
92
93class OCTINTERP_API mxArray;
94
95// A class to provide the default implementation of some of the
96// virtual functions declared in the mxArray class.
97
98class OCTINTERP_API mxArray_base
99{
100protected:
101
102 OCTINTERP_API mxArray_base (bool interleaved);
103
104public:
105
106 mxArray_base () = delete;
107
108 OCTAVE_DEFAULT_COPY_MOVE (mxArray_base)
109
110 virtual mxArray_base * dup () const = 0;
111
112 virtual mxArray * as_mxArray () const { return nullptr; }
113
114 virtual ~mxArray_base () = default;
115
116 virtual bool is_octave_value () const { return false; }
117
118 virtual int iscell () const = 0;
119
120 virtual int is_char () const = 0;
121
122 virtual int is_class (const char *name_arg) const
123 {
124 int retval = 0;
125
126 const char *cname = get_class_name ();
127
128 if (cname && name_arg)
129 retval = ! strcmp (cname, name_arg);
130
131 return retval;
132 }
133
134 virtual int is_complex () const = 0;
135
136 virtual int is_double () const = 0;
137
138 virtual int is_function_handle () const = 0;
139
140 virtual int is_int16 () const = 0;
141
142 virtual int is_int32 () const = 0;
143
144 virtual int is_int64 () const = 0;
145
146 virtual int is_int8 () const = 0;
147
148 virtual int is_logical () const = 0;
149
150 virtual int is_numeric () const = 0;
151
152 virtual int is_single () const = 0;
153
154 virtual int is_sparse () const = 0;
155
156 virtual int is_struct () const = 0;
157
158 virtual int is_uint16 () const = 0;
159
160 virtual int is_uint32 () const = 0;
161
162 virtual int is_uint64 () const = 0;
163
164 virtual int is_uint8 () const = 0;
165
166 virtual int is_logical_scalar () const
167 {
168 return is_logical () && get_number_of_elements () == 1;
169 }
170
171 virtual int is_logical_scalar_true () const = 0;
172
173 virtual mwSize get_m () const = 0;
174
175 virtual mwSize get_n () const = 0;
176
177 virtual mwSize * get_dimensions () const = 0;
178
179 virtual mwSize get_number_of_dimensions () const = 0;
180
181 virtual void set_m (mwSize m) = 0;
182
183 virtual void set_n (mwSize n) = 0;
184
185 virtual int set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0;
186
187 virtual mwSize get_number_of_elements () const = 0;
188
189 virtual int isempty () const = 0;
190
191 virtual bool is_scalar () const = 0;
192
193 virtual mxClassID get_class_id () const = 0;
194
195 virtual const char * get_class_name () const = 0;
196
197 virtual void set_class_name (const char *name_arg) = 0;
198
199 // The following functions aren't pure virtual because they are only
200 // valid for one type. Making them pure virtual would mean that they
201 // have to be implemented for all derived types, and all of those
202 // would need to throw errors instead of just doing it once here.
203
204 virtual mxArray *
205 get_property (mwIndex /*idx*/, const char * /*pname*/) const
206 {
207 return nullptr;
208 }
209
210 virtual void set_property (mwIndex /*idx*/, const char * /*pname*/,
211 const mxArray * /*pval*/)
212 {
213 err_invalid_type ("set_property");
214 }
215
216 virtual mxArray * get_cell (mwIndex /*idx*/) const
217 {
218 err_invalid_type ("get_cell");
219 }
220
221 virtual void set_cell (mwIndex idx, mxArray *val) = 0;
222
223 virtual double get_scalar () const = 0;
224
225 virtual void * get_data () const = 0;
226
227 virtual mxDouble * get_doubles () const = 0;
228 virtual mxSingle * get_singles () const = 0;
229 virtual mxInt8 * get_int8s () const = 0;
230 virtual mxInt16 * get_int16s () const = 0;
231 virtual mxInt32 * get_int32s () const = 0;
232 virtual mxInt64 * get_int64s () const = 0;
233 virtual mxUint8 * get_uint8s () const = 0;
234 virtual mxUint16 * get_uint16s () const = 0;
235 virtual mxUint32 * get_uint32s () const = 0;
236 virtual mxUint64 * get_uint64s () const = 0;
237
238 virtual mxComplexDouble * get_complex_doubles () const = 0;
239 virtual mxComplexSingle * get_complex_singles () const = 0;
240
241 virtual void * get_imag_data () const = 0;
242
243 virtual void set_data (void *pr) = 0;
244
245 virtual int set_doubles (mxDouble *data) = 0;
246 virtual int set_singles (mxSingle *data) = 0;
247 virtual int set_int8s (mxInt8 *data) = 0;
248 virtual int set_int16s (mxInt16 *data) = 0;
249 virtual int set_int32s (mxInt32 *data) = 0;
250 virtual int set_int64s (mxInt64 *data) = 0;
251 virtual int set_uint8s (mxUint8 *data) = 0;
252 virtual int set_uint16s (mxUint16 *data) = 0;
253 virtual int set_uint32s (mxUint32 *data) = 0;
254 virtual int set_uint64s (mxUint64 *data) = 0;
255
256 virtual int set_complex_doubles (mxComplexDouble *data) = 0;
257 virtual int set_complex_singles (mxComplexSingle *data) = 0;
258
259 virtual void set_imag_data (void *pi) = 0;
260
261 virtual mwIndex * get_ir () const = 0;
262
263 virtual mwIndex * get_jc () const = 0;
264
265 virtual mwSize get_nzmax () const = 0;
266
267 virtual void set_ir (mwIndex *ir) = 0;
268
269 virtual void set_jc (mwIndex *jc) = 0;
270
271 virtual void set_nzmax (mwSize nzmax) = 0;
272
273 virtual int add_field (const char *key) = 0;
274
275 virtual void remove_field (int key_num) = 0;
276
277 virtual mxArray * get_field_by_number (mwIndex index, int key_num) const = 0;
278
279 virtual void
280 set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0;
281
282 virtual int get_number_of_fields () const = 0;
283
284 virtual const char * get_field_name_by_number (int key_num) const = 0;
285
286 virtual int get_field_number (const char *key) const = 0;
287
288 virtual int get_string (char *buf, mwSize buflen) const = 0;
289
290 virtual char * array_to_string () const = 0;
291
292 virtual mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0;
293
294 virtual std::size_t get_element_size () const = 0;
295
296 virtual bool mutation_needed () const { return false; }
297
298 virtual mxArray * mutate () const { return nullptr; }
299
300 virtual octave_value as_octave_value () const = 0;
301
302protected:
303
304 std::size_t get_numeric_element_size (std::size_t size) const
305 {
306 return (m_interleaved
307 ? is_complex () ? 2 * size : size
308 : size);
309 }
310
311 OCTAVE_NORETURN void err_invalid_type (const char *op) const
312 {
313 error ("%s: invalid type for mxArray::%s", get_class_name (), op);
314 }
315
316 //--------
317
318 // If TRUE, we are using interleaved storage for complex numeric arrays.
320
321};
322
323// The main interface class. The representation can be based on an
324// octave_value object or a separate object that tries to reproduce
325// the semantics of mxArray objects in Matlab more directly.
326
328{
329public:
330
331 OCTINTERP_API mxArray (bool interleaved, const octave_value& ov);
332
333 OCTINTERP_API mxArray (bool interleaved, mxClassID id, mwSize ndims,
334 const mwSize *dims, mxComplexity flag = mxREAL,
335 bool init = true);
336
337 OCTINTERP_API mxArray (bool interleaved, mxClassID id, const dim_vector& dv,
338 mxComplexity flag = mxREAL);
339
340 OCTINTERP_API mxArray (bool interleaved, mxClassID id, mwSize m, mwSize n,
341 mxComplexity flag = mxREAL, bool init = true);
342
343 OCTINTERP_API mxArray (bool interleaved, mxClassID id, double val);
344
345 OCTINTERP_API mxArray (bool interleaved, mxClassID id, mxLogical val);
346
347 OCTINTERP_API mxArray (bool interleaved, const char *str);
348
349 OCTINTERP_API mxArray (bool interleaved, mwSize m, const char **str);
350
351 OCTINTERP_API mxArray (bool interleaved, mxClassID id, mwSize m, mwSize n,
352 mwSize nzmax, mxComplexity flag = mxREAL);
353
354 OCTINTERP_API mxArray (bool interleaved, mwSize ndims, const mwSize *dims,
355 int num_keys, const char **keys);
356
357 OCTINTERP_API mxArray (bool interleaved, const dim_vector& dv, int num_keys,
358 const char **keys);
359
360 OCTINTERP_API mxArray (bool interleaved, mwSize m, mwSize n, int num_keys,
361 const char **keys);
362
363 OCTINTERP_API mxArray (bool interleaved, mwSize ndims, const mwSize *dims);
364
365 OCTINTERP_API mxArray (bool interleaved, const dim_vector& dv);
366
367 OCTINTERP_API mxArray (bool interleaved, mwSize m, mwSize n);
368
369 mxArray * dup () const
370 {
371 mxArray *retval = m_rep->as_mxArray ();
372
373 if (retval)
374 retval->set_name (m_name);
375 else
376 {
377 mxArray_base *new_rep = m_rep->dup ();
378
379 retval = new mxArray (new_rep, m_name);
380 }
381
382 return retval;
383 }
384
385 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (mxArray)
386
387 OCTINTERP_API ~mxArray ();
388
389 bool is_octave_value () const { return m_rep->is_octave_value (); }
390
391 int iscell () const { return m_rep->iscell (); }
392
393 int is_char () const { return m_rep->is_char (); }
394
395 int is_class (const char *name_arg) const { return m_rep->is_class (name_arg); }
396
397 int is_complex () const { return m_rep->is_complex (); }
398
399 int is_double () const { return m_rep->is_double (); }
400
401 int is_function_handle () const { return m_rep->is_function_handle (); }
402
403 int is_int16 () const { return m_rep->is_int16 (); }
404
405 int is_int32 () const { return m_rep->is_int32 (); }
406
407 int is_int64 () const { return m_rep->is_int64 (); }
408
409 int is_int8 () const { return m_rep->is_int8 (); }
410
411 int is_logical () const { return m_rep->is_logical (); }
412
413 int is_numeric () const { return m_rep->is_numeric (); }
414
415 int is_single () const { return m_rep->is_single (); }
416
417 int is_sparse () const { return m_rep->is_sparse (); }
418
419 int is_struct () const { return m_rep->is_struct (); }
420
421 int is_uint16 () const { return m_rep->is_uint16 (); }
422
423 int is_uint32 () const { return m_rep->is_uint32 (); }
424
425 int is_uint64 () const { return m_rep->is_uint64 (); }
426
427 int is_uint8 () const { return m_rep->is_uint8 (); }
428
429 int is_logical_scalar () const { return m_rep->is_logical_scalar (); }
430
432 { return m_rep->is_logical_scalar_true (); }
433
434 mwSize get_m () const { return m_rep->get_m (); }
435
436 mwSize get_n () const { return m_rep->get_n (); }
437
438 mwSize * get_dimensions () const { return m_rep->get_dimensions (); }
439
441 { return m_rep->get_number_of_dimensions (); }
442
443 void set_m (mwSize m) { DO_VOID_MUTABLE_METHOD (set_m (m)); }
444
445 void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); }
446
447 int set_dimensions (mwSize *dims_arg, mwSize ndims_arg)
448 { DO_MUTABLE_METHOD (int, set_dimensions (dims_arg, ndims_arg)); }
449
451 { return m_rep->get_number_of_elements (); }
452
453 int isempty () const { return get_number_of_elements () == 0; }
454
455 bool is_scalar () const { return m_rep->is_scalar (); }
456
457 const char * get_name () const { return m_name; }
458
459 OCTINTERP_API void set_name (const char *name);
460
461 mxClassID get_class_id () const { return m_rep->get_class_id (); }
462
463 const char * get_class_name () const { return m_rep->get_class_name (); }
464
465 mxArray * get_property (mwIndex idx, const char *pname) const
466 { return m_rep->get_property (idx, pname); }
467
468 void set_property (mwIndex idx, const char *pname, const mxArray *pval)
469 { m_rep->set_property (idx, pname, pval); }
470
471 void set_class_name (const char *name_arg)
472 { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
473
474 mxArray * get_cell (mwIndex idx) const
475 { DO_MUTABLE_METHOD (mxArray *, get_cell (idx)); }
476
477 void set_cell (mwIndex idx, mxArray *val)
478 { DO_VOID_MUTABLE_METHOD (set_cell (idx, val)); }
479
480 double get_scalar () const { return m_rep->get_scalar (); }
481
482 void * get_data () const { DO_MUTABLE_METHOD (void *, get_data ()); }
483
484 mxDouble * get_doubles () const
485 { DO_MUTABLE_METHOD (mxDouble *, get_doubles ()); }
486
487 mxSingle * get_singles () const
488 { DO_MUTABLE_METHOD (mxSingle *, get_singles ()); }
489
490 mxInt8 * get_int8s () const
491 { DO_MUTABLE_METHOD (mxInt8 *, get_int8s ()); }
492
493 mxInt16 * get_int16s () const
494 { DO_MUTABLE_METHOD (mxInt16 *, get_int16s ()); }
495
496 mxInt32 * get_int32s () const
497 { DO_MUTABLE_METHOD (mxInt32 *, get_int32s ()); }
498
499 mxInt64 * get_int64s () const
500 { DO_MUTABLE_METHOD (mxInt64 *, get_int64s ()); }
501
502 mxUint8 * get_uint8s () const
503 { DO_MUTABLE_METHOD (mxUint8 *, get_uint8s ()); }
504
505 mxUint16 * get_uint16s () const
506 { DO_MUTABLE_METHOD (mxUint16 *, get_uint16s ()); }
507
508 mxUint32 * get_uint32s () const
509 { DO_MUTABLE_METHOD (mxUint32 *, get_uint32s ()); }
510
511 mxUint64 * get_uint64s () const
512 { DO_MUTABLE_METHOD (mxUint64 *, get_uint64s ()); }
513
514 mxComplexDouble * get_complex_doubles () const
515 { DO_MUTABLE_METHOD (mxComplexDouble *, get_complex_doubles ()); }
516
517 mxComplexSingle * get_complex_singles () const
518 { DO_MUTABLE_METHOD (mxComplexSingle *, get_complex_singles ()); }
519
520 void * get_imag_data () const
521 { DO_MUTABLE_METHOD (void *, get_imag_data ()); }
522
523 void set_data (void *pr) { DO_VOID_MUTABLE_METHOD (set_data (pr)); }
524
525 int set_doubles (mxDouble *data)
526 { DO_MUTABLE_METHOD (int, set_doubles (data)); }
527
528 int set_singles (mxSingle *data)
529 { DO_MUTABLE_METHOD (int, set_singles (data)); }
530
531 int set_int8s (mxInt8 *data)
532 { DO_MUTABLE_METHOD (int, set_int8s (data)); }
533
534 int set_int16s (mxInt16 *data)
535 { DO_MUTABLE_METHOD (int, set_int16s (data)); }
536
537 int set_int32s (mxInt32 *data)
538 { DO_MUTABLE_METHOD (int, set_int32s (data)); }
539
540 int set_int64s (mxInt64 *data)
541 { DO_MUTABLE_METHOD (int, set_int64s (data)); }
542
543 int set_uint8s (mxUint8 *data)
544 { DO_MUTABLE_METHOD (int, set_uint8s (data)); }
545
546 int set_uint16s (mxUint16 *data)
547 { DO_MUTABLE_METHOD (int, set_uint16s (data)); }
548
549 int set_uint32s (mxUint32 *data)
550 { DO_MUTABLE_METHOD (int, set_uint32s (data)); }
551
552 int set_uint64s (mxUint64 *data)
553 { DO_MUTABLE_METHOD (int, set_uint64s (data)); }
554
555 int set_complex_doubles (mxComplexDouble *data)
556 { DO_MUTABLE_METHOD (int, set_complex_doubles (data)); }
557
558 int set_complex_singles (mxComplexSingle *data)
559 { DO_MUTABLE_METHOD (int, set_complex_singles (data)); }
560
562
563 mwIndex * get_ir () const { DO_MUTABLE_METHOD (mwIndex *, get_ir ()); }
564
565 mwIndex * get_jc () const { DO_MUTABLE_METHOD (mwIndex *, get_jc ()); }
566
567 mwSize get_nzmax () const { return m_rep->get_nzmax (); }
568
569 void set_ir (mwIndex *ir) { DO_VOID_MUTABLE_METHOD (set_ir (ir)); }
570
571 void set_jc (mwIndex *jc) { DO_VOID_MUTABLE_METHOD (set_jc (jc)); }
572
573 void set_nzmax (mwSize nzmax) { DO_VOID_MUTABLE_METHOD (set_nzmax (nzmax)); }
574
575 int add_field (const char *key) { DO_MUTABLE_METHOD (int, add_field (key)); }
576
577 void remove_field (int key_num)
578 { DO_VOID_MUTABLE_METHOD (remove_field (key_num)); }
579
580 mxArray * get_field_by_number (mwIndex index, int key_num) const
581 { DO_MUTABLE_METHOD (mxArray *, get_field_by_number (index, key_num)); }
582
583 void set_field_by_number (mwIndex index, int key_num, mxArray *val)
584 { DO_VOID_MUTABLE_METHOD (set_field_by_number (index, key_num, val)); }
585
587 { return m_rep->get_number_of_fields (); }
588
589 const char * get_field_name_by_number (int key_num) const
590 { DO_MUTABLE_METHOD (const char *, get_field_name_by_number (key_num)); }
591
592 int get_field_number (const char *key) const
593 { DO_MUTABLE_METHOD (int, get_field_number (key)); }
594
595 int get_string (char *buf, mwSize buflen) const
596 { return m_rep->get_string (buf, buflen); }
597
598 char * array_to_string () const { return m_rep->array_to_string (); }
599
600 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const
601 { return m_rep->calc_single_subscript (nsubs, subs); }
602
603 std::size_t get_element_size () const
604 { return m_rep->get_element_size (); }
605
606 bool mutation_needed () const { return m_rep->mutation_needed (); }
607
608 mxArray * mutate () const { return m_rep->mutate (); }
609
610 static OCTINTERP_API void * malloc (std::size_t n);
611
612 static OCTINTERP_API void * calloc (std::size_t n, std::size_t t);
613
614 static OCTINTERP_API void * alloc (bool init, std::size_t n, std::size_t t);
615
616 static char * strsave (const char *str)
617 {
618 char *retval = nullptr;
619
620 if (str)
621 {
622 mwSize sz = sizeof (mxChar) * (strlen (str) + 1);
623
624 retval = static_cast<char *> (mxArray::malloc (sz));
625
626 if (retval)
627 strcpy (retval, str);
628 }
629
630 return retval;
631 }
632
633 static OCTINTERP_API octave_value
634 as_octave_value (const mxArray *ptr, bool null_is_empty = true);
635
636 OCTINTERP_API octave_value as_octave_value () const;
637
638private:
639
640 mxArray (mxArray_base *r, const char *n)
641 : m_rep (r), m_name (mxArray::strsave (n)) { }
642
643 static OCTINTERP_API mxArray_base *
644 create_rep (bool interleaved, const octave_value& ov);
645
646 static OCTINTERP_API mxArray_base *
647 create_rep (bool interleaved, mxClassID id, mwSize ndims,
648 const mwSize *dims, mxComplexity flag, bool init);
649
650 static OCTINTERP_API mxArray_base *
651 create_rep (bool interleaved, mxClassID id, const dim_vector& dv,
652 mxComplexity flag);
653
654 static OCTINTERP_API mxArray_base *
655 create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n,
656 mxComplexity flag, bool init);
657
658 static OCTINTERP_API mxArray_base *
659 create_rep (bool interleaved, mxClassID id, double val);
660
661 static OCTINTERP_API mxArray_base *
662 create_rep (bool interleaved, mxClassID id, mxLogical val);
663
664 static OCTINTERP_API mxArray_base *
665 create_rep (bool interleaved, const char *str);
666
667 static OCTINTERP_API mxArray_base *
668 create_rep (bool interleaved, mwSize m, const char **str);
669
670 static OCTINTERP_API mxArray_base *
671 create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n,
672 mwSize nzmax, mxComplexity flag);
673
674 OCTINTERP_API void maybe_mutate () const;
675
676 //--------
677
678 mutable mxArray_base *m_rep;
679
680 char *m_name;
681
682};
683
684// A class to manage calls to MEX functions. Mostly deals with memory
685// management.
686
687class OCTINTERP_API mex
688{
689public:
690
692 : m_curr_mex_fcn (f), m_memlist (), m_arraylist (), m_fname (nullptr) { }
693
694 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (mex)
695
696 ~mex ();
697
698 const char *function_name () const;
699
700 // Allocate memory.
701 void *malloc_unmarked (std::size_t n);
702
703 // Allocate memory to be freed on exit.
704 void *malloc (std::size_t n)
705 {
706 void *ptr = malloc_unmarked (n);
707
708 mark (ptr);
709
710 return ptr;
711 }
712
713 // Allocate memory and initialize to 0.
714 void *calloc_unmarked (std::size_t n, std::size_t t)
715 {
716 void *ptr = malloc_unmarked (n*t);
717
718 memset (ptr, 0, n*t);
719
720 return ptr;
721 }
722
723 // Allocate memory to be freed on exit and initialize to 0.
724 void *calloc (std::size_t n, std::size_t t)
725 {
726 void *ptr = calloc_unmarked (n, t);
727
728 mark (ptr);
729
730 return ptr;
731 }
732
733 // Reallocate a pointer obtained from malloc or calloc.
734 // If the pointer is NULL, allocate using malloc.
735 // We don't need an "unmarked" version of this.
736 void *realloc (void *ptr, std::size_t n);
737
738 // Free a pointer obtained from malloc or calloc.
739 void free (void *ptr);
740
741 // Mark a pointer to be freed on exit.
742 void mark (void *ptr)
743 {
744#if defined (DEBUG)
745 if (m_memlist.find (ptr) != m_memlist.end ())
746 warning ("%s: double registration ignored", function_name ());
747#endif
748
749 m_memlist.insert (ptr);
750 }
751
752 // Unmark a pointer to be freed on exit, either because it was
753 // made persistent, or because it was already freed.
754 void unmark (void *ptr)
755 {
756 auto p = m_memlist.find (ptr);
757
758 if (p != m_memlist.end ())
759 m_memlist.erase (p);
760#if defined (DEBUG)
761 else
762 warning ("%s: value not marked", function_name ());
763#endif
764 }
765
767 {
768 m_arraylist.insert (ptr);
769 return ptr;
770 }
771
773 {
774 auto p = m_arraylist.find (ptr);
775
776 if (p != m_arraylist.end ())
777 m_arraylist.erase (p);
778 }
779
780 // Mark a pointer as one we allocated.
781 void mark_foreign (void *ptr)
782 {
783#if defined (DEBUG)
784 if (m_foreign_memlist.find (ptr) != m_foreign_memlist.end ())
785 warning ("%s: double registration ignored", function_name ());
786#endif
787
788 m_foreign_memlist.insert (ptr);
789 }
790
791 // Unmark a pointer as one we allocated.
792 void unmark_foreign (void *ptr)
793 {
794 auto p = m_foreign_memlist.find (ptr);
795
796 if (p != m_foreign_memlist.end ())
797 m_foreign_memlist.erase (p);
798#if defined (DEBUG)
799 else
800 warning ("%s: value not marked", function_name ());
801#endif
802
803 }
804
805 // Make a new array value and initialize from an octave value; it will be
806 // freed on exit unless marked as persistent.
808 {
809 bool interleaved = m_curr_mex_fcn.use_interleaved_complex ();
810
811 return mark_array (new mxArray (interleaved, ov));
812 }
813
814 // Free an array and its contents.
815 bool free_value (mxArray *ptr)
816 {
817 bool inlist = false;
818
819 auto p = m_arraylist.find (ptr);
820
821 if (p != m_arraylist.end ())
822 {
823 inlist = true;
824 m_arraylist.erase (p);
825 delete ptr;
826 }
827#if defined (DEBUG)
828 else
829 warning ("mex::free_value: skipping memory not allocated by mex::make_value");
830#endif
831
832 return inlist;
833 }
834
836 {
837 return m_curr_mex_fcn;
838 }
839
840 // 1 if error should be returned to MEX file, 0 if abort.
841 int trap_feval_error = 0;
842
843 // Mark a pointer as one we allocated.
844 void global_mark (void *ptr)
845 {
846#if defined (DEBUG)
847 if (s_global_memlist.find (ptr) != s_global_memlist.end ())
848 warning ("%s: double registration ignored", function_name ());
849#endif
850
851 s_global_memlist.insert (ptr);
852 }
853
854 // Unmark a pointer as one we allocated.
855 void global_unmark (void *ptr)
856 {
857 auto p = s_global_memlist.find (ptr);
858
859 if (p != s_global_memlist.end ())
860 s_global_memlist.erase (p);
861#if defined (DEBUG)
862 else
863 warning ("%s: value not marked", function_name ());
864#endif
865 }
866
867private:
868
869 // Pointer to the mex function that corresponds to this mex context.
870 octave_mex_function& m_curr_mex_fcn;
871
872 // List of memory resources that need to be freed upon exit.
873 std::set<void *> m_memlist;
874
875 // List of mxArray objects that need to be freed upon exit.
876 std::set<mxArray *> m_arraylist;
877
878 // List of memory resources we know about, but that were allocated
879 // elsewhere.
880 std::set<void *> m_foreign_memlist;
881
882 // The name of the currently executing function.
883 mutable char *m_fname;
884
885 // List of memory resources we allocated.
886 static std::set<void *> s_global_memlist;
887
888};
889
890#undef DO_MUTABLE_METHOD
891#undef DO_VOID_MUTABLE_METHOD
892
893OCTINTERP_API octave_value_list
894mx_to_ov_args (int nargin, mxArray *argin[]);
895
896OCTINTERP_API void
897mexErrMsgTxt_impl (const char *who, const char *s);
898
899OCTINTERP_API int
900mexPutVariable_impl (const char *space, const char *name, const mxArray *ptr);
901
902OCTINTERP_API int
903mexSet_impl (double handle, const char *property, mxArray *val);
904
905#endif
906#endif
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
Definition mxarray.h:688
mex(octave_mex_function &f)
Definition mxarray.h:691
void unmark_array(mxArray *ptr)
Definition mxarray.h:772
mxArray * make_value(const octave_value &ov)
Definition mxarray.h:807
void * malloc(std::size_t n)
Definition mxarray.h:704
void mark(void *ptr)
Definition mxarray.h:742
mxArray * mark_array(mxArray *ptr)
Definition mxarray.h:766
void unmark(void *ptr)
Definition mxarray.h:754
octave_mex_function & current_mex_function() const
Definition mxarray.h:835
void global_unmark(void *ptr)
Definition mxarray.h:855
bool free_value(mxArray *ptr)
Definition mxarray.h:815
void global_mark(void *ptr)
Definition mxarray.h:844
void mark_foreign(void *ptr)
Definition mxarray.h:781
void * calloc(std::size_t n, std::size_t t)
Definition mxarray.h:724
void * calloc_unmarked(std::size_t n, std::size_t t)
Definition mxarray.h:714
void unmark_foreign(void *ptr)
Definition mxarray.h:792
virtual int set_int8s(mxInt8 *data)=0
virtual int set_complex_singles(mxComplexSingle *data)=0
OCTAVE_NORETURN void err_invalid_type(const char *op) const
Definition mxarray.h:311
virtual mxArray * as_mxArray() const
Definition mxarray.h:112
virtual bool is_octave_value() const
Definition mxarray.h:116
virtual void set_n(mwSize n)=0
virtual void set_cell(mwIndex idx, mxArray *val)=0
virtual int add_field(const char *key)=0
virtual mxInt64 * get_int64s() const =0
virtual mxUint32 * get_uint32s() const =0
virtual void set_nzmax(mwSize nzmax)=0
virtual int set_uint16s(mxUint16 *data)=0
virtual int is_logical() const =0
virtual int is_uint64() const =0
virtual int set_uint64s(mxUint64 *data)=0
virtual int get_string(char *buf, mwSize buflen) const =0
virtual bool is_scalar() const =0
virtual mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const =0
virtual mxArray * get_property(mwIndex, const char *) const
Definition mxarray.h:205
virtual int set_doubles(mxDouble *data)=0
virtual int set_int64s(mxInt64 *data)=0
virtual int is_complex() const =0
virtual octave_value as_octave_value() const =0
virtual mxDouble * get_doubles() const =0
virtual void set_imag_data(void *pi)=0
virtual int is_numeric() const =0
virtual mxArray * get_field_by_number(mwIndex index, int key_num) const =0
virtual int set_int16s(mxInt16 *data)=0
mxArray_base()=delete
virtual int is_double() const =0
virtual int set_singles(mxSingle *data)=0
virtual int is_char() const =0
virtual void * get_imag_data() const =0
virtual void set_m(mwSize m)=0
virtual void set_data(void *pr)=0
virtual int is_logical_scalar_true() const =0
bool m_interleaved
Definition mxarray.h:319
virtual mxComplexSingle * get_complex_singles() const =0
virtual int is_uint16() const =0
virtual double get_scalar() const =0
virtual mxInt16 * get_int16s() const =0
virtual int is_class(const char *name_arg) const
Definition mxarray.h:122
virtual mxInt8 * get_int8s() const =0
virtual mwSize get_nzmax() const =0
virtual const char * get_field_name_by_number(int key_num) const =0
std::size_t get_numeric_element_size(std::size_t size) const
Definition mxarray.h:304
virtual int iscell() const =0
virtual void set_property(mwIndex, const char *, const mxArray *)
Definition mxarray.h:210
virtual int set_complex_doubles(mxComplexDouble *data)=0
virtual int isempty() const =0
virtual mwSize get_number_of_elements() const =0
virtual mxUint8 * get_uint8s() const =0
virtual int is_logical_scalar() const
Definition mxarray.h:166
virtual void set_jc(mwIndex *jc)=0
virtual std::size_t get_element_size() const =0
virtual int set_uint32s(mxUint32 *data)=0
virtual int set_uint8s(mxUint8 *data)=0
virtual bool mutation_needed() const
Definition mxarray.h:296
virtual mxArray * mutate() const
Definition mxarray.h:298
virtual int set_dimensions(mwSize *dims_arg, mwSize ndims_arg)=0
virtual int is_int16() const =0
virtual int is_single() const =0
virtual void set_class_name(const char *name_arg)=0
virtual mxUint16 * get_uint16s() const =0
virtual mwSize * get_dimensions() const =0
virtual mxArray_base * dup() const =0
virtual mxInt32 * get_int32s() const =0
virtual mwSize get_number_of_dimensions() const =0
virtual int is_function_handle() const =0
virtual int is_uint8() const =0
virtual mxComplexDouble * get_complex_doubles() const =0
virtual mwSize get_m() const =0
virtual int is_int8() const =0
virtual char * array_to_string() const =0
virtual void * get_data() const =0
virtual int is_int32() const =0
virtual int get_number_of_fields() const =0
virtual void set_ir(mwIndex *ir)=0
virtual mxSingle * get_singles() const =0
virtual void remove_field(int key_num)=0
virtual int is_uint32() const =0
virtual mwIndex * get_jc() const =0
virtual mwIndex * get_ir() const =0
virtual int is_int64() const =0
virtual void set_field_by_number(mwIndex index, int key_num, mxArray *val)=0
virtual int is_struct() const =0
virtual int get_field_number(const char *key) const =0
virtual const char * get_class_name() const =0
virtual mwSize get_n() const =0
virtual mxArray * get_cell(mwIndex) const
Definition mxarray.h:216
virtual mxUint64 * get_uint64s() const =0
virtual int set_int32s(mxInt32 *data)=0
virtual ~mxArray_base()=default
virtual int is_sparse() const =0
virtual mxClassID get_class_id() const =0
mxInt16 * get_int16s() const
Definition mxarray.h:493
mxDouble * get_doubles() const
Definition mxarray.h:484
mxArray * get_field_by_number(mwIndex index, int key_num) const
Definition mxarray.h:580
int set_uint8s(mxUint8 *data)
Definition mxarray.h:543
int set_complex_singles(mxComplexSingle *data)
Definition mxarray.h:558
int is_logical() const
Definition mxarray.h:411
int is_logical_scalar() const
Definition mxarray.h:429
int is_single() const
Definition mxarray.h:415
mwSize get_m() const
Definition mxarray.h:434
int set_uint32s(mxUint32 *data)
Definition mxarray.h:549
mxUint64 * get_uint64s() const
Definition mxarray.h:511
int is_int64() const
Definition mxarray.h:407
int get_number_of_fields() const
Definition mxarray.h:586
mxComplexDouble * get_complex_doubles() const
Definition mxarray.h:514
double get_scalar() const
Definition mxarray.h:480
void set_name(const char *name)
Definition mxarray.cc:3097
mwIndex * get_jc() const
Definition mxarray.h:565
void set_n(mwSize n)
Definition mxarray.h:445
mxUint32 * get_uint32s() const
Definition mxarray.h:508
mwSize get_number_of_dimensions() const
Definition mxarray.h:440
bool mutation_needed() const
Definition mxarray.h:606
const char * get_class_name() const
Definition mxarray.h:463
void set_property(mwIndex idx, const char *pname, const mxArray *pval)
Definition mxarray.h:468
std::size_t get_element_size() const
Definition mxarray.h:603
int set_singles(mxSingle *data)
Definition mxarray.h:528
mxArray * get_property(mwIndex idx, const char *pname) const
Definition mxarray.h:465
int set_uint16s(mxUint16 *data)
Definition mxarray.h:546
void set_m(mwSize m)
Definition mxarray.h:443
static void * alloc(bool init, std::size_t n, std::size_t t)
Definition mxarray.cc:3388
int is_function_handle() const
Definition mxarray.h:401
mxArray * dup() const
Definition mxarray.h:369
int set_uint64s(mxUint64 *data)
Definition mxarray.h:552
int is_double() const
Definition mxarray.h:399
mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const
Definition mxarray.h:600
static char * strsave(const char *str)
Definition mxarray.h:616
int is_char() const
Definition mxarray.h:393
mwSize get_number_of_elements() const
Definition mxarray.h:450
int set_dimensions(mwSize *dims_arg, mwSize ndims_arg)
Definition mxarray.h:447
mxUint8 * get_uint8s() const
Definition mxarray.h:502
void set_data(void *pr)
Definition mxarray.h:523
int isempty() const
Definition mxarray.h:453
mwIndex * get_ir() const
Definition mxarray.h:563
int is_struct() const
Definition mxarray.h:419
static void * calloc(std::size_t n, std::size_t t)
Definition mxarray.cc:3382
int set_complex_doubles(mxComplexDouble *data)
Definition mxarray.h:555
int get_field_number(const char *key) const
Definition mxarray.h:592
int iscell() const
Definition mxarray.h:391
int add_field(const char *key)
Definition mxarray.h:575
char * array_to_string() const
Definition mxarray.h:598
mwSize get_nzmax() const
Definition mxarray.h:567
int is_uint32() const
Definition mxarray.h:423
mxInt8 * get_int8s() const
Definition mxarray.h:490
mxInt32 * get_int32s() const
Definition mxarray.h:496
void * get_data() const
Definition mxarray.h:482
bool is_scalar() const
Definition mxarray.h:455
int set_int32s(mxInt32 *data)
Definition mxarray.h:537
int set_int64s(mxInt64 *data)
Definition mxarray.h:540
int is_int32() const
Definition mxarray.h:405
int set_doubles(mxDouble *data)
Definition mxarray.h:525
void set_nzmax(mwSize nzmax)
Definition mxarray.h:573
mxSingle * get_singles() const
Definition mxarray.h:487
int is_logical_scalar_true() const
Definition mxarray.h:431
int is_numeric() const
Definition mxarray.h:413
const char * get_field_name_by_number(int key_num) const
Definition mxarray.h:589
const char * get_name() const
Definition mxarray.h:457
bool is_octave_value() const
Definition mxarray.h:389
mwSize get_n() const
Definition mxarray.h:436
void set_jc(mwIndex *jc)
Definition mxarray.h:571
octave_value as_octave_value() const
Definition mxarray.cc:3114
int set_int16s(mxInt16 *data)
Definition mxarray.h:534
int is_complex() const
Definition mxarray.h:397
mxClassID get_class_id() const
Definition mxarray.h:461
mxArray * get_cell(mwIndex idx) const
Definition mxarray.h:474
mwSize * get_dimensions() const
Definition mxarray.h:438
int is_uint64() const
Definition mxarray.h:425
int get_string(char *buf, mwSize buflen) const
Definition mxarray.h:595
int is_class(const char *name_arg) const
Definition mxarray.h:395
int set_int8s(mxInt8 *data)
Definition mxarray.h:531
void set_class_name(const char *name_arg)
Definition mxarray.h:471
void set_field_by_number(mwIndex index, int key_num, mxArray *val)
Definition mxarray.h:583
void set_cell(mwIndex idx, mxArray *val)
Definition mxarray.h:477
mxInt64 * get_int64s() const
Definition mxarray.h:499
int is_uint8() const
Definition mxarray.h:427
void set_ir(mwIndex *ir)
Definition mxarray.h:569
static void * malloc(std::size_t n)
Definition mxarray.cc:3376
mxUint16 * get_uint16s() const
Definition mxarray.h:505
void set_imag_data(void *pi)
Definition mxarray.h:561
mxComplexSingle * get_complex_singles() const
Definition mxarray.h:517
int is_uint16() const
Definition mxarray.h:421
mxArray * mutate() const
Definition mxarray.h:608
void remove_field(int key_num)
Definition mxarray.h:577
int is_int8() const
Definition mxarray.h:409
int is_sparse() const
Definition mxarray.h:417
void * get_imag_data() const
Definition mxarray.h:520
int is_int16() const
Definition mxarray.h:403
void warning(const char *fmt,...)
Definition error.cc:1078
void error(const char *fmt,...)
Definition error.cc:1003
F77_RET_T const F77_DBLE const F77_DBLE * f
int mexSet_impl(double handle, const char *property, mxArray *val)
Definition mxarray.cc:346
int mexPutVariable_impl(const char *space, const char *name, const mxArray *ptr)
Definition mxarray.cc:268
void mexErrMsgTxt_impl(const char *who, const char *s)
Definition mxarray.cc:245
#define DO_VOID_MUTABLE_METHOD(METHOD_CALL)
Definition mxarray.h:84
octave_value_list mx_to_ov_args(int nargin, mxArray *argin[])
Definition mxarray.cc:216
#define DO_MUTABLE_METHOD(RET_T, METHOD_CALL)
Definition mxarray.h:73
T::size_type strlen(const typename T::value_type *str)
Definition oct-string.cc:88
bool strcmp(const T &str_a, const T &str_b)
Octave string utility functions.
void free(void *)