26#if defined (HAVE_CONFIG_H)
39#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
40# include <memory_resource>
45#if defined (OCTAVE_MXARRAY_DEBUG)
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);
81#if defined (OCTAVE_MXARRAY_DEBUG)
82 std::cerr <<
"xmalloc (" << n <<
") = " << ptr << std::endl;
89xrealloc (
void *ptr,
size_t n)
91 void *newptr = std::realloc (ptr, n);
93#if defined (OCTAVE_MXARRAY_DEBUG)
94 std::cerr <<
"xrealloc (" << ptr <<
", " << n <<
") = " << newptr << std::endl;
103#if defined (OCTAVE_MXARRAY_DEBUG)
104 std::cerr <<
"xfree (" << ptr <<
")" << std::endl;
111max_str_len (mwSize m,
const char **str)
115 for (mwSize i = 0; i < m; i++)
117 mwSize tmp =
strlen (str[i]);
126static void * mxRealloc (
void *ptr, std::size_t size);
128static void mxFree (
void *ptr);
136 static const bool is_complex =
false;
143 static const bool is_complex =
true;
150 static const bool is_complex =
true;
153#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
155class mx_deleting_memory_resource :
public std::pmr::memory_resource
159 void * do_allocate (std::size_t bytes,
size_t )
161 void *ptr = xmalloc (bytes);
164 throw std::bad_alloc ();
169 void do_deallocate (
void *ptr, std::size_t ,
175 bool do_is_equal (
const std::pmr::memory_resource& other)
const noexcept
177 return this ==
dynamic_cast<const mx_deleting_memory_resource *
> (&other);
181class mx_preserving_memory_resource :
public std::pmr::memory_resource
185 void * do_allocate (std::size_t bytes,
size_t )
187 void *ptr = xmalloc (bytes);
190 throw std::bad_alloc ();
195 void do_deallocate (
void * , std::size_t ,
199 bool do_is_equal (
const std::pmr::memory_resource& other)
const noexcept
201 return this ==
dynamic_cast<const mx_preserving_memory_resource *
> (&other);
207static mx_deleting_memory_resource the_mx_deleting_memory_resource;
208OCTINTERP_API mx_preserving_memory_resource the_mx_preserving_memory_resource;
210OCTINTERP_API std::pmr::memory_resource *current_mx_memory_resource = &the_mx_deleting_memory_resource;
225#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
232 octave::unwind_protect_var<std::pmr::memory_resource *>
233 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
237 for (
int i = 0; i < nargin; i++)
250 if (s[
len - 1] ==
'\n')
252 std::string s_tmp (s,
len - 1);
253 error (
"%s: %s\n", who, s_tmp.c_str ());
256 error (
"%s: %s", who, s);
278 if (! name || name[0] ==
'\0')
281 octave::interpreter& interp = octave::__get_interpreter__ ();
283 if (!
strcmp (space,
"global"))
285#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
292 octave::unwind_protect_var<std::pmr::memory_resource *>
293 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
302 octave::unwind_protect frame;
304 bool caller = !
strcmp (space,
"caller");
305 bool base = !
strcmp (space,
"base");
314 octave::tree_evaluator& tw = interp.get_evaluator ();
316 frame.add (&octave::tree_evaluator::restore_frame, &tw,
317 tw.current_call_stack_frame_number ());
319 tw.goto_base_frame ();
322#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
329 octave::unwind_protect_var<std::pmr::memory_resource *>
330 upv (current_mx_memory_resource,
331 &the_mx_preserving_memory_resource);
338 "symbol table does not exist");
347#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
354 octave::unwind_protect_var<std::pmr::memory_resource *>
355 upv (current_mx_memory_resource, &the_mx_preserving_memory_resource);
359 bool ret = octave::set_property_in_handle (handle, property,
362 return (ret ? 0 : 1);
368 : m_interleaved (interleaved)
372calc_single_subscript_internal (mwSize ndims,
const mwSize *dims,
373 mwSize nsubs,
const mwIndex *subs)
390 mwSize n = (nsubs <= ndims ? nsubs : ndims);
395 retval = dims[n] * retval + subs[n];
414static inline void *maybe_mark_foreign (
void *ptr);
416#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
417static inline void maybe_disown_ptr (
void *ptr);
420#define VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
421 void FCN_NAME ARG_LIST { request_mutation (); }
423#define CONST_VOID_MUTATION_METHOD(FCN_NAME, ARG_LIST) \
424 void FCN_NAME ARG_LIST const { request_mutation (); }
426#define MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
427 RET_TYPE FCN_NAME ARG_LIST { request_mutation (); return RET_VAL; }
429#define CONST_MUTATION_METHOD(RET_TYPE, FCN_NAME, ARG_LIST, RET_VAL) \
430 RET_TYPE FCN_NAME ARG_LIST const { request_mutation (); return RET_VAL; }
432#define GET_DATA_METHOD(RT, FCN_NAME, ID, COMPLEXITY) \
433 RT * FCN_NAME () const { return get_data<RT> (ID, COMPLEXITY); }
439 mxArray_octave_value () =
delete;
441 mxArray_octave_value (
bool interleaved,
const octave_value& ov)
442 :
mxArray_base (interleaved), m_val (ov), m_mutate_flag (
false),
443 m_id (mxUNKNOWN_CLASS), m_class_name (
nullptr), m_ndims (-1),
450 mxArray_octave_value& operator = (
const mxArray_octave_value&) =
delete;
452 mxArray_base *
dup ()
const {
return new mxArray_octave_value (*
this); }
474 m_class_name =
nullptr;
492 ~mxArray_octave_value ()
494 mxFree (m_class_name);
500 int iscell ()
const {
return m_val.iscell (); }
502 int is_char ()
const {
return m_val.is_string (); }
504 int is_complex ()
const {
return m_val.iscomplex (); }
506 int is_double ()
const {
return m_val.is_double_type (); }
510 int is_int16 ()
const {
return m_val.is_int16_type (); }
512 int is_int32 ()
const {
return m_val.is_int32_type (); }
514 int is_int64 ()
const {
return m_val.is_int64_type (); }
516 int is_int8 ()
const {
return m_val.is_int8_type (); }
518 int is_logical ()
const {
return m_val.islogical (); }
520 int is_numeric ()
const {
return m_val.isnumeric (); }
522 int is_single ()
const {
return m_val.is_single_type (); }
524 int is_sparse ()
const {
return m_val.issparse (); }
526 int is_struct ()
const {
return m_val.isstruct (); }
528 int is_uint16 ()
const {
return m_val.is_uint16_type (); }
530 int is_uint32 ()
const {
return m_val.is_uint32_type (); }
532 int is_uint64 ()
const {
return m_val.is_uint64_type (); }
534 int is_uint8 ()
const {
return m_val.is_uint8_type (); }
536 int is_range ()
const {
return m_val.is_range (); }
538 int isreal ()
const {
return m_val.isreal (); }
545 mwSize
get_m ()
const {
return m_val.rows (); }
547 mwSize
get_n ()
const
554 for (mwIndex i = m_ndims - 1; i > 0; i--)
564 m_ndims = m_val.ndims ();
571 for (mwIndex i = 0; i < m_ndims; i++)
593 int isempty ()
const {
return m_val.isempty (); }
600 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
605 m_id = mxUNKNOWN_CLASS;
607 std::string cn = m_val.class_name ();
610 m_id = mxDOUBLE_CLASS;
611 else if (cn ==
"single")
612 m_id = mxSINGLE_CLASS;
613 else if (cn ==
"char")
615 else if (cn ==
"logical")
616 m_id = mxLOGICAL_CLASS;
617 else if (cn ==
"cell")
619 else if (cn ==
"struct")
620 m_id = mxSTRUCT_CLASS;
621 else if (cn ==
"function_handle")
622 m_id = mxFUNCTION_CLASS;
623 else if (cn ==
"int8")
625 else if (cn ==
"uint8")
626 m_id = mxUINT8_CLASS;
627 else if (cn ==
"int16")
628 m_id = mxINT16_CLASS;
629 else if (cn ==
"uint16")
630 m_id = mxUINT16_CLASS;
631 else if (cn ==
"int32")
632 m_id = mxINT32_CLASS;
633 else if (cn ==
"uint32")
634 m_id = mxUINT32_CLASS;
635 else if (cn ==
"int64")
636 m_id = mxINT64_CLASS;
637 else if (cn ==
"uint64")
638 m_id = mxUINT64_CLASS;
647 std::string s = m_val.class_name ();
661 if (m_val.is_classdef_object ())
679 if (m_val.is_classdef_object ())
697 if (m_val.issparse ())
700 const void *m_data = m_val.mex_get_data ();
701 if (m_data ==
nullptr)
704 if (m_val.islogical ())
705 return *
static_cast<const bool *
> (m_data);
706 else if (m_val.isreal ())
707 return *
static_cast<const double *
> (m_data);
709 return *
static_cast<const double *
> (m_data);
712 return m_val.scalar_value (
true);
719 void *retval =
const_cast<void *
> (m_val.mex_get_data ());
723 maybe_mark_foreign (retval);
731 template <
typename T>
732 T *
get_data (mxClassID class_id, mxComplexity complexity)
const
736 void *ptr =
const_cast<void *
> (m_val.mex_get_data (class_id, complexity));
738 T *retval =
static_cast<T *
> (ptr);
742 maybe_mark_foreign (retval);
771 mxDOUBLE_CLASS, mxCOMPLEX);
774 mxDOUBLE_CLASS, mxCOMPLEX);
778 void *retval =
nullptr;
780 if (is_numeric () && isreal ())
813 return static_cast<mwIndex *
> (maybe_mark_foreign (ptr));
821 return static_cast<mwIndex *
> (maybe_mark_foreign (ptr));
824 mwSize
get_nzmax ()
const {
return m_val.nzmax (); }
852 int get_string (
char *buf, mwSize buflen)
const
858 if (m_val.is_string () && nel < buflen)
862 const char *p = tmp.
data ();
864 for (mwIndex i = 0; i < nel; i++)
881 if (m_val.is_string ())
891 const char *p = tmp.
data ();
893 for (mwIndex i = 0; i < nel; i++)
908 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
918 case mxCELL_CLASS:
return sizeof (
mxArray *);
919 case mxSTRUCT_CLASS:
return sizeof (
mxArray *);
920 case mxLOGICAL_CLASS:
return sizeof (mxLogical);
921 case mxCHAR_CLASS:
return sizeof (mxChar);
932 case mxFUNCTION_CLASS:
return 0;
941 void request_mutation ()
const
944 error (
"unexpected: m_mutate_flag is true in mxArray_octave_value::request_mutation - please report this bug");
946 m_mutate_flag =
true;
955 mxArray_octave_value (
const mxArray_octave_value& arg)
956 :
mxArray_base (arg), m_val (arg.m_val), m_mutate_flag (arg.m_mutate_flag),
958 m_ndims (arg.m_ndims),
965 for (mwIndex i = 0; i < m_ndims; i++)
966 m_dims[i] = arg.m_dims[i];
974 mutable bool m_mutate_flag;
980 mutable mxClassID m_id;
981 mutable char *m_class_name;
982 mutable mwSize m_ndims;
983 mutable mwSize *m_dims;
993 mxArray_matlab () =
delete;
999 mxArray_matlab& operator = (
const mxArray_matlab&) =
delete;
1003 mxFree (m_class_name);
1007 int iscell ()
const {
return m_id == mxCELL_CLASS; }
1009 int is_char ()
const {
return m_id == mxCHAR_CLASS; }
1011 int is_complex ()
const {
return m_is_complex; }
1013 int is_double ()
const {
return m_id == mxDOUBLE_CLASS; }
1017 int is_int16 ()
const {
return m_id == mxINT16_CLASS; }
1019 int is_int32 ()
const {
return m_id == mxINT32_CLASS; }
1021 int is_int64 ()
const {
return m_id == mxINT64_CLASS; }
1023 int is_int8 ()
const {
return m_id == mxINT8_CLASS; }
1025 int is_logical ()
const {
return m_id == mxLOGICAL_CLASS; }
1029 return (m_id == mxDOUBLE_CLASS || m_id == mxSINGLE_CLASS
1030 || m_id == mxINT8_CLASS || m_id == mxUINT8_CLASS
1031 || m_id == mxINT16_CLASS || m_id == mxUINT16_CLASS
1032 || m_id == mxINT32_CLASS || m_id == mxUINT32_CLASS
1033 || m_id == mxINT64_CLASS || m_id == mxUINT64_CLASS);
1036 int is_single ()
const {
return m_id == mxSINGLE_CLASS; }
1040 int is_struct ()
const {
return m_id == mxSTRUCT_CLASS; }
1042 int is_uint16 ()
const {
return m_id == mxUINT16_CLASS; }
1044 int is_uint32 ()
const {
return m_id == mxUINT32_CLASS; }
1046 int is_uint64 ()
const {
return m_id == mxUINT64_CLASS; }
1048 int is_uint8 ()
const {
return m_id == mxUINT8_CLASS; }
1053 &&
static_cast<mxLogical *
> (get_data ())[0] != 0);
1056 mwSize
get_m ()
const {
return m_dims[0]; }
1058 mwSize
get_n ()
const
1062 for (mwSize i = m_ndims - 1 ; i > 0 ; i--)
1072 void set_m (mwSize m) { m_dims[0] = m; }
1074 void set_n (mwSize n) { m_dims[1] = n; }
1085 =
static_cast<mwSize *
> (
mxArray::malloc (m_ndims *
sizeof (mwSize)));
1087 if (m_dims ==
nullptr)
1090 for (
int i = 0; i < m_ndims; i++)
1091 m_dims[i] = dims[i];
1104 mwSize retval = m_dims[0];
1106 for (mwIndex i = 1; i < m_ndims; i++)
1107 retval *= m_dims[i];
1116 return m_ndims == 2 && m_dims[0] == 1 && m_dims[1] == 1;
1125 case mxDOUBLE_CLASS:
return "double";
1126 case mxSINGLE_CLASS:
return "single";
1127 case mxCHAR_CLASS:
return "char";
1128 case mxLOGICAL_CLASS:
return "logical";
1129 case mxCELL_CLASS:
return "cell";
1130 case mxSTRUCT_CLASS:
return "struct";
1131 case mxFUNCTION_CLASS:
return "function_handle";
1132 case mxINT8_CLASS:
return "int8";
1133 case mxUINT8_CLASS:
return "uint8";
1134 case mxINT16_CLASS:
return "int16";
1135 case mxUINT16_CLASS:
return "uint16";
1136 case mxINT32_CLASS:
return "int32";
1137 case mxUINT32_CLASS:
return "uint32";
1138 case mxINT64_CLASS:
return "int64";
1139 case mxUINT64_CLASS:
return "uint64";
1140 case mxUNKNOWN_CLASS:
return "unknown";
1142 default:
return "unknown";
1148 return m_class_name;
1153 mxFree (m_class_name);
1155 strcpy (m_class_name, name);
1313 mwIndex *
get_ir ()
const
1318 mwIndex *
get_jc ()
const
1391 return calc_single_subscript_internal (m_ndims, m_dims, nsubs, subs);
1398 case mxCELL_CLASS:
return sizeof (
mxArray *);
1399 case mxSTRUCT_CLASS:
return sizeof (
mxArray *);
1400 case mxLOGICAL_CLASS:
return sizeof (mxLogical);
1401 case mxCHAR_CLASS:
return sizeof (mxChar);
1412 case mxFUNCTION_CLASS:
return 0;
1421 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1422 mwSize ndims,
const mwSize *dims)
1423 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1424 m_is_complex (is_complex), m_ndims (ndims < 2 ? 2 : ndims),
1425 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1438 for (mwIndex i = 0; i < ndims; i++)
1439 m_dims[i] = dims[i];
1441 for (mwIndex i = m_ndims - 1; i > 1; i--)
1450 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1452 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1453 m_is_complex (is_complex), m_ndims (dv.ndims ()),
1454 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1456 for (mwIndex i = 0; i < m_ndims; i++)
1459 for (mwIndex i = m_ndims - 1; i > 1; i--)
1468 mxArray_matlab (
bool interleaved,
bool is_complex, mxClassID
id,
1470 :
mxArray_base (interleaved), m_class_name (nullptr), m_id (id),
1471 m_is_complex (is_complex), m_ndims (2),
1472 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1478 mxArray_matlab (
const mxArray_matlab& val)
1480 m_id (val.m_id), m_is_complex (val.m_is_complex), m_ndims (val.m_ndims),
1481 m_dims (static_cast<mwSize *> (
mxArray::
malloc (m_ndims * sizeof (mwSize))))
1483 for (mwIndex i = 0; i < m_ndims; i++)
1484 m_dims[i] = val.m_dims[i];
1487 void set_complexity (
bool is_complex) { m_is_complex = is_complex; }
1490 dims_to_dim_vector ()
const
1492 mwSize nd = get_number_of_dimensions ();
1499 for (mwIndex i = 0; i < nd; i++)
1520class mxArray_base_full :
public mxArray_matlab
1524 mxArray_base_full () =
delete;
1526 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1527 mwSize ndims,
const mwSize *dims,
bool init =
true)
1528 : mxArray_matlab (interleaved, is_complex, id, ndims, dims),
1529 m_pr (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1532 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1534 : mxArray_matlab (interleaved, is_complex, id, dv),
1535 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1538 mxArray_base_full (
bool interleaved,
bool is_complex, mxClassID
id,
1539 mwSize m, mwSize n,
bool init =
true)
1540 : mxArray_matlab (interleaved, is_complex, id, m, n),
1541 m_pr (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
1544 mxArray_base_full (
bool interleaved, mxClassID
id,
double val)
1545 : mxArray_matlab (interleaved, false, id, 1, 1),
1546 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1548 double *dpr =
static_cast<double *
> (m_pr);
1552 mxArray_base_full (
bool interleaved, mxClassID
id, mxLogical val)
1553 : mxArray_matlab (interleaved, false, id, 1, 1),
1554 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1556 mxLogical *lpr =
static_cast<mxLogical *
> (m_pr);
1560 mxArray_base_full (
bool interleaved,
const char *str)
1561 : mxArray_matlab (interleaved, false, mxCHAR_CLASS,
1562 str ? (
strlen (str) ? 1 : 0) : 0,
1564 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1566 mxChar *cpr =
static_cast<mxChar *
> (m_pr);
1567 mwSize nel = get_number_of_elements ();
1568 for (mwIndex i = 0; i < nel; i++)
1573 mxArray_base_full (
bool interleaved, mwSize m,
const char **str)
1574 : mxArray_matlab (interleaved, false, mxCHAR_CLASS, m, max_str_len (m, str)),
1575 m_pr (
mxArray::calloc (get_number_of_elements (), get_element_size ()))
1577 mxChar *cpr =
static_cast<mxChar *
> (m_pr);
1583 for (mwIndex j = 0; j < m; j++)
1585 const char *ptr = str[j];
1587 std::size_t tmp_len =
strlen (ptr);
1589 for (std::size_t i = 0; i < tmp_len; i++)
1590 cpr[m*i+j] =
static_cast<mxChar
> (ptr[i]);
1592 for (std::size_t i = tmp_len; i < static_cast<std::size_t> (nc); i++)
1593 cpr[m*i+j] =
static_cast<mxChar
> (
' ');
1600 mxArray_base_full& operator = (
const mxArray_base_full&) =
delete;
1604 return new mxArray_base_full (*
this);
1607 ~mxArray_base_full ()
1612 double get_scalar ()
const
1618 mxClassID
id = get_class_id ();
1622 case mxDOUBLE_CLASS:
1623 retval = *(
static_cast<double *
> (m_pr));
1626 case mxSINGLE_CLASS:
1627 retval = *(
static_cast<float *
> (m_pr));
1631 retval = *(
static_cast<mxChar *
> (m_pr));
1634 case mxLOGICAL_CLASS:
1635 retval = *(
static_cast<bool *
> (m_pr));
1639 retval = *(
static_cast<int8_t *
> (m_pr));
1643 retval = *(
static_cast<uint8_t *
> (m_pr));
1647 retval = *(
static_cast<int16_t *
> (m_pr));
1650 case mxUINT16_CLASS:
1651 retval = *(
static_cast<uint16_t *
> (m_pr));
1655 retval = *(
static_cast<int32_t *
> (m_pr));
1658 case mxUINT32_CLASS:
1659 retval = *(
static_cast<uint32_t *
> (m_pr));
1663 retval = *(
static_cast<int64_t *
> (m_pr));
1666 case mxUINT64_CLASS:
1667 retval = *(
static_cast<uint64_t *
> (m_pr));
1671 case mxFUNCTION_CLASS:
1672 case mxSTRUCT_CLASS:
1673 case mxUNKNOWN_CLASS:
1676 std::string dest_cname = get_class_name (
id);
1677 error (
"invalid conversion from %s mxArray to %s scalar value", get_class_name (), dest_cname.c_str ());
1690 void * get_data ()
const {
return m_pr; }
1692 void set_data (
void *pr) { m_pr = pr; }
1699 mxDouble * get_doubles ()
const
1701 return static_cast<mxDouble *
> (m_pr);
1704 mxSingle * get_singles ()
const
1706 return static_cast<mxSingle *
> (m_pr);
1709 mxInt8 * get_int8s ()
const
1711 return static_cast<mxInt8 *
> (m_pr);
1714 mxInt16 * get_int16s ()
const
1716 return static_cast<mxInt16 *
> (m_pr);
1719 mxInt32 * get_int32s ()
const
1721 return static_cast<mxInt32 *
> (m_pr);
1724 mxInt64 * get_int64s ()
const
1726 return static_cast<mxInt64 *
> (m_pr);
1729 mxUint8 * get_uint8s ()
const
1731 return static_cast<mxUint8 *
> (m_pr);
1734 mxUint16 * get_uint16s ()
const
1736 return static_cast<mxUint16 *
> (m_pr);
1739 mxUint32 * get_uint32s ()
const
1741 return static_cast<mxUint32 *
> (m_pr);
1744 mxUint64 * get_uint64s ()
const
1746 return static_cast<mxUint64 *
> (m_pr);
1749 mxComplexDouble * get_complex_doubles ()
const
1751 return static_cast<mxComplexDouble *
> (m_pr);
1754 mxComplexSingle * get_complex_singles ()
const
1756 return static_cast<mxComplexSingle *
> (m_pr);
1759 int set_doubles (mxDouble *
d)
1765 int set_singles (mxSingle *
d)
1771 int set_int8s (mxInt8 *
d)
1777 int set_int16s (mxInt16 *
d)
1783 int set_int32s (mxInt32 *
d)
1789 int set_int64s (mxInt64 *
d)
1795 int set_uint8s (mxUint8 *
d)
1801 int set_uint16s (mxUint16 *
d)
1807 int set_uint32s (mxUint32 *
d)
1813 int set_uint64s (mxUint64 *
d)
1819 int set_complex_doubles (mxComplexDouble *
d)
1825 int set_complex_singles (mxComplexSingle *
d)
1831 int get_string (
char *buf, mwSize buflen)
const
1835 mwSize nel = get_number_of_elements ();
1837 if (! (nel < buflen))
1846 mxChar *ptr =
static_cast<mxChar *
> (m_pr);
1848 for (mwIndex i = 0; i < nel; i++)
1849 buf[i] =
static_cast<char> (ptr[i]);
1857 char * array_to_string ()
const
1861 mwSize nel = get_number_of_elements ();
1867 mxChar *ptr =
static_cast<mxChar *
> (m_pr);
1869 for (mwIndex i = 0; i < nel; i++)
1870 buf[i] =
static_cast<char> (ptr[i]);
1882 const dim_vector& dv = dims_to_dim_vector ();
1884 switch (get_class_id ())
1886 case mxDOUBLE_CLASS:
1887 return (is_complex ()
1888 ? fp_to_ov<Complex> (dv) : fp_to_ov<
double> (dv));
1890 case mxSINGLE_CLASS:
1891 return (is_complex ()
1892 ? fp_to_ov<FloatComplex> (dv) : fp_to_ov<
float> (dv));
1895 return int_to_ov<mxChar, charNDArray, char> (dv);
1897 case mxLOGICAL_CLASS:
1898 return int_to_ov<mxLogical, boolNDArray, bool> (dv);
1901 return int_to_ov<int8_t, int8NDArray, octave_int8> (dv);
1904 return int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv);
1907 return int_to_ov<int16_t, int16NDArray, octave_int16> (dv);
1909 case mxUINT16_CLASS:
1910 return int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv);
1913 return int_to_ov<int32_t, int32NDArray, octave_int32> (dv);
1915 case mxUINT32_CLASS:
1916 return int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv);
1919 return int_to_ov<int64_t, int64NDArray, octave_int64> (dv);
1921 case mxUINT64_CLASS:
1922 return int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv);
1925 case mxFUNCTION_CLASS:
1926 case mxSTRUCT_CLASS:
1927 case mxUNKNOWN_CLASS:
1929 error (
"invalid conversion from %s%s mxArray to octave_value", (is_complex () ?
"complex " :
""), get_class_name ());
1943 mxArray_base_full (
const mxArray_base_full& val)
1944 : mxArray_matlab (val),
1945 m_pr (
mxArray::
malloc (get_number_of_elements () * get_element_size ()))
1948 memcpy (m_pr, val.m_pr, get_number_of_elements () * get_element_size ());
1951 template <
typename ELT_T>
1957 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
1959#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
1961 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
1963 octave::unwind_action act ([
this] () { maybe_disown_ptr (m_pr); });
1977 ELT_T *ptr = val.rwdata ();
1979 mwSize nel = get_number_of_elements ();
1981 for (mwIndex i = 0; i < nel; i++)
1989 template <
typename ELT_T,
typename ARRAY_T,
typename ARRAY_ELT_T>
1994 error (
"complex integer types are not supported");
1996 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
2003 ARRAY_ELT_T *ptr = val.rwdata ();
2005 mwSize nel = get_number_of_elements ();
2007 for (mwIndex i = 0; i < nel; i++)
2022class mxArray_interleaved_full :
public mxArray_base_full
2026 mxArray_interleaved_full () =
delete;
2028 mxArray_interleaved_full (mxClassID
id, mwSize ndims,
const mwSize *dims,
2029 mxComplexity flag = mxREAL,
bool init =
true)
2030 : mxArray_base_full (true, flag == mxCOMPLEX, id, ndims, dims, init)
2033 mxArray_interleaved_full (mxClassID
id,
const dim_vector& dv,
2034 mxComplexity flag = mxREAL)
2035 : mxArray_base_full (true, flag == mxCOMPLEX, id, dv)
2038 mxArray_interleaved_full (mxClassID
id, mwSize m, mwSize n,
2039 mxComplexity flag = mxREAL,
bool init =
true)
2040 : mxArray_base_full (true, flag == mxCOMPLEX, id, m, n, init)
2043 mxArray_interleaved_full (mxClassID
id,
double val)
2044 : mxArray_base_full (true, id, val)
2047 mxArray_interleaved_full (mxClassID
id, mxLogical val)
2048 : mxArray_base_full (true, id, val)
2051 mxArray_interleaved_full (
const char *str)
2052 : mxArray_base_full (true, str)
2056 mxArray_interleaved_full (mwSize m,
const char **str)
2057 : mxArray_base_full (true, m, str)
2063 mxArray_interleaved_full& operator = (
const mxArray_interleaved_full&) =
delete;
2067 return new mxArray_interleaved_full (*
this);
2070 ~mxArray_interleaved_full () =
default;
2072 void * get_imag_data ()
const { error_impossible_call (
"mxArray_interleaved_full::get_imag_data"); }
2074 void set_imag_data (
void *) { error_impossible_call (
"mxArray_interleaved_full::set_imag_data"); }
2078 mxArray_interleaved_full (
const mxArray_interleaved_full& val)
2079 : mxArray_base_full (val)
2083class mxArray_separate_full :
public mxArray_base_full
2087 mxArray_separate_full () =
delete;
2089 mxArray_separate_full (mxClassID
id, mwSize ndims,
const mwSize *dims,
2090 mxComplexity flag = mxREAL,
bool init =
true)
2091 : mxArray_base_full (false, flag == mxCOMPLEX, id, ndims, dims, init),
2092 m_pi (flag == mxCOMPLEX
2093 ?
mxArray::alloc (init, get_number_of_elements (), get_element_size ())
2097 mxArray_separate_full (mxClassID
id,
const dim_vector& dv,
2098 mxComplexity flag = mxREAL)
2099 : mxArray_base_full (false, flag == mxCOMPLEX, id, dv),
2101 ?
mxArray::calloc (get_number_of_elements (), get_element_size ())
2105 mxArray_separate_full (mxClassID
id, mwSize m, mwSize n,
2106 mxComplexity flag = mxREAL,
bool init =
true)
2107 : mxArray_base_full (false, flag == mxCOMPLEX, id, m, n, init),
2109 ? (
mxArray::alloc (init, get_number_of_elements (), get_element_size ()))
2113 mxArray_separate_full (mxClassID
id,
double val)
2114 : mxArray_base_full (false, id, val), m_pi (nullptr)
2117 mxArray_separate_full (mxClassID
id, mxLogical val)
2118 : mxArray_base_full (false, id, val), m_pi (nullptr)
2121 mxArray_separate_full (
const char *str)
2122 : mxArray_base_full (false, str), m_pi (nullptr)
2126 mxArray_separate_full (mwSize m,
const char **str)
2127 : mxArray_base_full (false, m, str), m_pi (nullptr)
2133 mxArray_separate_full& operator = (
const mxArray_separate_full&) =
delete;
2137 return new mxArray_separate_full (*
this);
2140 ~mxArray_separate_full ()
2145 void * get_imag_data ()
const {
return m_pi; }
2147 void set_imag_data (
void *pi)
2151 set_complexity (m_pi !=
nullptr);
2154 mxDouble * get_doubles ()
const { error_impossible_call (
"mxArray_separate_full::get_doubles"); }
2155 mxSingle * get_singles ()
const { error_impossible_call (
"mxArray_separate_full::get_singles"); }
2156 mxInt8 * get_int8s ()
const { error_impossible_call (
"mxArray_separate_full::get_int8s"); }
2157 mxInt16 * get_int16s ()
const { error_impossible_call (
"mxArray_separate_full::get_int16s"); }
2158 mxInt32 * get_int32s ()
const { error_impossible_call (
"mxArray_separate_full::get_int32s"); }
2159 mxInt64 * get_int64s ()
const { error_impossible_call (
"mxArray_separate_full::get_int64s"); }
2160 mxUint8 * get_uint8s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint8s"); }
2161 mxUint16 * get_uint16s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint16s"); }
2162 mxUint32 * get_uint32s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint32s"); }
2163 mxUint64 * get_uint64s ()
const { error_impossible_call (
"mxArray_separate_full::get_uint64s"); }
2165 mxComplexDouble * get_complex_doubles ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_doubles"); }
2166 mxComplexSingle * get_complex_singles ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_singles"); }
2170 mxComplexInt8 * get_complex_int8s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int8s"); }
2171 mxComplexInt16 * get_complex_int16s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int16s"); }
2172 mxComplexInt32 * get_complex_int32s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int32s"); }
2173 mxComplexInt64 * get_complex_int64s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_int64s"); }
2174 mxComplexUint8 * get_complex_uint8s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint8s"); }
2175 mxComplexUint16 * get_complex_uint16s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint16s"); }
2176 mxComplexUint32 * get_complex_uint32s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint32s"); }
2177 mxComplexUint64 * get_complex_uint64s ()
const { error_impossible_call (
"mxArray_separate_full::get_complex_uint64s"); }
2179 int set_doubles (mxDouble *) { error_impossible_call (
"mxArray_separate_full::set_doubles"); }
2180 int set_singles (mxSingle *) { error_impossible_call (
"mxArray_separate_full::set_singles"); }
2181 int set_int8s (mxInt8 *) { error_impossible_call (
"mxArray_separate_full::set_int8s"); }
2182 int set_int16s (mxInt16 *) { error_impossible_call (
"mxArray_separate_full::set_int16s"); }
2183 int set_int32s (mxInt32 *) { error_impossible_call (
"mxArray_separate_full::set_int32s"); }
2184 int set_int64s (mxInt64 *) { error_impossible_call (
"mxArray_separate_full::set_int64s"); }
2185 int set_uint8s (mxUint8 *) { error_impossible_call (
"mxArray_separate_full::set_uint8s"); }
2186 int set_uint16s (mxUint16 *) { error_impossible_call (
"mxArray_separate_full::set_uint16s"); }
2187 int set_uint32s (mxUint32 *) { error_impossible_call (
"mxArray_separate_full::set_uint32s"); }
2188 int set_uint64s (mxUint64 *) { error_impossible_call (
"mxArray_separate_full::set_uint64s"); }
2190 int set_complex_doubles (mxComplexDouble *) { error_impossible_call (
"mxArray_separate_full::set_complex_doubles"); }
2191 int set_complex_singles (mxComplexSingle *) { error_impossible_call (
"mxArray_separate_full::set_complex_singles"); }
2195 int set_complex_int8s (mxComplexInt8 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int8s"); }
2196 int set_complex_int16s (mxComplexInt16 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int16s"); }
2197 int set_complex_int32s (mxComplexInt32 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int32s"); }
2198 int set_complex_int64s (mxComplexInt64 *) { error_impossible_call (
"mxArray_separate_full::set_complex_int64s"); }
2199 int set_complex_uint8s (mxComplexUint8 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint8s"); }
2200 int set_complex_uint16s (mxComplexUint16 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint16s"); }
2201 int set_complex_uint32s (mxComplexUint32 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint32s"); }
2202 int set_complex_uint64s (mxComplexUint64 *) { error_impossible_call (
"mxArray_separate_full::set_complex_uint64s"); }
2206 if (! is_complex ())
2207 return mxArray_base_full::as_octave_value ();
2211 const dim_vector& dv = dims_to_dim_vector ();
2213 switch (get_class_id ())
2215 case mxDOUBLE_CLASS:
2216 return to_ov<double> (dv);
2218 case mxSINGLE_CLASS:
2219 return to_ov<float> (dv);
2221 case mxLOGICAL_CLASS:
2225 case mxUINT16_CLASS:
2227 case mxUINT32_CLASS:
2229 case mxUINT64_CLASS:
2230 error (
"complex integer types are not supported");
2234 case mxFUNCTION_CLASS:
2235 case mxSTRUCT_CLASS:
2236 case mxUNKNOWN_CLASS:
2238 error (
"invalid conversion from complex %s mxArray to octave_value", get_class_name ());
2252 mxArray_separate_full (
const mxArray_separate_full& val)
2253 : mxArray_base_full (val),
2255 ?
mxArray::
malloc (get_number_of_elements () * get_element_size ())
2259 memcpy (m_pi, val.m_pi, get_number_of_elements () * get_element_size ());
2264 template <
typename T>
2268 mwSize nel = get_number_of_elements ();
2270 T *ppr =
static_cast<T *
> (m_pr);
2277 std::complex<T> *ptr = val.rwdata ();
2279 T *ppi =
static_cast<T *
> (m_pi);
2281 for (mwIndex i = 0; i < nel; i++)
2282 ptr[i] = std::complex<T> (ppr[i], ppi[i]);
2293class mxArray_base_sparse :
public mxArray_matlab
2297 mxArray_base_sparse () =
delete;
2299 mxArray_base_sparse (
bool interleaved,
bool is_complex,
2300 mxClassID
id, mwSize m, mwSize n, mwSize nzmax)
2301 : mxArray_matlab (interleaved, is_complex, id, m, n),
2303 m_nzmax (nzmax > 0 ? nzmax : 1),
2304 m_ir (static_cast<mwIndex *> (
mxArray::calloc (m_nzmax, sizeof (mwIndex)))),
2305 m_jc (static_cast<mwIndex *> (
mxArray::calloc (n + 1, sizeof (mwIndex)))),
2306 m_pr (
mxArray::calloc (m_nzmax, get_element_size ()))
2311 mxArray_base_sparse (
const mxArray_base_sparse& val)
2312 : mxArray_matlab (val), m_nzmax (val.m_nzmax),
2313 m_ir (static_cast<mwIndex *> (
mxArray::
malloc (m_nzmax * sizeof (mwIndex)))),
2314 m_jc (static_cast<mwIndex *> (
mxArray::
malloc (m_nzmax * sizeof (mwIndex)))),
2318 memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex));
2321 memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex));
2324 memcpy (m_pr, val.m_pr, m_nzmax * get_element_size ());
2332 mxArray_base_sparse& operator = (
const mxArray_base_sparse&) =
delete;
2336 return new mxArray_base_sparse (*
this);
2339 ~mxArray_base_sparse ()
2346 int is_sparse ()
const {
return 1; }
2348 void * get_data ()
const {
return m_pr; }
2350 void set_data (
void *pr) { m_pr = pr; }
2352 mxDouble * get_doubles ()
const
2354 return static_cast<mxDouble *
> (m_pr);
2357 mxComplexDouble * get_complex_doubles ()
const
2359 return static_cast<mxComplexDouble *
> (m_pr);
2362 int set_doubles (mxDouble *
d)
2368 int set_complex_doubles (mxComplexDouble *
d)
2374 mwIndex * get_ir ()
const {
return m_ir; }
2376 mwIndex * get_jc ()
const {
return m_jc; }
2378 mwSize get_nzmax ()
const {
return m_nzmax; }
2380 void set_ir (mwIndex *ir) { m_ir = ir; }
2382 void set_jc (mwIndex *jc) { m_jc = jc; }
2384 void set_nzmax (mwSize nzmax)
2387 m_nzmax = (nzmax > 0 ? nzmax : 1);
2394 const dim_vector& dv = dims_to_dim_vector ();
2396 switch (get_class_id ())
2398 case mxDOUBLE_CLASS:
2399 return is_complex () ? to_ov<Complex> (dv):
to_ov<
double> (dv);
2401 case mxSINGLE_CLASS:
2402 error (
"single precision sparse data type not supported");
2404 case mxLOGICAL_CLASS:
2405 return to_ov<bool> (dv);
2410 case mxUINT16_CLASS:
2412 case mxUINT32_CLASS:
2414 case mxUINT64_CLASS:
2417 case mxFUNCTION_CLASS:
2418 case mxSTRUCT_CLASS:
2419 case mxUNKNOWN_CLASS:
2421 error (
"invalid conversion from %s%s sparse mxArray to octave_value", (is_complex () ?
"complex " :
""), get_class_name ());
2435 template <
typename ELT_T>
2439 ELT_T *ppr =
static_cast<ELT_T *
> (m_pr);
2441#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
2443 if (current_mx_memory_resource == &the_mx_deleting_memory_resource)
2445 octave::unwind_action act ([
this] ()
2447 maybe_disown_ptr (m_pr);
2448 maybe_disown_ptr (m_ir);
2449 maybe_disown_ptr (m_jc);
2454 ppr, m_ir, m_jc, current_mx_memory_resource));
2459 ppr, m_ir, m_jc, current_mx_memory_resource));
2470 for (mwIndex i = 0; i < m_nzmax; i++)
2472 val.xdata (i) = ppr[i];
2473 val.xridx (i) = m_ir[i];
2476 for (mwIndex i = 0; i < n + 1; i++)
2477 val.xcidx (i) = m_jc[i];
2497class mxArray_interleaved_sparse :
public mxArray_base_sparse
2501 mxArray_interleaved_sparse () =
delete;
2503 mxArray_interleaved_sparse (mxClassID
id, mwSize m, mwSize n, mwSize nzmax,
2504 mxComplexity flag = mxREAL)
2505 : mxArray_base_sparse (true, flag == mxCOMPLEX, id, m, n, nzmax)
2510 mxArray_interleaved_sparse (
const mxArray_interleaved_sparse& val)
2511 : mxArray_base_sparse (val)
2519 mxArray_interleaved_sparse& operator = (
const mxArray_interleaved_sparse&) =
delete;
2523 return new mxArray_interleaved_sparse (*
this);
2526 ~mxArray_interleaved_sparse () =
default;
2528 void * get_imag_data ()
const { error_impossible_call (
"mxArray_interleaved_sparse::get_imag_data"); }
2530 void set_imag_data (
void *) { error_impossible_call (
"mxArray_interleaved_sparse::set_imag_data"); }
2533class mxArray_separate_sparse :
public mxArray_base_sparse
2537 mxArray_separate_sparse () =
delete;
2539 mxArray_separate_sparse (mxClassID
id, mwSize m, mwSize n, mwSize nzmax,
2540 mxComplexity flag = mxREAL)
2541 : mxArray_base_sparse (false, flag == mxCOMPLEX, id, m, n, nzmax),
2543 ?
mxArray::calloc (m_nzmax, get_element_size ())
2549 mxArray_separate_sparse (
const mxArray_separate_sparse& val)
2550 : mxArray_base_sparse (val),
2556 memcpy (m_pi, val.m_pi, m_nzmax * get_element_size ());
2564 mxArray_separate_sparse& operator = (
const mxArray_separate_sparse&) =
delete;
2568 return new mxArray_separate_sparse (*
this);
2571 ~mxArray_separate_sparse ()
2576 void * get_imag_data ()
const {
return m_pi; }
2578 void set_imag_data (
void *pi)
2581 set_complexity (m_pi !=
nullptr);
2584 mxDouble * get_doubles ()
const { error_impossible_call (
"mxArray_separate_sparse::get_doubles"); }
2585 mxComplexDouble * get_complex_doubles ()
const { error_impossible_call (
"mxArray_separate_sparse::get_complex_doubles"); }
2587 int set_doubles (mxDouble *) { error_impossible_call (
"mxArray_separate_sparse::set_doubles"); }
2588 int set_complex_doubles (mxComplexDouble *) { error_impossible_call (
"mxArray_separate_sparse::set_complex_doubles"); }
2592 if (! is_complex ())
2593 return mxArray_base_sparse::as_octave_value ();
2597 switch (get_class_id ())
2599 case mxDOUBLE_CLASS:
2601 double *ppr =
static_cast<double *
> (m_pr);
2602 double *ppi =
static_cast<double *
> (m_pi);
2607 for (mwIndex i = 0; i < m_nzmax; i++)
2609 val.xdata (i) =
Complex (ppr[i], ppi[i]);
2610 val.xridx (i) = m_ir[i];
2613 for (mwIndex i = 0; i < get_n () + 1; i++)
2614 val.xcidx (i) = m_jc[i];
2620 case mxSINGLE_CLASS:
2621 error (
"single precision sparse data type not supported");
2623 case mxLOGICAL_CLASS:
2627 case mxUINT16_CLASS:
2629 case mxUINT32_CLASS:
2631 case mxUINT64_CLASS:
2634 case mxFUNCTION_CLASS:
2635 case mxSTRUCT_CLASS:
2636 case mxUNKNOWN_CLASS:
2638 error (
"invalid conversion from complex %s sparse mxArray to octave_value", get_class_name ());
2658class mxArray_struct :
public mxArray_matlab
2662 mxArray_struct () =
delete;
2664 mxArray_struct (
bool interleaved, mwSize ndims,
const mwSize *dims,
2665 int num_keys,
const char **keys)
2666 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, ndims, dims),
2667 m_nfields (num_keys),
2668 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2671 get_number_of_elements (),
2677 mxArray_struct (
bool interleaved,
const dim_vector& dv,
int num_keys,
2679 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, dv),
2680 m_nfields (num_keys),
2681 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2684 get_number_of_elements (),
2690 mxArray_struct (
bool interleaved, mwSize m, mwSize n,
int num_keys,
2692 : mxArray_matlab (interleaved, false, mxSTRUCT_CLASS, m, n),
2693 m_nfields (num_keys),
2694 m_fields (static_cast<char **> (
mxArray::calloc (m_nfields,
2697 get_number_of_elements (),
2705 mxArray_struct (
const mxArray_struct& val)
2706 : mxArray_matlab (val), m_nfields (val.m_nfields),
2708 * sizeof (char *)))),
2710 get_number_of_elements ()
2713 for (
int i = 0; i < m_nfields; i++)
2716 mwSize nel = get_number_of_elements ();
2718 for (mwIndex i = 0; i < nel * m_nfields; i++)
2721 m_data[i] = (ptr ? ptr->
dup () :
nullptr);
2730 mxArray_struct& operator = (
const mxArray_struct& val) =
delete;
2732 void init (
const char **keys)
2734 for (
int i = 0; i < m_nfields; i++)
2738 mxArray_base * dup ()
const {
return new mxArray_struct (*
this); }
2742 for (
int i = 0; i < m_nfields; i++)
2743 mxFree (m_fields[i]);
2747 mwSize ntot = m_nfields * get_number_of_elements ();
2749 for (mwIndex i = 0; i < ntot; i++)
2755 int add_field (
const char *key)
2761 m_fields =
static_cast<char **
>
2762 (mxRealloc (m_fields, m_nfields *
sizeof (
char *)));
2768 mwSize nel = get_number_of_elements ();
2770 mwSize ntot = m_nfields * nel;
2773 new_data =
static_cast<mxArray **
>
2782 for (mwIndex i = 0; i < ntot; i++)
2784 if (++n == m_nfields)
2786 new_data[j++] =
nullptr;
2790 new_data[j++] = m_data[k++];
2797 retval = m_nfields - 1;
2804 void remove_field (
int key_num)
2806 if (key_num >= 0 && key_num < m_nfields)
2808 mwSize nel = get_number_of_elements ();
2810 mwSize ntot = m_nfields * nel;
2812 int new_nfields = m_nfields - 1;
2814 char **new_fields =
static_cast<char **
>
2821 for (
int i = 0; i < key_num; i++)
2822 new_fields[i] = m_fields[i];
2824 for (
int i = key_num + 1; i < m_nfields; i++)
2825 new_fields[i-1] = m_fields[i];
2827 if (new_nfields > 0)
2833 for (mwIndex i = 0; i < ntot; i++)
2838 new_data[j++] = m_data[k++];
2840 if (++n == m_nfields)
2845 m_nfields = new_nfields;
2850 m_fields = new_fields;
2855 mxArray * get_field_by_number (mwIndex index,
int key_num)
const
2857 return key_num >= 0 && key_num < m_nfields
2858 ? m_data[m_nfields * index + key_num] :
nullptr;
2861 void set_field_by_number (mwIndex index,
int key_num,
mxArray *val);
2863 int get_number_of_fields ()
const {
return m_nfields; }
2865 const char * get_field_name_by_number (
int key_num)
const
2867 return key_num >= 0 && key_num < m_nfields ? m_fields[key_num] :
nullptr;
2870 int get_field_number (
const char *key)
const
2874 for (
int i = 0; i < m_nfields; i++)
2876 if (!
strcmp (key, m_fields[i]))
2886 void * get_data ()
const {
return m_data; }
2888 void set_data (
void *data) { m_data =
static_cast<mxArray **
> (data); }
2892 const dim_vector& dv = dims_to_dim_vector ();
2898 mwSize ntot = m_nfields * get_number_of_elements ();
2900 for (
int i = 0; i < m_nfields; i++)
2907 for (mwIndex j = i; j < ntot; j += m_nfields)
2910 m.assign (keys[i], c);
2927class mxArray_cell :
public mxArray_matlab
2931 mxArray_cell () =
delete;
2933 mxArray_cell (
bool interleaved, mwSize ndims,
const mwSize *dims)
2934 : mxArray_matlab (interleaved, false, mxCELL_CLASS, ndims, dims),
2938 mxArray_cell (
bool interleaved,
const dim_vector& dv)
2939 : mxArray_matlab (interleaved, false, mxCELL_CLASS, dv),
2943 mxArray_cell (
bool interleaved, mwSize m, mwSize n)
2944 : mxArray_matlab (interleaved, false, mxCELL_CLASS, m, n),
2950 mxArray_cell (
const mxArray_cell& val)
2951 : mxArray_matlab (val),
2954 mwSize nel = get_number_of_elements ();
2956 for (mwIndex i = 0; i < nel; i++)
2959 m_data[i] = (ptr ? ptr->
dup () :
nullptr);
2968 mxArray_cell& operator = (
const mxArray_cell&) =
delete;
2970 mxArray_base * dup ()
const {
return new mxArray_cell (*
this); }
2974 mwSize nel = get_number_of_elements ();
2976 for (mwIndex i = 0; i < nel; i++)
2982 mxArray * get_cell (mwIndex idx)
const
2984 return idx >= 0 && idx < get_number_of_elements () ? m_data[idx] :
nullptr;
2987 void set_cell (mwIndex idx,
mxArray *val);
2989 void * get_data ()
const {
return m_data; }
2991 void set_data (
void *data) { m_data =
static_cast<mxArray **
> (data); }
2995 const dim_vector& dv = dims_to_dim_vector ();
2999 mwSize nel = get_number_of_elements ();
3003 for (mwIndex i = 0; i < nel; i++)
3017 : m_rep (create_rep (interleaved, ov)), m_name (nullptr)
3021 const mwSize *dims, mxComplexity flag,
bool init)
3022 : m_rep (create_rep (interleaved, id, ndims, dims, flag, init)),
3028 : m_rep (create_rep (interleaved, id, dv, flag)), m_name (nullptr)
3032 mxComplexity flag,
bool init)
3033 : m_rep (create_rep (interleaved, id, m, n, flag, init)), m_name (nullptr)
3037 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3041 : m_rep (create_rep (interleaved, id, val)), m_name (nullptr)
3045 : m_rep (create_rep (interleaved, str)), m_name (nullptr)
3049 : m_rep (create_rep (interleaved, m, str)), m_name (nullptr)
3053 mwSize nzmax, mxComplexity flag)
3054 : m_rep (create_rep (interleaved, id, m, n, nzmax, flag)), m_name (nullptr)
3060 : m_rep (new mxArray_struct (interleaved, ndims, dims, num_keys, keys)),
3066 : m_rep (new mxArray_struct (interleaved, dv, num_keys, keys)),
3072 : m_rep (new mxArray_struct (interleaved, m, n, num_keys, keys)),
3077 : m_rep (new mxArray_cell (interleaved, ndims, dims)), m_name (nullptr)
3081 : m_rep (new mxArray_cell (interleaved, dv)), m_name (nullptr)
3085 : m_rep (new mxArray_cell (interleaved, m, n)), m_name (nullptr)
3119mxArray::create_rep (
bool interleaved,
const octave_value& ov)
3121 return new mxArray_octave_value (interleaved, ov);
3125mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize ndims,
3126 const mwSize *dims, mxComplexity flag,
bool init)
3129 return new mxArray_interleaved_full (
id, ndims, dims, flag, init);
3131 return new mxArray_separate_full (
id, ndims, dims, flag, init);
3135mxArray::create_rep (
bool interleaved, mxClassID
id,
const dim_vector& dv,
3139 return new mxArray_interleaved_full (
id, dv, flag);
3141 return new mxArray_separate_full (
id, dv, flag);
3145mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize m, mwSize n,
3146 mxComplexity flag,
bool init)
3149 return new mxArray_interleaved_full (
id, m, n, flag, init);
3151 return new mxArray_separate_full (
id, m, n, flag, init);
3155mxArray::create_rep (
bool interleaved, mxClassID
id,
double val)
3158 return new mxArray_interleaved_full (
id, val);
3160 return new mxArray_separate_full (
id, val);
3164mxArray::create_rep (
bool interleaved, mxClassID
id, mxLogical val)
3167 return new mxArray_interleaved_full (
id, val);
3169 return new mxArray_separate_full (
id, val);
3173mxArray::create_rep (
bool interleaved,
const char *str)
3176 return new mxArray_interleaved_full (str);
3178 return new mxArray_separate_full (str);
3182mxArray::create_rep (
bool interleaved, mwSize m,
const char **str)
3185 return new mxArray_interleaved_full (m, str);
3187 return new mxArray_separate_full (m, str);
3191mxArray::create_rep (
bool interleaved, mxClassID
id, mwSize m, mwSize n,
3192 mwSize nzmax, mxComplexity flag)
3195 return new mxArray_interleaved_sparse (
id, m, n, nzmax, flag);
3197 return new mxArray_separate_sparse (
id, m, n, nzmax, flag);
3201mxArray::maybe_mutate ()
const
3214 m_rep = new_val->m_rep;
3215 new_val->m_rep =
nullptr;
3229 while (! m_memlist.empty ())
3231 auto p = m_memlist.begin ();
3233 m_memlist.erase (p);
3237 while (! m_arraylist.empty ())
3239 auto p = m_arraylist.begin ();
3241 m_arraylist.erase (p);
3244 if (! (m_memlist.empty () && m_arraylist.empty ()))
3255 octave::tree_evaluator& tw = octave::__get_evaluator__ ();
3261 std::string nm = fcn->
name ();
3275 void *ptr = xmalloc (n);
3280 error (
"%s: failed to allocate %zd bytes of memory",
3299 auto p_local = m_memlist.find (ptr);
3300 auto p_global = s_global_memlist.find (ptr);
3302 v = xrealloc (ptr, n);
3306 if (p_local != m_memlist.end ())
3308 m_memlist.erase (p_local);
3309 m_memlist.insert (v);
3312 if (p_global != s_global_memlist.end ())
3314 s_global_memlist.erase (p_global);
3315 s_global_memlist.insert (v);
3332 auto p = s_global_memlist.find (ptr);
3334 if (p != s_global_memlist.end ())
3336 s_global_memlist.erase (p);
3342 p = m_foreign_memlist.find (ptr);
3344 if (p != m_foreign_memlist.end ())
3345 m_foreign_memlist.erase (p);
3346#if defined (OCTAVE_MXARRAY_DEBUG)
3348 warning (
"mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc");
3355std::set<void *> mex::s_global_memlist;
3360void * mxRealloc (
void *ptr, std::size_t size)
3366void mxFree (
void *ptr)
3393maybe_mark_foreign (
void *ptr)
3401#if defined (OCTAVE_HAVE_STD_PMR_POLYMORPHIC_ALLOCATOR)
3404maybe_disown_ptr (
void *ptr)
3417maybe_unmark_array (
mxArray *ptr)
3425template <
typename T>
3427maybe_unmark (T *ptr)
3436mxArray_struct::set_field_by_number (mwIndex index,
int key_num,
mxArray *val)
3438 if (key_num >= 0 && key_num < m_nfields)
3439 m_data[m_nfields * index + key_num] = maybe_unmark_array (val);
3443mxArray_cell::set_cell (mwIndex idx,
mxArray *val)
3445 if (idx >= 0 && idx < get_number_of_elements ())
3446 m_data[idx] = maybe_unmark_array (val);
3453 int nrhs,
const mxArray *prhs[]);
3467 int nargout = nargout_arg;
3469 int nargin = args.
length ();
3471 for (
int i = 0; i < nargin; i++)
3474 int nout = (nargout == 0 ? 1 : nargout);
3476 for (
int i = 0; i < nout; i++)
3477 argout[i] =
nullptr;
3480 octave::unwind_protect_var<mex *> restore_var (
mex_context);
3482 mex context (mex_fcn);
3484 for (
int i = 0; i < nargin; i++)
3491 fcn (nargout, argout, nargin,
const_cast<const mxArray **
> (argin));
3497 if (nargout == 0 && argout[0])
3509 for (
int i = 0; i < nargout; i++)
3515OCTAVE_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,...)
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)
#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.
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)