26#if defined (HAVE_CONFIG_H)
43#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
44# include <memory_resource>
70OCTAVE_NORETURN
static void
71error_impossible_call (
const char *fcn_name)
73 error (
"unexpected call to %s - please report this bug", fcn_name);
79 void *ptr = std::malloc (n);
82 std::cerr <<
"xmalloc (" << n <<
") = " << ptr << std::endl;
89xrealloc (
void *ptr,
size_t n)
91 void *newptr = std::realloc (ptr, n);
94 std::cerr <<
"xrealloc (" << ptr <<
", " << n <<
") = " << newptr
105 std::cerr <<
"xfree (" << ptr <<
")" << std::endl;
112max_str_len (mwSize m,
const char **str)
116 for (mwSize i = 0; i < m; i++)
118 mwSize tmp =
strlen (str[i]);
127static void * mxRealloc (
void *ptr, std::size_t size);
129static void mxFree (
void *ptr);
137 static const bool is_complex =
false;
144 static const bool is_complex =
true;
151 static const bool is_complex =
true;
154#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
156class mx_deleting_memory_resource :
public std::pmr::memory_resource
160 void * do_allocate (std::size_t bytes,
size_t )
162 void *ptr = xmalloc (bytes);
165 throw std::bad_alloc ();
170 void do_deallocate (
void *ptr, std::size_t ,
176 bool do_is_equal (
const std::pmr::memory_resource& other)
const noexcept
178 return this ==
dynamic_cast<const mx_deleting_memory_resource *
> (&other);
182class mx_preserving_memory_resource :
public std::pmr::memory_resource
186 void * do_allocate (std::size_t bytes,
size_t )
188 void *ptr = xmalloc (bytes);
191 throw std::bad_alloc ();
196 void do_deallocate (
void * , std::size_t ,
200 bool do_is_equal (
const std::pmr::memory_resource& other)
const noexcept
202 return this ==
dynamic_cast<const mx_preserving_memory_resource *
> (&other);
208static mx_deleting_memory_resource the_mx_deleting_memory_resource;
209OCTINTERP_API mx_preserving_memory_resource the_mx_preserving_memory_resource;
211OCTINTERP_API std::pmr::memory_resource *current_mx_memory_resource = &the_mx_deleting_memory_resource;
226#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
233 octave::unwind_protect_var<std::pmr::memory_resource *>
234 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
238 for (
int i = 0; i < nargin; i++)
251 if (s[
len - 1] ==
'\n')
253 std::string s_tmp (s,
len - 1);
254 error (
"%s: %s\n", who, s_tmp.c_str ());
257 error (
"%s: %s", who, s);
279 if (! name || name[0] ==
'\0')
282 octave::interpreter& interp = octave::__get_interpreter__ ();
284 if (!
strcmp (space,
"global"))
286#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
293 octave::unwind_protect_var<std::pmr::memory_resource *>
294 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
303 octave::unwind_protect frame;
305 bool caller = !
strcmp (space,
"caller");
306 bool base = !
strcmp (space,
"base");
315 octave::tree_evaluator& tw = interp.get_evaluator ();
317 frame.add (&octave::tree_evaluator::restore_frame, &tw,
318 tw.current_call_stack_frame_number ());
320 tw.goto_base_frame ();
323#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
330 octave::unwind_protect_var<std::pmr::memory_resource *>
331 upv (current_mx_memory_resource,
332 &the_mx_preserving_memory_resource);
339 "symbol table does not exist");
348#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
355 octave::unwind_protect_var<std::pmr::memory_resource *>
356 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
360 bool ret = octave::set_property_in_handle (handle, property,
363 return (ret ? 0 : 1);
369 : m_interleaved (interleaved)
373calc_single_subscript_internal (mwSize ndims,
const mwSize *dims,
374 mwSize nsubs,
const mwIndex *subs)
391 mwSize n = (nsubs <= ndims ? nsubs : ndims);
396 retval = dims[n] * retval + subs[n];
415static inline void *maybe_mark_foreign (
void *ptr);
417#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
418static inline void maybe_disown_ptr (
void *ptr);
421#define VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
422 void FCN_NAME ARG_LIST { request_mutation (); }
424#define CONST_VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
425 void FCN_NAME ARG_LIST const { request_mutation (); }
427#define MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
428 RET_TYPE FCN_NAME ARG_LIST { request_mutation (); return RET_VAL; }
430#define CONST_MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
431 RET_TYPE FCN_NAME ARG_LIST const { request_mutation (); return RET_VAL; }
433#define GET_DATA_METHOD(RT, FCN_NAME, ID, COMPLEXITY) \
434 RT * FCN_NAME () const { return get_data<RT> (ID, COMPLEXITY); }
440 mxArray_octave_value () =
delete;
442 mxArray_octave_value (
bool interleaved,
const octave_value& ov)
443 :
mxArray_base (interleaved), m_val (ov), m_mutate_flag (
false),
444 m_id (mxUNKNOWN_CLASS), m_class_name (
nullptr), m_ndims (-1),
451 mxArray_octave_value& operator = (
const mxArray_octave_value&) =
delete;
453 mxArray_base *
dup ()
const {
return new mxArray_octave_value (*
this); }
475 m_class_name =
nullptr;
493 ~mxArray_octave_value ()
495 mxFree (m_class_name);
501 int iscell ()
const {
return m_val.iscell (); }
503 int is_char ()
const {
return m_val.is_string (); }
505 int is_complex ()
const {
return m_val.iscomplex (); }
507 int is_double ()
const {
return m_val.is_double_type (); }
511 int is_int16 ()
const {
return m_val.is_int16_type (); }
513 int is_int32 ()
const {
return m_val.is_int32_type (); }
515 int is_int64 ()
const {
return m_val.is_int64_type (); }
517 int is_int8 ()
const {
return m_val.is_int8_type (); }
519 int is_logical ()
const {
return m_val.islogical (); }
521 int is_numeric ()
const {
return m_val.isnumeric (); }
523 int is_single ()
const {
return m_val.is_single_type (); }
525 int is_sparse ()
const {
return m_val.issparse (); }
527 int is_struct ()
const {
return m_val.isstruct (); }
529 int is_uint16 ()
const {
return m_val.is_uint16_type (); }
531 int is_uint32 ()
const {
return m_val.is_uint32_type (); }
533 int is_uint64 ()
const {
return m_val.is_uint64_type (); }
535 int is_uint8 ()
const {
return m_val.is_uint8_type (); }
537 int is_range ()
const {
return m_val.is_range (); }
539 int isreal ()
const {
return m_val.isreal (); }
546 mwSize
get_m ()
const {
return m_val.rows (); }
548 mwSize
get_n ()
const
555 for (mwIndex i = m_ndims - 1; i > 0; i--)
565 m_ndims = m_val.ndims ();
572 for (mwIndex i = 0; i < m_ndims; i++)
594 int isempty ()
const {
return m_val.isempty (); }
601 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
606 m_id = mxUNKNOWN_CLASS;
608 std::string cn = m_val.class_name ();
611 m_id = mxDOUBLE_CLASS;
612 else if (cn ==
"single")
613 m_id = mxSINGLE_CLASS;
614 else if (cn ==
"char")
616 else if (cn ==
"logical")
617 m_id = mxLOGICAL_CLASS;
618 else if (cn ==
"cell")
620 else if (cn ==
"struct")
621 m_id = mxSTRUCT_CLASS;
622 else if (cn ==
"function_handle")
623 m_id = mxFUNCTION_CLASS;
624 else if (cn ==
"int8")
626 else if (cn ==
"uint8")
627 m_id = mxUINT8_CLASS;
628 else if (cn ==
"int16")
629 m_id = mxINT16_CLASS;
630 else if (cn ==
"uint16")
631 m_id = mxUINT16_CLASS;
632 else if (cn ==
"int32")
633 m_id = mxINT32_CLASS;
634 else if (cn ==
"uint32")
635 m_id = mxUINT32_CLASS;
636 else if (cn ==
"int64")
637 m_id = mxINT64_CLASS;
638 else if (cn ==
"uint64")
639 m_id = mxUINT64_CLASS;
648 std::string s = m_val.class_name ();
662 if (m_val.is_classdef_object ())
680 if (m_val.is_classdef_object ())
698 if (m_val.issparse ())
701 const void *m_data = m_val.mex_get_data ();
702 if (m_data ==
nullptr)
705 if (m_val.islogical ())
706 return *
static_cast<const bool *
> (m_data);
707 else if (m_val.isreal ())
708 return *
static_cast<const double *
> (m_data);
710 return *
static_cast<const double *
> (m_data);
713 return m_val.scalar_value (
true);
720 void *retval =
const_cast<void *
> (m_val.mex_get_data ());
724 maybe_mark_foreign (retval);
732 template <
typename T>
733 T *
get_data (mxClassID class_id, mxComplexity complexity)
const
737 void *ptr =
const_cast<void *
> (m_val.mex_get_data (class_id, complexity));
739 T *retval =
static_cast<T *
> (ptr);
743 maybe_mark_foreign (retval);
772 mxDOUBLE_CLASS, mxCOMPLEX);
775 mxDOUBLE_CLASS, mxCOMPLEX);
779 void *retval =
nullptr;
781 if (is_numeric () && isreal ())
814 return static_cast<mwIndex *
> (maybe_mark_foreign (ptr));
822 return static_cast<mwIndex *
> (maybe_mark_foreign (ptr));
825 mwSize
get_nzmax ()
const {
return m_val.nzmax (); }
853 int get_string (
char *buf, mwSize buflen)
const
859 if (m_val.is_string () && nel < buflen)
863 const char *p = tmp.
data ();
865 for (mwIndex i = 0; i < nel; i++)
882 if (m_val.is_string ())
892 const char *p = tmp.
data ();
894 for (mwIndex i = 0; i < nel; i++)
909 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
919 case mxCELL_CLASS:
return sizeof (
mxArray *);
920 case mxSTRUCT_CLASS:
return sizeof (
mxArray *);
921 case mxLOGICAL_CLASS:
return sizeof (mxLogical);
922 case mxCHAR_CLASS:
return sizeof (mxChar);
933 case mxFUNCTION_CLASS:
return 0;
942 void request_mutation ()
const
945 error (
"unexpected: m_mutate_flag is true in mxArray_octave_value::request_mutation - please report this bug");
947 m_mutate_flag =
true;
956 mxArray_octave_value (
const mxArray_octave_value& arg)
957 :
mxArray_base (arg), m_val (arg.m_val), m_mutate_flag (arg.m_mutate_flag),
959 m_ndims (arg.m_ndims),
966 for (mwIndex i = 0; i < m_ndims; i++)
967 m_dims[i] = arg.m_dims[i];
975 mutable bool m_mutate_flag;
981 mutable mxClassID m_id;
982 mutable char *m_class_name;
983 mutable mwSize m_ndims;
984 mutable mwSize *m_dims;
994 mxArray_matlab () =
delete;
1000 mxArray_matlab& operator = (
const mxArray_matlab&) =
delete;
1004 mxFree (m_class_name);
1008 int iscell ()
const {
return m_id == mxCELL_CLASS; }
1010 int is_char ()
const {
return m_id == mxCHAR_CLASS; }
1012 int is_complex ()
const {
return m_is_complex; }
1014 int is_double ()
const {
return m_id == mxDOUBLE_CLASS; }
1018 int is_int16 ()
const {
return m_id == mxINT16_CLASS; }
1020 int is_int32 ()
const {
return m_id == mxINT32_CLASS; }
1022 int is_int64 ()
const {
return m_id == mxINT64_CLASS; }
1024 int is_int8 ()
const {
return m_id == mxINT8_CLASS; }
1026 int is_logical ()
const {
return m_id == mxLOGICAL_CLASS; }
1030 return (m_id == mxDOUBLE_CLASS || m_id == mxSINGLE_CLASS
1031 || m_id == mxINT8_CLASS || m_id == mxUINT8_CLASS
1032 || m_id == mxINT16_CLASS || m_id == mxUINT16_CLASS
1033 || m_id == mxINT32_CLASS || m_id == mxUINT32_CLASS
1034 || m_id == mxINT64_CLASS || m_id == mxUINT64_CLASS);
1037 int is_single ()
const {
return m_id == mxSINGLE_CLASS; }
1041 int is_struct ()
const {
return m_id == mxSTRUCT_CLASS; }
1043 int is_uint16 ()
const {
return m_id == mxUINT16_CLASS; }
1045 int is_uint32 ()
const {
return m_id == mxUINT32_CLASS; }
1047 int is_uint64 ()
const {
return m_id == mxUINT64_CLASS; }
1049 int is_uint8 ()
const {
return m_id == mxUINT8_CLASS; }
1054 &&
static_cast<mxLogical *
> (get_data ())[0] != 0);
1057 mwSize
get_m ()
const {
return m_dims[0]; }
1059 mwSize
get_n ()
const
1063 for (mwSize i = m_ndims - 1 ; i > 0 ; i--)
1073 void set_m (mwSize m) { m_dims[0] = m; }
1075 void set_n (mwSize n) { m_dims[1] = n; }
1086 =
static_cast<mwSize *
> (
mxArray::malloc (m_ndims *
sizeof (mwSize)));
1088 if (m_dims ==
nullptr)
1091 for (
int i = 0; i < m_ndims; i++)
1092 m_dims[i] = dims[i];
1105 mwSize retval = m_dims[0];
1107 for (mwIndex i = 1; i < m_ndims; i++)
1108 retval *= m_dims[i];
1117 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
1126 case mxDOUBLE_CLASS:
return "double";
1127 case mxSINGLE_CLASS:
return "single";
1128 case mxCHAR_CLASS:
return "char";
1129 case mxLOGICAL_CLASS:
return "logical";
1130 case mxCELL_CLASS:
return "cell";
1131 case mxSTRUCT_CLASS:
return "struct";
1132 case mxFUNCTION_CLASS:
return "function_handle";
1133 case mxINT8_CLASS:
return "int8";
1134 case mxUINT8_CLASS:
return "uint8";
1135 case mxINT16_CLASS:
return "int16";
1136 case mxUINT16_CLASS:
return "uint16";
1137 case mxINT32_CLASS:
return "int32";
1138 case mxUINT32_CLASS:
return "uint32";
1139 case mxINT64_CLASS:
return "int64";
1140 case mxUINT64_CLASS:
return "uint64";
1141 case mxUNKNOWN_CLASS:
return "unknown";
1143 default:
return "unknown";
1149 return m_class_name;
1154 mxFree (m_class_name);
1156 strcpy (m_class_name, name);
1314 mwIndex *
get_ir ()
const
1319 mwIndex *
get_jc ()
const
1392 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
1399 case mxCELL_CLASS:
return sizeof (
mxArray *);
1400 case mxSTRUCT_CLASS:
return sizeof (
mxArray *);
1401 case mxLOGICAL_CLASS:
return sizeof (mxLogical);
1402 case mxCHAR_CLASS:
return sizeof (mxChar);
1413 case mxFUNCTION_CLASS:
return 0;
1422 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1423 mwSize ndims,
const mwSize *dims)
1424 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1425 m_is_complex (is_complex), m_ndims (ndims < 2 ? 2 : ndims),
1426 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1439 for (mwIndex i = 0; i < ndims; i++)
1440 m_dims[i] = dims[i];
1442 for (mwIndex i = m_ndims - 1; i > 1; i--)
1451 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1453 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1454 m_is_complex (is_complex), m_ndims (dv.ndims ()),
1455 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1457 for (mwIndex i = 0; i < m_ndims; i++)
1460 for (mwIndex i = m_ndims - 1; i > 1; i--)
1469 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1471 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1472 m_is_complex (is_complex), m_ndims (2),
1473 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1479 mxArray_matlab (
const mxArray_matlab& val)
1481 m_id (val.m_id), m_is_complex (val.m_is_complex), m_ndims (val.m_ndims),
1482 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1484 for (mwIndex i = 0; i < m_ndims; i++)
1485 m_dims[i] = val.m_dims[i];
1488 void set_complexity (
bool is_complex) { m_is_complex = is_complex; }
1491 dims_to_dim_vector ()
const
1493 mwSize nd = get_number_of_dimensions ();
1500 for (mwIndex i = 0; i < nd; i++)
1521class mxArray_base_full :
public mxArray_matlab
1525 mxArray_base_full () =
delete;
1527 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1528 mwSize ndims,
const mwSize *dims,
bool init =
true)
1529 : mxArray_matlab (interleaved, is_complex, id, ndims, dims),
1530 m_pr (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1533 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1535 : mxArray_matlab (interleaved, is_complex, id, dv),
1536 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1539 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1540 mwSize m, mwSize n,
bool init =
true)
1541 : mxArray_matlab (interleaved, is_complex, id, m, n),
1542 m_pr (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1545 mxArray_base_full (
bool interleaved, mxClassID
id,
double val)
1546 : mxArray_matlab (interleaved, false, id, 1, 1),
1547 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1549 double *dpr =
static_cast<double *
> (m_pr);
1553 mxArray_base_full (
bool interleaved, mxClassID
id, mxLogical val)
1554 : mxArray_matlab (interleaved, false, id, 1, 1),
1555 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1557 mxLogical *lpr =
static_cast<mxLogical *
> (m_pr);
1561 mxArray_base_full (
bool interleaved,
const char *str)
1562 : mxArray_matlab (interleaved, false, mxCHAR_CLASS,
1563 str ? (
strlen (str) ? 1 : 0) : 0,
1565 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1567 mxChar *cpr =
static_cast<mxChar *
> (m_pr);
1568 mwSize nel = get_number_of_elements ();
1569 for (mwIndex i = 0; i < nel; i++)
1574 mxArray_base_full (
bool interleaved, mwSize m,
const char **str)
1575 : mxArray_matlab (interleaved, false, mxCHAR_CLASS, m, max_str_len (m, str)),
1576 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1578 mxChar *cpr =
static_cast<mxChar *
> (m_pr);
1584 for (mwIndex j = 0; j < m; j++)
1586 const char *ptr = str[j];
1588 std::size_t tmp_len =
strlen (ptr);
1590 for (std::size_t i = 0; i < tmp_len; i++)
1591 cpr[m*i+j] =
static_cast<mxChar
> (ptr[i]);
1593 for (std::size_t i = tmp_len; i < static_cast<std::size_t> (nc); i++)
1594 cpr[m*i+j] =
static_cast<mxChar
> (
' ');
1601 mxArray_base_full& operator = (
const mxArray_base_full&) =
delete;
1605 return new mxArray_base_full (*
this);
1608 ~mxArray_base_full ()
1613 double get_scalar ()
const
1619 mxClassID
id = get_class_id ();
1623 case mxDOUBLE_CLASS:
1624 retval = *(
static_cast<double *
> (m_pr));
1627 case mxSINGLE_CLASS:
1628 retval = *(
static_cast<float *
> (m_pr));
1632 retval = *(
static_cast<mxChar *
> (m_pr));
1635 case mxLOGICAL_CLASS:
1636 retval = *(
static_cast<bool *
> (m_pr));
1640 retval = *(
static_cast<int8_t *
> (m_pr));
1644 retval = *(
static_cast<uint8_t *
> (m_pr));
1648 retval = *(
static_cast<int16_t *
> (m_pr));
1651 case mxUINT16_CLASS:
1652 retval = *(
static_cast<uint16_t *
> (m_pr));
1656 retval = *(
static_cast<int32_t *
> (m_pr));
1659 case mxUINT32_CLASS:
1660 retval = *(
static_cast<uint32_t *
> (m_pr));
1664 retval = *(
static_cast<int64_t *
> (m_pr));
1667 case mxUINT64_CLASS:
1668 retval = *(
static_cast<uint64_t *
> (m_pr));
1672 case mxFUNCTION_CLASS:
1673 case mxSTRUCT_CLASS:
1674 case mxUNKNOWN_CLASS:
1677 std::string dest_cname = get_class_name (
id);
1678 error (
"invalid conversion from %s mxArray to %s scalar value", get_class_name (), dest_cname.c_str ());
1691 void * get_data ()
const {
return m_pr; }
1693 void set_data (
void *pr) { m_pr = pr; }
1700 mxDouble * get_doubles ()
const
1702 return static_cast<mxDouble *
> (m_pr);
1705 mxSingle * get_singles ()
const
1707 return static_cast<mxSingle *
> (m_pr);
1710 mxInt8 * get_int8s ()
const
1712 return static_cast<mxInt8 *
> (m_pr);
1715 mxInt16 * get_int16s ()
const
1717 return static_cast<mxInt16 *
> (m_pr);
1720 mxInt32 * get_int32s ()
const
1722 return static_cast<mxInt32 *
> (m_pr);
1725 mxInt64 * get_int64s ()
const
1727 return static_cast<mxInt64 *
> (m_pr);
1730 mxUint8 * get_uint8s ()
const
1732 return static_cast<mxUint8 *
> (m_pr);
1735 mxUint16 * get_uint16s ()
const
1737 return static_cast<mxUint16 *
> (m_pr);
1740 mxUint32 * get_uint32s ()
const
1742 return static_cast<mxUint32 *
> (m_pr);
1745 mxUint64 * get_uint64s ()
const
1747 return static_cast<mxUint64 *
> (m_pr);
1750 mxComplexDouble * get_complex_doubles ()
const
1752 return static_cast<mxComplexDouble *
> (m_pr);
1755 mxComplexSingle * get_complex_singles ()
const
1757 return static_cast<mxComplexSingle *
> (m_pr);
1760 int set_doubles (mxDouble *
d)
1766 int set_singles (mxSingle *
d)
1772 int set_int8s (mxInt8 *
d)
1778 int set_int16s (mxInt16 *
d)
1784 int set_int32s (mxInt32 *
d)
1790 int set_int64s (mxInt64 *
d)
1796 int set_uint8s (mxUint8 *
d)
1802 int set_uint16s (mxUint16 *
d)
1808 int set_uint32s (mxUint32 *
d)
1814 int set_uint64s (mxUint64 *
d)
1820 int set_complex_doubles (mxComplexDouble *
d)
1826 int set_complex_singles (mxComplexSingle *
d)
1832 int get_string (
char *buf, mwSize buflen)
const
1836 mwSize nel = get_number_of_elements ();
1838 if (! (nel < buflen))
1847 mxChar *ptr =
static_cast<mxChar *
> (m_pr);
1849 for (mwIndex i = 0; i < nel; i++)
1850 buf[i] =
static_cast<char> (ptr[i]);
1858 char * array_to_string ()
const
1862 mwSize nel = get_number_of_elements ();
1868 mxChar *ptr =
static_cast<mxChar *
> (m_pr);
1870 for (mwIndex i = 0; i < nel; i++)
1871 buf[i] =
static_cast<char> (ptr[i]);
1883 const dim_vector& dv = dims_to_dim_vector ();
1885 switch (get_class_id ())
1887 case mxDOUBLE_CLASS:
1888 return (is_complex ()
1889 ? fp_to_ov<Complex> (dv) : fp_to_ov<
double> (dv));
1891 case mxSINGLE_CLASS:
1892 return (is_complex ()
1893 ? fp_to_ov<FloatComplex> (dv) : fp_to_ov<
float> (dv));
1896 return int_to_ov<mxChar, charNDArray, char> (dv);
1898 case mxLOGICAL_CLASS:
1899 return int_to_ov<mxLogical, boolNDArray, bool> (dv);
1902 return int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
1905 return int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
1908 return int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
1910 case mxUINT16_CLASS:
1911 return int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
1914 return int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
1916 case mxUINT32_CLASS:
1917 return int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
1920 return int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
1922 case mxUINT64_CLASS:
1923 return int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
1926 case mxFUNCTION_CLASS:
1927 case mxSTRUCT_CLASS:
1928 case mxUNKNOWN_CLASS:
1930 error (
"invalid conversion from %s%s mxArray to octave_value", (is_complex () ?
"complex " :
""), get_class_name ());
1944 mxArray_base_full (
const mxArray_base_full& val)
1945 : mxArray_matlab (val),
1946 m_pr (
mxArray::
malloc (get_number_of_elements () * get_element_size ()))
1949 memcpy (m_pr, val.m_pr, get_number_of_elements () * get_element_size ());
1952 template <
typename ELT_T>
1958 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
1960#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
1962 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
1964 octave::unwind_action act ([
this] () { maybe_disown_ptr (m_pr); });
1978 ELT_T *ptr = val.rwdata ();
1980 mwSize nel = get_number_of_elements ();
1982 for (mwIndex i = 0; i < nel; i++)
1990 template <
typename ELT_T,
typename ARRAY_T,
typename ARRAY_ELT_T>
1995 error (
"complex integer types are not supported");
1997 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
2004 ARRAY_ELT_T *ptr = val.rwdata ();
2006 mwSize nel = get_number_of_elements ();
2008 for (mwIndex i = 0; i < nel; i++)
2023class mxArray_interleaved_full :
public mxArray_base_full
2027 mxArray_interleaved_full () =
delete;
2029 mxArray_interleaved_full (mxClassID
id, mwSize ndims,
const mwSize *dims,
2030 mxComplexity flag = mxREAL,
bool init =
true)
2031 : mxArray_base_full (true, flag == mxCOMPLEX, id, ndims, dims, init)
2034 mxArray_interleaved_full (mxClassID
id,
const dim_vector& dv,
2035 mxComplexity flag = mxREAL)
2036 : mxArray_base_full (true, flag == mxCOMPLEX, id, dv)
2039 mxArray_interleaved_full (mxClassID
id, mwSize m, mwSize n,
2040 mxComplexity flag = mxREAL,
bool init =
true)
2041 : mxArray_base_full (true, flag == mxCOMPLEX, id, m, n, init)
2044 mxArray_interleaved_full (mxClassID
id,
double val)
2045 : mxArray_base_full (true, id, val)
2048 mxArray_interleaved_full (mxClassID
id, mxLogical val)
2049 : mxArray_base_full (true, id, val)
2052 mxArray_interleaved_full (
const char *str)
2053 : mxArray_base_full (true, str)
2057 mxArray_interleaved_full (mwSize m,
const char **str)
2058 : mxArray_base_full (true, m, str)
2064 mxArray_interleaved_full& operator = (
const mxArray_interleaved_full&) =
delete;
2068 return new mxArray_interleaved_full (*
this);
2071 ~mxArray_interleaved_full () =
default;
2073 void * get_imag_data ()
const { error_impossible_call (
"mxArray_interleaved_full::get_imag_data"); }
2075 void set_imag_data (
void *) { error_impossible_call (
"mxArray_interleaved_full::set_imag_data"); }
2079 mxArray_interleaved_full (
const mxArray_interleaved_full& val)
2080 : mxArray_base_full (val)
2084class mxArray_separate_full :
public mxArray_base_full
2088 mxArray_separate_full () =
delete;
2090 mxArray_separate_full (mxClassID
id, mwSize ndims,
const mwSize *dims,
2091 mxComplexity flag = mxREAL,
bool init =
true)
2092 : mxArray_base_full (false, flag == mxCOMPLEX, id, ndims, dims, init),
2093 m_pi (flag == mxCOMPLEX
2094 ?
mxArray::alloc (init, get_number_of_elements (), get_element_size ())
2098 mxArray_separate_full (mxClassID
id,
const dim_vector& dv,
2099 mxComplexity flag = mxREAL)
2100 : mxArray_base_full (false, flag == mxCOMPLEX, id, dv),
2102 ?
mxArray::calloc (get_number_of_elements (), get_element_size ())
2106 mxArray_separate_full (mxClassID
id, mwSize m, mwSize n,
2107 mxComplexity flag = mxREAL,
bool init =
true)
2108 : mxArray_base_full (false, flag == mxCOMPLEX, id, m, n, init),
2110 ? (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
2114 mxArray_separate_full (mxClassID
id,
double val)
2115 : mxArray_base_full (false, id, val), m_pi (nullptr)
2118 mxArray_separate_full (mxClassID
id, mxLogical val)
2119 : mxArray_base_full (false, id, val), m_pi (nullptr)
2122 mxArray_separate_full (
const char *str)
2123 : mxArray_base_full (false, str), m_pi (nullptr)
2127 mxArray_separate_full (mwSize m,
const char **str)
2128 : mxArray_base_full (false, m, str), m_pi (nullptr)
2134 mxArray_separate_full& operator = (
const mxArray_separate_full&) =
delete;
2138 return new mxArray_separate_full (*
this);
2141 ~mxArray_separate_full ()
2146 void * get_imag_data ()
const {
return m_pi; }
2148 void set_imag_data (
void *pi)
2152 set_complexity (m_pi !=
nullptr);
2155 mxDouble * get_doubles ()
const { error_impossible_call (
"mxArray_separate_full::get_doubles"); }
2156 mxSingle * get_singles ()
const { error_impossible_call (
"mxArray_separate_full::get_singles"); }
2157 mxInt8 * get_int8s ()
const { error_impossible_call (
"mxArray_separate_full::get_int8s"); }
2158 mxInt16 * get_int16s ()
const { error_impossible_call (
"mxArray_separate_full::get_int16s"); }
2159 mxInt32 * get_int32s ()
const { error_impossible_call (
"mxArray_separate_full::get_int32s"); }
2160 mxInt64 * get_int64s ()
const { error_impossible_call (
"mxArray_separate_full::get_int64s"); }
2161 mxUint8 * get_uint8s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint8s"); }
2162 mxUint16 * get_uint16s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint16s"); }
2163 mxUint32 * get_uint32s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint32s"); }
2164 mxUint64 * get_uint64s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint64s"); }
2166 mxComplexDouble * get_complex_doubles ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_doubles"); }
2167 mxComplexSingle * get_complex_singles ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_singles"); }
2171 mxComplexInt8 * get_complex_int8s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int8s"); }
2172 mxComplexInt16 * get_complex_int16s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int16s"); }
2173 mxComplexInt32 * get_complex_int32s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int32s"); }
2174 mxComplexInt64 * get_complex_int64s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int64s"); }
2175 mxComplexUint8 * get_complex_uint8s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint8s"); }
2176 mxComplexUint16 * get_complex_uint16s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint16s"); }
2177 mxComplexUint32 * get_complex_uint32s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint32s"); }
2178 mxComplexUint64 * get_complex_uint64s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint64s"); }
2180 int set_doubles (mxDouble *) { error_impossible_call (
"mxArray_separate_full::set_doubles"); }
2181 int set_singles (mxSingle *) { error_impossible_call (
"mxArray_separate_full::set_singles"); }
2182 int set_int8s (mxInt8 *) { error_impossible_call (
"mxArray_separate_full::set_int8s"); }
2183 int set_int16s (mxInt16 *) { error_impossible_call (
"mxArray_separate_full::set_int16s"); }
2184 int set_int32s (mxInt32 *) { error_impossible_call (
"mxArray_separate_full::set_int32s"); }
2185 int set_int64s (mxInt64 *) { error_impossible_call (
"mxArray_separate_full::set_int64s"); }
2186 int set_uint8s (mxUint8 *) { error_impossible_call (
"mxArray_separate_full::set_uint8s"); }
2187 int set_uint16s (mxUint16 *) { error_impossible_call (
"mxArray_separate_full::set_uint16s"); }
2188 int set_uint32s (mxUint32 *) { error_impossible_call (
"mxArray_separate_full::set_uint32s"); }
2189 int set_uint64s (mxUint64 *) { error_impossible_call (
"mxArray_separate_full::set_uint64s"); }
2191 int set_complex_doubles (mxComplexDouble *) { error_impossible_call (
"mxArray_separate_full::set_complex_doubles"); }
2192 int set_complex_singles (mxComplexSingle *) { error_impossible_call (
"mxArray_separate_full::set_complex_singles"); }
2196 int set_complex_int8s (mxComplexInt8 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int8s"); }
2197 int set_complex_int16s (mxComplexInt16 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int16s"); }
2198 int set_complex_int32s (mxComplexInt32 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int32s"); }
2199 int set_complex_int64s (mxComplexInt64 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int64s"); }
2200 int set_complex_uint8s (mxComplexUint8 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint8s"); }
2201 int set_complex_uint16s (mxComplexUint16 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint16s"); }
2202 int set_complex_uint32s (mxComplexUint32 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint32s"); }
2203 int set_complex_uint64s (mxComplexUint64 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint64s"); }
2207 if (! is_complex ())
2208 return mxArray_base_full::as_octave_value ();
2212 const dim_vector& dv = dims_to_dim_vector ();
2214 switch (get_class_id ())
2216 case mxDOUBLE_CLASS:
2217 return to_ov<double> (dv);
2219 case mxSINGLE_CLASS:
2220 return to_ov<float> (dv);
2222 case mxLOGICAL_CLASS:
2226 case mxUINT16_CLASS:
2228 case mxUINT32_CLASS:
2230 case mxUINT64_CLASS:
2231 error (
"complex integer types are not supported");
2235 case mxFUNCTION_CLASS:
2236 case mxSTRUCT_CLASS:
2237 case mxUNKNOWN_CLASS:
2239 error (
"invalid conversion from complex %s mxArray to octave_value", get_class_name ());
2253 mxArray_separate_full (
const mxArray_separate_full& val)
2254 : mxArray_base_full (val),
2256 ?
mxArray::
malloc (get_number_of_elements () * get_element_size ())
2260 memcpy (m_pi, val.m_pi, get_number_of_elements () * get_element_size ());
2265 template <
typename T>
2269 mwSize nel = get_number_of_elements ();
2271 T *ppr =
static_cast<T *
> (m_pr);
2278 std::complex<T> *ptr = val.rwdata ();
2280 T *ppi =
static_cast<T *
> (m_pi);
2282 for (mwIndex i = 0; i < nel; i++)
2283 ptr[i] = std::complex<T> (ppr[i], ppi[i]);
2294class mxArray_base_sparse :
public mxArray_matlab
2298 mxArray_base_sparse () =
delete;
2300 mxArray_base_sparse (
bool interleaved,
bool is_complex,
2301 mxClassID
id, mwSize m, mwSize n, mwSize nzmax)
2302 : mxArray_matlab (interleaved, is_complex, id, m, n),
2304 m_nzmax (nzmax > 0 ? nzmax : 1),
2305 m_ir (static_cast<mwIndex *> (
mxArray::calloc (m_nzmax, sizeof (mwIndex)))),
2306 m_jc (static_cast<mwIndex *> (
mxArray::calloc (n + 1, sizeof (mwIndex)))),
2307 m_pr (
mxArray::calloc (m_nzmax, get_element_size ()))
2312 mxArray_base_sparse (
const mxArray_base_sparse& val)
2313 : mxArray_matlab (val), m_nzmax (val.m_nzmax),
2314 m_ir (static_cast<mwIndex *> (
mxArray::
malloc (m_nzmax * sizeof (mwIndex)))),
2315 m_jc (static_cast<mwIndex *> (
mxArray::
malloc (m_nzmax * sizeof (mwIndex)))),
2319 memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex));
2322 memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex));
2325 memcpy (m_pr, val.m_pr, m_nzmax * get_element_size ());
2333 mxArray_base_sparse& operator = (
const mxArray_base_sparse&) =
delete;
2337 return new mxArray_base_sparse (*
this);
2340 ~mxArray_base_sparse ()
2347 int is_sparse ()
const {
return 1; }
2349 void * get_data ()
const {
return m_pr; }
2351 void set_data (
void *pr) { m_pr = pr; }
2353 mxDouble * get_doubles ()
const
2355 return static_cast<mxDouble *
> (m_pr);
2358 mxComplexDouble * get_complex_doubles ()
const
2360 return static_cast<mxComplexDouble *
> (m_pr);
2363 int set_doubles (mxDouble *
d)
2369 int set_complex_doubles (mxComplexDouble *
d)
2375 mwIndex * get_ir ()
const {
return m_ir; }
2377 mwIndex * get_jc ()
const {
return m_jc; }
2379 mwSize get_nzmax ()
const {
return m_nzmax; }
2381 void set_ir (mwIndex *ir) { m_ir = ir; }
2383 void set_jc (mwIndex *jc) { m_jc = jc; }
2385 void set_nzmax (mwSize nzmax)
2388 m_nzmax = (nzmax > 0 ? nzmax : 1);
2395 const dim_vector& dv = dims_to_dim_vector ();
2397 switch (get_class_id ())
2399 case mxDOUBLE_CLASS:
2400 return is_complex () ? to_ov<Complex> (dv):
to_ov<
double> (dv);
2402 case mxSINGLE_CLASS:
2403 error (
"single precision sparse data type not supported");
2405 case mxLOGICAL_CLASS:
2406 return to_ov<bool> (dv);
2411 case mxUINT16_CLASS:
2413 case mxUINT32_CLASS:
2415 case mxUINT64_CLASS:
2418 case mxFUNCTION_CLASS:
2419 case mxSTRUCT_CLASS:
2420 case mxUNKNOWN_CLASS:
2422 error (
"invalid conversion from %s%s sparse mxArray to octave_value", (is_complex () ?
"complex " :
""), get_class_name ());
2436 template <
typename ELT_T>
2440 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
2442#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
2444 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
2446 octave::unwind_action act ([
this] ()
2448 maybe_disown_ptr (m_pr);
2449 maybe_disown_ptr (m_ir);
2450 maybe_disown_ptr (m_jc);
2455 ppr, m_ir, m_jc, current_mx_memory_resource));
2460 ppr, m_ir, m_jc, current_mx_memory_resource));
2471 for (mwIndex i = 0; i < m_nzmax; i++)
2473 val.xdata (i) = ppr[i];
2474 val.xridx (i) = m_ir[i];
2477 for (mwIndex i = 0; i < n + 1; i++)
2478 val.xcidx (i) = m_jc[i];
2498class mxArray_interleaved_sparse :
public mxArray_base_sparse
2502 mxArray_interleaved_sparse () =
delete;
2504 mxArray_interleaved_sparse (mxClassID
id, mwSize m, mwSize n, mwSize nzmax,
2505 mxComplexity flag = mxREAL)
2506 : mxArray_base_sparse (true, flag == mxCOMPLEX, id, m, n, nzmax)
2511 mxArray_interleaved_sparse (
const mxArray_interleaved_sparse& val)
2512 : mxArray_base_sparse (val)
2520 mxArray_interleaved_sparse& operator = (
const mxArray_interleaved_sparse&) =
delete;
2524 return new mxArray_interleaved_sparse (*
this);
2527 ~mxArray_interleaved_sparse () =
default;
2529 void * get_imag_data ()
const { error_impossible_call (
"mxArray_interleaved_sparse::get_imag_data"); }
2531 void set_imag_data (
void *) { error_impossible_call (
"mxArray_interleaved_sparse::set_imag_data"); }
2534class mxArray_separate_sparse :
public mxArray_base_sparse
2538 mxArray_separate_sparse () =
delete;
2540 mxArray_separate_sparse (mxClassID
id, mwSize m, mwSize n, mwSize nzmax,
2541 mxComplexity flag = mxREAL)
2542 : mxArray_base_sparse (false, flag == mxCOMPLEX, id, m, n, nzmax),
2544 ?
mxArray::calloc (m_nzmax, get_element_size ())
2550 mxArray_separate_sparse (
const mxArray_separate_sparse& val)
2551 : mxArray_base_sparse (val),
2557 memcpy (m_pi, val.m_pi, m_nzmax * get_element_size ());
2565 mxArray_separate_sparse& operator = (
const mxArray_separate_sparse&) =
delete;
2569 return new mxArray_separate_sparse (*
this);
2572 ~mxArray_separate_sparse ()
2577 void * get_imag_data ()
const {
return m_pi; }
2579 void set_imag_data (
void *pi)
2582 set_complexity (m_pi !=
nullptr);
2585 mxDouble * get_doubles ()
const { error_impossible_call (
"mxArray_separate_sparse::get_doubles"); }
2586 mxComplexDouble * get_complex_doubles ()
const { error_impossible_call (
"mxArray_separate_sparse::get_complex_doubles"); }
2588 int set_doubles (mxDouble *) { error_impossible_call (
"mxArray_separate_sparse::set_doubles"); }
2589 int set_complex_doubles (mxComplexDouble *) { error_impossible_call (
"mxArray_separate_sparse::set_complex_doubles"); }
2593 if (! is_complex ())
2594 return mxArray_base_sparse::as_octave_value ();
2598 switch (get_class_id ())
2600 case mxDOUBLE_CLASS:
2602 double *ppr =
static_cast<double *
> (m_pr);
2603 double *ppi =
static_cast<double *
> (m_pi);
2608 for (mwIndex i = 0; i < m_nzmax; i++)
2610 val.xdata (i) =
Complex (ppr[i], ppi[i]);
2611 val.xridx (i) = m_ir[i];
2614 for (mwIndex i = 0; i < get_n () + 1; i++)
2615 val.xcidx (i) = m_jc[i];
2621 case mxSINGLE_CLASS:
2622 error (
"single precision sparse data type not supported");
2624 case mxLOGICAL_CLASS:
2628 case mxUINT16_CLASS:
2630 case mxUINT32_CLASS:
2632 case mxUINT64_CLASS:
2635 case mxFUNCTION_CLASS:
2636 case mxSTRUCT_CLASS:
2637 case mxUNKNOWN_CLASS:
2639 error (
"invalid conversion from complex %s sparse mxArray to octave_value", get_class_name ());
2659class mxArray_struct :
public mxArray_matlab
2663 mxArray_struct () =
delete;
2665 mxArray_struct (
bool interleaved, mwSize ndims,
const mwSize *dims,
2666 int num_keys,
const char **keys)
2667 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, ndims, dims),
2668 m_nfields (num_keys),
2669 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2672 get_number_of_elements (),
2678 mxArray_struct (
bool interleaved,
const dim_vector& dv,
int num_keys,
2680 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, dv),
2681 m_nfields (num_keys),
2682 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2685 get_number_of_elements (),
2691 mxArray_struct (
bool interleaved, mwSize m, mwSize n,
int num_keys,
2693 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, m, n),
2694 m_nfields (num_keys),
2695 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2698 get_number_of_elements (),
2706 mxArray_struct (
const mxArray_struct& val)
2707 : mxArray_matlab (val), m_nfields (val.m_nfields),
2709 * sizeof (char *)))),
2711 get_number_of_elements ()
2714 for (
int i = 0; i < m_nfields; i++)
2717 mwSize nel = get_number_of_elements ();
2719 for (mwIndex i = 0; i < nel * m_nfields; i++)
2722 m_data[i] = (ptr ? ptr->
dup () :
nullptr);
2731 mxArray_struct& operator = (
const mxArray_struct& val) =
delete;
2733 void init (
const char **keys)
2735 for (
int i = 0; i < m_nfields; i++)
2739 mxArray_base * dup ()
const {
return new mxArray_struct (*
this); }
2743 for (
int i = 0; i < m_nfields; i++)
2744 mxFree (m_fields[i]);
2748 mwSize ntot = m_nfields * get_number_of_elements ();
2750 for (mwIndex i = 0; i < ntot; i++)
2756 int add_field (
const char *key)
2762 m_fields =
static_cast<char **
>
2763 (mxRealloc (m_fields, m_nfields *
sizeof (
char *)));
2769 mwSize nel = get_number_of_elements ();
2771 mwSize ntot = m_nfields * nel;
2774 new_data =
static_cast<mxArray **
>
2783 for (mwIndex i = 0; i < ntot; i++)
2785 if (++n == m_nfields)
2787 new_data[j++] =
nullptr;
2791 new_data[j++] = m_data[k++];
2798 retval = m_nfields - 1;
2805 void remove_field (
int key_num)
2807 if (key_num >= 0 && key_num < m_nfields)
2809 mwSize nel = get_number_of_elements ();
2811 mwSize ntot = m_nfields * nel;
2813 int new_nfields = m_nfields - 1;
2815 char **new_fields =
static_cast<char **
>
2822 for (
int i = 0; i < key_num; i++)
2823 new_fields[i] = m_fields[i];
2825 for (
int i = key_num + 1; i < m_nfields; i++)
2826 new_fields[i-1] = m_fields[i];
2828 if (new_nfields > 0)
2834 for (mwIndex i = 0; i < ntot; i++)
2839 new_data[j++] = m_data[k++];
2841 if (++n == m_nfields)
2846 m_nfields = new_nfields;
2851 m_fields = new_fields;
2856 mxArray * get_field_by_number (mwIndex index,
int key_num)
const
2858 return key_num >= 0 && key_num < m_nfields
2859 ? m_data[m_nfields * index + key_num] :
nullptr;
2862 void set_field_by_number (mwIndex index,
int key_num,
mxArray *val);
2864 int get_number_of_fields ()
const {
return m_nfields; }
2866 const char * get_field_name_by_number (
int key_num)
const
2868 return key_num >= 0 && key_num < m_nfields ? m_fields[key_num] :
nullptr;
2871 int get_field_number (
const char *key)
const
2875 for (
int i = 0; i < m_nfields; i++)
2877 if (!
strcmp (key, m_fields[i]))
2887 void * get_data ()
const {
return m_data; }
2889 void set_data (
void *data) { m_data =
static_cast<mxArray **
> (data); }
2893 const dim_vector& dv = dims_to_dim_vector ();
2899 mwSize ntot = m_nfields * get_number_of_elements ();
2901 for (
int i = 0; i < m_nfields; i++)
2908 for (mwIndex j = i; j < ntot; j += m_nfields)
2911 m.assign (keys[i], c);
2928class mxArray_cell :
public mxArray_matlab
2932 mxArray_cell () =
delete;
2934 mxArray_cell (
bool interleaved, mwSize ndims,
const mwSize *dims)
2935 : mxArray_matlab (interleaved, false, mxCELL_CLASS, ndims, dims),
2939 mxArray_cell (
bool interleaved,
const dim_vector& dv)
2940 : mxArray_matlab (interleaved, false, mxCELL_CLASS, dv),
2944 mxArray_cell (
bool interleaved, mwSize m, mwSize n)
2945 : mxArray_matlab (interleaved, false, mxCELL_CLASS, m, n),
2951 mxArray_cell (
const mxArray_cell& val)
2952 : mxArray_matlab (val),
2955 mwSize nel = get_number_of_elements ();
2957 for (mwIndex i = 0; i < nel; i++)
2960 m_data[i] = (ptr ? ptr->
dup () :
nullptr);
2969 mxArray_cell& operator = (
const mxArray_cell&) =
delete;
2971 mxArray_base * dup ()
const {
return new mxArray_cell (*
this); }
2975 mwSize nel = get_number_of_elements ();
2977 for (mwIndex i = 0; i < nel; i++)
2983 mxArray * get_cell (mwIndex idx)
const
2985 return idx >= 0 && idx < get_number_of_elements () ? m_data[idx] :
nullptr;
2988 void set_cell (mwIndex idx,
mxArray *val);
2990 void * get_data ()
const {
return m_data; }
2992 void set_data (
void *data) { m_data =
static_cast<mxArray **
> (data); }
2996 const dim_vector& dv = dims_to_dim_vector ();
3000 mwSize nel = get_number_of_elements ();
3004 for (mwIndex i = 0; i < nel; i++)
3018 : m_rep (create_rep (interleaved, ov)), m_name (nullptr)
3022 const mwSize *dims, mxComplexity flag,
bool init)
3023 : m_rep (create_rep (interleaved, id, ndims, dims, flag, init)),
3029 : m_rep (create_rep (interleaved, id, dv, flag)), m_name (nullptr)
3033 mxComplexity flag,
bool init)
3034 : m_rep (create_rep (interleaved, id, m, n, flag, init)), m_name (nullptr)
3038 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3042 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3046 : m_rep (create_rep (interleaved, str)), m_name (nullptr)
3050 : m_rep (create_rep (interleaved, m, str)), m_name (nullptr)
3054 mwSize nzmax, mxComplexity flag)
3055 : m_rep (create_rep (interleaved, id, m, n, nzmax, flag)), m_name (nullptr)
3061 : m_rep (new mxArray_struct (interleaved, ndims, dims, num_keys, keys)),
3067 : m_rep (new mxArray_struct (interleaved, dv, num_keys, keys)),
3073 : m_rep (new mxArray_struct (interleaved, m, n, num_keys, keys)),
3078 : m_rep (new mxArray_cell (interleaved, ndims, dims)), m_name (nullptr)
3082 : m_rep (new mxArray_cell (interleaved, dv)), m_name (nullptr)
3086 : m_rep (new mxArray_cell (interleaved, m, n)), m_name (nullptr)
3120mxArray::create_rep (
bool interleaved,
const octave_value& ov)
3122 return new mxArray_octave_value (interleaved, ov);
3126mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize ndims,
3127 const mwSize *dims, mxComplexity flag,
bool init)
3130 return new mxArray_interleaved_full (
id, ndims, dims, flag, init);
3132 return new mxArray_separate_full (
id, ndims, dims, flag, init);
3136mxArray::create_rep (
bool interleaved, mxClassID
id,
const dim_vector& dv,
3140 return new mxArray_interleaved_full (
id, dv, flag);
3142 return new mxArray_separate_full (
id, dv, flag);
3146mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize m, mwSize n,
3147 mxComplexity flag,
bool init)
3150 return new mxArray_interleaved_full (
id, m, n, flag, init);
3152 return new mxArray_separate_full (
id, m, n, flag, init);
3156mxArray::create_rep (
bool interleaved, mxClassID
id,
double val)
3159 return new mxArray_interleaved_full (
id, val);
3161 return new mxArray_separate_full (
id, val);
3165mxArray::create_rep (
bool interleaved, mxClassID
id, mxLogical val)
3168 return new mxArray_interleaved_full (
id, val);
3170 return new mxArray_separate_full (
id, val);
3174mxArray::create_rep (
bool interleaved,
const char *str)
3177 return new mxArray_interleaved_full (str);
3179 return new mxArray_separate_full (str);
3183mxArray::create_rep (
bool interleaved, mwSize m,
const char **str)
3186 return new mxArray_interleaved_full (m, str);
3188 return new mxArray_separate_full (m, str);
3192mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize m, mwSize n,
3193 mwSize nzmax, mxComplexity flag)
3196 return new mxArray_interleaved_sparse (
id, m, n, nzmax, flag);
3198 return new mxArray_separate_sparse (
id, m, n, nzmax, flag);
3202mxArray::maybe_mutate ()
const
3215 m_rep = new_val->m_rep;
3216 new_val->m_rep =
nullptr;
3230 while (! m_memlist.empty ())
3232 auto p = m_memlist.begin ();
3234 m_memlist.erase (p);
3238 while (! m_arraylist.empty ())
3240 auto p = m_arraylist.begin ();
3242 m_arraylist.erase (p);
3245 if (! (m_memlist.empty () && m_arraylist.empty ()))
3256 octave::tree_evaluator& tw = octave::__get_evaluator__ ();
3262 std::string nm = fcn->
name ();
3276 void *ptr = xmalloc (n);
3281 error (
"%s: failed to allocate %zd bytes of memory",
3300 auto p_local = m_memlist.find (ptr);
3301 auto p_global = s_global_memlist.find (ptr);
3303 v = xrealloc (ptr, n);
3307 if (p_local != m_memlist.end ())
3309 m_memlist.erase (p_local);
3310 m_memlist.insert (v);
3313 if (p_global != s_global_memlist.end ())
3315 s_global_memlist.erase (p_global);
3316 s_global_memlist.insert (v);
3333 auto p = s_global_memlist.find (ptr);
3335 if (p != s_global_memlist.end ())
3337 s_global_memlist.erase (p);
3343 p = m_foreign_memlist.find (ptr);
3345 if (p != m_foreign_memlist.end ())
3346 m_foreign_memlist.erase (p);
3349 warning (
"mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
3356std::set<void *> mex::s_global_memlist;
3361void * mxRealloc (
void *ptr, std::size_t size)
3367void mxFree (
void *ptr)
3394maybe_mark_foreign (
void *ptr)
3402#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
3405maybe_disown_ptr (
void *ptr)
3418maybe_unmark_array (
mxArray *ptr)
3426template <
typename T>
3428maybe_unmark (T *ptr)
3437mxArray_struct::set_field_by_number (mwIndex index,
int key_num,
mxArray *val)
3439 if (key_num >= 0 && key_num < m_nfields)
3440 m_data[m_nfields * index + key_num] = maybe_unmark_array (val);
3444mxArray_cell::set_cell (mwIndex idx,
mxArray *val)
3446 if (idx >= 0 && idx < get_number_of_elements ())
3447 m_data[idx] = maybe_unmark_array (val);
3454 int nrhs,
const mxArray *prhs[]);
3470 int nargout = nargout_arg;
3472 int nargin = args.
length ();
3474 for (
int i = 0; i < nargin; i++)
3477 int nout = (nargout == 0 ? 1 : nargout);
3479 for (
int i = 0; i < nout; i++)
3480 argout[i] =
nullptr;
3483 octave::unwind_protect_var<mex *> restore_var (
mex_context);
3485 mex context (mex_fcn);
3487 for (
int i = 0; i < nargin; i++)
3498 F77_INT tmp_nargout = nargout;
3501 fcn (tmp_nargout, argout, tmp_nargin, argin);
3507 fcn (nargout, argout, nargin,
const_cast<const mxArray **
> (argin));
3514 if (nargout == 0 && argout[0])
3526 for (
int i = 0; i < nargout; i++)
3532OCTAVE_END_NAMESPACE(octave)
octave_value to_ov(const cdef_object &obj)
N Dimensional Array with copy-on-write semantics.
const T * data() const
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
void resize(int n, int fill_value=0)
void unmark_array(mxArray *ptr)
mxArray * make_value(const octave_value &ov)
void * malloc(std::size_t n)
void * malloc_unmarked(std::size_t n)
void global_unmark(void *ptr)
void * realloc(void *ptr, std::size_t n)
void global_mark(void *ptr)
void mark_foreign(void *ptr)
const char * function_name() const
void * calloc_unmarked(std::size_t n, std::size_t t)
virtual int set_int8s(mxInt8 *data)=0
virtual int set_complex_singles(mxComplexSingle *data)=0
OCTAVE_NORETURN void err_invalid_type(const char *op) const
virtual mxArray * as_mxArray() const
virtual bool is_octave_value() const
virtual void set_n(mwSize n)=0
virtual void set_cell(mwIndex idx, mxArray *val)=0
virtual int add_field(const char *key)=0
virtual mxInt64 * get_int64s() const =0
virtual mxUint32 * get_uint32s() const =0
virtual void set_nzmax(mwSize nzmax)=0
virtual int set_uint16s(mxUint16 *data)=0
virtual int is_logical() const =0
virtual int is_uint64() const =0
virtual int set_uint64s(mxUint64 *data)=0
virtual int get_string(char *buf, mwSize buflen) const =0
virtual bool is_scalar() const =0
virtual mwIndex calc_single_subscript(mwSize nsubs, mwIndex *subs) const =0
virtual mxArray * get_property(mwIndex, const char *) const
virtual int set_doubles(mxDouble *data)=0
virtual int set_int64s(mxInt64 *data)=0
virtual int is_complex() const =0
virtual octave_value as_octave_value() const =0
virtual mxDouble * get_doubles() const =0
virtual void set_imag_data(void *pi)=0
virtual int is_numeric() const =0
virtual mxArray * get_field_by_number(mwIndex index, int key_num) const =0
virtual int set_int16s(mxInt16 *data)=0
virtual int is_double() const =0
virtual int set_singles(mxSingle *data)=0
virtual int is_char() const =0
virtual void * get_imag_data() const =0
virtual void set_m(mwSize m)=0
virtual void set_data(void *pr)=0
virtual int is_logical_scalar_true() const =0
virtual mxComplexSingle * get_complex_singles() const =0
virtual int is_uint16() const =0
virtual double get_scalar() const =0
virtual mxInt16 * get_int16s() const =0
virtual mxInt8 * get_int8s() const =0
virtual mwSize get_nzmax() const =0
virtual const char * get_field_name_by_number(int key_num) const =0
std::size_t get_numeric_element_size(std::size_t size) const
virtual int iscell() const =0
virtual void set_property(mwIndex, const char *, const mxArray *)
virtual int set_complex_doubles(mxComplexDouble *data)=0
virtual int isempty() const =0
virtual mwSize get_number_of_elements() const =0
virtual mxUint8 * get_uint8s() const =0
virtual int is_logical_scalar() const
virtual void set_jc(mwIndex *jc)=0
virtual std::size_t get_element_size() const =0
virtual int set_uint32s(mxUint32 *data)=0
virtual int set_uint8s(mxUint8 *data)=0
virtual bool mutation_needed() const
virtual mxArray * mutate() const
virtual int set_dimensions(mwSize *dims_arg, mwSize ndims_arg)=0
virtual int is_int16() const =0
virtual int is_single() const =0
virtual void set_class_name(const char *name_arg)=0
virtual mxUint16 * get_uint16s() const =0
virtual mwSize * get_dimensions() const =0
virtual mxArray_base * dup() const =0
virtual mxInt32 * get_int32s() const =0
virtual mwSize get_number_of_dimensions() const =0
virtual int is_function_handle() const =0
virtual int is_uint8() const =0
virtual mxComplexDouble * get_complex_doubles() const =0
virtual mwSize get_m() const =0
virtual int is_int8() const =0
virtual char * array_to_string() const =0
virtual void * get_data() const =0
virtual int is_int32() const =0
virtual int get_number_of_fields() const =0
virtual void set_ir(mwIndex *ir)=0
virtual mxSingle * get_singles() const =0
virtual void remove_field(int key_num)=0
virtual int is_uint32() const =0
virtual mwIndex * get_jc() const =0
virtual mwIndex * get_ir() const =0
virtual int is_int64() const =0
virtual void set_field_by_number(mwIndex index, int key_num, mxArray *val)=0
virtual int is_struct() const =0
virtual int get_field_number(const char *key) const =0
virtual const char * get_class_name() const =0
virtual mwSize get_n() const =0
virtual mxArray * get_cell(mwIndex) const
virtual mxUint64 * get_uint64s() const =0
virtual int set_int32s(mxInt32 *data)=0
virtual int is_sparse() const =0
virtual mxClassID get_class_id() const =0
void set_name(const char *name)
static void * alloc(bool init, std::size_t n, std::size_t t)
static char * strsave(const char *str)
int set_dimensions(mwSize *dims_arg, mwSize ndims_arg)
static void * calloc(std::size_t n, std::size_t t)
mxArray(bool interleaved, const octave_value &ov)
static octave_value as_octave_value(const mxArray *ptr, bool null_is_empty=true)
const char * get_name() const
octave_value as_octave_value() const
mwSize * get_dimensions() const
void set_class_name(const char *name_arg)
static void * malloc(std::size_t n)
octave_classdef * classdef_object_value(bool=false)
octave_value get_property(octave_idx_type idx, const std::string &name) const
void set_property(octave_idx_type idx, const std::string &name, const octave_value &pval)
void * mex_fcn_ptr() const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_idx_type length() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
void error(const char *fmt,...)
octave_f77_int_type F77_INT
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
char * strsave(const char *s)
void(* cmex_fptr)(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
#define CONST_MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL)
int mexSet_impl(double handle, const char *property, mxArray *val)
int mexPutVariable_impl(const char *space, const char *name, const mxArray *ptr)
void mexErrMsgTxt_impl(const char *who, const char *s)
octave_value_list call_mex(octave_mex_function &mex_fcn, const octave_value_list &args, int nargout_arg)
F77_RET_T(* fmex_fptr)(F77_INT &nlhs, mxArray **plhs, F77_INT &nrhs, mxArray **prhs)
#define GET_DATA_METHOD(RT, FCN_NAME, ID, COMPLEXITY)
octave_value_list mx_to_ov_args(int nargin, mxArray *argin[])
#define VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST)
#define MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL)
std::complex< double > Complex
std::complex< float > FloatComplex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
T::size_type strlen(const typename T::value_type *str)
bool strcmp(const T &str_a, const T &str_b)
Octave string utility functions.
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)