GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
mex.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2006-2022 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#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30// #define DEBUG 1
31
32#if defined (DEBUG)
33# include <iostream>
34#endif
35
36#include <cstdarg>
37#include <cstdlib>
38#include <cstring>
39#include <cctype>
40
41#include <limits>
42#include <map>
43#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
44# include <memory_resource>
45#endif
46#include <set>
47#include <string>
48
49// Needed to instantiate Array objects with custom allocator.
50#include "Array.cc"
51#include "f77-fcn.h"
52#include "lo-ieee.h"
53#include "oct-locbuf.h"
54#include "quit.h"
55
56#include "Cell.h"
57#include "error.h"
58#include "interpreter-private.h"
59#include "interpreter.h"
60// mxArray must be declared as a class before including mexproto.h.
61#include "mxarray.h"
62#include "mexproto.h"
63#include "oct-map.h"
64#include "ovl.h"
65#include "ov.h"
66#include "ov-classdef.h"
67#include "ov-mex-fcn.h"
68#include "ov-usr-fcn.h"
69#include "pager.h"
70#include "parse.h"
71#include "unwind-prot.h"
72#include "utils.h"
73#include "variables.h"
74#include "graphics.h"
75
76// These must be declared extern "C" but may be omitted from the set of
77// symbols declared in mexproto.h, so we declare them here as well.
78
79extern "C"
80{
81 extern OCTINTERP_API const mxArray *
82 mexGet_interleaved (double handle, const char *property);
83
84 extern OCTINTERP_API mxArray *
85 mxCreateCellArray (mwSize ndims, const mwSize *dims);
86
87 extern OCTINTERP_API mxArray *
88 mxCreateCellMatrix (mwSize m, mwSize n);
89
90 extern OCTINTERP_API mxArray *
91 mxCreateCharArray (mwSize ndims, const mwSize *dims);
92
93 extern OCTINTERP_API mxArray *
94 mxCreateCharMatrixFromStrings (mwSize m, const char **str);
95
96 extern OCTINTERP_API mxArray *
97 mxCreateDoubleMatrix (mwSize nr, mwSize nc, mxComplexity flag);
98
99 extern OCTINTERP_API mxArray *
100 mxCreateDoubleScalar (double val);
101
102 extern OCTINTERP_API mxArray *
103 mxCreateLogicalArray (mwSize ndims, const mwSize *dims);
104
105 extern OCTINTERP_API mxArray *
106 mxCreateLogicalMatrix (mwSize m, mwSize n);
107
108 extern OCTINTERP_API mxArray *
109 mxCreateLogicalScalar (mxLogical val);
110
111 extern OCTINTERP_API mxArray *
112 mxCreateNumericArray (mwSize ndims, const mwSize *dims, mxClassID class_id,
113 mxComplexity flag);
114
115 extern OCTINTERP_API mxArray *
116 mxCreateNumericMatrix (mwSize m, mwSize n, mxClassID class_id,
117 mxComplexity flag);
118
119 extern OCTINTERP_API mxArray *
120 mxCreateUninitNumericArray (mwSize ndims, const mwSize *dims,
121 mxClassID class_id, mxComplexity flag);
122
123 extern OCTINTERP_API mxArray *
124 mxCreateUninitNumericMatrix (mwSize m, mwSize n, mxClassID class_id,
125 mxComplexity flag);
126
127 extern OCTINTERP_API mxArray *
128 mxCreateSparse (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag);
129
130 extern OCTINTERP_API mxArray *
131 mxCreateSparseLogicalMatrix (mwSize m, mwSize n, mwSize nzmax);
132
133 extern OCTINTERP_API mxArray *
134 mxCreateString (const char *str);
135
136 extern OCTINTERP_API mxArray *
137 mxCreateStructArray (mwSize ndims, const mwSize *dims, int num_keys,
138 const char **keys);
139
140 extern OCTINTERP_API mxArray *
141 mxCreateStructMatrix (mwSize rows, mwSize cols, int num_keys,
142 const char **keys);
143
144 extern OCTINTERP_API mxArray *
145 mxCreateCellArray_interleaved (mwSize ndims, const mwSize *dims);
146
147 extern OCTINTERP_API mxArray *
148 mxCreateCellMatrix_interleaved (mwSize m, mwSize n);
149
150 extern OCTINTERP_API mxArray *
151 mxCreateCharArray_interleaved (mwSize ndims, const mwSize *dims);
152
153 extern OCTINTERP_API mxArray *
154 mxCreateCharMatrixFromStrings_interleaved (mwSize m, const char **str);
155
156 extern OCTINTERP_API mxArray *
157 mxCreateDoubleMatrix_interleaved (mwSize nr, mwSize nc, mxComplexity flag);
158
159 extern OCTINTERP_API mxArray *
161
162 extern OCTINTERP_API mxArray *
163 mxCreateLogicalArray_interleaved (mwSize ndims, const mwSize *dims);
164
165 extern OCTINTERP_API mxArray *
166 mxCreateLogicalMatrix_interleaved (mwSize m, mwSize n);
167
168 extern OCTINTERP_API mxArray *
169 mxCreateLogicalScalar_interleaved (mxLogical val);
170
171 extern OCTINTERP_API mxArray *
172 mxCreateNumericArray_interleaved (mwSize ndims, const mwSize *dims,
173 mxClassID class_id, mxComplexity flag);
174
175 extern OCTINTERP_API mxArray *
176 mxCreateNumericMatrix_interleaved (mwSize m, mwSize n, mxClassID class_id,
177 mxComplexity flag);
178
179 extern OCTINTERP_API mxArray *
180 mxCreateUninitNumericArray_interleaved (mwSize ndims, const mwSize *dims,
181 mxClassID class_id,
182 mxComplexity flag);
183
184 extern OCTINTERP_API mxArray *
185 mxCreateUninitNumericMatrix_interleaved (mwSize m, mwSize n,
186 mxClassID class_id,
187 mxComplexity flag);
188
189 extern OCTINTERP_API mxArray *
190 mxCreateSparse_interleaved (mwSize m, mwSize n, mwSize nzmax,
191 mxComplexity flag);
192
193 extern OCTINTERP_API mxArray *
194 mxCreateSparseLogicalMatrix_interleaved (mwSize m, mwSize n, mwSize nzmax);
195
196 extern OCTINTERP_API mxArray *
197 mxCreateString_interleaved (const char *str);
198
199 extern OCTINTERP_API mxArray *
200 mxCreateStructArray_interleaved (mwSize ndims, const mwSize *dims,
201 int num_keys, const char **keys);
202
203 extern OCTINTERP_API mxArray *
204 mxCreateStructMatrix_interleaved (mwSize rows, mwSize cols, int num_keys,
205 const char **keys);
206
207 extern OCTINTERP_API int mxMakeArrayReal (mxArray *ptr);
208 extern OCTINTERP_API int mxMakeArrayComplex (mxArray *ptr);
209
210 extern OCTINTERP_API mxDouble * mxGetDoubles (const mxArray *p);
211 extern OCTINTERP_API mxSingle * mxGetSingles (const mxArray *p);
212 extern OCTINTERP_API mxInt8 * mxGetInt8s (const mxArray *p);
213 extern OCTINTERP_API mxInt16 * mxGetInt16s (const mxArray *p);
214 extern OCTINTERP_API mxInt32 * mxGetInt32s (const mxArray *p);
215 extern OCTINTERP_API mxInt64 * mxGetInt64s (const mxArray *p);
216 extern OCTINTERP_API mxUint8 * mxGetUint8s (const mxArray *p);
217 extern OCTINTERP_API mxUint16 * mxGetUint16s (const mxArray *p);
218 extern OCTINTERP_API mxUint32 * mxGetUint32s (const mxArray *p);
219 extern OCTINTERP_API mxUint64 * mxGetUint64s (const mxArray *p);
220
221 extern OCTINTERP_API mxComplexDouble * mxGetComplexDoubles (const mxArray *p);
222 extern OCTINTERP_API mxComplexSingle * mxGetComplexSingles (const mxArray *p);
223#if 0
224 /* We don't have these yet. */
225 extern OCTINTERP_API mxComplexInt8 * mxGetComplexInt8s (const mxArray *p);
226 extern OCTINTERP_API mxComplexInt16 * mxGetComplexInt16s (const mxArray *p);
227 extern OCTINTERP_API mxComplexInt32 * mxGetComplexInt32s (const mxArray *p);
228 extern OCTINTERP_API mxComplexInt64 * mxGetComplexInt64s (const mxArray *p);
229 extern OCTINTERP_API mxComplexUint8 * mxGetComplexUint8s (const mxArray *p);
230 extern OCTINTERP_API mxComplexUint16 * mxGetComplexUint16s (const mxArray *p);
231 extern OCTINTERP_API mxComplexUint32 * mxGetComplexUint32s (const mxArray *p);
232 extern OCTINTERP_API mxComplexUint64 * mxGetComplexUint64s (const mxArray *p);
233#endif
234
235 extern OCTINTERP_API double * mxGetPi (const mxArray *ptr);
236 extern OCTINTERP_API void * mxGetImagData (const mxArray *ptr);
237
238 extern OCTINTERP_API int mxSetDoubles (mxArray *p, mxDouble *d);
239 extern OCTINTERP_API int mxSetSingles (mxArray *p, mxSingle *d);
240 extern OCTINTERP_API int mxSetInt8s (mxArray *p, mxInt8 *d);
241 extern OCTINTERP_API int mxSetInt16s (mxArray *p, mxInt16 *d);
242 extern OCTINTERP_API int mxSetInt32s (mxArray *p, mxInt32 *d);
243 extern OCTINTERP_API int mxSetInt64s (mxArray *p, mxInt64 *d);
244 extern OCTINTERP_API int mxSetUint8s (mxArray *p, mxUint8 *d);
245 extern OCTINTERP_API int mxSetUint16s (mxArray *p, mxUint16 *d);
246 extern OCTINTERP_API int mxSetUint32s (mxArray *p, mxUint32 *d);
247 extern OCTINTERP_API int mxSetUint64s (mxArray *p, mxUint64 *d);
248
249 extern OCTINTERP_API int mxSetComplexDoubles (mxArray *p, mxComplexDouble *d);
250 extern OCTINTERP_API int mxSetComplexSingles (mxArray *p, mxComplexSingle *d);
251#if 0
252 /* We don't have these yet. */
253 extern OCTINTERP_API int mxSetComplexInt8s (mxArray *p, mxComplexInt8 *d);
254 extern OCTINTERP_API int mxSetComplexInt16s (mxArray *p, mxComplexInt16 *d);
255 extern OCTINTERP_API int mxSetComplexInt32s (mxArray *p, mxComplexInt32 *d);
256 extern OCTINTERP_API int mxSetComplexInt64s (mxArray *p, mxComplexInt64 *d);
257 extern OCTINTERP_API int mxSetComplexUint8s (mxArray *p, mxComplexUint8 *d);
258 extern OCTINTERP_API int mxSetComplexUint16s (mxArray *p, mxComplexUint16 *d);
259 extern OCTINTERP_API int mxSetComplexUint32s (mxArray *p, mxComplexUint32 *d);
260 extern OCTINTERP_API int mxSetComplexUint64s (mxArray *p, mxComplexUint64 *d);
261#endif
262
263 extern OCTINTERP_API void mxSetPi (mxArray *ptr, double *pi);
264 extern OCTINTERP_API void mxSetImagData (mxArray *ptr, void *pi);
265}
266
267static void *
268xmalloc (size_t n)
269{
270 void *ptr = std::malloc (n);
271
272#if defined (DEBUG)
273 std::cerr << "xmalloc (" << n << ") = " << ptr << std::endl;
274#endif
275
276 return ptr;
277}
278
279static void *
280xrealloc (void *ptr, size_t n)
281{
282 void *newptr = std::realloc (ptr, n);
283
284#if defined (DEBUG)
285 std::cerr << "xrealloc (" << ptr << ", " << n << ") = " << newptr
286 << std::endl;
287#endif
288
289 return newptr;
290}
291
292static void
293xfree (void *ptr)
294{
295#if defined (DEBUG)
296 std::cerr << "xfree (" << ptr << ")" << std::endl;
297#endif
298
299 std::free (ptr);
300}
301
302static mwSize
303max_str_len (mwSize m, const char **str)
304{
305 int max_len = 0;
306
307 for (mwSize i = 0; i < m; i++)
308 {
309 mwSize tmp = strlen (str[i]);
310
311 if (tmp > max_len)
312 max_len = tmp;
313 }
314
315 return max_len;
316}
317
318// FIXME: Is there a better/standard way to do this job?
319
320template <typename T>
322{
323public:
324 static const bool is_complex = false;
325};
326
327template <>
329{
330public:
331 static const bool is_complex = true;
332};
333
334template <>
336{
337public:
338 static const bool is_complex = true;
339};
340
341#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
342
343class mx_deleting_memory_resource : public std::pmr::memory_resource
344{
345private:
346
347 void * do_allocate (std::size_t bytes, size_t /*alignment*/)
348 {
349 void *ptr = xmalloc (bytes);
350
351 if (! ptr)
352 throw std::bad_alloc ();
353
354 return ptr;
355 }
356
357 void do_deallocate (void* ptr, std::size_t /*bytes*/,
358 std::size_t /*alignment*/)
359 {
360 xfree (ptr);
361 }
362
363 bool do_is_equal (const std::pmr::memory_resource& other) const noexcept
364 {
365 return this == dynamic_cast<const mx_deleting_memory_resource *> (&other);
366 }
367};
368
369class mx_preserving_memory_resource : public std::pmr::memory_resource
370{
371private:
372
373 void * do_allocate (std::size_t bytes, size_t /*alignment*/)
374 {
375 void *ptr = xmalloc (bytes);
376
377 if (! ptr)
378 throw std::bad_alloc ();
379
380 return ptr;
381 }
382
383 void do_deallocate (void* /*ptr*/, std::size_t /*bytes*/,
384 std::size_t /*alignment*/)
385 { }
386
387 bool do_is_equal (const std::pmr::memory_resource& other) const noexcept
388 {
389 return this == dynamic_cast<const mx_preserving_memory_resource *> (&other);
390 }
391};
392
393// FIXME: Is it OK for the memory resource object to be defined this
394// way?
395static mx_deleting_memory_resource the_mx_deleting_memory_resource;
396static mx_preserving_memory_resource the_mx_preserving_memory_resource;
397
398static std::pmr::memory_resource *current_mx_memory_resource = &the_mx_deleting_memory_resource;
399
400#endif
401
402// ------------------------------------------------------------------
403
405 : m_interleaved (interleaved)
406{ }
407
408static mwIndex
409calc_single_subscript_internal (mwSize ndims, const mwSize *dims,
410 mwSize nsubs, const mwIndex *subs)
411{
412 mwIndex retval = 0;
413
414 switch (nsubs)
415 {
416 case 0:
417 break;
418
419 case 1:
420 retval = subs[0];
421 break;
422
423 default:
424 {
425 // Both nsubs and ndims should be at least 2 here.
426
427 mwSize n = (nsubs <= ndims ? nsubs : ndims);
428
429 retval = subs[--n];
430
431 while (--n >= 0)
432 retval = dims[n] * retval + subs[n];
433 }
434 break;
435 }
436
437 return retval;
438}
439
440// The object that handles values pass to MEX files from Octave. Some
441// methods in this class may set mutate_flag to TRUE to tell the
442// mxArray class to convert to the Matlab-style representation and
443// then invoke the method on that object instead (for example, getting
444// a pointer to real or imaginary data from a complex object requires
445// a mutation but getting a pointer to real data from a real object
446// does not). Changing the representation causes a copy so we try to
447// avoid it unless it is really necessary. Once the conversion
448// happens, we delete this representation, so the conversion can only
449// happen once per call to a MEX file.
450
451static inline void * maybe_mark_foreign (void *ptr);
452
453static inline void maybe_disown_ptr (void *ptr);
454
455#define VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
456 void FCN_NAME ARG_LIST { request_mutation (); }
457
458#define CONST_VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
459 void FCN_NAME ARG_LIST const { request_mutation (); }
460
461#define MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
462 RET_TYPE FCN_NAME ARG_LIST { request_mutation (); return RET_VAL; }
463
464#define CONST_MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
465 RET_TYPE FCN_NAME ARG_LIST const { request_mutation (); return RET_VAL; }
466
467#define GET_DATA_METHOD(RT, FCN_NAME, ID, COMPLEXITY) \
468 RT * FCN_NAME (void) const { return get_data<RT> (ID, COMPLEXITY); }
469
471{
472public:
473
474 mxArray_octave_value (bool interleaved, const octave_value& ov)
475 : mxArray_base (interleaved), m_val (ov), m_mutate_flag (false),
476 m_id (mxUNKNOWN_CLASS), m_class_name (nullptr), m_ndims (-1),
477 m_dims (nullptr)
478 { }
479
480 // No assignment! FIXME: should this be implemented? Note that we
481 // do have a copy constructor.
482
484
485 mxArray_base * dup (void) const { return new mxArray_octave_value (*this); }
486
487 mxArray * as_mxArray (void) const
488 {
490
491 // RETVAL is assumed to be an mxArray_matlab object. Should we
492 // assert that condition here?
493
494 if (retval)
495 {
496 // Preserve cached values of class name and dimensions in case
497 // they will be used after we mutate.
498
499 // set_class_name will handle deleting class name that comes
500 // from as_mxArray conversion function.
501
502 if (m_class_name)
503 {
505
506 m_class_name = nullptr;
507 }
508
509 if (m_dims)
510 {
511 mwSize *xdims = retval->get_dimensions ();
512
513 mxFree (xdims);
514
515 retval->set_dimensions (m_dims, m_ndims);
516
517 m_dims = nullptr;
518 }
519 }
520
521 return retval;
522 }
523
525 {
527 mxFree (m_dims);
528 }
529
530 bool is_octave_value (void) const { return true; }
531
532 int iscell (void) const { return m_val.iscell (); }
533
534 int is_char (void) const { return m_val.is_string (); }
535
536 int is_complex (void) const { return m_val.iscomplex (); }
537
538 int is_double (void) const { return m_val.is_double_type (); }
539
540 int is_function_handle (void) const { return m_val.is_function_handle (); }
541
542 int is_int16 (void) const { return m_val.is_int16_type (); }
543
544 int is_int32 (void) const { return m_val.is_int32_type (); }
545
546 int is_int64 (void) const { return m_val.is_int64_type (); }
547
548 int is_int8 (void) const { return m_val.is_int8_type (); }
549
550 int is_logical (void) const { return m_val.islogical (); }
551
552 int is_numeric (void) const { return m_val.isnumeric (); }
553
554 int is_single (void) const { return m_val.is_single_type (); }
555
556 int is_sparse (void) const { return m_val.issparse (); }
557
558 int is_struct (void) const { return m_val.isstruct (); }
559
560 int is_uint16 (void) const { return m_val.is_uint16_type (); }
561
562 int is_uint32 (void) const { return m_val.is_uint32_type (); }
563
564 int is_uint64 (void) const { return m_val.is_uint64_type (); }
565
566 int is_uint8 (void) const { return m_val.is_uint8_type (); }
567
568 int is_range (void) const { return m_val.is_range (); }
569
570 int isreal (void) const { return m_val.isreal (); }
571
572 int is_logical_scalar_true (void) const
573 {
574 return (is_logical_scalar () && m_val.is_true ());
575 }
576
577 mwSize get_m (void) const { return m_val.rows (); }
578
579 mwSize get_n (void) const
580 {
581 mwSize n = 1;
582
583 // Force m_dims and m_ndims to be cached.
585
586 for (mwIndex i = m_ndims - 1; i > 0; i--)
587 n *= m_dims[i];
588
589 return n;
590 }
591
592 mwSize * get_dimensions (void) const
593 {
594 if (! m_dims)
595 {
596 m_ndims = m_val.ndims ();
597
598 m_dims = static_cast<mwSize *> (mxArray::malloc (m_ndims
599 * sizeof (mwSize)));
600
601 dim_vector dv = m_val.dims ();
602
603 for (mwIndex i = 0; i < m_ndims; i++)
604 m_dims[i] = dv(i);
605 }
606
607 return m_dims;
608 }
609
610 mwSize get_number_of_dimensions (void) const
611 {
612 // Force m_dims and m_ndims to be cached.
614
615 return m_ndims;
616 }
617
620
621 MUTATION_METHOD (int, set_dimensions, (mwSize *, mwSize), 0)
622
623 mwSize get_number_of_elements (void) const { return m_val.numel (); }
624
625 int isempty (void) const { return m_val.isempty (); }
626
627 bool is_scalar (void) const
628 {
629 // Force m_dims and m_ndims to be cached.
631
632 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
633 }
634
635 mxClassID get_class_id (void) const
636 {
637 m_id = mxUNKNOWN_CLASS;
638
639 std::string cn = m_val.class_name ();
640
641 if (cn == "double")
642 m_id = mxDOUBLE_CLASS;
643 else if (cn == "single")
644 m_id = mxSINGLE_CLASS;
645 else if (cn == "char")
646 m_id = mxCHAR_CLASS;
647 else if (cn == "logical")
648 m_id = mxLOGICAL_CLASS;
649 else if (cn == "cell")
650 m_id = mxCELL_CLASS;
651 else if (cn == "struct")
652 m_id = mxSTRUCT_CLASS;
653 else if (cn == "function_handle")
654 m_id = mxFUNCTION_CLASS;
655 else if (cn == "int8")
656 m_id = mxINT8_CLASS;
657 else if (cn == "uint8")
658 m_id = mxUINT8_CLASS;
659 else if (cn == "int16")
660 m_id = mxINT16_CLASS;
661 else if (cn == "uint16")
662 m_id = mxUINT16_CLASS;
663 else if (cn == "int32")
664 m_id = mxINT32_CLASS;
665 else if (cn == "uint32")
666 m_id = mxUINT32_CLASS;
667 else if (cn == "int64")
668 m_id = mxINT64_CLASS;
669 else if (cn == "uint64")
670 m_id = mxUINT64_CLASS;
671
672 return m_id;
673 }
674
675 const char * get_class_name (void) const
676 {
677 if (! m_class_name)
678 {
679 std::string s = m_val.class_name ();
680 m_class_name = mxArray::strsave (s.c_str ());
681 }
682
683 return m_class_name;
684 }
685
686 // Not allowed.
688
689 mxArray * get_property (mwIndex idx, const char *pname) const
690 {
691 mxArray *retval = nullptr;
692
694 {
696
697 if (ov_cdef)
698 {
699 octave_value pval = ov_cdef->get_property (idx, pname);
700
701 if (pval.is_defined())
702 retval = new mxArray (m_interleaved, pval);
703 }
704 }
705
706 return retval;
707 }
708
709 void set_property (mwIndex idx, const char *pname, const mxArray *pval)
710 {
712 {
714
715 if (ov_cdef)
716 ov_cdef->set_property (idx, pname, pval->as_octave_value ());
717 }
718 else
719 err_invalid_type ("set_property");
720 }
721
722 CONST_MUTATION_METHOD (mxArray *, get_cell, (mwIndex), nullptr)
723
724 // Not allowed.
726
727 double get_scalar (void) const
728 {
729 if (m_val.issparse ())
730 {
731 // For sparse arrays, return the first non-zero value.
732 const void *m_data = m_val.mex_get_data ();
733 if (m_data == nullptr)
734 return 0.0;
735
736 if (m_val.islogical ())
737 return *static_cast<const bool *> (m_data);
738 else if (m_val.isreal ())
739 return *static_cast<const double *> (m_data);
740 else // Complex type, only return real part
741 return *static_cast<const double *> (m_data);
742 }
743 else
744 return m_val.scalar_value (true);
745 }
746
747 void * get_data (void) const
748 {
749 // Casting away const required for MEX interface.
750
751 void *retval = const_cast<void *> (m_val.mex_get_data ());
752
753 if (retval && (m_val.isreal () || m_interleaved))
754 {
755 maybe_mark_foreign (retval);
756 return retval;
757 }
758
760 return nullptr;
761 }
762
763 template <typename T>
764 T * get_data (mxClassID class_id, mxComplexity complexity) const
765 {
766 // Casting away const required for MEX interface.
767
768 void *ptr = const_cast<void *> (m_val.mex_get_data (class_id, complexity));
769
770 T *retval = static_cast<T *> (ptr);
771
772 if (retval && (complexity == mxREAL || m_interleaved))
773 {
774 maybe_mark_foreign (retval);
775 return retval;
776 }
777
779 return nullptr;
780 }
781
782 GET_DATA_METHOD (mxDouble, get_doubles, mxDOUBLE_CLASS, mxREAL);
783
784 GET_DATA_METHOD (mxSingle, get_singles, mxSINGLE_CLASS, mxREAL);
785
786 GET_DATA_METHOD (mxInt8, get_int8s, mxINT8_CLASS, mxREAL);
787
788 GET_DATA_METHOD (mxInt16, get_int16s, mxINT16_CLASS, mxREAL);
789
790 GET_DATA_METHOD (mxInt32, get_int32s, mxINT32_CLASS, mxREAL);
791
792 GET_DATA_METHOD (mxInt64, get_int64s, mxINT64_CLASS, mxREAL);
793
794 GET_DATA_METHOD (mxUint8, get_uint8s, mxUINT8_CLASS, mxREAL);
795
796 GET_DATA_METHOD (mxUint16, get_uint16s, mxUINT16_CLASS, mxREAL);
797
798 GET_DATA_METHOD (mxUint32, get_uint32s, mxUINT32_CLASS, mxREAL);
799
800 GET_DATA_METHOD (mxUint64, get_uint64s, mxUINT64_CLASS, mxREAL);
801
802 GET_DATA_METHOD (mxComplexDouble, get_complex_doubles, mxDOUBLE_CLASS, mxCOMPLEX);
803
804 GET_DATA_METHOD (mxComplexSingle, get_complex_singles, mxDOUBLE_CLASS, mxCOMPLEX);
805
806#if 0
807 /* We don't have these yet. */
808 GET_DATA_METHOD (mxComplexInt8 *, get_complex_int8s, (void), nullptr);
809
810 GET_DATA_METHOD (mxComplexInt16 *, get_complex_int16s, (void), nullptr);
811
812 GET_DATA_METHOD (mxComplexInt32 *, get_complex_int32s, (void), nullptr);
813
814 GET_DATA_METHOD (mxComplexInt64 *, get_complex_int64s, (void), nullptr);
815
816 GET_DATA_METHOD (mxComplexUint8 *, get_complex_uint8s, (void), nullptr);
817
818 GET_DATA_METHOD (mxComplexUint16 *, get_complex_uint16s, (void), nullptr);
819
820 GET_DATA_METHOD (mxComplexUint32 *, get_complex_uint32s, (void), nullptr);
821
822 GET_DATA_METHOD (mxComplexUint64 *, get_complex_uint64s, (void), nullptr);
823#endif
824
825 void * get_imag_data (void) const
826 {
827 void *retval = nullptr;
828
829 if (is_numeric () && isreal ())
830 retval = nullptr;
831 else
833
834 return retval;
835 }
836
837 // Not allowed.
839
840 MUTATION_METHOD (int, set_doubles, (mxDouble *), 0)
841 MUTATION_METHOD (int, set_singles, (mxSingle *), 0)
842 MUTATION_METHOD (int, set_int8s, (mxInt8 *), 0)
843 MUTATION_METHOD (int, set_int16s, (mxInt16 *), 0)
844 MUTATION_METHOD (int, set_int32s, (mxInt32 *), 0)
845 MUTATION_METHOD (int, set_int64s, (mxInt64 *), 0)
846 MUTATION_METHOD (int, set_uint8s, (mxUint8 *), 0)
847 MUTATION_METHOD (int, set_uint16s, (mxUint16 *), 0)
848 MUTATION_METHOD (int, set_uint32s, (mxUint32 *), 0)
849 MUTATION_METHOD (int, set_uint64s, (mxUint64 *), 0)
850
851 MUTATION_METHOD (int, set_complex_doubles, (mxComplexDouble *), 0)
852 MUTATION_METHOD (int, set_complex_singles, (mxComplexSingle *), 0)
853#if 0
854 /* We don't have these yet. */
855 MUTATION_METHOD (int, set_complex_int8s, (mxComplexInt8 *), 0)
856 MUTATION_METHOD (int, set_complex_int16s, (mxComplexInt16 *), 0)
857 MUTATION_METHOD (int, set_complex_int32s, (mxComplexInt32 *), 0)
858 MUTATION_METHOD (int, set_complex_int64s, (mxComplexInt64 *), 0)
859 MUTATION_METHOD (int, set_complex_uint8s, (mxComplexUint8 *), 0)
860 MUTATION_METHOD (int, set_complex_uint16s, (mxComplexUint16 *), 0)
861 MUTATION_METHOD (int, set_complex_uint32s, (mxComplexUint32 *), 0)
862 MUTATION_METHOD (int, set_complex_uint64s, (mxComplexUint64 *), 0)
863#endif
864
865 // Not allowed.
867
868 mwIndex * get_ir (void) const
869 {
870 // Casting away const required for MEX interface.
871
872 octave_idx_type *ptr = const_cast<octave_idx_type *> (m_val.mex_get_ir ());
873 return static_cast<mwIndex *> (maybe_mark_foreign (ptr));
874 }
875
876 mwIndex * get_jc (void) const
877 {
878 // Casting away const required for MEX interface.
879
880 octave_idx_type *ptr = const_cast<octave_idx_type *> (m_val.mex_get_jc ());
881 return static_cast<mwIndex *> (maybe_mark_foreign (ptr));
882 }
883
884 mwSize get_nzmax (void) const { return m_val.nzmax (); }
885
886 // Not allowed.
888
889 // Not allowed.
891
892 // Not allowed.
894
895 // Not allowed.
896 MUTATION_METHOD (int, add_field, (const char *), 0)
897
898 // Not allowed.
900
902
903 // Not allowed.
905
906 int get_number_of_fields (void) const { return m_val.nfields (); }
907
908 CONST_MUTATION_METHOD (const char *, get_field_name_by_number, (int), nullptr)
909
910 CONST_MUTATION_METHOD (int, get_field_number, (const char *), 0)
911
912 int get_string (char *buf, mwSize buflen) const
913 {
914 int retval = 1;
915
916 mwSize nel = get_number_of_elements ();
917
918 if (m_val.is_string () && nel < buflen)
919 {
921
922 const char *p = tmp.data ();
923
924 for (mwIndex i = 0; i < nel; i++)
925 buf[i] = p[i];
926
927 buf[nel] = 0;
928
929 retval = 0;
930 }
931
932 return retval;
933 }
934
935 char * array_to_string (void) const
936 {
937 // FIXME: this is supposed to handle multi-byte character strings.
938
939 char *buf = nullptr;
940
941 if (m_val.is_string ())
942 {
943 mwSize nel = get_number_of_elements ();
944
945 buf = static_cast<char *> (mxArray::malloc (nel + 1));
946
947 if (buf)
948 {
950
951 const char *p = tmp.data ();
952
953 for (mwIndex i = 0; i < nel; i++)
954 buf[i] = p[i];
955
956 buf[nel] = '\0';
957 }
958 }
959
960 return buf;
961 }
962
963 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const
964 {
965 // Force m_ndims, n_dims to be cached.
967
968 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
969 }
970
971 std::size_t get_element_size (void) const
972 {
973 // Force m_id to be cached.
974 get_class_id ();
975
976 switch (m_id)
977 {
978 case mxCELL_CLASS: return sizeof (mxArray *);
979 case mxSTRUCT_CLASS: return sizeof (mxArray *);
980 case mxLOGICAL_CLASS: return sizeof (mxLogical);
981 case mxCHAR_CLASS: return sizeof (mxChar);
982 case mxDOUBLE_CLASS: return get_numeric_element_size (sizeof (mxDouble));
983 case mxSINGLE_CLASS: return get_numeric_element_size (sizeof (mxSingle));
984 case mxINT8_CLASS: return get_numeric_element_size (sizeof (mxInt8));
985 case mxUINT8_CLASS: return get_numeric_element_size (sizeof (mxUint8));
986 case mxINT16_CLASS: return get_numeric_element_size (sizeof (mxInt16));
987 case mxUINT16_CLASS: return get_numeric_element_size (sizeof (mxUint16));
988 case mxINT32_CLASS: return get_numeric_element_size (sizeof (mxInt32));
989 case mxUINT32_CLASS: return get_numeric_element_size (sizeof (mxUint32));
990 case mxINT64_CLASS: return get_numeric_element_size (sizeof (mxInt64));
991 case mxUINT64_CLASS: return get_numeric_element_size (sizeof (mxUint64));
992 case mxFUNCTION_CLASS: return 0;
993 // FIXME: user-defined objects need their own class ID.
994 // What should they return, size of pointer?
995 default: return 0;
996 }
997 }
998
999 bool mutation_needed (void) const { return m_mutate_flag; }
1000
1001 void request_mutation (void) const
1002 {
1003 if (m_mutate_flag)
1005
1006 m_mutate_flag = true;
1007 }
1008
1009 mxArray * mutate (void) const { return as_mxArray (); }
1010
1011 octave_value as_octave_value (void) const { return m_val; }
1012
1013protected:
1014
1016 : mxArray_base (arg), m_val (arg.m_val), m_mutate_flag (arg.m_mutate_flag),
1018 m_ndims (arg.m_ndims),
1019 m_dims (m_ndims > 0
1020 ? static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize)))
1021 : nullptr)
1022 {
1023 if (m_dims)
1024 {
1025 for (mwIndex i = 0; i < m_ndims; i++)
1026 m_dims[i] = arg.m_dims[i];
1027 }
1028 }
1029
1030private:
1031
1033
1034 mutable bool m_mutate_flag;
1035
1036 // Caching these does not cost much or lead to much duplicated
1037 // code. For other things, we just request mutation to a
1038 // Matlab-style mxArray object.
1039
1040 mutable mxClassID m_id;
1041 mutable char *m_class_name;
1042 mutable mwSize m_ndims;
1043 mutable mwSize *m_dims;
1044};
1045
1046// The base class for the Matlab-style representation, used to handle
1047// things that are common to all Matlab-style objects.
1048
1050{
1051public:
1052
1053 // No assignment!
1054 // FIXME: should this be implemented?
1055 // Note that we *do* have a copy constructor.
1056
1058
1060 {
1062 mxFree (m_dims);
1063 }
1064
1065 int iscell (void) const { return m_id == mxCELL_CLASS; }
1066
1067 int is_char (void) const { return m_id == mxCHAR_CLASS; }
1068
1069 int is_complex (void) const { return 0; }
1070
1071 int is_double (void) const { return m_id == mxDOUBLE_CLASS; }
1072
1073 int is_function_handle (void) const { return m_id == mxFUNCTION_CLASS; }
1074
1075 int is_int16 (void) const { return m_id == mxINT16_CLASS; }
1076
1077 int is_int32 (void) const { return m_id == mxINT32_CLASS; }
1078
1079 int is_int64 (void) const { return m_id == mxINT64_CLASS; }
1080
1081 int is_int8 (void) const { return m_id == mxINT8_CLASS; }
1082
1083 int is_logical (void) const { return m_id == mxLOGICAL_CLASS; }
1084
1085 int is_numeric (void) const
1086 {
1087 return (m_id == mxDOUBLE_CLASS || m_id == mxSINGLE_CLASS
1088 || m_id == mxINT8_CLASS || m_id == mxUINT8_CLASS
1089 || m_id == mxINT16_CLASS || m_id == mxUINT16_CLASS
1090 || m_id == mxINT32_CLASS || m_id == mxUINT32_CLASS
1091 || m_id == mxINT64_CLASS || m_id == mxUINT64_CLASS);
1092 }
1093
1094 int is_single (void) const { return m_id == mxSINGLE_CLASS; }
1095
1096 int is_sparse (void) const { return 0; }
1097
1098 int is_struct (void) const { return m_id == mxSTRUCT_CLASS; }
1099
1100 int is_uint16 (void) const { return m_id == mxUINT16_CLASS; }
1101
1102 int is_uint32 (void) const { return m_id == mxUINT32_CLASS; }
1103
1104 int is_uint64 (void) const { return m_id == mxUINT64_CLASS; }
1105
1106 int is_uint8 (void) const { return m_id == mxUINT8_CLASS; }
1107
1108 int is_logical_scalar_true (void) const
1109 {
1110 return (is_logical_scalar ()
1111 && static_cast<mxLogical *> (get_data ())[0] != 0);
1112 }
1113
1114 mwSize get_m (void) const { return m_dims[0]; }
1115
1116 mwSize get_n (void) const
1117 {
1118 mwSize n = 1;
1119
1120 for (mwSize i = m_ndims - 1 ; i > 0 ; i--)
1121 n *= m_dims[i];
1122
1123 return n;
1124 }
1125
1126 mwSize * get_dimensions (void) const { return m_dims; }
1127
1128 mwSize get_number_of_dimensions (void) const { return m_ndims; }
1129
1130 void set_m (mwSize m) { m_dims[0] = m; }
1131
1132 void set_n (mwSize n) { m_dims[1] = n; }
1133
1134 int set_dimensions (mwSize *dims, mwSize ndims)
1135 {
1136 m_ndims = ndims;
1137
1138 mxFree (m_dims);
1139
1140 if (m_ndims > 0)
1141 {
1142 m_dims
1143 = static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize)));
1144
1145 if (m_dims == nullptr)
1146 return 1;
1147
1148 for (int i = 0; i < m_ndims; i++)
1149 m_dims[i] = dims[i];
1150
1151 return 0;
1152 }
1153 else
1154 {
1155 m_dims = nullptr;
1156 return 0;
1157 }
1158 }
1159
1160 mwSize get_number_of_elements (void) const
1161 {
1162 mwSize retval = m_dims[0];
1163
1164 for (mwIndex i = 1; i < m_ndims; i++)
1165 retval *= m_dims[i];
1166
1167 return retval;
1168 }
1169
1170 int isempty (void) const { return get_number_of_elements () == 0; }
1171
1172 bool is_scalar (void) const
1173 {
1174 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
1175 }
1176
1177 mxClassID get_class_id (void) const { return m_id; }
1178
1179 const char * get_class_name (void) const
1180 {
1181 switch (m_id)
1182 {
1183 case mxDOUBLE_CLASS: return "double";
1184 case mxSINGLE_CLASS: return "single";
1185 case mxCHAR_CLASS: return "char";
1186 case mxLOGICAL_CLASS: return "logical";
1187 case mxCELL_CLASS: return "cell";
1188 case mxSTRUCT_CLASS: return "struct";
1189 case mxFUNCTION_CLASS: return "function_handle";
1190 case mxINT8_CLASS: return "int8";
1191 case mxUINT8_CLASS: return "uint8";
1192 case mxINT16_CLASS: return "int16";
1193 case mxUINT16_CLASS: return "uint16";
1194 case mxINT32_CLASS: return "int32";
1195 case mxUINT32_CLASS: return "uint32";
1196 case mxINT64_CLASS: return "int64";
1197 case mxUINT64_CLASS: return "uint64";
1198 case mxUNKNOWN_CLASS: return "unknown";
1199 // FIXME: should return the classname of user-defined objects
1200 default: return "unknown";
1201 }
1202 }
1203
1204 void set_class_name (const char *name)
1205 {
1207 m_class_name = static_cast<char *> (mxArray::malloc (strlen (name) + 1));
1208 strcpy (m_class_name, name);
1209 }
1210
1211 mxArray * get_cell (mwIndex /*idx*/) const
1212 {
1213 err_invalid_type ("get_cell");
1214 }
1215
1216 void set_cell (mwIndex /*idx*/, mxArray * /*val*/)
1217 {
1218 err_invalid_type ("set_cell");
1219 }
1220
1221 double get_scalar (void) const
1222 {
1223 err_invalid_type ("get_scalar");
1224 }
1225
1226 void * get_data (void) const
1227 {
1228 err_invalid_type ("get_data");
1229 }
1230
1231 mxDouble * get_doubles (void) const
1232 {
1233 err_invalid_type ("get_doubles");
1234 }
1235
1236 mxSingle * get_singles (void) const
1237 {
1238 err_invalid_type ("get_singles");
1239 }
1240
1241 mxInt8 * get_int8s (void) const
1242 {
1243 err_invalid_type ("get_int8s");
1244 }
1245
1246 mxInt16 * get_int16s (void) const
1247 {
1248 err_invalid_type ("get_int16s");
1249 }
1250
1251 mxInt32 * get_int32s (void) const
1252 {
1253 err_invalid_type ("get_int32s");
1254 }
1255
1256 mxInt64 * get_int64s (void) const
1257 {
1258 err_invalid_type ("get_int64s");
1259 }
1260
1261 mxUint8 * get_uint8s (void) const
1262 {
1263 err_invalid_type ("get_uint8s");
1264 }
1265
1266 mxUint16 * get_uint16s (void) const
1267 {
1268 err_invalid_type ("get_uint16s");
1269 }
1270
1271 mxUint32 * get_uint32s (void) const
1272 {
1273 err_invalid_type ("get_uint32s");
1274 }
1275
1276 mxUint64 * get_uint64s (void) const
1277 {
1278 err_invalid_type ("get_uint64s");
1279 }
1280
1281 mxComplexDouble * get_complex_doubles (void) const
1282 {
1283 err_invalid_type ("get_complex_doubles");
1284 }
1285
1286 mxComplexSingle * get_complex_singles (void) const
1287 {
1288 err_invalid_type ("get_complex_singles");
1289 }
1290
1291#if 0
1292 /* We don't have these yet. */
1293 mxComplexInt8 * get_complex_int8s (void) const
1294 {
1295 err_invalid_type ("get_complex_int8s");
1296 }
1297
1298 mxComplexInt16 * get_complex_int16s (void) const
1299 {
1300 err_invalid_type ("get_complex_int16s");
1301 }
1302
1303 mxComplexInt32 * get_complex_int32s (void) const
1304 {
1305 err_invalid_type ("get_complex_int32s");
1306 }
1307
1308 mxComplexInt64 * get_complex_int64s (void) const
1309 {
1310 err_invalid_type ("get_complex_int64s");
1311 }
1312
1313 mxComplexUint8 * get_complex_uint8s (void) const
1314 {
1315 err_invalid_type ("get_complex_uint8s");
1316 }
1317
1318 mxComplexUint16 * get_complex_uint16s (void) const
1319 {
1320 err_invalid_type ("get_complex_uint16s");
1321 }
1322
1323 mxComplexUint32 * get_complex_uint32s (void) const
1324 {
1325 err_invalid_type ("get_complex_uint32s");
1326 }
1327
1328 mxComplexUint64 * get_complex_uint64s (void) const
1329 {
1330 err_invalid_type ("get_complex_uint64s");
1331 }
1332#endif
1333
1334 void * get_imag_data (void) const
1335 {
1336 err_invalid_type ("get_imag_data");
1337 }
1338
1339 void set_data (void * /*pr*/)
1340 {
1341 err_invalid_type ("set_data");
1342 }
1343
1344 int set_doubles (mxDouble *)
1345 {
1346 err_invalid_type ("set_doubles");
1347 }
1348
1349 int set_singles (mxSingle *)
1350 {
1351 err_invalid_type ("set_singles");
1352 }
1353
1354 int set_int8s (mxInt8 *)
1355 {
1356 err_invalid_type ("set_int8s");
1357 }
1358
1359 int set_int16s (mxInt16 *)
1360 {
1361 err_invalid_type ("set_int16s");
1362 }
1363
1364 int set_int32s (mxInt32 *)
1365 {
1366 err_invalid_type ("set_int32s");
1367 }
1368
1369 int set_int64s (mxInt64 *)
1370 {
1371 err_invalid_type ("set_int64s");
1372 }
1373
1374 int set_uint8s (mxUint8 *)
1375 {
1376 err_invalid_type ("set_uint8s");
1377 }
1378
1379 int set_uint16s (mxUint16 *)
1380 {
1381 err_invalid_type ("set_uint16s");
1382 }
1383
1384 int set_uint32s (mxUint32 *)
1385 {
1386 err_invalid_type ("set_uint32s");
1387 }
1388
1389 int set_uint64s (mxUint64 *)
1390 {
1391 err_invalid_type ("set_uint64s");
1392 }
1393
1394 int set_complex_doubles (mxComplexDouble *)
1395 {
1396 err_invalid_type ("set_complex_doubles");
1397 }
1398
1399 int set_complex_singles (mxComplexSingle *)
1400 {
1401 err_invalid_type ("set_complex_singles");
1402 }
1403
1404#if 0
1405 /* We don't have these yet. */
1406 int set_complex_int8s (mxComplexInt8 *)
1407 {
1408 err_invalid_type ("set_complex_int8s");
1409 }
1410
1411 int set_complex_int16s (mxComplexInt16 *)
1412 {
1413 err_invalid_type ("set_complex_int16s");
1414 }
1415
1416 int set_complex_int32s (mxComplexInt32 *)
1417 {
1418 err_invalid_type ("set_complex_int32s");
1419 }
1420
1421 int set_complex_int64s (mxComplexInt64 *)
1422 {
1423 err_invalid_type ("set_complex_int64s");
1424 }
1425
1426 int set_complex_uint8s (mxComplexUint8 *)
1427 {
1428 err_invalid_type ("set_complex_uint8s");
1429 }
1430
1431 int set_complex_uint16s (mxComplexUint16 *)
1432 {
1433 err_invalid_type ("set_complex_uint16s");
1434 }
1435
1436 int set_complex_uint32s (mxComplexUint32 *)
1437 {
1438 err_invalid_type ("set_complex_uint32s");
1439 }
1440
1441 int set_complex_uint64s (mxComplexUint64 *)
1442 {
1443 err_invalid_type ("set_complex_uint64s");
1444 }
1445#endif
1446
1447 void set_imag_data (void * /*pi*/)
1448 {
1449 err_invalid_type ("set_imag_data");
1450 }
1451
1452 mwIndex * get_ir (void) const
1453 {
1454 err_invalid_type ("get_ir");
1455 }
1456
1457 mwIndex * get_jc (void) const
1458 {
1459 err_invalid_type ("get_jc");
1460 }
1461
1462 mwSize get_nzmax (void) const
1463 {
1464 err_invalid_type ("get_nzmax");
1465 }
1466
1467 void set_ir (mwIndex * /*ir*/)
1468 {
1469 err_invalid_type ("set_ir");
1470 }
1471
1472 void set_jc (mwIndex * /*jc*/)
1473 {
1474 err_invalid_type ("set_jc");
1475 }
1476
1477 void set_nzmax (mwSize /*nzmax*/)
1478 {
1479 err_invalid_type ("set_nzmax");
1480 }
1481
1482 int add_field (const char * /*key*/)
1483 {
1484 err_invalid_type ("add_field");
1485 }
1486
1487 void remove_field (int /*key_num*/)
1488 {
1489 err_invalid_type ("remove_field");
1490 }
1491
1492 mxArray * get_field_by_number (mwIndex /*index*/, int /*key_num*/) const
1493 {
1494 err_invalid_type ("get_field_by_number");
1495 }
1496
1497 void set_field_by_number (mwIndex /*index*/, int /*key_num*/,
1498 mxArray * /*val*/)
1499 {
1500 err_invalid_type ("set_field_by_number");
1501 }
1502
1503 int get_number_of_fields (void) const
1504 {
1505 err_invalid_type ("get_number_of_fields");
1506 }
1507
1508 const char * get_field_name_by_number (int /*key_num*/) const
1509 {
1510 err_invalid_type ("get_field_name_by_number");
1511 }
1512
1513 int get_field_number (const char * /*key*/) const
1514 {
1515 return -1;
1516 }
1517
1518 int get_string (char * /*buf*/, mwSize /*buflen*/) const
1519 {
1520 err_invalid_type ("get_string");
1521 }
1522
1523 char * array_to_string (void) const
1524 {
1525 err_invalid_type ("array_to_string");
1526 }
1527
1528 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const
1529 {
1530 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
1531 }
1532
1533 std::size_t get_element_size (void) const
1534 {
1535 switch (m_id)
1536 {
1537 case mxCELL_CLASS: return sizeof (mxArray *);
1538 case mxSTRUCT_CLASS: return sizeof (mxArray *);
1539 case mxLOGICAL_CLASS: return sizeof (mxLogical);
1540 case mxCHAR_CLASS: return sizeof (mxChar);
1541 case mxDOUBLE_CLASS: return get_numeric_element_size (sizeof (mxDouble));
1542 case mxSINGLE_CLASS: return get_numeric_element_size (sizeof (mxSingle));
1543 case mxINT8_CLASS: return get_numeric_element_size (sizeof (mxInt8));
1544 case mxUINT8_CLASS: return get_numeric_element_size (sizeof (mxUint8));
1545 case mxINT16_CLASS: return get_numeric_element_size (sizeof (mxInt16));
1546 case mxUINT16_CLASS: return get_numeric_element_size (sizeof (mxUint16));
1547 case mxINT32_CLASS: return get_numeric_element_size (sizeof (mxInt32));
1548 case mxUINT32_CLASS: return get_numeric_element_size (sizeof (mxUint32));
1549 case mxINT64_CLASS: return get_numeric_element_size (sizeof (mxInt64));
1550 case mxUINT64_CLASS: return get_numeric_element_size (sizeof (mxUint64));
1551 case mxFUNCTION_CLASS: return 0;
1552 // FIXME: user-defined objects need their own class ID.
1553 // What should they return, size of pointer?
1554 default: return 0;
1555 }
1556 }
1557
1558protected:
1559
1560 mxArray_matlab (bool interleaved, mxClassID id = mxUNKNOWN_CLASS)
1561 : mxArray_base (interleaved), m_class_name (nullptr), m_id (id), m_ndims (0),
1562 m_dims (nullptr)
1563 { }
1564
1565 mxArray_matlab (bool interleaved, mxClassID id, mwSize ndims,
1566 const mwSize *dims)
1567 : mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1568 m_ndims (ndims < 2 ? 2 : ndims),
1569 m_dims (static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize))))
1570 {
1571 if (ndims == 0)
1572 {
1573 m_dims[0] = 0;
1574 m_dims[1] = 0;
1575 }
1576 else if (ndims < 2)
1577 {
1578 m_dims[0] = 1;
1579 m_dims[1] = 1;
1580 }
1581
1582 for (mwIndex i = 0; i < ndims; i++)
1583 m_dims[i] = dims[i];
1584
1585 for (mwIndex i = m_ndims - 1; i > 1; i--)
1586 {
1587 if (m_dims[i] == 1)
1588 m_ndims--;
1589 else
1590 break;
1591 }
1592 }
1593
1594 mxArray_matlab (bool interleaved, mxClassID id, const dim_vector& dv)
1595 : mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1596 m_ndims (dv.ndims ()),
1597 m_dims (static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize))))
1598 {
1599 for (mwIndex i = 0; i < m_ndims; i++)
1600 m_dims[i] = dv(i);
1601
1602 for (mwIndex i = m_ndims - 1; i > 1; i--)
1603 {
1604 if (m_dims[i] == 1)
1605 m_ndims--;
1606 else
1607 break;
1608 }
1609 }
1610
1611 mxArray_matlab (bool interleaved, mxClassID id, mwSize m, mwSize n)
1612 : mxArray_base (interleaved), m_class_name (nullptr), m_id (id), m_ndims (2),
1613 m_dims (static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize))))
1614 {
1615 m_dims[0] = m;
1616 m_dims[1] = n;
1617 }
1618
1621 m_id (val.m_id), m_ndims (val.m_ndims),
1622 m_dims (static_cast<mwSize *> (mxArray::malloc (m_ndims * sizeof (mwSize))))
1623 {
1624 for (mwIndex i = 0; i < m_ndims; i++)
1625 m_dims[i] = val.m_dims[i];
1626 }
1627
1630 {
1631 mwSize nd = get_number_of_dimensions ();
1632
1633 mwSize *d = get_dimensions ();
1634
1635 dim_vector dv;
1636 dv.resize (nd);
1637
1638 for (mwIndex i = 0; i < nd; i++)
1639 dv(i) = d[i];
1640
1641 return dv;
1642 }
1643
1644private:
1645
1647
1648 mxClassID m_id;
1649
1650 mwSize m_ndims;
1651 mwSize *m_dims;
1652};
1653
1654
1655// Matlab-style numeric, character, and logical data.
1656
1658{
1659public:
1660
1661 mxArray_base_full (bool interleaved, mxClassID id, mwSize ndims,
1662 const mwSize *dims, bool init = true)
1663 : mxArray_matlab (interleaved, id, ndims, dims),
1664 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1665 { }
1666
1667 mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv)
1668 : mxArray_matlab (interleaved, id, dv),
1670 { }
1671
1672 mxArray_base_full (bool interleaved, mxClassID id, mwSize m, mwSize n,
1673 bool init = true)
1674 : mxArray_matlab (interleaved, id, m, n),
1675 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1676 { }
1677
1678 mxArray_base_full (bool interleaved, mxClassID id, double val)
1679 : mxArray_matlab (interleaved, id, 1, 1),
1681 {
1682 double *dpr = static_cast<double *> (m_pr);
1683 dpr[0] = val;
1684 }
1685
1686 mxArray_base_full (bool interleaved, mxClassID id, mxLogical val)
1687 : mxArray_matlab (interleaved, id, 1, 1),
1689 {
1690 mxLogical *lpr = static_cast<mxLogical *> (m_pr);
1691 lpr[0] = val;
1692 }
1693
1694 mxArray_base_full (bool interleaved, const char *str)
1695 : mxArray_matlab (interleaved, mxCHAR_CLASS,
1696 str ? (strlen (str) ? 1 : 0) : 0,
1697 str ? strlen (str) : 0),
1699 {
1700 mxChar *cpr = static_cast<mxChar *> (m_pr);
1701 mwSize nel = get_number_of_elements ();
1702 for (mwIndex i = 0; i < nel; i++)
1703 cpr[i] = str[i];
1704 }
1705
1706 // FIXME: ???
1707 mxArray_base_full (bool interleaved, mwSize m, const char **str)
1708 : mxArray_matlab (interleaved, mxCHAR_CLASS, m, max_str_len (m, str)),
1710 {
1711 mxChar *cpr = static_cast<mxChar *> (m_pr);
1712
1713 mwSize *dv = get_dimensions ();
1714
1715 mwSize nc = dv[1];
1716
1717 for (mwIndex j = 0; j < m; j++)
1718 {
1719 const char *ptr = str[j];
1720
1721 std::size_t tmp_len = strlen (ptr);
1722
1723 for (std::size_t i = 0; i < tmp_len; i++)
1724 cpr[m*i+j] = static_cast<mxChar> (ptr[i]);
1725
1726 for (std::size_t i = tmp_len; i < static_cast<std::size_t> (nc); i++)
1727 cpr[m*i+j] = static_cast<mxChar> (' ');
1728 }
1729 }
1730
1731 // No assignment! FIXME: should this be implemented? Note that we
1732 // do have a copy constructor.
1733
1735
1736 mxArray_base * dup (void) const
1737 {
1738 return new mxArray_base_full (*this);
1739 }
1740
1742 {
1743 mxFree (m_pr);
1744 }
1745
1746 double get_scalar (void) const
1747 {
1748 // FIXME: how does this work for interleaved complex arrays?
1749
1750 double retval = 0;
1751
1752 switch (get_class_id ())
1753 {
1754 case mxDOUBLE_CLASS:
1755 retval = *(static_cast<double *> (m_pr));
1756 break;
1757
1758 case mxSINGLE_CLASS:
1759 retval = *(static_cast<float *> (m_pr));
1760 break;
1761
1762 case mxCHAR_CLASS:
1763 retval = *(static_cast<mxChar *> (m_pr));
1764 break;
1765
1766 case mxLOGICAL_CLASS:
1767 retval = *(static_cast<bool *> (m_pr));
1768 break;
1769
1770 case mxINT8_CLASS:
1771 retval = *(static_cast<int8_t *> (m_pr));
1772 break;
1773
1774 case mxUINT8_CLASS:
1775 retval = *(static_cast<uint8_t *> (m_pr));
1776 break;
1777
1778 case mxINT16_CLASS:
1779 retval = *(static_cast<int16_t *> (m_pr));
1780 break;
1781
1782 case mxUINT16_CLASS:
1783 retval = *(static_cast<uint16_t *> (m_pr));
1784 break;
1785
1786 case mxINT32_CLASS:
1787 retval = *(static_cast<int32_t *> (m_pr));
1788 break;
1789
1790 case mxUINT32_CLASS:
1791 retval = *(static_cast<uint32_t *> (m_pr));
1792 break;
1793
1794 case mxINT64_CLASS:
1795 retval = *(static_cast<int64_t *> (m_pr));
1796 break;
1797
1798 case mxUINT64_CLASS:
1799 retval = *(static_cast<uint64_t *> (m_pr));
1800 break;
1801
1802 default:
1804 }
1805
1806 return retval;
1807 }
1808
1809 void * get_data (void) const { return m_pr; }
1810
1811 void set_data (void *pr) { m_pr = pr; }
1812
1813 // The typed get and set functions only work for interleaved data but
1814 // they are defined here because this class owns PR. There are
1815 // definitions in the mxArray_separate_full class that override these
1816 // functions.
1817
1818 mxDouble * get_doubles (void) const
1819 {
1820 return static_cast<mxDouble *> (m_pr);
1821 }
1822
1823 mxSingle * get_singles (void) const
1824 {
1825 return static_cast<mxSingle *> (m_pr);
1826 }
1827
1828 mxInt8 * get_int8s (void) const
1829 {
1830 return static_cast<mxInt8 *> (m_pr);
1831 }
1832
1833 mxInt16 * get_int16s (void) const
1834 {
1835 return static_cast<mxInt16 *> (m_pr);
1836 }
1837
1838 mxInt32 * get_int32s (void) const
1839 {
1840 return static_cast<mxInt32 *> (m_pr);
1841 }
1842
1843 mxInt64 * get_int64s (void) const
1844 {
1845 return static_cast<mxInt64 *> (m_pr);
1846 }
1847
1848 mxUint8 * get_uint8s (void) const
1849 {
1850 return static_cast<mxUint8 *> (m_pr);
1851 }
1852
1853 mxUint16 * get_uint16s (void) const
1854 {
1855 return static_cast<mxUint16 *> (m_pr);
1856 }
1857
1858 mxUint32 * get_uint32s (void) const
1859 {
1860 return static_cast<mxUint32 *> (m_pr);
1861 }
1862
1863 mxUint64 * get_uint64s (void) const
1864 {
1865 return static_cast<mxUint64 *> (m_pr);
1866 }
1867
1868 mxComplexDouble * get_complex_doubles (void) const
1869 {
1870 return static_cast<mxComplexDouble *> (m_pr);
1871 }
1872
1873 mxComplexSingle * get_complex_singles (void) const
1874 {
1875 return static_cast<mxComplexSingle *> (m_pr);
1876 }
1877
1878#if 0
1879 // We don't have these data types.
1880
1881 int get_complex_int8s (mxComplexInt8 *d)
1882 {
1883 m_pr = d;
1884 return 0;
1885 }
1886
1887 int get_complex_int16s (mxComplexInt16 *d)
1888 {
1889 m_pr = d;
1890 return 0;
1891 }
1892
1893 int get_complex_int32s (mxComplexInt32 *d)
1894 {
1895 m_pr = d;
1896 return 0;
1897 }
1898
1899 int get_complex_int64s (mxComplexInt64 *d)
1900 {
1901 m_pr = d;
1902 return 0;
1903 }
1904
1905 int get_complex_uint8s (mxComplexUint8 *d)
1906 {
1907 m_pr = d;
1908 return 0;
1909 }
1910
1911 int get_complex_uint16s (mxComplexUint16 *d)
1912 {
1913 m_pr = d;
1914 return 0;
1915 }
1916
1917 int get_complex_uint32s (mxComplexUint32 *d)
1918 {
1919 m_pr = d;
1920 return 0;
1921 }
1922
1923 int get_complex_uint64s (mxComplexUint64 *d)
1924 {
1925 m_pr = d;
1926 return 0;
1927 }
1928#endif
1929
1930 int set_doubles (mxDouble *d)
1931 {
1932 m_pr = d;
1933 return 0;
1934 }
1935
1936 int set_singles (mxSingle *d)
1937 {
1938 m_pr = d;
1939 return 0;
1940 }
1941
1942 int set_int8s (mxInt8 *d)
1943 {
1944 m_pr = d;
1945 return 0;
1946 }
1947
1948 int set_int16s (mxInt16 *d)
1949 {
1950 m_pr = d;
1951 return 0;
1952 }
1953
1954 int set_int32s (mxInt32 *d)
1955 {
1956 m_pr = d;
1957 return 0;
1958 }
1959
1960 int set_int64s (mxInt64 *d)
1961 {
1962 m_pr = d;
1963 return 0;
1964 }
1965
1966 int set_uint8s (mxUint8 *d)
1967 {
1968 m_pr = d;
1969 return 0;
1970 }
1971
1972 int set_uint16s (mxUint16 *d)
1973 {
1974 m_pr = d;
1975 return 0;
1976 }
1977
1978 int set_uint32s (mxUint32 *d)
1979 {
1980 m_pr = d;
1981 return 0;
1982 }
1983
1984 int set_uint64s (mxUint64 *d)
1985 {
1986 m_pr = d;
1987 return 0;
1988 }
1989
1990 int set_complex_doubles (mxComplexDouble *d)
1991 {
1992 m_pr = d;
1993 return 0;
1994 }
1995
1996 int set_complex_singles (mxComplexSingle *d)
1997 {
1998 m_pr = d;
1999 return 0;
2000 }
2001
2002#if 0
2003 // We don't have these data types.
2004
2005 int set_complex_int8s (mxComplexInt8 *d)
2006 {
2007 m_pr = d;
2008 return 0;
2009 }
2010
2011 int set_complex_int16s (mxComplexInt16 *d)
2012 {
2013 m_pr = d;
2014 return 0;
2015 }
2016
2017 int set_complex_int32s (mxComplexInt32 *d)
2018 {
2019 m_pr = d;
2020 return 0;
2021 }
2022
2023 int set_complex_int64s (mxComplexInt64 *d)
2024 {
2025 m_pr = d;
2026 return 0;
2027 }
2028
2029 int set_complex_uint8s (mxComplexUint8 *d)
2030 {
2031 m_pr = d;
2032 return 0;
2033 }
2034
2035 int set_complex_uint16s (mxComplexUint16 *d)
2036 {
2037 m_pr = d;
2038 return 0;
2039 }
2040
2041 int set_complex_uint32s (mxComplexUint32 *d)
2042 {
2043 m_pr = d;
2044 return 0;
2045 }
2046
2047 int set_complex_uint64s (mxComplexUint64 *d)
2048 {
2049 m_pr = d;
2050 return 0;
2051 }
2052#endif
2053
2054 int get_string (char *buf, mwSize buflen) const
2055 {
2056 int retval = 0;
2057
2058 mwSize nel = get_number_of_elements ();
2059
2060 if (! (nel < buflen))
2061 {
2062 retval = 1;
2063 if (buflen > 0)
2064 nel = buflen-1;
2065 }
2066
2067 if (nel < buflen)
2068 {
2069 mxChar *ptr = static_cast<mxChar *> (m_pr);
2070
2071 for (mwIndex i = 0; i < nel; i++)
2072 buf[i] = static_cast<char> (ptr[i]);
2073
2074 buf[nel] = 0;
2075 }
2076
2077 return retval;
2078 }
2079
2080 char * array_to_string (void) const
2081 {
2082 // FIXME: this is supposed to handle multi-byte character strings.
2083
2084 mwSize nel = get_number_of_elements ();
2085
2086 char *buf = static_cast<char *> (mxArray::malloc (nel + 1));
2087
2088 if (buf)
2089 {
2090 mxChar *ptr = static_cast<mxChar *> (m_pr);
2091
2092 for (mwIndex i = 0; i < nel; i++)
2093 buf[i] = static_cast<char> (ptr[i]);
2094
2095 buf[nel] = '\0';
2096 }
2097
2098 return buf;
2099 }
2100
2102 {
2103 octave_value retval;
2104
2106
2107 switch (get_class_id ())
2108 {
2109 case mxDOUBLE_CLASS:
2110 return (is_complex ()
2111 ? fp_to_ov<Complex> (dv) : fp_to_ov<double> (dv));
2112
2113 case mxSINGLE_CLASS:
2114 return (is_complex ()
2115 ? fp_to_ov<FloatComplex> (dv) : fp_to_ov<float> (dv));
2116
2117 case mxCHAR_CLASS:
2118 return int_to_ov<mxChar, charNDArray, char> (dv);
2119
2120 case mxLOGICAL_CLASS:
2121 return int_to_ov<mxLogical, boolNDArray, bool> (dv);
2122
2123 case mxINT8_CLASS:
2124 return int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
2125
2126 case mxUINT8_CLASS:
2127 return int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
2128
2129 case mxINT16_CLASS:
2130 return int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
2131
2132 case mxUINT16_CLASS:
2133 return int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
2134
2135 case mxINT32_CLASS:
2136 return int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
2137
2138 case mxUINT32_CLASS:
2139 return int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
2140
2141 case mxINT64_CLASS:
2142 return int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
2143
2144 case mxUINT64_CLASS:
2145 return int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
2146
2147 default:
2149 }
2150
2151 return retval;
2152 }
2153
2154protected:
2155
2157 : mxArray_matlab (val),
2159 {
2160 if (m_pr)
2161 memcpy (m_pr, val.m_pr, get_number_of_elements () * get_element_size ());
2162 }
2163
2164 template <typename ELT_T>
2166 fp_to_ov (const dim_vector& dv) const
2167 {
2168 octave_value retval;
2169
2170 ELT_T *ppr = static_cast<ELT_T *> (m_pr);
2171
2172#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
2173
2174 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
2175 {
2176 octave::unwind_action act ([=] () { maybe_disown_ptr (m_pr); });
2177
2178 return octave_value (Array<ELT_T> (ppr, dv, current_mx_memory_resource));
2179 }
2180 else
2181 return octave_value (Array<ELT_T> (ppr, dv, current_mx_memory_resource));
2182
2183#else
2184
2185 // Copy data instead of allowing the octave_value object to borrow
2186 // the mxArray object data.
2187
2188 Array<ELT_T> val (dv);
2189
2190 ELT_T *ptr = val.fortran_vec ();
2191
2192 mwSize nel = get_number_of_elements ();
2193
2194 for (mwIndex i = 0; i < nel; i++)
2195 ptr[i] = ppr[i];
2196
2197 return octave_value (val);
2198
2199#endif
2200 }
2201
2202 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T>
2204 int_to_ov (const dim_vector& dv) const
2205 {
2206 if (is_complex ())
2207 error ("complex integer types are not supported");
2208
2209 ELT_T *ppr = static_cast<ELT_T *> (m_pr);
2210
2211#if 0 && defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
2212
2213 // FIXME: Currently not allowed because we don't have the necessary
2214 // constructors for integer arrays.
2215
2216 octave::unwind_action act ([=] () { maybe_disown_ptr (m_pr); });
2217
2218 return ARRAY_T (ppr, dv, current_mx_memory_resource);
2219
2220#else
2221
2222 // Copy data instead of allowing the octave_value object to borrow
2223 // the mxArray object data.
2224
2225 ARRAY_T val (dv);
2226
2227 ARRAY_ELT_T *ptr = val.fortran_vec ();
2228
2229 mwSize nel = get_number_of_elements ();
2230
2231 for (mwIndex i = 0; i < nel; i++)
2232 ptr[i] = ppr[i];
2233
2234 return octave_value (val);
2235
2236#endif
2237 }
2238
2239protected:
2240
2241 // If using interleaved complex storage, this is the pointer to data
2242 // (real, complex, or logical). Otherwise, it is the pointer to the
2243 // real part of the data.
2244 void *m_pr;
2245};
2246
2248{
2249public:
2250
2251 mxArray_interleaved_full (mxClassID id, mwSize ndims, const mwSize *dims,
2252 mxComplexity flag = mxREAL, bool init = true)
2253 : mxArray_base_full (true, id, ndims, dims, init),
2254 m_complex (flag == mxCOMPLEX)
2255 { }
2256
2257 mxArray_interleaved_full (mxClassID id, const dim_vector& dv,
2258 mxComplexity flag = mxREAL)
2259 : mxArray_base_full (true, id, dv),
2260 m_complex (flag == mxCOMPLEX)
2261 { }
2262
2263 mxArray_interleaved_full (mxClassID id, mwSize m, mwSize n,
2264 mxComplexity flag = mxREAL, bool init = true)
2265 : mxArray_base_full (true, id, m, n, init),
2266 m_complex (flag == mxCOMPLEX)
2267 { }
2268
2269 mxArray_interleaved_full (mxClassID id, double val)
2270 : mxArray_base_full (true, id, val), m_complex (false)
2271 { }
2272
2273 mxArray_interleaved_full (mxClassID id, mxLogical val)
2274 : mxArray_base_full (true, id, val), m_complex (false)
2275 { }
2276
2278 : mxArray_base_full (true, str), m_complex (false)
2279 { }
2280
2281 // FIXME: ???
2282 mxArray_interleaved_full (mwSize m, const char **str)
2283 : mxArray_base_full (true, m, str), m_complex (false)
2284 { }
2285
2286 // No assignment! FIXME: should this be implemented? Note that we
2287 // do have a copy constructor.
2288
2290
2291 mxArray_base * dup (void) const
2292 {
2293 return new mxArray_interleaved_full (*this);
2294 }
2295
2297
2298 int is_complex (void) const { return m_complex; }
2299
2300 void * get_imag_data (void) const { panic_impossible (); }
2301
2302 void set_imag_data (void */*pi*/) { panic_impossible (); }
2303
2304protected:
2305
2308 { }
2309
2310 // Flag to identify complex object.
2312};
2313
2315{
2316public:
2317
2318 mxArray_separate_full (mxClassID id, mwSize ndims, const mwSize *dims,
2319 mxComplexity flag = mxREAL, bool init = true)
2320 : mxArray_base_full (false, id, ndims, dims, init),
2321 m_pi (flag == mxCOMPLEX
2322 ? mxArray::alloc (init, get_number_of_elements (), get_element_size ())
2323 : nullptr)
2324 { }
2325
2326 mxArray_separate_full (mxClassID id, const dim_vector& dv,
2327 mxComplexity flag = mxREAL)
2328 : mxArray_base_full (false, id, dv),
2329 m_pi (flag == mxCOMPLEX
2331 : nullptr)
2332 { }
2333
2334 mxArray_separate_full (mxClassID id, mwSize m, mwSize n,
2335 mxComplexity flag = mxREAL, bool init = true)
2336 : mxArray_base_full (false, id, m, n, init),
2337 m_pi (flag == mxCOMPLEX
2338 ? (mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
2339 : nullptr)
2340 { }
2341
2342 mxArray_separate_full (mxClassID id, double val)
2343 : mxArray_base_full (false, id, val), m_pi (nullptr)
2344 { }
2345
2346 mxArray_separate_full (mxClassID id, mxLogical val)
2347 : mxArray_base_full (false, id, val), m_pi (nullptr)
2348 { }
2349
2350 mxArray_separate_full (const char *str)
2351 : mxArray_base_full (false, str), m_pi (nullptr)
2352 { }
2353
2354 // FIXME: ???
2355 mxArray_separate_full (mwSize m, const char **str)
2356 : mxArray_base_full (false, m, str), m_pi (nullptr)
2357 { }
2358
2359 // No assignment! FIXME: should this be implemented? Note that we
2360 // do have a copy constructor.
2361
2363
2364 mxArray_base * dup (void) const
2365 {
2366 return new mxArray_separate_full (*this);
2367 }
2368
2370 {
2371 mxFree (m_pi);
2372 }
2373
2374 int is_complex (void) const { return m_pi != nullptr; }
2375
2376 void * get_imag_data (void) const { return m_pi; }
2377
2378 void set_imag_data (void *pi) { m_pi = pi; }
2379
2380 mxDouble * get_doubles (void) const { panic_impossible (); }
2381 mxSingle * get_singles (void) const { panic_impossible (); }
2382 mxInt8 * get_int8s (void) const { panic_impossible (); }
2383 mxInt16 * get_int16s (void) const { panic_impossible (); }
2384 mxInt32 * get_int32s (void) const { panic_impossible (); }
2385 mxInt64 * get_int64s (void) const { panic_impossible (); }
2386 mxUint8 * get_uint8s (void) const { panic_impossible (); }
2387 mxUint16 * get_uint16s (void) const { panic_impossible (); }
2388 mxUint32 * get_uint32s (void) const { panic_impossible (); }
2389 mxUint64 * get_uint64s (void) const { panic_impossible (); }
2390
2391 mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); }
2392 mxComplexSingle * get_complex_singles (void) const { panic_impossible (); }
2393
2394 // We don't have complex integer types, but for separate storage they
2395 // still would not work.
2396 mxComplexInt8 * get_complex_int8s (void) const { panic_impossible (); }
2397 mxComplexInt16 * get_complex_int16s (void) const { panic_impossible (); }
2398 mxComplexInt32 * get_complex_int32s (void) const { panic_impossible (); }
2399 mxComplexInt64 * get_complex_int64s (void) const { panic_impossible (); }
2400 mxComplexUint8 * get_complex_uint8s (void) const { panic_impossible (); }
2401 mxComplexUint16 * get_complex_uint16s (void) const { panic_impossible (); }
2402 mxComplexUint32 * get_complex_uint32s (void) const { panic_impossible (); }
2403 mxComplexUint64 * get_complex_uint64s (void) const { panic_impossible (); }
2404
2405 int set_doubles (mxDouble *) { panic_impossible (); }
2406 int set_singles (mxSingle *) { panic_impossible (); }
2407 int set_int8s (mxInt8 *) { panic_impossible (); }
2408 int set_int16s (mxInt16 *) { panic_impossible (); }
2409 int set_int32s (mxInt32 *) { panic_impossible (); }
2410 int set_int64s (mxInt64 *) { panic_impossible (); }
2411 int set_uint8s (mxUint8 *) { panic_impossible (); }
2412 int set_uint16s (mxUint16 *) { panic_impossible (); }
2413 int set_uint32s (mxUint32 *) { panic_impossible (); }
2414 int set_uint64s (mxUint64 *) { panic_impossible (); }
2415
2416 int set_complex_doubles (mxComplexDouble *) { panic_impossible (); }
2417 int set_complex_singles (mxComplexSingle *) { panic_impossible (); }
2418
2419 // We don't have complex integer types, but for separate storage they
2420 // still would not work.
2421 int set_complex_int8s (mxComplexInt8 *) { panic_impossible (); }
2422 int set_complex_int16s (mxComplexInt16 *) { panic_impossible (); }
2423 int set_complex_int32s (mxComplexInt32 *) { panic_impossible (); }
2424 int set_complex_int64s (mxComplexInt64 *) { panic_impossible (); }
2425 int set_complex_uint8s (mxComplexUint8 *) { panic_impossible (); }
2426 int set_complex_uint16s (mxComplexUint16 *) { panic_impossible (); }
2427 int set_complex_uint32s (mxComplexUint32 *) { panic_impossible (); }
2428 int set_complex_uint64s (mxComplexUint64 *) { panic_impossible (); }
2429
2431 {
2432 if (! is_complex ())
2434
2435 octave_value retval;
2436
2438
2439 switch (get_class_id ())
2440 {
2441 case mxDOUBLE_CLASS:
2442 return to_ov<double> (dv);
2443
2444 case mxSINGLE_CLASS:
2445 return to_ov<float> (dv);
2446
2447 case mxLOGICAL_CLASS:
2448 case mxINT8_CLASS:
2449 case mxUINT8_CLASS:
2450 case mxINT16_CLASS:
2451 case mxUINT16_CLASS:
2452 case mxINT32_CLASS:
2453 case mxUINT32_CLASS:
2454 case mxINT64_CLASS:
2455 case mxUINT64_CLASS:
2456 error ("complex integer types are not supported");
2457
2458 default:
2460 }
2461
2462 return retval;
2463 }
2464
2465protected:
2466
2468 : mxArray_base_full (val),
2469 m_pi (val.m_pi
2471 : nullptr)
2472 {
2473 if (m_pi)
2474 memcpy (m_pi, val.m_pi, get_number_of_elements () * get_element_size ());
2475 }
2476
2477private:
2478
2479 template <typename T>
2481 to_ov (const dim_vector& dv) const
2482 {
2483 mwSize nel = get_number_of_elements ();
2484
2485 T *ppr = static_cast<T *> (m_pr);
2486
2487 // We allocate in the Array<T> constructor and copy here, so we
2488 // don't need the custom allocator for this object.
2489
2490 Array<std::complex<T>> val (dv);
2491
2492 std::complex<T> *ptr = val.fortran_vec ();
2493
2494 T *ppi = static_cast<T *> (m_pi);
2495
2496 for (mwIndex i = 0; i < nel; i++)
2497 ptr[i] = std::complex<T> (ppr[i], ppi[i]);
2498
2499 return octave_value (val);
2500 }
2501
2502 // Pointer to the imaginary part of the data.
2503 void *m_pi;
2504};
2505
2506// Matlab-style sparse arrays.
2507
2509{
2510public:
2511
2512 mxArray_base_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n,
2513 mwSize nzmax)
2514 : mxArray_matlab (interleaved, id, m, n),
2515
2516 m_nzmax (nzmax > 0 ? nzmax : 1),
2517 m_ir (static_cast<mwIndex *> (mxArray::calloc (m_nzmax, sizeof (mwIndex)))),
2518 m_jc (static_cast<mwIndex *> (mxArray::calloc (n + 1, sizeof (mwIndex)))),
2519 m_pr (mxArray::calloc (m_nzmax, get_element_size ()))
2520 { }
2521
2522protected:
2523
2525 : mxArray_matlab (val), m_nzmax (val.m_nzmax),
2526 m_ir (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))),
2527 m_jc (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))),
2529 {
2530 if (m_ir)
2531 memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex));
2532
2533 if (m_jc)
2534 memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex));
2535
2536 if (m_pr)
2537 memcpy (m_pr, val.m_pr, m_nzmax * get_element_size ());
2538 }
2539
2540public:
2541
2542 // No assignment! FIXME: should this be implemented? Note that we
2543 // do have a copy constructor.
2544
2546
2547 mxArray_base * dup (void) const
2548 {
2549 return new mxArray_base_sparse (*this);
2550 }
2551
2553 {
2554 mxFree (m_ir);
2555 mxFree (m_jc);
2556 mxFree (m_pr);
2557 }
2558
2559 int is_sparse (void) const { return 1; }
2560
2561 void * get_data (void) const { return m_pr; }
2562
2563 void set_data (void *pr) { m_pr = pr; }
2564
2565 mxDouble * get_doubles (void) const
2566 {
2567 return static_cast<mxDouble *> (m_pr);
2568 }
2569
2570 mxComplexDouble * get_complex_doubles (void) const
2571 {
2572 return static_cast<mxComplexDouble *> (m_pr);
2573 }
2574
2575 int set_doubles (mxDouble *d)
2576 {
2577 m_pr = d;
2578 return 0;
2579 }
2580
2581 int set_complex_doubles (mxComplexDouble *d)
2582 {
2583 m_pr = d;
2584 return 0;
2585 }
2586
2587 mwIndex * get_ir (void) const { return m_ir; }
2588
2589 mwIndex * get_jc (void) const { return m_jc; }
2590
2591 mwSize get_nzmax (void) const { return m_nzmax; }
2592
2593 void set_ir (mwIndex *ir) { m_ir = ir; }
2594
2595 void set_jc (mwIndex *jc) { m_jc = jc; }
2596
2597 void set_nzmax (mwSize nzmax)
2598 {
2599 /* Require storage for at least 1 element */
2600 m_nzmax = (nzmax > 0 ? nzmax : 1);
2601 }
2602
2604 {
2605 octave_value retval;
2606
2608
2609 switch (get_class_id ())
2610 {
2611 case mxDOUBLE_CLASS:
2612 return is_complex () ? to_ov<Complex> (dv): to_ov<double> (dv);
2613
2614 case mxSINGLE_CLASS:
2615 error ("single precision sparse data type not supported");
2616
2617 case mxLOGICAL_CLASS:
2618 return to_ov<bool> (dv);
2619
2620 default:
2622 }
2623
2624 return retval;
2625 }
2626
2627protected:
2628
2629 template <typename ELT_T>
2631 to_ov (const dim_vector& dv) const
2632 {
2633 ELT_T *ppr = static_cast<ELT_T *> (m_pr);
2634
2635#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
2636
2637 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
2638 {
2639 octave::unwind_action act ([=] () {
2643 });
2644
2645 return octave_value
2646 (Sparse<ELT_T> (dv, static_cast<octave_idx_type> (m_nzmax),
2647 ppr, m_ir, m_jc, current_mx_memory_resource));
2648 }
2649 else
2650 return octave_value
2651 (Sparse<ELT_T> (dv, static_cast<octave_idx_type> (m_nzmax),
2652 ppr, m_ir, m_jc, current_mx_memory_resource));
2653#else
2654
2655 // Copy data instead of allowing the octave_value object to borrow
2656 // the mxArray object data.
2657
2658 octave_idx_type m = dv(0);
2659 octave_idx_type n = dv(1);
2660
2661 Sparse<ELT_T> val (m, n, static_cast<octave_idx_type> (m_nzmax));
2662
2663 for (mwIndex i = 0; i < m_nzmax; i++)
2664 {
2665 val.xdata (i) = ppr[i];
2666 val.xridx (i) = m_ir[i];
2667 }
2668
2669 for (mwIndex i = 0; i < n + 1; i++)
2670 val.xcidx (i) = m_jc[i];
2671
2672 return octave_value (val);
2673
2674#endif
2675 }
2676
2677 // Maximun number of nonzero elements.
2678 mwSize m_nzmax;
2679
2680 // Sparse storage indexing arrays.
2681 mwIndex *m_ir;
2682 mwIndex *m_jc;
2683
2684 // If using interleaved complex storage, this is the pointer to data
2685 // (real, complex, or logical). Otherwise, it is the pointer to the
2686 // real part of the data.
2687 void *m_pr;
2688};
2689
2691{
2692public:
2693
2694 mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax,
2695 mxComplexity flag = mxREAL)
2696 : mxArray_base_sparse (true, id, m, n, nzmax),
2697 m_complex (flag == mxCOMPLEX)
2698 { }
2699
2700private:
2701
2704 { }
2705
2706public:
2707
2708 // No assignment! FIXME: should this be implemented? Note that we
2709 // do have a copy constructor.
2710
2712
2713 mxArray_base * dup (void) const
2714 {
2715 return new mxArray_interleaved_sparse (*this);
2716 }
2717
2719
2720 int is_complex (void) const { return m_complex; }
2721
2722 void * get_imag_data (void) const { panic_impossible (); }
2723
2724 void set_imag_data (void */*pi*/) { panic_impossible (); }
2725
2726private:
2727
2728 // Flag to identify complex object if using interleaved data and PI is
2729 // always nullptr.
2731};
2732
2734{
2735public:
2736
2737 mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax,
2738 mxComplexity flag = mxREAL)
2739 : mxArray_base_sparse (false, id, m, n, nzmax),
2740 m_pi (flag == mxCOMPLEX
2741 ? mxArray::calloc (m_nzmax, get_element_size ())
2742 : nullptr)
2743 { }
2744
2745private:
2746
2748 : mxArray_base_sparse (val),
2749 m_pi (val.m_pi
2751 : nullptr)
2752 {
2753 if (m_pi)
2754 memcpy (m_pi, val.m_pi, m_nzmax * get_element_size ());
2755 }
2756
2757public:
2758
2759 // No assignment! FIXME: should this be implemented? Note that we
2760 // do have a copy constructor.
2761
2763
2764 mxArray_base * dup (void) const
2765 {
2766 return new mxArray_separate_sparse (*this);
2767 }
2768
2770 {
2771 mxFree (m_pi);
2772 }
2773
2774 int is_complex (void) const
2775 {
2776 return m_pi != nullptr;
2777 }
2778
2779 void * get_imag_data (void) const { return m_pi; }
2780
2781 void set_imag_data (void *pi) { m_pi = pi; }
2782
2783 mxDouble * get_doubles (void) const { panic_impossible (); }
2784 mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); }
2785
2786 int set_doubles (mxDouble *) { panic_impossible (); }
2787 int set_complex_doubles (mxComplexDouble *) { panic_impossible (); }
2788
2790 {
2791 if (! is_complex ())
2793
2794 octave_value retval;
2795
2797
2798 switch (get_class_id ())
2799 {
2800 case mxDOUBLE_CLASS:
2801 {
2802 double *ppr = static_cast<double *> (m_pr);
2803 double *ppi = static_cast<double *> (m_pi);
2804
2805 SparseComplexMatrix val (get_m (), get_n (),
2806 static_cast<octave_idx_type> (m_nzmax));
2807
2808 for (mwIndex i = 0; i < m_nzmax; i++)
2809 {
2810 val.xdata (i) = Complex (ppr[i], ppi[i]);
2811 val.xridx (i) = m_ir[i];
2812 }
2813
2814 for (mwIndex i = 0; i < get_n () + 1; i++)
2815 val.xcidx (i) = m_jc[i];
2816
2817 retval = val;
2818 }
2819 break;
2820
2821 case mxSINGLE_CLASS:
2822 error ("single precision sparse data type not supported");
2823
2824 default:
2826 }
2827
2828 return retval;
2829 }
2830
2831private:
2832
2833 // Pointer to the imaginary part of the data.
2834 void *m_pi;
2835};
2836
2837// Matlab-style struct arrays.
2838
2840{
2841public:
2842
2843 mxArray_struct (bool interleaved, mwSize ndims, const mwSize *dims,
2844 int num_keys, const char **keys)
2845 : mxArray_matlab (interleaved, mxSTRUCT_CLASS, ndims, dims),
2846 m_nfields (num_keys),
2847 m_fields (static_cast<char **> (mxArray::calloc (m_nfields,
2848 sizeof (char *)))),
2849 m_data (static_cast<mxArray **> (mxArray::calloc (m_nfields *
2851 sizeof (mxArray *))))
2852 {
2853 init (keys);
2854 }
2855
2856 mxArray_struct (bool interleaved, const dim_vector& dv, int num_keys,
2857 const char **keys)
2858 : mxArray_matlab (interleaved, mxSTRUCT_CLASS, dv),
2859 m_nfields (num_keys),
2860 m_fields (static_cast<char **> (mxArray::calloc (m_nfields,
2861 sizeof (char *)))),
2862 m_data (static_cast<mxArray **> (mxArray::calloc (m_nfields *
2864 sizeof (mxArray *))))
2865 {
2866 init (keys);
2867 }
2868
2869 mxArray_struct (bool interleaved, mwSize m, mwSize n, int num_keys,
2870 const char **keys)
2871 : mxArray_matlab (interleaved, mxSTRUCT_CLASS, m, n),
2872 m_nfields (num_keys),
2873 m_fields (static_cast<char **> (mxArray::calloc (m_nfields,
2874 sizeof (char *)))),
2875 m_data (static_cast<mxArray **> (mxArray::calloc (m_nfields *
2877 sizeof (mxArray *))))
2878 {
2879 init (keys);
2880 }
2881
2882private:
2883
2885 : mxArray_matlab (val), m_nfields (val.m_nfields),
2886 m_fields (static_cast<char **> (mxArray::malloc (m_nfields
2887 * sizeof (char *)))),
2888 m_data (static_cast<mxArray **> (mxArray::malloc (m_nfields *
2890 * sizeof (mxArray *))))
2891 {
2892 for (int i = 0; i < m_nfields; i++)
2893 m_fields[i] = mxArray::strsave (val.m_fields[i]);
2894
2895 mwSize nel = get_number_of_elements ();
2896
2897 for (mwIndex i = 0; i < nel * m_nfields; i++)
2898 {
2899 mxArray *ptr = val.m_data[i];
2900 m_data[i] = (ptr ? ptr->dup () : nullptr);
2901 }
2902 }
2903
2904public:
2905
2906 // No assignment! FIXME: should this be implemented? Note that we
2907 // do have a copy constructor.
2908
2910
2911 void init (const char **keys)
2912 {
2913 for (int i = 0; i < m_nfields; i++)
2914 m_fields[i] = mxArray::strsave (keys[i]);
2915 }
2916
2917 mxArray_base * dup (void) const { return new mxArray_struct (*this); }
2918
2920 {
2921 for (int i = 0; i < m_nfields; i++)
2922 mxFree (m_fields[i]);
2923
2924 mxFree (m_fields);
2925
2926 mwSize ntot = m_nfields * get_number_of_elements ();
2927
2928 for (mwIndex i = 0; i < ntot; i++)
2929 delete m_data[i];
2930
2931 mxFree (m_data);
2932 }
2933
2934 int add_field (const char *key)
2935 {
2936 int retval = -1;
2937
2938 m_nfields++;
2939
2940 m_fields = static_cast<char **>
2941 (mxRealloc (m_fields, m_nfields * sizeof (char *)));
2942
2943 if (m_fields)
2944 {
2946
2947 mwSize nel = get_number_of_elements ();
2948
2949 mwSize ntot = m_nfields * nel;
2950
2951 mxArray **new_data;
2952 new_data = static_cast<mxArray **>
2953 (mxArray::malloc (ntot * sizeof (mxArray *)));
2954
2955 if (new_data)
2956 {
2957 mwIndex j = 0;
2958 mwIndex k = 0;
2959 mwIndex n = 0;
2960
2961 for (mwIndex i = 0; i < ntot; i++)
2962 {
2963 if (++n == m_nfields)
2964 {
2965 new_data[j++] = nullptr;
2966 n = 0;
2967 }
2968 else
2969 new_data[j++] = m_data[k++];
2970 }
2971
2972 mxFree (m_data);
2973
2974 m_data = new_data;
2975
2976 retval = m_nfields - 1;
2977 }
2978 }
2979
2980 return retval;
2981 }
2982
2983 void remove_field (int key_num)
2984 {
2985 if (key_num >= 0 && key_num < m_nfields)
2986 {
2987 mwSize nel = get_number_of_elements ();
2988
2989 mwSize ntot = m_nfields * nel;
2990
2991 int new_nfields = m_nfields - 1;
2992
2993 char **new_fields = static_cast<char **>
2994 (mxArray::malloc (new_nfields * sizeof (char *)));
2995
2996 mxArray **new_data = static_cast<mxArray **>
2997 (mxArray::malloc (new_nfields * nel
2998 * sizeof (mxArray *)));
2999
3000 for (int i = 0; i < key_num; i++)
3001 new_fields[i] = m_fields[i];
3002
3003 for (int i = key_num + 1; i < m_nfields; i++)
3004 new_fields[i-1] = m_fields[i];
3005
3006 if (new_nfields > 0)
3007 {
3008 mwIndex j = 0;
3009 mwIndex k = 0;
3010 mwIndex n = 0;
3011
3012 for (mwIndex i = 0; i < ntot; i++)
3013 {
3014 if (n == key_num)
3015 k++;
3016 else
3017 new_data[j++] = m_data[k++];
3018
3019 if (++n == m_nfields)
3020 n = 0;
3021 }
3022 }
3023
3024 m_nfields = new_nfields;
3025
3026 mxFree (m_fields);
3027 mxFree (m_data);
3028
3029 m_fields = new_fields;
3030 m_data = new_data;
3031 }
3032 }
3033
3034 mxArray * get_field_by_number (mwIndex index, int key_num) const
3035 {
3036 return key_num >= 0 && key_num < m_nfields
3037 ? m_data[m_nfields * index + key_num] : nullptr;
3038 }
3039
3040 void set_field_by_number (mwIndex index, int key_num, mxArray *val);
3041
3042 int get_number_of_fields (void) const { return m_nfields; }
3043
3044 const char * get_field_name_by_number (int key_num) const
3045 {
3046 return key_num >= 0 && key_num < m_nfields ? m_fields[key_num] : nullptr;
3047 }
3048
3049 int get_field_number (const char *key) const
3050 {
3051 int retval = -1;
3052
3053 for (int i = 0; i < m_nfields; i++)
3054 {
3055 if (! strcmp (key, m_fields[i]))
3056 {
3057 retval = i;
3058 break;
3059 }
3060 }
3061
3062 return retval;
3063 }
3064
3065 void * get_data (void) const { return m_data; }
3066
3067 void set_data (void *data) { m_data = static_cast<mxArray **> (data); }
3068
3070 {
3072
3074
3075 octave_map m (dv);
3076
3077 mwSize ntot = m_nfields * get_number_of_elements ();
3078
3079 for (int i = 0; i < m_nfields; i++)
3080 {
3081 Cell c (dv);
3082
3083 octave_value *p = c.fortran_vec ();
3084
3085 mwIndex k = 0;
3086 for (mwIndex j = i; j < ntot; j += m_nfields)
3087 p[k++] = mxArray::as_octave_value (m_data[j]);
3088
3089 m.assign (keys[i], c);
3090 }
3091
3092 return m;
3093 }
3094
3095private:
3096
3098
3099 char **m_fields;
3100
3102};
3103
3104// Matlab-style cell arrays.
3105
3107{
3108public:
3109
3110 mxArray_cell (bool interleaved, mwSize ndims, const mwSize *dims)
3111 : mxArray_matlab (interleaved, mxCELL_CLASS, ndims, dims),
3112 m_data (static_cast<mxArray **> (
3113 mxArray::calloc (get_number_of_elements (), sizeof (mxArray *))))
3114 { }
3115
3116 mxArray_cell (bool interleaved, const dim_vector& dv)
3117 : mxArray_matlab (interleaved, mxCELL_CLASS, dv),
3118 m_data (static_cast<mxArray **> (
3119 mxArray::calloc (get_number_of_elements (), sizeof (mxArray *))))
3120 { }
3121
3122 mxArray_cell (bool interleaved, mwSize m, mwSize n)
3123 : mxArray_matlab (interleaved, mxCELL_CLASS, m, n),
3124 m_data (static_cast<mxArray **> (
3125 mxArray::calloc (get_number_of_elements (), sizeof (mxArray *))))
3126 { }
3127
3128private:
3129
3131 : mxArray_matlab (val),
3132 m_data (static_cast<mxArray **> (
3133 mxArray::malloc (get_number_of_elements () * sizeof (mxArray *))))
3134 {
3135 mwSize nel = get_number_of_elements ();
3136
3137 for (mwIndex i = 0; i < nel; i++)
3138 {
3139 mxArray *ptr = val.m_data[i];
3140 m_data[i] = (ptr ? ptr->dup () : nullptr);
3141 }
3142 }
3143
3144public:
3145
3146 // No assignment! FIXME: should this be implemented? Note that we
3147 // do have a copy constructor.
3148
3150
3151 mxArray_base * dup (void) const { return new mxArray_cell (*this); }
3152
3154 {
3155 mwSize nel = get_number_of_elements ();
3156
3157 for (mwIndex i = 0; i < nel; i++)
3158 delete m_data[i];
3159
3160 mxFree (m_data);
3161 }
3162
3163 mxArray * get_cell (mwIndex idx) const
3164 {
3165 return idx >= 0 && idx < get_number_of_elements () ? m_data[idx] : nullptr;
3166 }
3167
3168 void set_cell (mwIndex idx, mxArray *val);
3169
3170 void * get_data (void) const { return m_data; }
3171
3172 void set_data (void *data) { m_data = static_cast<mxArray **> (data); }
3173
3175 {
3177
3178 Cell c (dv);
3179
3180 mwSize nel = get_number_of_elements ();
3181
3182 octave_value *p = c.fortran_vec ();
3183
3184 for (mwIndex i = 0; i < nel; i++)
3185 p[i] = mxArray::as_octave_value (m_data[i]);
3186
3187 return c;
3188 }
3189
3190private:
3191
3193};
3194
3195// ------------------------------------------------------------------
3196
3197mxArray::mxArray (bool interleaved, const octave_value& ov)
3198 : m_rep (create_rep (interleaved, ov)), m_name (nullptr)
3199{ }
3200
3201mxArray::mxArray (bool interleaved, mxClassID id, mwSize ndims,
3202 const mwSize *dims, mxComplexity flag, bool init)
3203 : m_rep (create_rep (interleaved, id, ndims, dims, flag, init)),
3204 m_name (nullptr)
3205{ }
3206
3207mxArray::mxArray (bool interleaved, mxClassID id, const dim_vector& dv,
3208 mxComplexity flag)
3209 : m_rep (create_rep (interleaved, id, dv, flag)), m_name (nullptr)
3210{ }
3211
3212mxArray::mxArray (bool interleaved, mxClassID id, mwSize m, mwSize n,
3213 mxComplexity flag, bool init)
3214 : m_rep (create_rep (interleaved, id, m, n, flag, init)), m_name (nullptr)
3215{ }
3216
3217mxArray::mxArray (bool interleaved, mxClassID id, double val)
3218 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3219{ }
3220
3221mxArray::mxArray (bool interleaved, mxClassID id, mxLogical val)
3222 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3223{ }
3224
3225mxArray::mxArray (bool interleaved, const char *str)
3226 : m_rep (create_rep (interleaved, str)), m_name (nullptr)
3227{ }
3228
3229mxArray::mxArray (bool interleaved, mwSize m, const char **str)
3230 : m_rep (create_rep (interleaved, m, str)), m_name (nullptr)
3231{ }
3232
3233mxArray::mxArray (bool interleaved, mxClassID id, mwSize m, mwSize n,
3234 mwSize nzmax, mxComplexity flag)
3235 : m_rep (create_rep (interleaved, id, m, n, nzmax, flag)), m_name (nullptr)
3236{ }
3237
3238mxArray::mxArray (bool interleaved, mwSize ndims, const mwSize *dims,
3239 int num_keys,
3240 const char **keys)
3241 : m_rep (new mxArray_struct (interleaved, ndims, dims, num_keys, keys)),
3242 m_name (nullptr)
3243{ }
3244
3245mxArray::mxArray (bool interleaved, const dim_vector& dv, int num_keys,
3246 const char **keys)
3247 : m_rep (new mxArray_struct (interleaved, dv, num_keys, keys)),
3248 m_name (nullptr)
3249{ }
3250
3251mxArray::mxArray (bool interleaved, mwSize m, mwSize n, int num_keys,
3252 const char **keys)
3253 : m_rep (new mxArray_struct (interleaved, m, n, num_keys, keys)),
3254 m_name (nullptr)
3255{ }
3256
3257mxArray::mxArray (bool interleaved, mwSize ndims, const mwSize *dims)
3258 : m_rep (new mxArray_cell (interleaved, ndims, dims)), m_name (nullptr)
3259{ }
3260
3261mxArray::mxArray (bool interleaved, const dim_vector& dv)
3262 : m_rep (new mxArray_cell (interleaved, dv)), m_name (nullptr)
3263{ }
3264
3265mxArray::mxArray (bool interleaved, mwSize m, mwSize n)
3266 : m_rep (new mxArray_cell (interleaved, m, n)), m_name (nullptr)
3267{ }
3268
3270{
3271 mxFree (m_name);
3272
3273 delete m_rep;
3274}
3275
3276void
3278{
3279 mxFree (m_name);
3281}
3282
3284mxArray::as_octave_value (const mxArray *ptr, bool null_is_empty)
3285{
3286 static const octave_value empty_matrix = Matrix ();
3287
3288 return (ptr
3289 ? ptr->as_octave_value ()
3290 : (null_is_empty ? empty_matrix : octave_value ()));
3291}
3292
3295{
3296 return m_rep->as_octave_value ();
3297}
3298
3300mxArray::create_rep (bool interleaved, const octave_value& ov)
3301{
3302 return new mxArray_octave_value (interleaved, ov);
3303}
3304
3306mxArray::create_rep (bool interleaved, mxClassID id, mwSize ndims,
3307 const mwSize *dims, mxComplexity flag, bool init)
3308{
3309 if (interleaved)
3310 return new mxArray_interleaved_full (id, ndims, dims, flag, init);
3311 else
3312 return new mxArray_separate_full (id, ndims, dims, flag, init);
3313}
3314
3316mxArray::create_rep (bool interleaved, mxClassID id, const dim_vector& dv,
3317 mxComplexity flag)
3318{
3319 if (interleaved)
3320 return new mxArray_interleaved_full (id, dv, flag);
3321 else
3322 return new mxArray_separate_full (id, dv, flag);
3323}
3324
3326mxArray::create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n,
3327 mxComplexity flag, bool init)
3328{
3329 if (interleaved)
3330 return new mxArray_interleaved_full (id, m, n, flag, init);
3331 else
3332 return new mxArray_separate_full (id, m, n, flag, init);
3333}
3334
3336mxArray::create_rep (bool interleaved, mxClassID id, double val)
3337{
3338 if (interleaved)
3339 return new mxArray_interleaved_full (id, val);
3340 else
3341 return new mxArray_separate_full (id, val);
3342}
3343
3345mxArray::create_rep (bool interleaved, mxClassID id, mxLogical val)
3346{
3347 if (interleaved)
3348 return new mxArray_interleaved_full (id, val);
3349 else
3350 return new mxArray_separate_full (id, val);
3351}
3352
3354mxArray::create_rep (bool interleaved, const char *str)
3355{
3356 if (interleaved)
3357 return new mxArray_interleaved_full (str);
3358 else
3359 return new mxArray_separate_full (str);
3360}
3361
3363mxArray::create_rep (bool interleaved, mwSize m, const char **str)
3364{
3365 if (interleaved)
3366 return new mxArray_interleaved_full (m, str);
3367 else
3368 return new mxArray_separate_full (m, str);
3369}
3370
3372mxArray::create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n,
3373 mwSize nzmax, mxComplexity flag)
3374{
3375 if (interleaved)
3376 return new mxArray_interleaved_sparse (id, m, n, nzmax, flag);
3377 else
3378 return new mxArray_separate_sparse (id, m, n, nzmax, flag);
3379}
3380
3381void
3383{
3384 if (m_rep->is_octave_value ())
3385 {
3386 // The mutate function returns a pointer to a complete new
3387 // mxArray object (or 0, if no mutation happened). We just want
3388 // to replace the existing rep with the rep from the new object.
3389
3390 mxArray *new_val = m_rep->mutate ();
3391
3392 if (new_val)
3393 {
3394 delete m_rep;
3395 m_rep = new_val->m_rep;
3396 new_val->m_rep = nullptr;
3397 delete new_val;
3398 }
3399 }
3400}
3401
3402// ------------------------------------------------------------------
3403
3404// A class to manage calls to MEX functions. Mostly deals with memory
3405// management.
3406
3407class mex
3408{
3409public:
3410
3412 : m_curr_mex_fcn (f), m_memlist (), m_arraylist (), m_fname (nullptr) { }
3413
3414 // No copying!
3415
3416 mex (const mex&) = delete;
3417
3418 mex& operator = (const mex&) = delete;
3419
3420 ~mex (void)
3421 {
3422 // We can't use mex::free here because it modifies memlist.
3423 while (! m_memlist.empty ())
3424 {
3425 auto p = m_memlist.begin ();
3426 xfree (*p);
3427 m_memlist.erase (p);
3428 }
3429
3430 // We can't use mex::free_value here because it modifies arraylist.
3431 while (! m_arraylist.empty ())
3432 {
3433 auto p = m_arraylist.begin ();
3434 delete *p;
3435 m_arraylist.erase (p);
3436 }
3437
3438 if (! (m_memlist.empty () && m_arraylist.empty ()))
3439 error ("mex: %s: cleanup failed", function_name ());
3440
3441 mxFree (m_fname);
3442 }
3443
3444 const char * function_name (void) const
3445 {
3446 if (! m_fname)
3447 {
3448 octave::tree_evaluator& tw
3449 = octave::__get_evaluator__ ("mex::function_name");
3450
3451 octave_function *fcn = tw.current_function ();
3452
3453 if (fcn)
3454 {
3455 std::string nm = fcn->name ();
3456 m_fname = mxArray::strsave (nm.c_str ());
3457 }
3458 else
3459 m_fname = mxArray::strsave ("unknown");
3460 }
3461
3462 return m_fname;
3463 }
3464
3465 // Allocate memory.
3466 void * malloc_unmarked (std::size_t n)
3467 {
3468 void *ptr = xmalloc (n);
3469
3470 if (! ptr)
3471 {
3472 // FIXME: could use "octave_new_handler();" instead
3473 error ("%s: failed to allocate %zd bytes of memory",
3474 function_name (), n);
3475 }
3476
3477 global_mark (ptr);
3478
3479 return ptr;
3480 }
3481
3482 // Allocate memory to be freed on exit.
3483 void * malloc (std::size_t n)
3484 {
3485 void *ptr = malloc_unmarked (n);
3486
3487 mark (ptr);
3488
3489 return ptr;
3490 }
3491
3492 // Allocate memory and initialize to 0.
3493 void * calloc_unmarked (std::size_t n, std::size_t t)
3494 {
3495 void *ptr = malloc_unmarked (n*t);
3496
3497 memset (ptr, 0, n*t);
3498
3499 return ptr;
3500 }
3501
3502 // Allocate memory to be freed on exit and initialize to 0.
3503 void * calloc (std::size_t n, std::size_t t)
3504 {
3505 void *ptr = calloc_unmarked (n, t);
3506
3507 mark (ptr);
3508
3509 return ptr;
3510 }
3511
3512 // Reallocate a pointer obtained from malloc or calloc.
3513 // If the pointer is NULL, allocate using malloc.
3514 // We don't need an "unmarked" version of this.
3515 void * realloc (void *ptr, std::size_t n)
3516 {
3517 void *v;
3518
3519 if (ptr)
3520 {
3521 auto p_local = m_memlist.find (ptr);
3522 auto p_global = s_global_memlist.find (ptr);
3523
3524 v = xrealloc (ptr, n);
3525
3526 if (v)
3527 {
3528 if (p_local != m_memlist.end ())
3529 {
3530 m_memlist.erase (p_local);
3531 m_memlist.insert (v);
3532 }
3533
3534 if (p_global != s_global_memlist.end ())
3535 {
3536 s_global_memlist.erase (p_global);
3537 s_global_memlist.insert (v);
3538 }
3539 }
3540 }
3541 else
3542 v = malloc (n);
3543
3544 return v;
3545 }
3546
3547 // Free a pointer obtained from malloc or calloc.
3548 void free (void *ptr)
3549 {
3550 if (ptr)
3551 {
3552 unmark (ptr);
3553
3554 auto p = s_global_memlist.find (ptr);
3555
3556 if (p != s_global_memlist.end ())
3557 {
3558 s_global_memlist.erase (p);
3559
3560 xfree (ptr);
3561 }
3562 else
3563 {
3564 p = m_foreign_memlist.find (ptr);
3565
3566 if (p != m_foreign_memlist.end ())
3567 m_foreign_memlist.erase (p);
3568#if defined (DEBUG)
3569 else
3570 warning ("mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
3571#endif
3572 }
3573 }
3574 }
3575
3576 // Mark a pointer to be freed on exit.
3577 void mark (void *ptr)
3578 {
3579#if defined (DEBUG)
3580 if (m_memlist.find (ptr) != m_memlist.end ())
3581 warning ("%s: double registration ignored", function_name ());
3582#endif
3583
3584 m_memlist.insert (ptr);
3585 }
3586
3587 // Unmark a pointer to be freed on exit, either because it was
3588 // made persistent, or because it was already freed.
3589 void unmark (void *ptr)
3590 {
3591 auto p = m_memlist.find (ptr);
3592
3593 if (p != m_memlist.end ())
3594 m_memlist.erase (p);
3595#if defined (DEBUG)
3596 else
3597 warning ("%s: value not marked", function_name ());
3598#endif
3599 }
3600
3602 {
3603 m_arraylist.insert (ptr);
3604 return ptr;
3605 }
3606
3608 {
3609 auto p = m_arraylist.find (ptr);
3610
3611 if (p != m_arraylist.end ())
3612 m_arraylist.erase (p);
3613 }
3614
3615 // Mark a pointer as one we allocated.
3616 void mark_foreign (void *ptr)
3617 {
3618#if defined (DEBUG)
3619 if (m_foreign_memlist.find (ptr) != m_foreign_memlist.end ())
3620 warning ("%s: double registration ignored", function_name ());
3621#endif
3622
3623 m_foreign_memlist.insert (ptr);
3624 }
3625
3626 // Unmark a pointer as one we allocated.
3627 void unmark_foreign (void *ptr)
3628 {
3629 auto p = m_foreign_memlist.find (ptr);
3630
3631 if (p != m_foreign_memlist.end ())
3632 m_foreign_memlist.erase (p);
3633#if defined (DEBUG)
3634 else
3635 warning ("%s: value not marked", function_name ());
3636#endif
3637
3638 }
3639
3640 // Make a new array value and initialize from an octave value; it will be
3641 // freed on exit unless marked as persistent.
3643 {
3644 bool interleaved = m_curr_mex_fcn.use_interleaved_complex ();
3645
3646 return mark_array (new mxArray (interleaved, ov));
3647 }
3648
3649 // Free an array and its contents.
3651 {
3652 bool inlist = false;
3653
3654 auto p = m_arraylist.find (ptr);
3655
3656 if (p != m_arraylist.end ())
3657 {
3658 inlist = true;
3659 m_arraylist.erase (p);
3660 delete ptr;
3661 }
3662#if defined (DEBUG)
3663 else
3664 warning ("mex::free_value: skipping memory not allocated by mex::make_value");
3665#endif
3666
3667 return inlist;
3668 }
3669
3671 {
3672 return m_curr_mex_fcn;
3673 }
3674
3675 // 1 if error should be returned to MEX file, 0 if abort.
3677
3678 // Mark a pointer as one we allocated.
3679 void global_mark (void *ptr)
3680 {
3681#if defined (DEBUG)
3682 if (s_global_memlist.find (ptr) != s_global_memlist.end ())
3683 warning ("%s: double registration ignored", function_name ());
3684#endif
3685
3686 s_global_memlist.insert (ptr);
3687 }
3688
3689 // Unmark a pointer as one we allocated.
3690 void global_unmark (void *ptr)
3691 {
3692 auto p = s_global_memlist.find (ptr);
3693
3694 if (p != s_global_memlist.end ())
3695 s_global_memlist.erase (p);
3696#if defined (DEBUG)
3697 else
3698 warning ("%s: value not marked", function_name ());
3699#endif
3700 }
3701
3702private:
3703
3704 // Pointer to the mex function that corresponds to this mex context.
3706
3707 // List of memory resources that need to be freed upon exit.
3708 std::set<void *> m_memlist;
3709
3710 // List of mxArray objects that need to be freed upon exit.
3711 std::set<mxArray *> m_arraylist;
3712
3713 // List of memory resources we know about, but that were allocated
3714 // elsewhere.
3715 std::set<void *> m_foreign_memlist;
3716
3717 // The name of the currently executing function.
3718 mutable char *m_fname;
3719
3720 // List of memory resources we allocated.
3721 static std::set<void *> s_global_memlist;
3722
3723};
3724
3725// List of memory resources we allocated.
3726std::set<void *> mex::s_global_memlist;
3727
3728// Current context.
3729mex *mex_context = nullptr;
3730
3731void *
3732mxArray::malloc (std::size_t n)
3733{
3734 return mex_context ? mex_context->malloc_unmarked (n) : xmalloc (n);
3735}
3736
3737void *
3738mxArray::calloc (std::size_t n, std::size_t t)
3739{
3740 return mex_context ? mex_context->calloc_unmarked (n, t) : ::calloc (n, t);
3741}
3742
3743void *
3744mxArray::alloc (bool init, std::size_t n, std::size_t t)
3745{
3746 return init ? mxArray::calloc (n, t) : mxArray::malloc (n * t);
3747}
3748
3749static inline void *
3751{
3752 if (mex_context)
3754
3755 return ptr;
3756}
3757
3758static inline void
3760{
3761 if (mex_context)
3762 {
3763 mex_context->unmark (ptr);
3766 }
3767}
3768
3769static inline mxArray *
3771{
3772 if (mex_context)
3774
3775 return ptr;
3776}
3777
3778template <typename T>
3779static inline T *
3781{
3782 if (mex_context)
3783 mex_context->unmark (ptr);
3784
3785 return ptr;
3786}
3787
3788void
3789mxArray_struct::set_field_by_number (mwIndex index, int key_num, mxArray *val)
3790{
3791 if (key_num >= 0 && key_num < m_nfields)
3792 m_data[m_nfields * index + key_num] = maybe_unmark_array (val);
3793}
3794
3795void
3797{
3798 if (idx >= 0 && idx < get_number_of_elements ())
3799 m_data[idx] = maybe_unmark_array (val);
3800}
3801
3802// ------------------------------------------------------------------
3803
3804// C interface to mxArray objects:
3805
3806// Floating point predicates.
3807
3808bool
3809mxIsFinite (const double v)
3810{
3811 return lo_ieee_isfinite (v) != 0;
3812}
3813
3814bool
3815mxIsInf (const double v)
3816{
3817 return lo_ieee_isinf (v) != 0;
3818}
3819
3820bool
3821mxIsNaN (const double v)
3822{
3823 return lo_ieee_isnan (v) != 0;
3824}
3825
3826double
3828{
3829 return std::numeric_limits<double>::epsilon ();
3830}
3831
3832double
3834{
3835 return lo_ieee_inf_value ();
3836}
3837
3838double
3840{
3841 return lo_ieee_nan_value ();
3842}
3843
3844// Memory management.
3845void *
3846mxCalloc (std::size_t n, std::size_t size)
3847{
3848 return mex_context ? mex_context->calloc (n, size) : ::calloc (n, size);
3849}
3850
3851void *
3852mxMalloc (std::size_t n)
3853{
3854 return mex_context ? mex_context->malloc (n) : xmalloc (n);
3855}
3856
3857void *
3858mxRealloc (void *ptr, std::size_t size)
3859{
3860 return (mex_context
3861 ? mex_context->realloc (ptr, size) : xrealloc (ptr, size));
3862}
3863
3864void
3865mxFree (void *ptr)
3866{
3867 if (mex_context)
3868 mex_context->free (ptr);
3869 else
3870 xfree (ptr);
3871}
3872
3873static inline mxArray *
3875{
3876 return mex_context ? mex_context->mark_array (ptr) : ptr;
3877}
3878
3879// Constructors.
3880mxArray *
3881mxCreateCellArray_interleaved (mwSize ndims, const mwSize *dims)
3882{
3883 return maybe_mark_array (new mxArray (true, ndims, dims));
3884}
3885
3886mxArray *
3887mxCreateCellArray (mwSize ndims, const mwSize *dims)
3888{
3889 return maybe_mark_array (new mxArray (false, ndims, dims));
3890}
3891
3892mxArray *
3894{
3895 return maybe_mark_array (new mxArray (true, m, n));
3896}
3897
3898mxArray *
3899mxCreateCellMatrix (mwSize m, mwSize n)
3900{
3901 return maybe_mark_array (new mxArray (false, m, n));
3902}
3903
3904mxArray *
3905mxCreateCharArray_interleaved (mwSize ndims, const mwSize *dims)
3906{
3907 return maybe_mark_array (new mxArray (true, mxCHAR_CLASS, ndims, dims));
3908}
3909
3910mxArray *
3911mxCreateCharArray (mwSize ndims, const mwSize *dims)
3912{
3913 return maybe_mark_array (new mxArray (false, mxCHAR_CLASS, ndims, dims));
3914}
3915
3916mxArray *
3918{
3919 return maybe_mark_array (new mxArray (true, m, str));
3920}
3921
3922mxArray *
3923mxCreateCharMatrixFromStrings (mwSize m, const char **str)
3924{
3925 return maybe_mark_array (new mxArray (false, m, str));
3926}
3927
3928mxArray *
3929mxCreateDoubleMatrix_interleaved (mwSize m, mwSize n, mxComplexity flag)
3930{
3931 return maybe_mark_array (new mxArray (true, mxDOUBLE_CLASS, m, n, flag));
3932}
3933
3934mxArray *
3935mxCreateDoubleMatrix (mwSize m, mwSize n, mxComplexity flag)
3936{
3937 return maybe_mark_array (new mxArray (false, mxDOUBLE_CLASS, m, n, flag));
3938}
3939
3940mxArray *
3942{
3943 return maybe_mark_array (new mxArray (true, mxDOUBLE_CLASS, val));
3944}
3945
3946mxArray *
3948{
3949 return maybe_mark_array (new mxArray (false, mxDOUBLE_CLASS, val));
3950}
3951
3952mxArray *
3953mxCreateLogicalArray_interleaved (mwSize ndims, const mwSize *dims)
3954{
3955 return maybe_mark_array (new mxArray (true, mxLOGICAL_CLASS, ndims, dims));
3956}
3957
3958mxArray *
3959mxCreateLogicalArray (mwSize ndims, const mwSize *dims)
3960{
3961 return maybe_mark_array (new mxArray (false, mxLOGICAL_CLASS, ndims, dims));
3962}
3963
3964mxArray *
3966{
3967 return maybe_mark_array (new mxArray (true, mxLOGICAL_CLASS, m, n));
3968}
3969
3970mxArray *
3971mxCreateLogicalMatrix (mwSize m, mwSize n)
3972{
3973 return maybe_mark_array (new mxArray (false, mxLOGICAL_CLASS, m, n));
3974}
3975
3976mxArray *
3978{
3979 return maybe_mark_array (new mxArray (true, mxLOGICAL_CLASS, val));
3980}
3981
3982mxArray *
3984{
3985 return maybe_mark_array (new mxArray (false, mxLOGICAL_CLASS, val));
3986}
3987
3988mxArray *
3989mxCreateNumericArray_interleaved (mwSize ndims, const mwSize *dims,
3990 mxClassID class_id, mxComplexity flag)
3991{
3992 return maybe_mark_array (new mxArray (true, class_id, ndims, dims, flag));
3993}
3994
3995mxArray *
3996mxCreateNumericArray (mwSize ndims, const mwSize *dims,
3997 mxClassID class_id, mxComplexity flag)
3998{
3999 return maybe_mark_array (new mxArray (false, class_id, ndims, dims, flag));
4000}
4001
4002mxArray *
4003mxCreateNumericMatrix_interleaved (mwSize m, mwSize n, mxClassID class_id,
4004 mxComplexity flag)
4005{
4006 return maybe_mark_array (new mxArray (true, class_id, m, n, flag));
4007}
4008
4009mxArray *
4010mxCreateNumericMatrix (mwSize m, mwSize n, mxClassID class_id,
4011 mxComplexity flag)
4012{
4013 return maybe_mark_array (new mxArray (false, class_id, m, n, flag));
4014}
4015
4016mxArray *
4017mxCreateUninitNumericArray_interleaved (mwSize ndims, const mwSize *dims,
4018 mxClassID class_id, mxComplexity flag)
4019{
4020 return maybe_mark_array (new mxArray (true, class_id, ndims, dims, flag,
4021 false));
4022}
4023
4024mxArray *
4025mxCreateUninitNumericArray (mwSize ndims, const mwSize *dims,
4026 mxClassID class_id, mxComplexity flag)
4027{
4028 return maybe_mark_array (new mxArray (false, class_id, ndims, dims, flag,
4029 false));
4030}
4031
4032mxArray *
4034 mxClassID class_id, mxComplexity flag)
4035{
4036 return maybe_mark_array (new mxArray (true, class_id, m, n, flag, false));
4037}
4038
4039mxArray *
4040mxCreateUninitNumericMatrix (mwSize m, mwSize n, mxClassID class_id,
4041 mxComplexity flag)
4042{
4043 return maybe_mark_array (new mxArray (false, class_id, m, n, flag, false));
4044}
4045
4046mxArray *
4047mxCreateSparse_interleaved (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
4048{
4049 return maybe_mark_array (new mxArray (true, mxDOUBLE_CLASS, m, n, nzmax,
4050 flag));
4051}
4052
4053mxArray *
4054mxCreateSparse (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
4055{
4056 return maybe_mark_array (new mxArray (false, mxDOUBLE_CLASS, m, n, nzmax,
4057 flag));
4058}
4059
4060mxArray *
4061mxCreateSparseLogicalMatrix_interleaved (mwSize m, mwSize n, mwSize nzmax)
4062{
4063 return maybe_mark_array (new mxArray (true, mxLOGICAL_CLASS, m, n, nzmax));
4064}
4065
4066mxArray *
4067mxCreateSparseLogicalMatrix (mwSize m, mwSize n, mwSize nzmax)
4068{
4069 return maybe_mark_array (new mxArray (false, mxLOGICAL_CLASS, m, n, nzmax));
4070}
4071
4072mxArray *
4074{
4075 return maybe_mark_array (new mxArray (true, str));
4076}
4077
4078mxArray *
4079mxCreateString (const char *str)
4080{
4081 return maybe_mark_array (new mxArray (false, str));
4082}
4083
4084mxArray *
4085mxCreateStructArray_interleaved (mwSize ndims, const mwSize *dims,
4086 int num_keys, const char **keys)
4087{
4088 return maybe_mark_array (new mxArray (true, ndims, dims, num_keys, keys));
4089}
4090
4091mxArray *
4092mxCreateStructArray (mwSize ndims, const mwSize *dims, int num_keys,
4093 const char **keys)
4094{
4095 return maybe_mark_array (new mxArray (false, ndims, dims, num_keys, keys));
4096}
4097
4098mxArray *
4099mxCreateStructMatrix_interleaved (mwSize m, mwSize n, int num_keys,
4100 const char **keys)
4101{
4102 return maybe_mark_array (new mxArray (true, m, n, num_keys, keys));
4103}
4104
4105mxArray *
4106mxCreateStructMatrix (mwSize m, mwSize n, int num_keys,
4107 const char **keys)
4108{
4109 return maybe_mark_array (new mxArray (false, m, n, num_keys, keys));
4110}
4111
4112// Copy constructor.
4113mxArray *
4115{
4116 return maybe_mark_array (ptr->dup ());
4117}
4118
4119// Destructor.
4120void
4122{
4123 if (! (mex_context && mex_context->free_value (ptr)))
4124 delete ptr;
4125}
4126
4127// Type Predicates.
4128bool
4129mxIsCell (const mxArray *ptr)
4130{
4131 return ptr->iscell ();
4132}
4133
4134bool
4135mxIsChar (const mxArray *ptr)
4136{
4137 return ptr->is_char ();
4138}
4139
4140bool
4141mxIsClass (const mxArray *ptr, const char *name)
4142{
4143 return ptr->is_class (name);
4144}
4145
4146bool
4148{
4149 return ptr->is_complex ();
4150}
4151
4152bool
4154{
4155 return ptr->is_double ();
4156}
4157
4158bool
4160{
4161 return ptr->is_function_handle ();
4162}
4163
4164bool
4165mxIsInt16 (const mxArray *ptr)
4166{
4167 return ptr->is_int16 ();
4168}
4169
4170bool
4171mxIsInt32 (const mxArray *ptr)
4172{
4173 return ptr->is_int32 ();
4174}
4175
4176bool
4177mxIsInt64 (const mxArray *ptr)
4178{
4179 return ptr->is_int64 ();
4180}
4181
4182bool
4183mxIsInt8 (const mxArray *ptr)
4184{
4185 return ptr->is_int8 ();
4186}
4187
4188bool
4190{
4191 return ptr->is_logical ();
4192}
4193
4194bool
4196{
4197 return ptr->is_numeric ();
4198}
4199
4200bool
4202{
4203 return ptr->is_single ();
4204}
4205
4206bool
4208{
4209 return ptr->is_sparse ();
4210}
4211
4212bool
4214{
4215 return ptr->is_struct ();
4216}
4217
4218bool
4220{
4221 return ptr->is_uint16 ();
4222}
4223
4224bool
4226{
4227 return ptr->is_uint32 ();
4228}
4229
4230bool
4232{
4233 return ptr->is_uint64 ();
4234}
4235
4236bool
4237mxIsUint8 (const mxArray *ptr)
4238{
4239 return ptr->is_uint8 ();
4240}
4241
4242// Odd type+size predicate.
4243bool
4245{
4246 return ptr->is_logical_scalar ();
4247}
4248
4249// Odd type+size+value predicate.
4250bool
4252{
4253 return ptr->is_logical_scalar_true ();
4254}
4255
4256// Size predicate.
4257bool
4258mxIsEmpty (const mxArray *ptr)
4259{
4260 return ptr->isempty ();
4261}
4262
4263bool
4265{
4266 return ptr->is_scalar ();
4267}
4268
4269// FIXME: Just plain odd thing to ask of a value.
4270// Still, Octave is incompatible because it does not implement this.
4271bool
4272mxIsFromGlobalWS (const mxArray * /*ptr*/)
4273{
4274 mexErrMsgTxt ("mxIsFromGlobalWS() is unimplemented");
4275
4276 return 0;
4277}
4278
4279// Dimension extractors.
4280std::size_t
4281mxGetM (const mxArray *ptr)
4282{
4283 return ptr->get_m ();
4284}
4285
4286std::size_t
4287mxGetN (const mxArray *ptr)
4288{
4289 return ptr->get_n ();
4290}
4291
4292const mwSize *
4294{
4295 return ptr->get_dimensions ();
4296}
4297
4298mwSize
4300{
4301 return ptr->get_number_of_dimensions ();
4302}
4303
4304std::size_t
4306{
4307 return ptr->get_number_of_elements ();
4308}
4309
4310// Dimension setters.
4311void
4312mxSetM (mxArray *ptr, mwSize m)
4313{
4314 ptr->set_m (m);
4315}
4316
4317void
4318mxSetN (mxArray *ptr, mwSize n)
4319{
4320 ptr->set_n (n);
4321}
4322
4323int
4324mxSetDimensions (mxArray *ptr, const mwSize *dims, mwSize ndims)
4325{
4326 return (ptr->set_dimensions (static_cast<mwSize *>
4327 (maybe_unmark (const_cast<mwSize *> (dims))),
4328 ndims));
4329}
4330
4331// Data extractors.
4332double *
4333mxGetPr (const mxArray *ptr)
4334{
4335 return static_cast<double *> (ptr->get_data ());
4336}
4337
4338double
4340{
4341 return ptr->get_scalar ();
4342}
4343
4344mxChar *
4346{
4347 if (mxIsChar (ptr))
4348 return static_cast<mxChar *> (ptr->get_data ());
4349 else
4350 return nullptr;
4351}
4352
4353mxLogical *
4355{
4356 return static_cast<mxLogical *> (ptr->get_data ());
4357}
4358
4359void *
4360mxGetData (const mxArray *ptr)
4361{
4362 return ptr->get_data ();
4363}
4364
4365double *
4366mxGetPi (const mxArray *ptr)
4367{
4368 return static_cast<double *> (ptr->get_imag_data ());
4369}
4370
4371void *
4373{
4374 return ptr->get_imag_data ();
4375}
4376
4377mxDouble * mxGetDoubles (const mxArray *ptr)
4378{
4379 return ptr->get_doubles ();
4380}
4381
4382mxSingle * mxGetSingles (const mxArray *ptr)
4383{
4384 return ptr->get_singles ();
4385}
4386
4387mxInt8 * mxGetInt8s (const mxArray *ptr)
4388{
4389 return ptr->get_int8s ();
4390}
4391
4392mxInt16 * mxGetInt16s (const mxArray *ptr)
4393{
4394 return ptr->get_int16s ();
4395}
4396
4397mxInt32 * mxGetInt32s (const mxArray *ptr)
4398{
4399 return ptr->get_int32s ();
4400}
4401
4402mxInt64 * mxGetInt64s (const mxArray *ptr)
4403{
4404 return ptr->get_int64s ();
4405}
4406
4407mxUint8 * mxGetUint8s (const mxArray *ptr)
4408{
4409 return ptr->get_uint8s ();
4410}
4411
4412mxUint16 * mxGetUint16s (const mxArray *ptr)
4413{
4414 return ptr->get_uint16s ();
4415}
4416
4417mxUint32 * mxGetUint32s (const mxArray *ptr)
4418{
4419 return ptr->get_uint32s ();
4420}
4421
4422mxUint64 * mxGetUint64s (const mxArray *ptr)
4423{
4424 return ptr->get_uint64s ();
4425}
4426
4427mxComplexDouble * mxGetComplexDoubles (const mxArray *ptr)
4428{
4429 return ptr->get_complex_doubles ();
4430}
4431
4432mxComplexSingle * mxGetComplexSingles (const mxArray *ptr)
4433{
4434 return ptr->get_complex_singles ();
4435}
4436
4437#if 0
4438/* We don't have these yet. */
4439mxComplexInt8 * mxGetComplexInt8s (const mxArray *ptr)
4440{
4441 return ptr->get_complex_int8s ();
4442}
4443
4444mxComplexInt16 * mxGetComplexInt16s (const mxArray *ptr)
4445{
4446 return ptr->get_complex_int16s ();
4447}
4448
4449mxComplexInt32 * mxGetComplexInt32s (const mxArray *ptr)
4450{
4451 return ptr->get_complex_int32s ();
4452}
4453
4454mxComplexInt64 * mxGetComplexInt64s (const mxArray *ptr)
4455{
4456 return ptr->get_complex_int64s ();
4457}
4458
4459mxComplexUint8 * mxGetComplexUint8s (const mxArray *ptr)
4460{
4461 return ptr->get_complex_uint8s ();
4462}
4463
4464mxComplexUint16 * mxGetComplexUint16s (const mxArray *ptr)
4465{
4466 return ptr->get_complex_uint16s ();
4467}
4468
4469mxComplexUint32 * mxGetComplexUint32s (const mxArray *ptr)
4470{
4471 return ptr->get_complex_uint32s ();
4472}
4473
4474mxComplexUint64 * mxGetComplexUint64s (const mxArray *ptr)
4475{
4476 return ptr->get_complex_uint64s ();
4477}
4478#endif
4479
4480// Data setters.
4481void
4482mxSetPr (mxArray *ptr, double *pr)
4483{
4484 ptr->set_data (maybe_unmark (pr));
4485}
4486
4487void
4488mxSetData (mxArray *ptr, void *pr)
4489{
4490 ptr->set_data (maybe_unmark (pr));
4491}
4492
4493int mxSetDoubles (mxArray *ptr, mxDouble *data)
4494{
4495 return ptr->set_doubles (maybe_unmark (data));
4496}
4497
4498int mxSetSingles (mxArray *ptr, mxSingle *data)
4499{
4500 return ptr->set_singles (maybe_unmark (data));
4501}
4502
4503int mxSetInt8s (mxArray *ptr, mxInt8 *data)
4504{
4505 return ptr->set_int8s (maybe_unmark (data));
4506}
4507
4508int mxSetInt16s (mxArray *ptr, mxInt16 *data)
4509{
4510 return ptr->set_int16s (maybe_unmark (data));
4511}
4512
4513int mxSetInt32s (mxArray *ptr, mxInt32 *data)
4514{
4515 return ptr->set_int32s (maybe_unmark (data));
4516}
4517
4518int mxSetInt64s (mxArray *ptr, mxInt64 *data)
4519{
4520 return ptr->set_int64s (maybe_unmark (data));
4521}
4522
4523int mxSetUint8s (mxArray *ptr, mxUint8 *data)
4524{
4525 return ptr->set_uint8s (maybe_unmark (data));
4526}
4527
4528int mxSetUint16s (mxArray *ptr, mxUint16 *data)
4529{
4530 return ptr->set_uint16s (maybe_unmark (data));
4531}
4532
4533int mxSetUint32s (mxArray *ptr, mxUint32 *data)
4534{
4535 return ptr->set_uint32s (maybe_unmark (data));
4536}
4537
4538int mxSetUint64s (mxArray *ptr, mxUint64 *data)
4539{
4540 return ptr->set_uint64s (maybe_unmark (data));
4541}
4542
4543int mxSetComplexDoubles (mxArray *ptr, mxComplexDouble *data)
4544{
4545 return ptr->set_complex_doubles (maybe_unmark (data));
4546}
4547
4548int mxSetComplexSingles (mxArray *ptr, mxComplexSingle *data)
4549{
4550 return ptr->set_complex_singles (maybe_unmark (data));
4551}
4552
4553#if 0
4554/* We don't have these yet. */
4555int mxSetComplexInt8s (mxArray *ptr, mxComplexInt8 *data)
4556{
4557 return ptr->set_complex_int8s (maybe_unmark (data));
4558}
4559
4560int mxSetComplexInt16s (mxArray *ptr, mxComplexInt16 *data)
4561{
4562 return ptr->set_complex_int16s (maybe_unmark (data));
4563}
4564
4565int mxSetComplexInt32s (mxArray *ptr, mxComplexInt32 *data)
4566{
4567 return ptr->set_complex_int32s (maybe_unmark (data));
4568}
4569
4570int mxSetComplexInt64s (mxArray *ptr, mxComplexInt64 *data)
4571{
4572 return ptr->set_complex_int64s (maybe_unmark (data));
4573}
4574
4575int mxSetComplexUint8s (mxArray *ptr, mxComplexUint8 *data)
4576{
4577 return ptr->set_complex_uint8s (maybe_unmark (data));
4578}
4579
4580int mxSetComplexUint16s (mxArray *ptr, mxComplexUint16 *data)
4581{
4582 return ptr->set_complex_uint16s (maybe_unmark (data));
4583}
4584
4585int mxSetComplexUint32s (mxArray *ptr, mxComplexUint32 *data)
4586{
4587 return ptr->set_complex_uint32s (maybe_unmark (data));
4588}
4589
4590int mxSetComplexUint64s (mxArray *ptr, mxComplexUint64 *data)
4591{
4592 return ptr->set_complex_uint64s (maybe_unmark (data));
4593}
4594#endif
4595
4596void
4597mxSetPi (mxArray *ptr, double *pi)
4598{
4599 ptr->set_imag_data (maybe_unmark (pi));
4600}
4601
4602void
4604{
4605 ptr->set_imag_data (maybe_unmark (pi));
4606}
4607
4608// Classes.
4609mxClassID
4611{
4612 return ptr->get_class_id ();
4613}
4614
4615const char *
4617{
4618 return ptr->get_class_name ();
4619}
4620
4621void
4622mxSetClassName (mxArray *ptr, const char *name)
4623{
4624 ptr->set_class_name (name);
4625}
4626
4627void
4628mxSetProperty (mxArray *ptr, mwIndex idx, const char *property_name,
4629 const mxArray *property_value)
4630{
4631 ptr->set_property (idx, property_name, property_value);
4632}
4633
4634mxArray *
4635mxGetProperty (const mxArray *ptr, mwIndex idx, const char *property_name)
4636{
4637 return ptr->get_property (idx, property_name);
4638}
4639
4640// Cell support.
4641mxArray *
4642mxGetCell (const mxArray *ptr, mwIndex idx)
4643{
4644 return ptr->get_cell (idx);
4645}
4646
4647void
4648mxSetCell (mxArray *ptr, mwIndex idx, mxArray *val)
4649{
4650 ptr->set_cell (idx, val);
4651}
4652
4653// Sparse support.
4654mwIndex *
4655mxGetIr (const mxArray *ptr)
4656{
4657 return ptr->get_ir ();
4658}
4659
4660mwIndex *
4661mxGetJc (const mxArray *ptr)
4662{
4663 return ptr->get_jc ();
4664}
4665
4666mwSize
4668{
4669 return ptr->get_nzmax ();
4670}
4671
4672void
4673mxSetIr (mxArray *ptr, mwIndex *ir)
4674{
4675 ptr->set_ir (static_cast<mwIndex *> (maybe_unmark (ir)));
4676}
4677
4678void
4679mxSetJc (mxArray *ptr, mwIndex *jc)
4680{
4681 ptr->set_jc (static_cast<mwIndex *> (maybe_unmark (jc)));
4682}
4683
4684void
4685mxSetNzmax (mxArray *ptr, mwSize nzmax)
4686{
4687 ptr->set_nzmax (nzmax);
4688}
4689
4690// Structure support.
4691int
4692mxAddField (mxArray *ptr, const char *key)
4693{
4694 return ptr->add_field (key);
4695}
4696
4697void
4698mxRemoveField (mxArray *ptr, int key_num)
4699{
4700 ptr->remove_field (key_num);
4701}
4702
4703mxArray *
4704mxGetField (const mxArray *ptr, mwIndex index, const char *key)
4705{
4706 int key_num = mxGetFieldNumber (ptr, key);
4707 return mxGetFieldByNumber (ptr, index, key_num);
4708}
4709
4710mxArray *
4711mxGetFieldByNumber (const mxArray *ptr, mwIndex index, int key_num)
4712{
4713 return ptr->get_field_by_number (index, key_num);
4714}
4715
4716void
4717mxSetField (mxArray *ptr, mwIndex index, const char *key, mxArray *val)
4718{
4719 int key_num = mxGetFieldNumber (ptr, key);
4720 mxSetFieldByNumber (ptr, index, key_num, val);
4721}
4722
4723void
4724mxSetFieldByNumber (mxArray *ptr, mwIndex index, int key_num, mxArray *val)
4725{
4726 ptr->set_field_by_number (index, key_num, val);
4727}
4728
4729int
4731{
4732 return ptr->get_number_of_fields ();
4733}
4734
4735const char *
4736mxGetFieldNameByNumber (const mxArray *ptr, int key_num)
4737{
4738 return ptr->get_field_name_by_number (key_num);
4739}
4740
4741int
4742mxGetFieldNumber (const mxArray *ptr, const char *key)
4743{
4744 return ptr->get_field_number (key);
4745}
4746
4747int
4748mxGetString (const mxArray *ptr, char *buf, mwSize buflen)
4749{
4750 return ptr->get_string (buf, buflen);
4751}
4752
4753char *
4755{
4756 return ptr->array_to_string ();
4757}
4758
4759mwIndex
4760mxCalcSingleSubscript (const mxArray *ptr, mwSize nsubs, mwIndex *subs)
4761{
4762 return ptr->calc_single_subscript (nsubs, subs);
4763}
4764
4765std::size_t
4767{
4768 return ptr->get_element_size ();
4769}
4770
4771// ------------------------------------------------------------------
4772
4773typedef void (*cmex_fptr) (int nlhs, mxArray **plhs, int nrhs, mxArray **prhs);
4774typedef F77_RET_T (*fmex_fptr) (F77_INT& nlhs, mxArray **plhs,
4775 F77_INT& nrhs, mxArray **prhs);
4776
4779 int nargout_arg)
4780{
4781 octave_quit ();
4782
4783 // Use at least 1 for nargout since even for zero specified args,
4784 // still want to be able to return an ans.
4785
4786 volatile int nargout = nargout_arg;
4787
4788 int nargin = args.length ();
4789 OCTAVE_LOCAL_BUFFER (mxArray *, argin, nargin);
4790 for (int i = 0; i < nargin; i++)
4791 argin[i] = nullptr;
4792
4793 int nout = (nargout == 0 ? 1 : nargout);
4794 OCTAVE_LOCAL_BUFFER (mxArray *, argout, nout);
4795 for (int i = 0; i < nout; i++)
4796 argout[i] = nullptr;
4797
4798 // Save old mex pointer.
4800
4801 mex context (mex_fcn);
4802
4803 for (int i = 0; i < nargin; i++)
4804 argin[i] = context.make_value (args(i));
4805
4806 mex_context = &context;
4807
4808 void *mex_fcn_ptr = mex_fcn.mex_fcn_ptr ();
4809
4810 if (mex_fcn.is_fmex ())
4811 {
4812 fmex_fptr fcn = reinterpret_cast<fmex_fptr> (mex_fcn_ptr);
4813
4814 F77_INT tmp_nargout = nargout;
4815 F77_INT tmp_nargin = nargin;
4816
4817 fcn (tmp_nargout, argout, tmp_nargin, argin);
4818 }
4819 else
4820 {
4821 cmex_fptr fcn = reinterpret_cast<cmex_fptr> (mex_fcn_ptr);
4822
4823 fcn (nargout, argout, nargin, argin);
4824 }
4825
4826 // Convert returned array entries back into octave values.
4827
4828 octave_value_list retval;
4829
4830 if (nargout == 0 && argout[0])
4831 {
4832 // We have something for ans.
4833 nargout = 1;
4834 }
4835
4836 retval.resize (nargout);
4837
4838 // If using std::pmr::memory_resource object to manage memory, pass
4839 // default allocator here because we are done with these mxArray
4840 // values and want Octave to delete them.
4841
4842 for (int i = 0; i < nargout; i++)
4843 retval(i) = mxArray::as_octave_value (argout[i], false);
4844
4845 return retval;
4846}
4847
4848// C interface to mex functions:
4849
4850const char *
4852{
4853 return mex_context ? mex_context->function_name () : "unknown";
4854}
4855
4856static inline octave_value_list
4857mx_to_ov_args (int nargin, mxArray *argin[])
4858{
4859 // Use a separate function for this job so that the
4860 // current_mx_memory_resource will be restored immediately after the
4861 // octave_value objects borrow the mxArray data. We could also use a
4862 // dummy scope in mexCallMATLAB, but this function seems less likely
4863 // to be accidentally deleted.
4864
4865 octave_value_list args (nargin);
4866
4867#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
4868
4869 // Use allocator that doesn't free memory because Octave may mutate
4870 // the value (single element mxArray -> scalar octave_value object,
4871 // for example) and we need these objects to continue to exist after
4872 // mexCallMATLAB returns.
4873
4875 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
4876
4877#endif
4878
4879 for (int i = 0; i < nargin; i++)
4880 args(i) = mxArray::as_octave_value (argin[i]);
4881
4882 return args;
4883}
4884
4885int
4886mexCallMATLAB (int nargout, mxArray *argout[], int nargin,
4887 mxArray *argin[], const char *fname)
4888{
4889 octave_value_list args = mx_to_ov_args (nargin, argin);
4890
4891 octave::interpreter& interp = octave::__get_interpreter__ ("mexCallMATLAB");
4892
4893 bool execution_error = false;
4894
4895 octave_value_list retval;
4896
4897 try
4898 {
4899 octave::tree_evaluator& tw = interp.get_evaluator ();
4900
4902 ([&tw] (const std::list<octave::octave_lvalue> *lvl)
4903 {
4904 tw.set_lvalue_list (lvl);
4905 }, tw.lvalue_list ());
4906
4907 tw.set_lvalue_list (nullptr);
4908
4909 retval = octave::feval (fname, args, nargout);
4910 }
4911 catch (const octave::execution_exception&)
4912 {
4914 {
4915 // FIXME: is there a way to indicate what error occurred?
4916 // Should the error message be displayed here? Do we need to
4917 // save the exception info for lasterror?
4918
4919 interp.recover_from_exception ();
4920
4921 execution_error = true;
4922 }
4923 else
4924 {
4925 args.resize (0);
4926 retval.resize (0);
4927
4928 throw;
4929 }
4930 }
4931
4932 int num_to_copy = retval.length ();
4933
4934 if (nargout < retval.length ())
4935 num_to_copy = nargout;
4936
4937 for (int i = 0; i < num_to_copy; i++)
4938 {
4939 // FIXME: it would be nice to avoid copying the value here,
4940 // but there is no way to steal memory from a matrix, never mind
4941 // that matrix memory is allocated by new[] and mxArray memory
4942 // is allocated by malloc().
4943 argout[i] = mex_context->make_value (retval(i));
4944 }
4945
4946 while (num_to_copy < nargout)
4947 argout[num_to_copy++] = nullptr;
4948
4949 return execution_error ? 1 : 0;
4950}
4951
4952mxArray *
4953mexCallMATLABWithTrap (int nargout, mxArray *argout[], int nargin,
4954 mxArray *argin[], const char *fname)
4955{
4956 mxArray *mx = nullptr;
4957
4958 int old_flag = (mex_context ? mex_context->trap_feval_error : 0);
4959 mexSetTrapFlag (1);
4960 if (mexCallMATLAB (nargout, argout, nargin, argin, fname))
4961 {
4962 const char *field_names[] = {"identifier", "message", "case", "stack"};
4963 mx = mxCreateStructMatrix (1, 1, 4, field_names);
4964 mxSetFieldByNumber (mx, 0, 0, mxCreateString ("Octave:MEX"));
4965 std::string msg = "mexCallMATLABWithTrap: function call <"
4966 + std::string (fname) + "> failed";
4967 mxSetFieldByNumber (mx, 0, 1, mxCreateString (msg.c_str ()));
4968 mxSetFieldByNumber (mx, 0, 2, mxCreateCellMatrix (0, 0));
4969 mxSetFieldByNumber (mx, 0, 3, mxCreateStructMatrix (0, 1, 0, nullptr));
4970 }
4971 mexSetTrapFlag (old_flag);
4972
4973 return mx;
4974}
4975
4976void
4978{
4979 if (mex_context)
4981}
4982
4983int
4984mexEvalString (const char *s)
4985{
4986 int retval = 0;
4987
4988 octave::interpreter& interp = octave::__get_interpreter__ ("mexEvalString");
4989
4990 int parse_status;
4991 bool execution_error = false;
4992
4994
4995 try
4996 {
4997 ret = interp.eval_string (std::string (s), false, parse_status, 0);
4998 }
4999 catch (const octave::execution_exception&)
5000 {
5001 interp.recover_from_exception ();
5002
5003 execution_error = true;
5004 }
5005
5006 if (parse_status || execution_error)
5007 retval = 1;
5008
5009 return retval;
5010}
5011
5012mxArray *
5014{
5015 mxArray *mx = nullptr;
5016
5017 octave::interpreter& interp = octave::__get_interpreter__ ("mexEvalString");
5018
5019 int parse_status;
5020 bool execution_error = false;
5021
5023
5024 try
5025 {
5026 ret = interp.eval_string (std::string (s), false, parse_status, 0);
5027 }
5028 catch (const octave::execution_exception&)
5029 {
5030 interp.recover_from_exception ();
5031
5032 execution_error = true;
5033 }
5034
5035 if (parse_status || execution_error)
5036 {
5037 const char *field_names[] = {"identifier", "message", "case", "stack"};
5038 mx = mxCreateStructMatrix (1, 1, 4, field_names);
5039 mxSetFieldByNumber (mx, 0, 0, mxCreateString ("Octave:MEX"));
5040 std::string msg = "mexEvalStringWithTrap: eval of <"
5041 + std::string (s) + "> failed";
5042 mxSetFieldByNumber (mx, 0, 1, mxCreateString (msg.c_str ()));
5043 mxSetFieldByNumber (mx, 0, 2, mxCreateCellMatrix (0, 0));
5044 mxSetFieldByNumber (mx, 0, 3, mxCreateStructMatrix (0, 1, 0, nullptr));
5045 }
5046
5047 return mx;
5048}
5049
5050void
5051mexErrMsgTxt (const char *s)
5052{
5053 std::size_t len;
5054
5055 if (s && (len = strlen (s)) > 0)
5056 {
5057 if (s[len - 1] == '\n')
5058 {
5059 std::string s_tmp (s, len - 1);
5060 error ("%s: %s\n", mexFunctionName (), s_tmp.c_str ());
5061 }
5062 else
5063 error ("%s: %s", mexFunctionName (), s);
5064 }
5065 else
5066 {
5067 // For compatibility with Matlab, print an empty message.
5068 // Octave's error routine requires a non-null input so use a SPACE.
5069 error (" ");
5070 }
5071}
5072
5073void
5074mexErrMsgIdAndTxt (const char *id, const char *fmt, ...)
5075{
5076 if (fmt && strlen (fmt) > 0)
5077 {
5078 const char *fname = mexFunctionName ();
5079 std::size_t len = strlen (fname) + 2 + strlen (fmt) + 1;
5080 OCTAVE_LOCAL_BUFFER (char, tmpfmt, len);
5081 sprintf (tmpfmt, "%s: %s", fname, fmt);
5082 va_list args;
5083 va_start (args, fmt);
5084 verror_with_id (id, tmpfmt, args);
5085 va_end (args);
5086 }
5087 else
5088 {
5089 // For compatibility with Matlab, print an empty message.
5090 // Octave's error routine requires a non-null input so use a SPACE.
5091 error (" ");
5092 }
5093}
5094
5095void
5096mexWarnMsgTxt (const char *s)
5097{
5098 std::size_t len;
5099
5100 if (s && (len = strlen (s)) > 0)
5101 {
5102 if (s[len - 1] == '\n')
5103 {
5104 std::string s_tmp (s, len - 1);
5105 warning ("%s\n", s_tmp.c_str ());
5106 }
5107 else
5108 warning ("%s", s);
5109 }
5110 else
5111 {
5112 // For compatibility with Matlab, print an empty message.
5113 // Octave's warning routine requires a non-null input so use a SPACE.
5114 warning (" ");
5115 }
5116}
5117
5118void
5119mexWarnMsgIdAndTxt (const char *id, const char *fmt, ...)
5120{
5121 // FIXME: is this right? What does Matlab do if fmt is NULL or
5122 // an empty string?
5123
5124 if (fmt && strlen (fmt) > 0)
5125 {
5126 const char *fname = mexFunctionName ();
5127 std::size_t len = strlen (fname) + 2 + strlen (fmt) + 1;
5128 OCTAVE_LOCAL_BUFFER (char, tmpfmt, len);
5129 sprintf (tmpfmt, "%s: %s", fname, fmt);
5130 va_list args;
5131 va_start (args, fmt);
5132 vwarning_with_id (id, tmpfmt, args);
5133 va_end (args);
5134 }
5135}
5136
5137int
5138mexPrintf (const char *fmt, ...)
5139{
5140 int retval;
5141 va_list args;
5142 va_start (args, fmt);
5143 retval = octave::vformat (octave_stdout, fmt, args);
5144 va_end (args);
5145 return retval;
5146}
5147
5148mxArray *
5149mexGetVariable (const char *space, const char *name)
5150{
5151 mxArray *retval = nullptr;
5152
5153 octave_value val;
5154
5155 octave::interpreter& interp = octave::__get_interpreter__ ("mexGetVariable");
5156
5157 if (! strcmp (space, "global"))
5158 val = interp.global_varval (name);
5159 else
5160 {
5161 // FIXME: should this be in variables.cc?
5162
5164
5165 bool caller = ! strcmp (space, "caller");
5166 bool base = ! strcmp (space, "base");
5167
5168 if (caller || base)
5169 {
5170 // MEX files don't create a separate frame in the call stack,
5171 // so we are already in the "caller" frame.
5172
5173 if (base)
5174 {
5175 octave::tree_evaluator& tw = interp.get_evaluator ();
5176
5177 frame.add (&octave::tree_evaluator::restore_frame, &tw,
5178 tw.current_call_stack_frame_number ());
5179
5180 tw.goto_base_frame ();
5181 }
5182
5183 val = interp.varval (name);
5184 }
5185 else
5186 mexErrMsgTxt ("mexGetVariable: symbol table does not exist");
5187 }
5188
5189 if (val.is_defined ())
5190 {
5191 retval = mex_context->make_value (val);
5192
5193 retval->set_name (name);
5194 }
5195
5196 return retval;
5197}
5198
5199const mxArray *
5200mexGetVariablePtr (const char *space, const char *name)
5201{
5202 return mexGetVariable (space, name);
5203}
5204
5205int
5206mexPutVariable (const char *space, const char *name, const mxArray *ptr)
5207{
5208 if (! ptr)
5209 return 1;
5210
5211 if (! name)
5212 return 1;
5213
5214 if (name[0] == '\0')
5215 name = ptr->get_name ();
5216
5217 if (! name || name[0] == '\0')
5218 return 1;
5219
5220 octave::interpreter& interp = octave::__get_interpreter__ ("mexPutVariable");
5221
5222 if (! strcmp (space, "global"))
5223 {
5224#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
5225
5226 // Use allocator that doesn't free memory because Octave may mutate
5227 // the value (single element mxArray -> scalar octave_value object,
5228 // for example) and we need these objects to continue to exist after
5229 // mexCallMATLAB returns.
5230
5232 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
5233#endif
5234
5235 interp.global_assign (name, mxArray::as_octave_value (ptr));
5236 }
5237 else
5238 {
5239 // FIXME: should this be in variables.cc?
5240
5242
5243 bool caller = ! strcmp (space, "caller");
5244 bool base = ! strcmp (space, "base");
5245
5246 if (caller || base)
5247 {
5248 // MEX files don't create a separate frame in the call stack,
5249 // so we are already in the "caller" frame.
5250
5251 if (base)
5252 {
5253 octave::tree_evaluator& tw = interp.get_evaluator ();
5254
5255 frame.add (&octave::tree_evaluator::restore_frame, &tw,
5256 tw.current_call_stack_frame_number ());
5257
5258 tw.goto_base_frame ();
5259 }
5260
5261#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
5262
5263 // Use allocator that doesn't free memory because Octave may
5264 // mutate the value (single element mxArray -> scalar
5265 // octave_value object, for example) and we need these objects
5266 // to continue to exist after mexCallMATLAB returns.
5267
5269 upv (current_mx_memory_resource,
5270 &the_mx_preserving_memory_resource);
5271#endif
5272
5273 interp.assign (name, mxArray::as_octave_value (ptr));
5274 }
5275 else
5276 mexErrMsgTxt ("mexPutVariable: symbol table does not exist");
5277 }
5278
5279 return 0;
5280}
5281
5282void
5284{
5285 maybe_unmark_array (ptr);
5286}
5287
5288void
5290{
5291 maybe_unmark (ptr);
5292}
5293
5294int
5295mexAtExit (void (*f) (void))
5296{
5297 if (mex_context)
5298 {
5300
5301 curr_mex_fcn.atexit (f);
5302 }
5303
5304 return 0;
5305}
5306
5307const mxArray *
5308mexGet_interleaved (double handle, const char *property)
5309{
5310 mxArray *m = nullptr;
5311
5312 octave_value ret
5313 = octave::get_property_from_handle (handle, property, "mexGet");
5314
5315 if (ret.is_defined ())
5316 m = ret.as_mxArray (true);
5317
5318 return m;
5319}
5320
5321const mxArray *
5322mexGet (double handle, const char *property)
5323{
5324 mxArray *m = nullptr;
5325
5326 octave_value ret
5327 = octave::get_property_from_handle (handle, property, "mexGet");
5328
5329 if (ret.is_defined ())
5330 m = ret.as_mxArray (false);
5331
5332 return m;
5333}
5334
5335int
5337{
5338 return mxIsFromGlobalWS (ptr);
5339}
5340
5341int
5343{
5344 int retval = 0;
5345
5346 if (mex_context)
5347 {
5348 const char *fname = mexFunctionName ();
5349
5350 octave::interpreter& interp = octave::__get_interpreter__ ("mexIsLocked");
5351
5352 retval = interp.mislocked (fname);
5353 }
5354
5355 return retval;
5356}
5357
5358std::map<std::string, int> mex_lock_count;
5359
5360void
5362{
5363 if (mex_context)
5364 {
5365 const char *fname = mexFunctionName ();
5366
5367 if (mex_lock_count.find (fname) == mex_lock_count.end ())
5368 mex_lock_count[fname] = 1;
5369 else
5370 mex_lock_count[fname]++;
5371
5372 octave::interpreter& interp = octave::__get_interpreter__ ("mexLock");
5373
5374 interp.mlock ();
5375 }
5376}
5377
5378int
5379mexSet (double handle, const char *property, mxArray *val)
5380{
5381#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
5382
5383 // Use allocator that doesn't free memory because Octave may mutate
5384 // the value (single element mxArray -> scalar octave_value object,
5385 // for example) and we need these objects to continue to exist after
5386 // mexCallMATLAB returns.
5387
5389 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
5390
5391#endif
5392
5393 bool ret = octave::set_property_in_handle (handle, property,
5395 "mexSet");
5396 return (ret ? 0 : 1);
5397}
5398
5399void
5401{
5402 if (mex_context)
5403 {
5404 const char *fname = mexFunctionName ();
5405
5406 auto p = mex_lock_count.find (fname);
5407
5408 if (p != mex_lock_count.end ())
5409 {
5410 int count = --mex_lock_count[fname];
5411
5412 if (count == 0)
5413 {
5414 octave::interpreter& interp
5415 = octave::__get_interpreter__ ("mexUnLock");
5416
5417 interp.munlock (fname);
5418
5419 mex_lock_count.erase (p);
5420 }
5421 }
5422 }
5423}
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:129
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:616
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
Definition: Array.cc:1744
Definition: Cell.h:43
Definition: Sparse.h:49
T * xdata(void)
Definition: Sparse.h:576
octave_idx_type * xridx(void)
Definition: Sparse.h:589
octave_idx_type * xcidx(void)
Definition: Sparse.h:602
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
void resize(int n, int fill_value=0)
Definition: dim-vector.h:272
static const bool is_complex
Definition: mex.cc:324
Definition: mex.cc:3408
std::set< void * > m_foreign_memlist
Definition: mex.cc:3715
char * m_fname
Definition: mex.cc:3718
mex(octave_mex_function &f)
Definition: mex.cc:3411
void unmark_array(mxArray *ptr)
Definition: mex.cc:3607
void free(void *ptr)
Definition: mex.cc:3548
octave_mex_function & m_curr_mex_fcn
Definition: mex.cc:3705
~mex(void)
Definition: mex.cc:3420
mxArray * make_value(const octave_value &ov)
Definition: mex.cc:3642
void * malloc(std::size_t n)
Definition: mex.cc:3483
void mark(void *ptr)
Definition: mex.cc:3577
static std::set< void * > s_global_memlist
Definition: mex.cc:3721
mxArray * mark_array(mxArray *ptr)
Definition: mex.cc:3601
void * malloc_unmarked(std::size_t n)
Definition: mex.cc:3466
void unmark(void *ptr)
Definition: mex.cc:3589
mex & operator=(const mex &)=delete
mex(const mex &)=delete
void global_unmark(void *ptr)
Definition: mex.cc:3690
bool free_value(mxArray *ptr)
Definition: mex.cc:3650
std::set< mxArray * > m_arraylist
Definition: mex.cc:3711
void * realloc(void *ptr, std::size_t n)
Definition: mex.cc:3515
void global_mark(void *ptr)
Definition: mex.cc:3679
std::set< void * > m_memlist
Definition: mex.cc:3708
void mark_foreign(void *ptr)
Definition: mex.cc:3616
octave_mex_function & current_mex_function(void) const
Definition: mex.cc:3670
void * calloc(std::size_t n, std::size_t t)
Definition: mex.cc:3503
int trap_feval_error
Definition: mex.cc:3676
const char * function_name(void) const
Definition: mex.cc:3444
void * calloc_unmarked(std::size_t n, std::size_t t)
Definition: mex.cc:3493
void unmark_foreign(void *ptr)
Definition: mex.cc:3627
mxInt16 * get_int16s(void) const
Definition: mex.cc:1833
mxArray_base_full & operator=(const mxArray_base_full &)
int set_complex_doubles(mxComplexDouble *d)
Definition: mex.cc:1990
int set_uint16s(mxUint16 *d)
Definition: mex.cc:1972
mxInt32 * get_int32s(void) const
Definition: mex.cc:1838
mxArray_base_full(bool interleaved, mxClassID id, mwSize m, mwSize n, bool init=true)
Definition: mex.cc:1672
mxArray_base_full(bool interleaved, mwSize m, const char **str)
Definition: mex.cc:1707
void * get_data(void) const
Definition: mex.cc:1809
int set_doubles(mxDouble *d)
Definition: mex.cc:1930
int set_int32s(mxInt32 *d)
Definition: mex.cc:1954
mxArray_base_full(bool interleaved, const char *str)
Definition: mex.cc:1694
int set_complex_singles(mxComplexSingle *d)
Definition: mex.cc:1996
void set_data(void *pr)
Definition: mex.cc:1811
~mxArray_base_full(void)
Definition: mex.cc:1741
mxInt8 * get_int8s(void) const
Definition: mex.cc:1828
int set_uint64s(mxUint64 *d)
Definition: mex.cc:1984
mxInt64 * get_int64s(void) const
Definition: mex.cc:1843
char * array_to_string(void) const
Definition: mex.cc:2080
void * m_pr
Definition: mex.cc:2244
int set_uint32s(mxUint32 *d)
Definition: mex.cc:1978
mxComplexSingle * get_complex_singles(void) const
Definition: mex.cc:1873
int set_int16s(mxInt16 *d)
Definition: mex.cc:1948
mxArray_base_full(bool interleaved, mxClassID id, mxLogical val)
Definition: mex.cc:1686
mxUint16 * get_uint16s(void) const
Definition: mex.cc:1853
octave_value fp_to_ov(const dim_vector &dv) const
Definition: mex.cc:2166
mxArray_base_full(bool interleaved, mxClassID id, double val)
Definition: mex.cc:1678
octave_value as_octave_value(void) const
Definition: mex.cc:2101
int set_int64s(mxInt64 *d)
Definition: mex.cc:1960
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:1868
mxUint64 * get_uint64s(void) const
Definition: mex.cc:1863
int set_uint8s(mxUint8 *d)
Definition: mex.cc:1966
mxDouble * get_doubles(void) const
Definition: mex.cc:1818
int set_singles(mxSingle *d)
Definition: mex.cc:1936
mxArray_base * dup(void) const
Definition: mex.cc:1736
octave_value int_to_ov(const dim_vector &dv) const
Definition: mex.cc:2204
double get_scalar(void) const
Definition: mex.cc:1746
int set_int8s(mxInt8 *d)
Definition: mex.cc:1942
mxUint8 * get_uint8s(void) const
Definition: mex.cc:1848
mxArray_base_full(const mxArray_base_full &val)
Definition: mex.cc:2156
mxArray_base_full(bool interleaved, mxClassID id, const dim_vector &dv)
Definition: mex.cc:1667
int get_string(char *buf, mwSize buflen) const
Definition: mex.cc:2054
mxArray_base_full(bool interleaved, mxClassID id, mwSize ndims, const mwSize *dims, bool init=true)
Definition: mex.cc:1661
mxUint32 * get_uint32s(void) const
Definition: mex.cc:1858
mxSingle * get_singles(void) const
Definition: mex.cc:1823
octave_value to_ov(const dim_vector &dv) const
Definition: mex.cc:2631
int set_complex_doubles(mxComplexDouble *d)
Definition: mex.cc:2581
void set_ir(mwIndex *ir)
Definition: mex.cc:2593
int set_doubles(mxDouble *d)
Definition: mex.cc:2575
void set_nzmax(mwSize nzmax)
Definition: mex.cc:2597
void set_jc(mwIndex *jc)
Definition: mex.cc:2595
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:2570
mwSize get_nzmax(void) const
Definition: mex.cc:2591
mxArray_base_sparse(const mxArray_base_sparse &val)
Definition: mex.cc:2524
mxArray_base * dup(void) const
Definition: mex.cc:2547
int is_sparse(void) const
Definition: mex.cc:2559
mwIndex * get_ir(void) const
Definition: mex.cc:2587
mxDouble * get_doubles(void) const
Definition: mex.cc:2565
mwIndex * m_ir
Definition: mex.cc:2681
mwIndex * get_jc(void) const
Definition: mex.cc:2589
void * get_data(void) const
Definition: mex.cc:2561
~mxArray_base_sparse(void)
Definition: mex.cc:2552
mxArray_base_sparse & operator=(const mxArray_base_sparse &)
mwSize m_nzmax
Definition: mex.cc:2678
void set_data(void *pr)
Definition: mex.cc:2563
mxArray_base_sparse(bool interleaved, mxClassID id, mwSize m, mwSize n, mwSize nzmax)
Definition: mex.cc:2512
octave_value as_octave_value(void) const
Definition: mex.cc:2603
mwIndex * m_jc
Definition: mex.cc:2682
OCTAVE_NORETURN void err_invalid_type(const char *op) const
Definition: mxarray.h:322
OCTINTERP_API mxArray_base(bool interleaved)
Definition: mex.cc:404
virtual mxArray * mutate(void) const
Definition: mxarray.h:307
bool m_interleaved
Definition: mxarray.h:330
virtual int is_logical_scalar(void) const
Definition: mxarray.h:153
std::size_t get_numeric_element_size(std::size_t size) const
Definition: mxarray.h:315
virtual bool is_octave_value(void) const
Definition: mxarray.h:103
virtual octave_value as_octave_value(void) const =0
mxArray_cell & operator=(const mxArray_cell &)
mxArray_cell(bool interleaved, mwSize m, mwSize n)
Definition: mex.cc:3122
mxArray_base * dup(void) const
Definition: mex.cc:3151
void * get_data(void) const
Definition: mex.cc:3170
~mxArray_cell(void)
Definition: mex.cc:3153
mxArray_cell(const mxArray_cell &val)
Definition: mex.cc:3130
mxArray * get_cell(mwIndex idx) const
Definition: mex.cc:3163
void set_data(void *data)
Definition: mex.cc:3172
void set_cell(mwIndex idx, mxArray *val)
Definition: mex.cc:3796
mxArray_cell(bool interleaved, mwSize ndims, const mwSize *dims)
Definition: mex.cc:3110
mxArray ** m_data
Definition: mex.cc:3192
octave_value as_octave_value(void) const
Definition: mex.cc:3174
mxArray_cell(bool interleaved, const dim_vector &dv)
Definition: mex.cc:3116
mxArray_interleaved_full(const char *str)
Definition: mex.cc:2277
mxArray_interleaved_full(mxClassID id, mxLogical val)
Definition: mex.cc:2273
mxArray_interleaved_full(mxClassID id, mwSize m, mwSize n, mxComplexity flag=mxREAL, bool init=true)
Definition: mex.cc:2263
int is_complex(void) const
Definition: mex.cc:2298
mxArray_interleaved_full(const mxArray_interleaved_full &val)
Definition: mex.cc:2306
void * get_imag_data(void) const
Definition: mex.cc:2300
mxArray_interleaved_full(mxClassID id, double val)
Definition: mex.cc:2269
mxArray_base * dup(void) const
Definition: mex.cc:2291
mxArray_interleaved_full & operator=(const mxArray_interleaved_full &)
mxArray_interleaved_full(mwSize m, const char **str)
Definition: mex.cc:2282
mxArray_interleaved_full(mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag=mxREAL, bool init=true)
Definition: mex.cc:2251
~mxArray_interleaved_full(void)=default
void set_imag_data(void *)
Definition: mex.cc:2302
mxArray_interleaved_full(mxClassID id, const dim_vector &dv, mxComplexity flag=mxREAL)
Definition: mex.cc:2257
void * get_imag_data(void) const
Definition: mex.cc:2722
mxArray_interleaved_sparse(const mxArray_interleaved_sparse &val)
Definition: mex.cc:2702
mxArray_base * dup(void) const
Definition: mex.cc:2713
int is_complex(void) const
Definition: mex.cc:2720
mxArray_interleaved_sparse & operator=(const mxArray_interleaved_sparse &)
mxArray_interleaved_sparse(mxClassID id, mwSize m, mwSize n, mwSize nzmax, mxComplexity flag=mxREAL)
Definition: mex.cc:2694
void set_imag_data(void *)
Definition: mex.cc:2724
~mxArray_interleaved_sparse(void)=default
void set_cell(mwIndex, mxArray *)
Definition: mex.cc:1216
const char * get_class_name(void) const
Definition: mex.cc:1179
void set_field_by_number(mwIndex, int, mxArray *)
Definition: mex.cc:1497
int set_complex_singles(mxComplexSingle *)
Definition: mex.cc:1399
mxUint8 * get_uint8s(void) const
Definition: mex.cc:1261
int set_int8s(mxInt8 *)
Definition: mex.cc:1354
int set_doubles(mxDouble *)
Definition: mex.cc:1344
int add_field(const char *)
Definition: mex.cc:1482
int set_uint16s(mxUint16 *)
Definition: mex.cc:1379
mxClassID get_class_id(void) const
Definition: mex.cc:1177
mwIndex * get_jc(void) const
Definition: mex.cc:1457
int is_char(void) const
Definition: mex.cc:1067
int is_int64(void) const
Definition: mex.cc:1079
bool is_scalar(void) const
Definition: mex.cc:1172
mxArray * get_cell(mwIndex) const
Definition: mex.cc:1211
void set_nzmax(mwSize)
Definition: mex.cc:1477
void set_m(mwSize m)
Definition: mex.cc:1130
mwSize get_n(void) const
Definition: mex.cc:1116
mwIndex * get_ir(void) const
Definition: mex.cc:1452
mxArray * get_field_by_number(mwIndex, int) const
Definition: mex.cc:1492
int iscell(void) const
Definition: mex.cc:1065
int set_dimensions(mwSize *dims, mwSize ndims)
Definition: mex.cc:1134
int set_int64s(mxInt64 *)
Definition: mex.cc:1369
mxComplexSingle * get_complex_singles(void) const
Definition: mex.cc:1286
int get_number_of_fields(void) const
Definition: mex.cc:1503
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:1281
mxInt8 * get_int8s(void) const
Definition: mex.cc:1241
mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const
Definition: mex.cc:1528
~mxArray_matlab(void)
Definition: mex.cc:1059
int isempty(void) const
Definition: mex.cc:1170
char * array_to_string(void) const
Definition: mex.cc:1523
int is_numeric(void) const
Definition: mex.cc:1085
mxArray_matlab(const mxArray_matlab &val)
Definition: mex.cc:1619
int set_uint64s(mxUint64 *)
Definition: mex.cc:1389
mxInt64 * get_int64s(void) const
Definition: mex.cc:1256
int is_complex(void) const
Definition: mex.cc:1069
mxUint32 * get_uint32s(void) const
Definition: mex.cc:1271
mwSize * m_dims
Definition: mex.cc:1651
mxArray_matlab(bool interleaved, mxClassID id=mxUNKNOWN_CLASS)
Definition: mex.cc:1560
mxArray_matlab & operator=(const mxArray_matlab &)
int is_logical_scalar_true(void) const
Definition: mex.cc:1108
mxUint64 * get_uint64s(void) const
Definition: mex.cc:1276
mwSize get_m(void) const
Definition: mex.cc:1114
const char * get_field_name_by_number(int) const
Definition: mex.cc:1508
int is_double(void) const
Definition: mex.cc:1071
int is_logical(void) const
Definition: mex.cc:1083
int is_struct(void) const
Definition: mex.cc:1098
void set_n(mwSize n)
Definition: mex.cc:1132
int get_field_number(const char *) const
Definition: mex.cc:1513
void * get_imag_data(void) const
Definition: mex.cc:1334
mxDouble * get_doubles(void) const
Definition: mex.cc:1231
char * m_class_name
Definition: mex.cc:1646
mxUint16 * get_uint16s(void) const
Definition: mex.cc:1266
int is_function_handle(void) const
Definition: mex.cc:1073
mxArray_matlab(bool interleaved, mxClassID id, const dim_vector &dv)
Definition: mex.cc:1594
void set_jc(mwIndex *)
Definition: mex.cc:1472
int set_int16s(mxInt16 *)
Definition: mex.cc:1359
mxArray_matlab(bool interleaved, mxClassID id, mwSize ndims, const mwSize *dims)
Definition: mex.cc:1565
mxInt32 * get_int32s(void) const
Definition: mex.cc:1251
int is_uint32(void) const
Definition: mex.cc:1102
int is_single(void) const
Definition: mex.cc:1094
int is_int8(void) const
Definition: mex.cc:1081
void set_class_name(const char *name)
Definition: mex.cc:1204
mwSize * get_dimensions(void) const
Definition: mex.cc:1126
mwSize get_number_of_dimensions(void) const
Definition: mex.cc:1128
int set_uint32s(mxUint32 *)
Definition: mex.cc:1384
mwSize get_nzmax(void) const
Definition: mex.cc:1462
int is_int16(void) const
Definition: mex.cc:1075
mxInt16 * get_int16s(void) const
Definition: mex.cc:1246
double get_scalar(void) const
Definition: mex.cc:1221
int is_uint8(void) const
Definition: mex.cc:1106
int is_sparse(void) const
Definition: mex.cc:1096
mxArray_matlab(bool interleaved, mxClassID id, mwSize m, mwSize n)
Definition: mex.cc:1611
int is_uint64(void) const
Definition: mex.cc:1104
void set_ir(mwIndex *)
Definition: mex.cc:1467
int set_singles(mxSingle *)
Definition: mex.cc:1349
mxClassID m_id
Definition: mex.cc:1648
void set_imag_data(void *)
Definition: mex.cc:1447
int get_string(char *, mwSize) const
Definition: mex.cc:1518
std::size_t get_element_size(void) const
Definition: mex.cc:1533
int set_complex_doubles(mxComplexDouble *)
Definition: mex.cc:1394
void remove_field(int)
Definition: mex.cc:1487
void * get_data(void) const
Definition: mex.cc:1226
int is_uint16(void) const
Definition: mex.cc:1100
int set_int32s(mxInt32 *)
Definition: mex.cc:1364
mxSingle * get_singles(void) const
Definition: mex.cc:1236
mwSize m_ndims
Definition: mex.cc:1650
dim_vector dims_to_dim_vector(void) const
Definition: mex.cc:1629
mwSize get_number_of_elements(void) const
Definition: mex.cc:1160
int set_uint8s(mxUint8 *)
Definition: mex.cc:1374
int is_int32(void) const
Definition: mex.cc:1077
void set_data(void *)
Definition: mex.cc:1339
int is_sparse(void) const
Definition: mex.cc:556
int set_uint16s(mxUint16 *)
Definition: mex.cc:847
bool mutation_needed(void) const
Definition: mex.cc:999
int set_dimensions(mwSize *, mwSize)
Definition: mex.cc:621
mxArray_base * dup(void) const
Definition: mex.cc:485
T * get_data(mxClassID class_id, mxComplexity complexity) const
Definition: mex.cc:764
mxClassID get_class_id(void) const
Definition: mex.cc:635
int is_uint16(void) const
Definition: mex.cc:560
int add_field(const char *)
Definition: mex.cc:896
void * get_imag_data(void) const
Definition: mex.cc:825
void set_nzmax(mwSize)
Definition: mex.cc:893
octave_value as_octave_value(void) const
Definition: mex.cc:1011
mxInt32 * get_int32s(void) const
Definition: mex.cc:790
int isreal(void) const
Definition: mex.cc:570
mwSize get_number_of_elements(void) const
Definition: mex.cc:623
void * get_data(void) const
Definition: mex.cc:747
mxSingle * get_singles(void) const
Definition: mex.cc:784
int set_doubles(mxDouble *)
Definition: mex.cc:840
void set_cell(mwIndex, mxArray *)
Definition: mex.cc:725
const char * get_field_name_by_number(int) const
Definition: mex.cc:908
mxArray * mutate(void) const
Definition: mex.cc:1009
void set_ir(mwIndex *)
Definition: mex.cc:887
void set_data(void *)
Definition: mex.cc:838
mxArray_octave_value & operator=(const mxArray_octave_value &)=delete
int set_singles(mxSingle *)
Definition: mex.cc:841
int set_uint32s(mxUint32 *)
Definition: mex.cc:848
mxUint32 * get_uint32s(void) const
Definition: mex.cc:798
int is_logical(void) const
Definition: mex.cc:550
int is_uint8(void) const
Definition: mex.cc:566
~mxArray_octave_value(void)
Definition: mex.cc:524
int set_int64s(mxInt64 *)
Definition: mex.cc:845
std::size_t get_element_size(void) const
Definition: mex.cc:971
mxArray * get_cell(mwIndex) const
Definition: mex.cc:722
void set_jc(mwIndex *)
Definition: mex.cc:890
mxArray_octave_value(const mxArray_octave_value &arg)
Definition: mex.cc:1015
int is_uint64(void) const
Definition: mex.cc:564
int set_uint8s(mxUint8 *)
Definition: mex.cc:846
mxArray * get_field_by_number(mwIndex, int) const
Definition: mex.cc:901
mxUint16 * get_uint16s(void) const
Definition: mex.cc:796
mwIndex * get_ir(void) const
Definition: mex.cc:868
int is_int8(void) const
Definition: mex.cc:548
mwIndex * get_jc(void) const
Definition: mex.cc:876
mxUint64 * get_uint64s(void) const
Definition: mex.cc:800
mxComplexSingle * get_complex_singles(void) const
Definition: mex.cc:804
void set_m(mwSize)
Definition: mex.cc:618
mwSize * get_dimensions(void) const
Definition: mex.cc:592
int is_int64(void) const
Definition: mex.cc:546
int set_uint64s(mxUint64 *)
Definition: mex.cc:849
int set_complex_doubles(mxComplexDouble *)
Definition: mex.cc:851
void set_class_name(const char *)
Definition: mex.cc:687
int iscell(void) const
Definition: mex.cc:532
mxInt16 * get_int16s(void) const
Definition: mex.cc:788
int is_numeric(void) const
Definition: mex.cc:552
mwSize get_m(void) const
Definition: mex.cc:577
char * array_to_string(void) const
Definition: mex.cc:935
octave_value m_val
Definition: mex.cc:1032
int is_int16(void) const
Definition: mex.cc:542
int is_char(void) const
Definition: mex.cc:534
mxDouble * get_doubles(void) const
Definition: mex.cc:782
void set_imag_data(void *)
Definition: mex.cc:866
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:802
int set_int8s(mxInt8 *)
Definition: mex.cc:842
int get_field_number(const char *) const
Definition: mex.cc:910
void set_property(mwIndex idx, const char *pname, const mxArray *pval)
Definition: mex.cc:709
bool is_scalar(void) const
Definition: mex.cc:627
void remove_field(int)
Definition: mex.cc:899
int get_number_of_fields(void) const
Definition: mex.cc:906
int set_int32s(mxInt32 *)
Definition: mex.cc:844
mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const
Definition: mex.cc:963
int is_int32(void) const
Definition: mex.cc:544
mxInt8 * get_int8s(void) const
Definition: mex.cc:786
bool is_octave_value(void) const
Definition: mex.cc:530
void set_n(mwSize)
Definition: mex.cc:619
mxArray_octave_value(bool interleaved, const octave_value &ov)
Definition: mex.cc:474
int isempty(void) const
Definition: mex.cc:625
mxArray * as_mxArray(void) const
Definition: mex.cc:487
mwSize get_n(void) const
Definition: mex.cc:579
mxUint8 * get_uint8s(void) const
Definition: mex.cc:794
int is_range(void) const
Definition: mex.cc:568
int is_complex(void) const
Definition: mex.cc:536
int set_int16s(mxInt16 *)
Definition: mex.cc:843
mwSize get_nzmax(void) const
Definition: mex.cc:884
int is_double(void) const
Definition: mex.cc:538
void request_mutation(void) const
Definition: mex.cc:1001
int is_uint32(void) const
Definition: mex.cc:562
mxInt64 * get_int64s(void) const
Definition: mex.cc:792
int is_single(void) const
Definition: mex.cc:554
int get_string(char *buf, mwSize buflen) const
Definition: mex.cc:912
int set_complex_singles(mxComplexSingle *)
Definition: mex.cc:852
double get_scalar(void) const
Definition: mex.cc:727
const char * get_class_name(void) const
Definition: mex.cc:675
char * m_class_name
Definition: mex.cc:1041
mwSize get_number_of_dimensions(void) const
Definition: mex.cc:610
void set_field_by_number(mwIndex, int, mxArray *)
Definition: mex.cc:904
int is_logical_scalar_true(void) const
Definition: mex.cc:572
int is_function_handle(void) const
Definition: mex.cc:540
mxArray * get_property(mwIndex idx, const char *pname) const
Definition: mex.cc:689
mxClassID m_id
Definition: mex.cc:1040
int is_struct(void) const
Definition: mex.cc:558
mwSize * m_dims
Definition: mex.cc:1043
mxInt16 * get_int16s(void) const
Definition: mex.cc:2383
mxArray_separate_full(const mxArray_separate_full &val)
Definition: mex.cc:2467
mxComplexInt64 * get_complex_int64s(void) const
Definition: mex.cc:2399
mxArray_separate_full(const char *str)
Definition: mex.cc:2350
int set_complex_uint32s(mxComplexUint32 *)
Definition: mex.cc:2427
mxComplexUint16 * get_complex_uint16s(void) const
Definition: mex.cc:2401
mxArray_separate_full(mxClassID id, mwSize m, mwSize n, mxComplexity flag=mxREAL, bool init=true)
Definition: mex.cc:2334
int is_complex(void) const
Definition: mex.cc:2374
mxInt64 * get_int64s(void) const
Definition: mex.cc:2385
mxComplexInt32 * get_complex_int32s(void) const
Definition: mex.cc:2398
void set_imag_data(void *pi)
Definition: mex.cc:2378
mxDouble * get_doubles(void) const
Definition: mex.cc:2380
mxUint16 * get_uint16s(void) const
Definition: mex.cc:2387
mxComplexUint8 * get_complex_uint8s(void) const
Definition: mex.cc:2400
int set_complex_int16s(mxComplexInt16 *)
Definition: mex.cc:2422
mxInt32 * get_int32s(void) const
Definition: mex.cc:2384
mxComplexInt16 * get_complex_int16s(void) const
Definition: mex.cc:2397
int set_uint64s(mxUint64 *)
Definition: mex.cc:2414
int set_int16s(mxInt16 *)
Definition: mex.cc:2408
int set_int32s(mxInt32 *)
Definition: mex.cc:2409
int set_uint8s(mxUint8 *)
Definition: mex.cc:2411
mxArray_separate_full(mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag=mxREAL, bool init=true)
Definition: mex.cc:2318
mxArray_separate_full(mxClassID id, mxLogical val)
Definition: mex.cc:2346
int set_complex_int32s(mxComplexInt32 *)
Definition: mex.cc:2423
mxInt8 * get_int8s(void) const
Definition: mex.cc:2382
int set_complex_uint64s(mxComplexUint64 *)
Definition: mex.cc:2428
mxComplexInt8 * get_complex_int8s(void) const
Definition: mex.cc:2396
octave_value as_octave_value(void) const
Definition: mex.cc:2430
mxArray_separate_full & operator=(const mxArray_separate_full &)
int set_complex_int8s(mxComplexInt8 *)
Definition: mex.cc:2421
int set_int64s(mxInt64 *)
Definition: mex.cc:2410
~mxArray_separate_full(void)
Definition: mex.cc:2369
int set_doubles(mxDouble *)
Definition: mex.cc:2405
mxArray_base * dup(void) const
Definition: mex.cc:2364
mxSingle * get_singles(void) const
Definition: mex.cc:2381
mxUint64 * get_uint64s(void) const
Definition: mex.cc:2389
int set_singles(mxSingle *)
Definition: mex.cc:2406
octave_value to_ov(const dim_vector &dv) const
Definition: mex.cc:2481
int set_uint32s(mxUint32 *)
Definition: mex.cc:2413
int set_complex_int64s(mxComplexInt64 *)
Definition: mex.cc:2424
int set_complex_doubles(mxComplexDouble *)
Definition: mex.cc:2416
mxComplexUint64 * get_complex_uint64s(void) const
Definition: mex.cc:2403
int set_complex_singles(mxComplexSingle *)
Definition: mex.cc:2417
mxArray_separate_full(mxClassID id, const dim_vector &dv, mxComplexity flag=mxREAL)
Definition: mex.cc:2326
mxArray_separate_full(mwSize m, const char **str)
Definition: mex.cc:2355
mxComplexSingle * get_complex_singles(void) const
Definition: mex.cc:2392
int set_complex_uint16s(mxComplexUint16 *)
Definition: mex.cc:2426
mxComplexUint32 * get_complex_uint32s(void) const
Definition: mex.cc:2402
void * get_imag_data(void) const
Definition: mex.cc:2376
mxArray_separate_full(mxClassID id, double val)
Definition: mex.cc:2342
int set_uint16s(mxUint16 *)
Definition: mex.cc:2412
mxUint8 * get_uint8s(void) const
Definition: mex.cc:2386
mxUint32 * get_uint32s(void) const
Definition: mex.cc:2388
int set_complex_uint8s(mxComplexUint8 *)
Definition: mex.cc:2425
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:2391
int set_int8s(mxInt8 *)
Definition: mex.cc:2407
void * get_imag_data(void) const
Definition: mex.cc:2779
mxArray_separate_sparse & operator=(const mxArray_separate_sparse &)
mxComplexDouble * get_complex_doubles(void) const
Definition: mex.cc:2784
mxDouble * get_doubles(void) const
Definition: mex.cc:2783
void set_imag_data(void *pi)
Definition: mex.cc:2781
int is_complex(void) const
Definition: mex.cc:2774
int set_doubles(mxDouble *)
Definition: mex.cc:2786
mxArray_separate_sparse(mxClassID id, mwSize m, mwSize n, mwSize nzmax, mxComplexity flag=mxREAL)
Definition: mex.cc:2737
mxArray_separate_sparse(const mxArray_separate_sparse &val)
Definition: mex.cc:2747
mxArray_base * dup(void) const
Definition: mex.cc:2764
octave_value as_octave_value(void) const
Definition: mex.cc:2789
int set_complex_doubles(mxComplexDouble *)
Definition: mex.cc:2787
~mxArray_separate_sparse(void)
Definition: mex.cc:2769
mxArray_struct(bool interleaved, mwSize ndims, const mwSize *dims, int num_keys, const char **keys)
Definition: mex.cc:2843
mxArray_struct & operator=(const mxArray_struct &val)
~mxArray_struct(void)
Definition: mex.cc:2919
int get_number_of_fields(void) const
Definition: mex.cc:3042
mxArray ** m_data
Definition: mex.cc:3101
octave_value as_octave_value(void) const
Definition: mex.cc:3069
void * get_data(void) const
Definition: mex.cc:3065
mxArray_struct(bool interleaved, const dim_vector &dv, int num_keys, const char **keys)
Definition: mex.cc:2856
void remove_field(int key_num)
Definition: mex.cc:2983
mxArray_struct(const mxArray_struct &val)
Definition: mex.cc:2884
int get_field_number(const char *key) const
Definition: mex.cc:3049
mxArray_struct(bool interleaved, mwSize m, mwSize n, int num_keys, const char **keys)
Definition: mex.cc:2869
mxArray_base * dup(void) const
Definition: mex.cc:2917
const char * get_field_name_by_number(int key_num) const
Definition: mex.cc:3044
void set_data(void *data)
Definition: mex.cc:3067
int m_nfields
Definition: mex.cc:3097
mxArray * get_field_by_number(mwIndex index, int key_num) const
Definition: mex.cc:3034
int add_field(const char *key)
Definition: mex.cc:2934
void init(const char **keys)
Definition: mex.cc:2911
char ** m_fields
Definition: mex.cc:3099
void set_field_by_number(mwIndex index, int key_num, mxArray *val)
Definition: mex.cc:3789
mxArray * get_field_by_number(mwIndex index, int key_num) const
Definition: mxarray.h:649
int set_uint8s(mxUint8 *data)
Definition: mxarray.h:585
mxClassID get_class_id(void) const
Definition: mxarray.h:476
int is_int64(void) const
Definition: mxarray.h:422
int is_single(void) const
Definition: mxarray.h:430
int set_complex_singles(mxComplexSingle *data)
Definition: mxarray.h:600
mxUint8 * get_uint8s(void) const
Definition: mxarray.h:517
mxUint32 * get_uint32s(void) const
Definition: mxarray.h:523
mxSingle * get_singles(void) const
Definition: mxarray.h:502
OCTINTERP_API void maybe_mutate(void) const
Definition: mex.cc:3382
int set_uint32s(mxUint32 *data)
Definition: mxarray.h:591
mxComplexDouble * get_complex_doubles(void) const
Definition: mxarray.h:529
OCTINTERP_API void set_name(const char *name)
Definition: mex.cc:3277
void set_n(mwSize n)
Definition: mxarray.h:460
char * m_name
Definition: mxarray.h:747
mxUint64 * get_uint64s(void) const
Definition: mxarray.h:526
int is_logical_scalar_true(void) const
Definition: mxarray.h:446
int is_uint32(void) const
Definition: mxarray.h:438
int is_char(void) const
Definition: mxarray.h:408
mwIndex * get_jc(void) const
Definition: mxarray.h:634
OCTINTERP_API ~mxArray(void)
Definition: mex.cc:3269
void set_property(mwIndex idx, const char *pname, const mxArray *pval)
Definition: mxarray.h:483
mxUint16 * get_uint16s(void) const
Definition: mxarray.h:520
int set_singles(mxSingle *data)
Definition: mxarray.h:570
mxArray * get_property(mwIndex idx, const char *pname) const
Definition: mxarray.h:480
int set_uint16s(mxUint16 *data)
Definition: mxarray.h:588
void set_m(mwSize m)
Definition: mxarray.h:458
static OCTINTERP_API void * alloc(bool init, std::size_t n, std::size_t t)
Definition: mex.cc:3744
int set_uint64s(mxUint64 *data)
Definition: mxarray.h:594
mwIndex * get_ir(void) const
Definition: mxarray.h:632
mxArray * dup(void) const
Definition: mxarray.h:380
mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const
Definition: mxarray.h:668
static char * strsave(const char *str)
Definition: mxarray.h:683
const char * get_name(void) const
Definition: mxarray.h:472
int is_function_handle(void) const
Definition: mxarray.h:416
int set_dimensions(mwSize *dims_arg, mwSize ndims_arg)
Definition: mxarray.h:462
int isempty(void) const
Definition: mxarray.h:468
mwSize get_m(void) const
Definition: mxarray.h:449
void set_data(void *pr)
Definition: mxarray.h:565
int is_uint64(void) const
Definition: mxarray.h:440
int is_struct(void) const
Definition: mxarray.h:434
static OCTINTERP_API void * calloc(std::size_t n, std::size_t t)
Definition: mex.cc:3738
OCTINTERP_API mxArray(bool interleaved, const octave_value &ov)
Definition: mex.cc:3197
int set_complex_doubles(mxComplexDouble *data)
Definition: mxarray.h:597
int get_field_number(const char *key) const
Definition: mxarray.h:660
std::size_t get_element_size(void) const
Definition: mxarray.h:671
int iscell(void) const
Definition: mxarray.h:406
int add_field(const char *key)
Definition: mxarray.h:644
int is_int8(void) const
Definition: mxarray.h:424
int get_number_of_fields(void) const
Definition: mxarray.h:655
int is_sparse(void) const
Definition: mxarray.h:432
void * get_data(void) const
Definition: mxarray.h:497
int is_double(void) const
Definition: mxarray.h:414
mwSize get_nzmax(void) const
Definition: mxarray.h:636
mxArray_base * m_rep
Definition: mxarray.h:745
int is_uint8(void) const
Definition: mxarray.h:442
static OCTINTERP_API octave_value as_octave_value(const mxArray *ptr, bool null_is_empty=true)
Definition: mex.cc:3284
int set_int32s(mxInt32 *data)
Definition: mxarray.h:579
bool is_scalar(void) const
Definition: mxarray.h:470
int set_int64s(mxInt64 *data)
Definition: mxarray.h:582
int set_doubles(mxDouble *data)
Definition: mxarray.h:567
void set_nzmax(mwSize nzmax)
Definition: mxarray.h:642
mxInt8 * get_int8s(void) const
Definition: mxarray.h:505
int is_logical(void) const
Definition: mxarray.h:426
int is_int16(void) const
Definition: mxarray.h:418
const char * get_field_name_by_number(int key_num) const
Definition: mxarray.h:657
double get_scalar(void) const
Definition: mxarray.h:495
void set_jc(mwIndex *jc)
Definition: mxarray.h:640
mwSize get_number_of_dimensions(void) const
Definition: mxarray.h:455
int set_int16s(mxInt16 *data)
Definition: mxarray.h:576
mwSize * get_dimensions(void) const
Definition: mxarray.h:453
mxArray * get_cell(mwIndex idx) const
Definition: mxarray.h:489
int is_numeric(void) const
Definition: mxarray.h:428
mwSize get_number_of_elements(void) const
Definition: mxarray.h:465
mxDouble * get_doubles(void) const
Definition: mxarray.h:499
int get_string(char *buf, mwSize buflen) const
Definition: mxarray.h:663
int is_class(const char *name_arg) const
Definition: mxarray.h:410
int set_int8s(mxInt8 *data)
Definition: mxarray.h:573
mwSize get_n(void) const
Definition: mxarray.h:451
void set_class_name(const char *name_arg)
Definition: mxarray.h:486
int is_complex(void) const
Definition: mxarray.h:412
int is_uint16(void) const
Definition: mxarray.h:436
void set_field_by_number(mwIndex index, int key_num, mxArray *val)
Definition: mxarray.h:652
void set_cell(mwIndex idx, mxArray *val)
Definition: mxarray.h:492
static OCTINTERP_API mxArray_base * create_rep(bool interleaved, const octave_value &ov)
Definition: mex.cc:3300
void set_ir(mwIndex *ir)
Definition: mxarray.h:638
int is_logical_scalar(void) const
Definition: mxarray.h:444
static OCTINTERP_API void * malloc(std::size_t n)
Definition: mex.cc:3732
OCTINTERP_API octave_value as_octave_value(void) const
Definition: mex.cc:3294
void * get_imag_data(void) const
Definition: mxarray.h:562
void set_imag_data(void *pi)
Definition: mxarray.h:630
char * array_to_string(void) const
Definition: mxarray.h:666
mxInt16 * get_int16s(void) const
Definition: mxarray.h:508
void remove_field(int key_num)
Definition: mxarray.h:646
mxComplexSingle * get_complex_singles(void) const
Definition: mxarray.h:532
const char * get_class_name(void) const
Definition: mxarray.h:478
int is_int32(void) const
Definition: mxarray.h:420
mxInt64 * get_int64s(void) const
Definition: mxarray.h:514
mxInt32 * get_int32s(void) const
Definition: mxarray.h:511
void add(F &&fcn, Args &&... args)
octave_value get_property(octave_idx_type idx, const std::string &name) const
Definition: ov-classdef.h:139
void set_property(octave_idx_type idx, const std::string &name, const octave_value &pval)
Definition: ov-classdef.h:132
std::string name(void) const
Definition: ov-fcn.h:207
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:365
bool is_fmex(void) const
Definition: ov-mex-fcn.h:105
void atexit(void(*fcn)(void))
Definition: ov-mex-fcn.h:99
bool use_interleaved_complex(void) const
Definition: ov-mex-fcn.h:93
void * mex_fcn_ptr(void) const
Definition: ov-mex-fcn.h:103
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
octave_idx_type length(void) const
Definition: ovl.h:113
bool is_classdef_object(void) const
Definition: ov.h:700
OCTINTERP_API const void * mex_get_data(mxClassID class_id=mxUNKNOWN_CLASS, mxComplexity complexity=mxREAL) const
bool iscell(void) const
Definition: ov.h:649
bool isreal(void) const
Definition: ov.h:783
bool issparse(void) const
Definition: ov.h:798
bool is_uint16_type(void) const
Definition: ov.h:766
bool is_true(void) const
Definition: ov.h:803
bool is_int8_type(void) const
Definition: ov.h:751
octave_idx_type rows(void) const
Definition: ov.h:590
bool isnumeric(void) const
Definition: ov.h:795
octave_idx_type numel(void) const
Definition: ov.h:604
const octave_idx_type * mex_get_ir(void) const
Definition: ov.h:1517
bool is_string(void) const
Definition: ov.h:682
bool is_defined(void) const
Definition: ov.h:637
charNDArray char_array_value(bool frc_str_conv=false) const
Definition: ov.h:942
bool is_double_type(void) const
Definition: ov.h:740
bool is_function_handle(void) const
Definition: ov.h:813
std::string class_name(void) const
Definition: ov.h:1451
bool is_uint32_type(void) const
Definition: ov.h:769
int ndims(void) const
Definition: ov.h:596
bool is_int64_type(void) const
Definition: ov.h:760
const octave_idx_type * mex_get_jc(void) const
Definition: ov.h:1523
bool isstruct(void) const
Definition: ov.h:694
OCTINTERP_API octave_classdef * classdef_object_value(bool silent=false) const
double scalar_value(bool frc_str_conv=false) const
Definition: ov.h:892
octave_idx_type nfields(void) const
Definition: ov.h:614
bool is_int32_type(void) const
Definition: ov.h:757
bool is_uint64_type(void) const
Definition: ov.h:772
octave_idx_type nzmax(void) const
Definition: ov.h:612
bool is_int16_type(void) const
Definition: ov.h:754
mxArray * as_mxArray(bool interleaved=false) const
Definition: ov.h:1528
bool is_range(void) const
Definition: ov.h:691
bool isempty(void) const
Definition: ov.h:646
bool is_single_type(void) const
Definition: ov.h:743
bool is_uint8_type(void) const
Definition: ov.h:763
bool iscomplex(void) const
Definition: ov.h:786
bool islogical(void) const
Definition: ov.h:780
dim_vector dims(void) const
Definition: ov.h:586
void warning(const char *fmt,...)
Definition: error.cc:1055
void vwarning_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:1064
void verror_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:1019
void error(const char *fmt,...)
Definition: error.cc:980
#define panic_impossible()
Definition: error.h:411
octave_f77_int_type F77_INT
Definition: f77-fcn.h:306
bool set_property_in_handle(double handle, const std::string &property, const octave_value &arg, const std::string &func)
Definition: graphics.cc:14271
octave_value get_property_from_handle(double handle, const std::string &property, const std::string &func)
Definition: graphics.cc:14255
QString name
double lo_ieee_inf_value(void)
Definition: lo-ieee.cc:68
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:84
#define lo_ieee_isnan(x)
Definition: lo-ieee.h:100
#define lo_ieee_isinf(x)
Definition: lo-ieee.h:108
#define lo_ieee_isfinite(x)
Definition: lo-ieee.h:104
F77_RET_T(F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, const F77_INT &, const F77_INT &, const F77_INT &, F77_INT &, F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_DBLE *, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_INT *, F77_INT &F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE const F77_DBLE * f
static char * strsave(const char *s)
Definition: main.in.cc:214
void mxSetIr(mxArray *ptr, mwIndex *ir)
Definition: mex.cc:4673
OCTINTERP_API mxUint16 * mxGetUint16s(const mxArray *p)
Definition: mex.cc:4412
static void * xmalloc(size_t n)
Definition: mex.cc:268
void mxSetCell(mxArray *ptr, mwIndex idx, mxArray *val)
Definition: mex.cc:4648
bool mxIsUint16(const mxArray *ptr)
Definition: mex.cc:4219
static T * maybe_unmark(T *ptr)
Definition: mex.cc:3780
mxArray * mxDuplicateArray(const mxArray *ptr)
Definition: mex.cc:4114
std::size_t mxGetM(const mxArray *ptr)
Definition: mex.cc:4281
const char * mexFunctionName(void)
Definition: mex.cc:4851
OCTINTERP_API int mxSetDoubles(mxArray *p, mxDouble *d)
Definition: mex.cc:4493
static void maybe_disown_ptr(void *ptr)
Definition: mex.cc:3759
OCTINTERP_API mxDouble * mxGetDoubles(const mxArray *p)
Definition: mex.cc:4377
void mexWarnMsgIdAndTxt(const char *id, const char *fmt,...)
Definition: mex.cc:5119
OCTINTERP_API int mxSetUint8s(mxArray *p, mxUint8 *d)
Definition: mex.cc:4523
#define CONST_MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL)
Definition: mex.cc:464
mwIndex mxCalcSingleSubscript(const mxArray *ptr, mwSize nsubs, mwIndex *subs)
Definition: mex.cc:4760
OCTINTERP_API int mxSetInt16s(mxArray *p, mxInt16 *d)
Definition: mex.cc:4508
OCTINTERP_API mxInt64 * mxGetInt64s(const mxArray *p)
Definition: mex.cc:4402
bool mxIsFunctionHandle(const mxArray *ptr)
Definition: mex.cc:4159
bool mxIsStruct(const mxArray *ptr)
Definition: mex.cc:4213
int mxGetFieldNumber(const mxArray *ptr, const char *key)
Definition: mex.cc:4742
static mxArray * maybe_mark_array(mxArray *ptr)
Definition: mex.cc:3874
static mxArray * maybe_unmark_array(mxArray *ptr)
Definition: mex.cc:3770
void mexErrMsgTxt(const char *s)
Definition: mex.cc:5051
mex * mex_context
Definition: mex.cc:3729
void mxSetField(mxArray *ptr, mwIndex index, const char *key, mxArray *val)
Definition: mex.cc:4717
OCTINTERP_API mxArray * mxCreateCellMatrix_interleaved(mwSize m, mwSize n)
Definition: mex.cc:3893
void(* cmex_fptr)(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs)
Definition: mex.cc:4773
bool mxIsUint32(const mxArray *ptr)
Definition: mex.cc:4225
void mxSetProperty(mxArray *ptr, mwIndex idx, const char *property_name, const mxArray *property_value)
Definition: mex.cc:4628
OCTINTERP_API int mxSetComplexDoubles(mxArray *p, mxComplexDouble *d)
Definition: mex.cc:4543
OCTINTERP_API mxUint64 * mxGetUint64s(const mxArray *p)
Definition: mex.cc:4422
bool mxIsComplex(const mxArray *ptr)
Definition: mex.cc:4147
OCTINTERP_API mxArray * mxCreateCharArray_interleaved(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3905
OCTINTERP_API mxComplexDouble * mxGetComplexDoubles(const mxArray *p)
Definition: mex.cc:4427
OCTINTERP_API mxArray * mxCreateString(const char *str)
Definition: mex.cc:4079
OCTINTERP_API mxArray * mxCreateSparseLogicalMatrix_interleaved(mwSize m, mwSize n, mwSize nzmax)
Definition: mex.cc:4061
char * mxArrayToString(const mxArray *ptr)
Definition: mex.cc:4754
OCTINTERP_API mxArray * mxCreateCellArray(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3887
OCTINTERP_API int mxSetUint32s(mxArray *p, mxUint32 *d)
Definition: mex.cc:4533
OCTINTERP_API int mxSetInt8s(mxArray *p, mxInt8 *d)
Definition: mex.cc:4503
OCTINTERP_API mxArray * mxCreateNumericMatrix(mwSize m, mwSize n, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4010
mxArray * mexEvalStringWithTrap(const char *s)
Definition: mex.cc:5013
int mexAtExit(void(*f)(void))
Definition: mex.cc:5295
OCTINTERP_API int mxSetUint16s(mxArray *p, mxUint16 *d)
Definition: mex.cc:4528
bool mxIsFinite(const double v)
Definition: mex.cc:3809
OCTINTERP_API mxSingle * mxGetSingles(const mxArray *p)
Definition: mex.cc:4382
bool mxIsScalar(const mxArray *ptr)
Definition: mex.cc:4264
bool mxIsFromGlobalWS(const mxArray *)
Definition: mex.cc:4272
const char * mxGetClassName(const mxArray *ptr)
Definition: mex.cc:4616
void mxSetFieldByNumber(mxArray *ptr, mwIndex index, int key_num, mxArray *val)
Definition: mex.cc:4724
bool mxIsLogicalScalarTrue(const mxArray *ptr)
Definition: mex.cc:4251
OCTINTERP_API int mxSetInt32s(mxArray *p, mxInt32 *d)
Definition: mex.cc:4513
OCTINTERP_API mxArray * mxCreateSparse(mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
Definition: mex.cc:4054
static octave_value_list mx_to_ov_args(int nargin, mxArray *argin[])
Definition: mex.cc:4857
OCTINTERP_API mxArray * mxCreateStructArray(mwSize ndims, const mwSize *dims, int num_keys, const char **keys)
Definition: mex.cc:4092
OCTINTERP_API void * mxGetImagData(const mxArray *ptr)
Definition: mex.cc:4372
mxClassID mxGetClassID(const mxArray *ptr)
Definition: mex.cc:4610
bool mxIsLogical(const mxArray *ptr)
Definition: mex.cc:4189
double * mxGetPr(const mxArray *ptr)
Definition: mex.cc:4333
void * mxCalloc(std::size_t n, std::size_t size)
Definition: mex.cc:3846
std::map< std::string, int > mex_lock_count
Definition: mex.cc:5358
void mexWarnMsgTxt(const char *s)
Definition: mex.cc:5096
OCTINTERP_API mxInt16 * mxGetInt16s(const mxArray *p)
Definition: mex.cc:4392
mwIndex * mxGetIr(const mxArray *ptr)
Definition: mex.cc:4655
void mxSetData(mxArray *ptr, void *pr)
Definition: mex.cc:4488
mxLogical * mxGetLogicals(const mxArray *ptr)
Definition: mex.cc:4354
OCTINTERP_API int mxSetUint64s(mxArray *p, mxUint64 *d)
Definition: mex.cc:4538
OCTINTERP_API mxInt8 * mxGetInt8s(const mxArray *p)
Definition: mex.cc:4387
bool mxIsInt64(const mxArray *ptr)
Definition: mex.cc:4177
int mxSetDimensions(mxArray *ptr, const mwSize *dims, mwSize ndims)
Definition: mex.cc:4324
std::size_t mxGetNumberOfElements(const mxArray *ptr)
Definition: mex.cc:4305
octave_value_list call_mex(octave_mex_function &mex_fcn, const octave_value_list &args, int nargout_arg)
Definition: mex.cc:4778
int mexPrintf(const char *fmt,...)
Definition: mex.cc:5138
bool mxIsChar(const mxArray *ptr)
Definition: mex.cc:4135
bool mxIsInf(const double v)
Definition: mex.cc:3815
bool mxIsUint8(const mxArray *ptr)
Definition: mex.cc:4237
void mxDestroyArray(mxArray *ptr)
Definition: mex.cc:4121
void mxSetNzmax(mxArray *ptr, mwSize nzmax)
Definition: mex.cc:4685
mxChar * mxGetChars(const mxArray *ptr)
Definition: mex.cc:4345
bool mxIsSingle(const mxArray *ptr)
Definition: mex.cc:4201
void mexErrMsgIdAndTxt(const char *id, const char *fmt,...)
Definition: mex.cc:5074
F77_RET_T(* fmex_fptr)(F77_INT &nlhs, mxArray **plhs, F77_INT &nrhs, mxArray **prhs)
Definition: mex.cc:4774
int mxAddField(mxArray *ptr, const char *key)
Definition: mex.cc:4692
void mexMakeMemoryPersistent(void *ptr)
Definition: mex.cc:5289
bool mxIsInt8(const mxArray *ptr)
Definition: mex.cc:4183
OCTINTERP_API mxComplexSingle * mxGetComplexSingles(const mxArray *p)
Definition: mex.cc:4432
std::size_t mxGetElementSize(const mxArray *ptr)
Definition: mex.cc:4766
OCTINTERP_API void mxSetImagData(mxArray *ptr, void *pi)
Definition: mex.cc:4603
OCTINTERP_API mxArray * mxCreateLogicalArray(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3959
int mexCallMATLAB(int nargout, mxArray *argout[], int nargin, mxArray *argin[], const char *fname)
Definition: mex.cc:4886
bool mxIsNaN(const double v)
Definition: mex.cc:3821
OCTINTERP_API mxArray * mxCreateCharArray(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3911
OCTINTERP_API mxUint8 * mxGetUint8s(const mxArray *p)
Definition: mex.cc:4407
void mxSetPr(mxArray *ptr, double *pr)
Definition: mex.cc:4482
bool mxIsClass(const mxArray *ptr, const char *name)
Definition: mex.cc:4141
void * mxMalloc(std::size_t n)
Definition: mex.cc:3852
OCTINTERP_API mxArray * mxCreateString_interleaved(const char *str)
Definition: mex.cc:4073
OCTINTERP_API mxInt32 * mxGetInt32s(const mxArray *p)
Definition: mex.cc:4397
OCTINTERP_API mxArray * mxCreateUninitNumericMatrix_interleaved(mwSize m, mwSize n, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4033
mxArray * mexCallMATLABWithTrap(int nargout, mxArray *argout[], int nargin, mxArray *argin[], const char *fname)
Definition: mex.cc:4953
static mwSize max_str_len(mwSize m, const char **str)
Definition: mex.cc:303
int mxGetNumberOfFields(const mxArray *ptr)
Definition: mex.cc:4730
#define GET_DATA_METHOD(RT, FCN_NAME, ID, COMPLEXITY)
Definition: mex.cc:467
mxArray * mxGetProperty(const mxArray *ptr, mwIndex idx, const char *property_name)
Definition: mex.cc:4635
OCTINTERP_API mxArray * mxCreateCellArray_interleaved(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3881
OCTINTERP_API mxArray * mxCreateNumericArray_interleaved(mwSize ndims, const mwSize *dims, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:3989
int mexPutVariable(const char *space, const char *name, const mxArray *ptr)
Definition: mex.cc:5206
void mxSetN(mxArray *ptr, mwSize n)
Definition: mex.cc:4318
OCTINTERP_API mxArray * mxCreateNumericArray(mwSize ndims, const mwSize *dims, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:3996
OCTINTERP_API int mxSetInt64s(mxArray *p, mxInt64 *d)
Definition: mex.cc:4518
OCTINTERP_API mxArray * mxCreateSparseLogicalMatrix(mwSize m, mwSize n, mwSize nzmax)
Definition: mex.cc:4067
bool mxIsInt32(const mxArray *ptr)
Definition: mex.cc:4171
mxArray * mxGetFieldByNumber(const mxArray *ptr, mwIndex index, int key_num)
Definition: mex.cc:4711
OCTINTERP_API double * mxGetPi(const mxArray *ptr)
Definition: mex.cc:4366
OCTINTERP_API mxArray * mxCreateCharMatrixFromStrings_interleaved(mwSize m, const char **str)
Definition: mex.cc:3917
void * mxRealloc(void *ptr, std::size_t size)
Definition: mex.cc:3858
void mexUnlock(void)
Definition: mex.cc:5400
int mexIsGlobal(const mxArray *ptr)
Definition: mex.cc:5336
const mwSize * mxGetDimensions(const mxArray *ptr)
Definition: mex.cc:4293
void mxSetJc(mxArray *ptr, mwIndex *jc)
Definition: mex.cc:4679
bool mxIsInt16(const mxArray *ptr)
Definition: mex.cc:4165
OCTINTERP_API int mxSetComplexSingles(mxArray *p, mxComplexSingle *d)
Definition: mex.cc:4548
OCTINTERP_API mxArray * mxCreateCellMatrix(mwSize m, mwSize n)
Definition: mex.cc:3899
int mexEvalString(const char *s)
Definition: mex.cc:4984
void mexSetTrapFlag(int flag)
Definition: mex.cc:4977
mwSize mxGetNzmax(const mxArray *ptr)
Definition: mex.cc:4667
OCTINTERP_API mxArray * mxCreateLogicalScalar(mxLogical val)
Definition: mex.cc:3983
void mxSetClassName(mxArray *ptr, const char *name)
Definition: mex.cc:4622
void * mxGetData(const mxArray *ptr)
Definition: mex.cc:4360
OCTINTERP_API mxUint32 * mxGetUint32s(const mxArray *p)
Definition: mex.cc:4417
bool mxIsNumeric(const mxArray *ptr)
Definition: mex.cc:4195
OCTINTERP_API mxArray * mxCreateSparse_interleaved(mwSize m, mwSize n, mwSize nzmax, mxComplexity flag)
Definition: mex.cc:4047
int mexIsLocked(void)
Definition: mex.cc:5342
OCTINTERP_API mxArray * mxCreateDoubleMatrix(mwSize nr, mwSize nc, mxComplexity flag)
Definition: mex.cc:3935
bool mxIsCell(const mxArray *ptr)
Definition: mex.cc:4129
static void * xrealloc(void *ptr, size_t n)
Definition: mex.cc:280
void mexMakeArrayPersistent(mxArray *ptr)
Definition: mex.cc:5283
mwIndex * mxGetJc(const mxArray *ptr)
Definition: mex.cc:4661
OCTINTERP_API mxArray * mxCreateCharMatrixFromStrings(mwSize m, const char **str)
Definition: mex.cc:3923
double mxGetScalar(const mxArray *ptr)
Definition: mex.cc:4339
#define VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST)
Definition: mex.cc:455
void mxRemoveField(mxArray *ptr, int key_num)
Definition: mex.cc:4698
int mxGetString(const mxArray *ptr, char *buf, mwSize buflen)
Definition: mex.cc:4748
OCTINTERP_API mxArray * mxCreateStructMatrix(mwSize rows, mwSize cols, int num_keys, const char **keys)
Definition: mex.cc:4106
const mxArray * mexGet(double handle, const char *property)
Definition: mex.cc:5322
mxArray * mxGetField(const mxArray *ptr, mwIndex index, const char *key)
Definition: mex.cc:4704
bool mxIsLogicalScalar(const mxArray *ptr)
Definition: mex.cc:4244
OCTINTERP_API mxArray * mxCreateDoubleScalar(double val)
Definition: mex.cc:3947
double mxGetInf(void)
Definition: mex.cc:3833
double mxGetNaN(void)
Definition: mex.cc:3839
OCTINTERP_API mxArray * mxCreateUninitNumericArray(mwSize ndims, const mwSize *dims, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4025
static void xfree(void *ptr)
Definition: mex.cc:293
std::size_t mxGetN(const mxArray *ptr)
Definition: mex.cc:4287
OCTINTERP_API mxArray * mxCreateNumericMatrix_interleaved(mwSize m, mwSize n, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4003
mwSize mxGetNumberOfDimensions(const mxArray *ptr)
Definition: mex.cc:4299
OCTINTERP_API mxArray * mxCreateUninitNumericMatrix(mwSize m, mwSize n, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4040
OCTINTERP_API int mxMakeArrayComplex(mxArray *ptr)
double mxGetEps(void)
Definition: mex.cc:3827
int mexSet(double handle, const char *property, mxArray *val)
Definition: mex.cc:5379
void mexLock(void)
Definition: mex.cc:5361
#define MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL)
Definition: mex.cc:461
OCTINTERP_API mxArray * mxCreateStructMatrix_interleaved(mwSize rows, mwSize cols, int num_keys, const char **keys)
Definition: mex.cc:4099
bool mxIsEmpty(const mxArray *ptr)
Definition: mex.cc:4258
OCTINTERP_API mxArray * mxCreateLogicalArray_interleaved(mwSize ndims, const mwSize *dims)
Definition: mex.cc:3953
OCTINTERP_API mxArray * mxCreateLogicalMatrix_interleaved(mwSize m, mwSize n)
Definition: mex.cc:3965
const mxArray * mexGetVariablePtr(const char *space, const char *name)
Definition: mex.cc:5200
mxArray * mexGetVariable(const char *space, const char *name)
Definition: mex.cc:5149
void mxFree(void *ptr)
Definition: mex.cc:3865
OCTINTERP_API int mxMakeArrayReal(mxArray *ptr)
OCTINTERP_API const mxArray * mexGet_interleaved(double handle, const char *property)
Definition: mex.cc:5308
bool mxIsSparse(const mxArray *ptr)
Definition: mex.cc:4207
bool mxIsUint64(const mxArray *ptr)
Definition: mex.cc:4231
OCTINTERP_API mxArray * mxCreateDoubleScalar_interleaved(double val)
Definition: mex.cc:3941
bool mxIsDouble(const mxArray *ptr)
Definition: mex.cc:4153
OCTINTERP_API mxArray * mxCreateStructArray_interleaved(mwSize ndims, const mwSize *dims, int num_keys, const char **keys)
Definition: mex.cc:4085
OCTINTERP_API mxArray * mxCreateLogicalScalar_interleaved(mxLogical val)
Definition: mex.cc:3977
OCTINTERP_API void mxSetPi(mxArray *ptr, double *pi)
Definition: mex.cc:4597
OCTINTERP_API mxArray * mxCreateUninitNumericArray_interleaved(mwSize ndims, const mwSize *dims, mxClassID class_id, mxComplexity flag)
Definition: mex.cc:4017
mxArray * mxGetCell(const mxArray *ptr, mwIndex idx)
Definition: mex.cc:4642
OCTINTERP_API int mxSetSingles(mxArray *p, mxSingle *d)
Definition: mex.cc:4498
void mxSetM(mxArray *ptr, mwSize m)
Definition: mex.cc:4312
OCTINTERP_API mxArray * mxCreateLogicalMatrix(mwSize m, mwSize n)
Definition: mex.cc:3971
static mwIndex calc_single_subscript_internal(mwSize ndims, const mwSize *dims, mwSize nsubs, const mwIndex *subs)
Definition: mex.cc:409
const char * mxGetFieldNameByNumber(const mxArray *ptr, int key_num)
Definition: mex.cc:4736
OCTINTERP_API mxArray * mxCreateDoubleMatrix_interleaved(mwSize nr, mwSize nc, mxComplexity flag)
Definition: mex.cc:3929
static void * maybe_mark_foreign(void *ptr)
Definition: mex.cc:3750
void mxArray
Definition: mex.h:58
class OCTAVE_API Matrix
Definition: mx-fwd.h:31
static const double pi
Definition: lo-specfun.cc:1995
OCTAVE_API bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
OCTINTERP_API octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
interpreter & __get_interpreter__(const std::string &who)
tree_evaluator & __get_evaluator__(const std::string &who)
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:85
void * malloc(unsigned)
void free(void *)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
#define octave_stdout
Definition: pager.h:314
std::size_t vformat(std::ostream &os, const char *fmt, va_list args)
Definition: utils.cc:1485
F77_RET_T len
Definition: xerbla.cc:61