MocoExtendProblem: Interface Between OpenSim and MATLAB for Rapidly Developing Direct Collocation Goals in Moco 1.1.0
add custom Moco goals to existing matlab scripts
mxarray.h
Go to the documentation of this file.
1
50#ifndef INCLUDE_MEXPLUS_MXARRAY_H_
51#define INCLUDE_MEXPLUS_MXARRAY_H_
52
53#include <mex.h>
54#include <algorithm>
55#include <cstdint>
56#include <set>
57#include <string>
58#include <typeinfo>
59#include <vector>
60#include "mexplus/mxtypes.h"
61
62#pragma warning(once : 4244)
63
66#define MEXPLUS_CHECK_NOTNULL(pointer) \
67 if (!(pointer)) \
68 mexErrMsgIdAndTxt("mexplus:error", \
69 "Null pointer exception: %s:%d:%s `" #pointer "`.", \
70 __FILE__, \
71 __LINE__, \
72 __FUNCTION__)
73
74#define MEXPLUS_ERROR(...) mexErrMsgIdAndTxt("mexplus:error", __VA_ARGS__)
75#define MEXPLUS_WARNING(...) mexWarnMsgIdAndTxt("mexplus:warning", __VA_ARGS__)
76#define MEXPLUS_ASSERT(condition, ...) \
77 if (!(condition)) mexErrMsgIdAndTxt("mexplus:error", __VA_ARGS__)
78
79// Is noexcept supported?
80#ifndef NOEXCEPT
81 #if defined(_MSC_VER) && defined(_NOEXCEPT)
82 // MSVC
83 #define NOEXCEPT _NOEXCEPT
84 #elif __cplusplus > 199711L
85 #define NOEXCEPT noexcept
86 #else
87 #define NOEXCEPT
88 #endif
89#endif
90
91namespace mexplus {
92
101class MxArray {
102 public:
105 MxArray() : array_(NULL), owner_(false) {}
108 MxArray& operator= (std::nullptr_t) {
109 reset();
110 return *this;
111 }
114 MxArray(MxArray&& array) NOEXCEPT: array_(NULL), owner_(false) {
115 *this = std::move(array);
116 }
120 if (this != &rhs) {
121 array_ = rhs.array_;
122 owner_ = rhs.owner_;
123 rhs.array_ = NULL;
124 rhs.owner_ = false;
125 }
126 return *this;
127 }
131 explicit MxArray(const mxArray* array) :
132 array_(const_cast<mxArray*>(array)),
133 owner_(false) {}
137 explicit MxArray(mxArray* array) : array_(array), owner_(array != NULL) {}
140 MxArray& operator= (const mxArray* rhs) {
141 reset(rhs);
142 return *this;
143 }
146 MxArray& operator= (mxArray* rhs) {
147 reset(rhs);
148 return *this;
149 }
152 template <typename T>
153 explicit MxArray(const T& value) : array_(from(value)), owner_(true) {}
156 virtual ~MxArray() {
157 if (array_ && owner_)
158 mxDestroyArray(array_);
159 }
162 void swap(MxArray& rhs) {
163 if (this != &rhs) {
164 mxArray* array = rhs.array_;
165 bool owner = rhs.owner_;
166 rhs.array_ = array_;
167 rhs.owner_ = owner_;
168 array_ = array;
169 owner_ = owner;
170 }
171 }
185 void reset(const mxArray* array = NULL) {
186 if (array_ && owner_)
187 mxDestroyArray(array_);
188 array_ = const_cast<mxArray*>(array);
189 owner_ = false;
190 }
193 void reset(mxArray* array) {
194 if (array_ && owner_)
195 mxDestroyArray(array_);
196 array_ = array;
197 owner_ = (array != NULL);
198 }
202 mxArray* release() {
204 mxArray* array = (owner_) ? array_ : clone();
205 array_ = NULL;
206 owner_ = false;
207 return array;
208 }
212 mxArray* clone() const {
214 mxArray* array = mxDuplicateArray(array_);
216 return array;
217 }
221 inline const mxArray* get() const { return array_; }
225 inline mxArray* getMutable() { return array_; }
228 operator bool() const { return array_ != NULL; }
231 inline bool isOwner() const { return owner_; }
236 template <typename T>
237 static mxArray* Numeric(int rows = 1, int columns = 1);
243 template <typename T>
244 static mxArray* Numeric(std::vector<std::size_t> dims);
249 static mxArray* Logical(int rows = 1, int columns = 1) {
250 mxArray* logical_array = mxCreateLogicalMatrix(rows, columns);
251 MEXPLUS_CHECK_NOTNULL(logical_array);
252 return logical_array;
253 }
266 static mxArray* Cell(int rows = 1, int columns = 1) {
267 mxArray* cell_array = mxCreateCellMatrix(rows, columns);
268 MEXPLUS_CHECK_NOTNULL(cell_array);
269 return cell_array;
270 }
286 static mxArray* Struct(int nfields = 0,
287 const char** fields = NULL,
288 int rows = 1,
289 int columns = 1) {
290 mxArray* struct_array = mxCreateStructMatrix(rows,
291 columns,
292 nfields,
293 fields);
294 MEXPLUS_CHECK_NOTNULL(struct_array);
295 return struct_array;
296 }
299 template <typename T>
300 static mxArray* from(const T& value) { return fromInternal<T>(value); }
301 static mxArray* from(const char* value) {
302 mxArray* array = mxCreateString(value);
304 return array;
305 }
306 static mxArray* from(int32_t value) {
307 mxArray* array = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
309 *reinterpret_cast<int32_t*>(mxGetData(array)) = value;
310 return array;
311 }
314 template <typename T>
315 static void to(const mxArray* array, T* value) {
316 toInternal<T>(array, value);
317 }
318 template <typename T>
319 static T to(const mxArray* array) {
320 T value;
321 toInternal<T>(array, &value);
322 return value;
323 }
326 template <typename T>
327 static T at(const mxArray* array, mwIndex index) {
328 T value;
329 atInternal<T>(array, index, &value);
330 return value;
331 }
332 template <typename T>
333 static void at(const mxArray* array, mwIndex index, T* value) {
334 atInternal<T>(array, index, value);
335 }
336 static const mxArray* at(const mxArray* array, mwIndex index) {
338 MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
339 return mxGetCell(array, index);
340 }
341 template <typename T>
342 static void at(const mxArray* array,
343 const std::string& field,
344 T* value,
345 mwIndex index = 0) {
346 atInternal<T>(array, field, index, value);
347 }
348 static const mxArray* at(const mxArray* array,
349 const std::string& field,
350 mwIndex index = 0) {
352 MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
353 return mxGetField(array, index, field.c_str());
354 }
357 template <typename T>
358 static void set(mxArray* array, mwIndex index, const T& value) {
359 setInternal<T>(array, index, value);
360 }
361 static void set(mxArray* array, mwIndex index, mxArray* value) {
364 MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
365 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
366 "Index out of range: %u.",
367 index);
368 mxDestroyArray(mxGetCell(array, index));
369 mxSetCell(array, index, value);
370 }
371 template <typename T>
372 static void set(mxArray* array,
373 const std::string& field,
374 const T& value,
375 mwIndex index = 0) {
376 setInternal<T>(array, field, index, value);
377 }
378 static void set(mxArray* array,
379 const std::string& field,
380 mxArray* value,
381 mwIndex index = 0) {
384 MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
385 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
386 "Index out of range: %u.",
387 index);
388 int field_number = mxGetFieldNumber(array, field.c_str());
389 if (field_number < 0) {
390 field_number = mxAddField(array, field.c_str());
391 MEXPLUS_ASSERT(field_number >= 0,
392 "Failed to create a field '%s'",
393 field.c_str());
394 }
395 mxDestroyArray(mxGetFieldByNumber(array, index, field_number));
396 mxSetFieldByNumber(array, index, field_number, value);
397 }
398
401 template <typename T>
402 T to() const {
403 T value;
404 toInternal<T>(array_, &value);
405 return value;
406 }
407 template <typename T>
408 void to(T* value) const { toInternal<T>(array_, value); }
420 template <typename T>
421 T at(mwIndex index) const {
422 T value;
423 atInternal<T>(array_, index, &value);
424 return value;
425 }
426 template <typename T>
427 void at(mwIndex index, T* value) const {
428 atInternal<T>(array_, index, value);
429 }
430 const mxArray* at(mwIndex index) const {
431 return at(array_, index);
432 }
438 template <typename T>
439 T at(mwIndex row, mwIndex column) const;
444 template <typename T>
445 T at(const std::vector<mwIndex>& subscripts) const;
451 template <typename T>
452 T at(const std::string& field, mwIndex index = 0) const {
453 T value;
454 atInternal<T>(array_, field, index, &value);
455 return value;
456 }
457 template <typename T>
458 void at(const std::string& field, T* value, mwIndex index = 0) const {
459 atInternal<T>(array_, field, index, value);
460 }
461 const mxArray* at(const std::string& field, mwIndex index = 0) const {
462 return at(array_, field, index);
463 }
464
469 template <typename T>
470 void set(mwIndex index, const T& value) {
471 setInternal<T>(array_, index, value);
472 }
478 template <typename T>
479 void set(mwIndex row, mwIndex column, const T& value);
484 template <typename T>
485 void set(const std::vector<mwIndex>& subscripts, const T& value);
490 void set(mwIndex index, mxArray* value) {
491 MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
492 set(array_, index, value);
493 }
499 void set(mwIndex row, mwIndex column, mxArray* value) {
500 MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
501 set(array_, subscriptIndex(row, column), value);
502 }
507 void set(const std::vector<mwIndex>& subscripts, mxArray* value) {
508 MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
509 set(array_, subscriptIndex(subscripts), value);
510 }
516 template <typename T>
517 void set(const std::string& field, const T& value, mwIndex index = 0) {
518 MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
519 setInternal<T>(array_, field, index, value);
520 }
526 void set(const std::string& field, mxArray* value, mwIndex index = 0) {
527 MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
528 set(array_, field, value, index);
529 }
533 template <typename T>
534 T* getData() const;
538 template <typename T>
539 T* getImagData() const;
540 mxLogical* getLogicals() const {
543 "Expected a logical array but %s.",
544 className().c_str());
545 return mxGetLogicals(array_);
546 }
547 mxChar* getChars() const {
550 "Expected a char array but %s.",
551 className().c_str());
552 return mxGetChars(array_);
553 }
556 inline mxClassID classID() const { return mxGetClassID(array_); }
559 inline const std::string className() const {
560 return std::string(mxGetClassName(array_));
561 }
564 inline mwSize size() const {
565 return static_cast<mwSize>(mxGetNumberOfElements(array_));
566 }
569 inline mwSize dimensionSize() const {
570 return mxGetNumberOfDimensions(array_);
571 }
574 inline std::vector<mwSize> dimensions() const {
575 const mwSize* dimensions = mxGetDimensions(array_);
576 return std::vector<mwSize>(dimensions, dimensions + dimensionSize());
577 }
580 inline mwSize rows() const { return static_cast<mwSize>(mxGetM(array_)); }
583 inline mwSize cols() const { return static_cast<mwSize>(mxGetN(array_)); }
586 inline int fieldSize() const { return mxGetNumberOfFields(array_); }
591 std::string fieldName(int index) const {
592 const char* field = mxGetFieldNameByNumber(array_, index);
593 MEXPLUS_ASSERT(field, "Failed to get field name at %d.", index);
594 return std::string(field);
595 }
599 std::vector<std::string> fieldNames() const {
600 MEXPLUS_ASSERT(isStruct(), "Expected a struct array.");
601 std::vector<std::string> fields(fieldSize());
602 for (int i = 0; i < fields.size(); ++i)
603 fields[i] = fieldName(i);
604 return fields;
605 }
608 inline mwSize nonZeroMax() const { return mxGetNzmax(array_); }
614 mwIndex subscriptIndex(mwIndex row, mwIndex column) const {
615 MEXPLUS_ASSERT(row < rows() && column < cols(),
616 "Subscript is out of range.");
617 mwIndex subscripts[] = {row, column};
618 return mxCalcSingleSubscript(array_, 2, subscripts);
619 }
624 mwIndex subscriptIndex(const std::vector<mwIndex>& subscripts) const {
625 return mxCalcSingleSubscript(array_,
626 static_cast<mwSize>(subscripts.size()),
627 const_cast<mwIndex*>(&subscripts[0]));
628 }
631 inline bool isCell() const { return mxIsCell(array_); }
634 inline bool isChar() const { return mxIsChar(array_); }
637 inline bool isVector() const {
638 return mxGetNumberOfDimensions(array_) == 2 &&
639 (mxGetM(array_) == 1 || mxGetN(array_) == 1);
640 }
643 inline bool isIntegral(const char* name) const {
644 return mxIsNumeric(array_) && !mxIsDouble(array_);
645 }
648 inline bool isClass(const char* name) const {
649 return mxIsClass(array_, name);
650 }
653 inline bool isComplex() const { return mxIsComplex(array_); }
657 inline bool isDouble() const { return mxIsDouble(array_); }
660 inline bool isEmpty() const { return mxIsEmpty(array_); }
663 static inline bool IsFinite(double value) { return mxIsFinite(value); }
666 inline bool isFromGlobalWS() const { return mxIsFromGlobalWS(array_); }
669 static inline bool IsInf(double value) { return mxIsInf(value); }
672 inline bool isInt8() const { return mxIsInt8(array_); }
675 inline bool isInt16() const { return mxIsInt16(array_); }
678 inline bool isInt32() const { return mxIsInt32(array_); }
681 inline bool isInt64() const { return mxIsInt64(array_); }
684 inline bool isLogical() const { return mxIsLogical(array_); }
687 inline bool isLogicalScalar() const { return mxIsLogicalScalar(array_); }
690 inline bool isLogicalScalarTrue() const {
691 return mxIsLogicalScalarTrue(array_);
692 }
695 inline bool isNumeric() const { return mxIsNumeric(array_); }
699 inline bool isSingle() const { return mxIsSingle(array_); }
702 inline bool isSparse() const { return mxIsSparse(array_); }
705 inline bool isStruct() const { return mxIsStruct(array_); }
708 inline bool isUint8() const { return mxIsUint8(array_); }
711 inline bool isUint16() const { return mxIsUint16(array_); }
714 inline bool isUint32() const { return mxIsUint32(array_); }
717 inline bool isUint64() const { return mxIsUint64(array_); }
720 bool hasField(const std::string& field_name, mwIndex index = 0) const {
721 return isStruct() &&
722 mxGetField(array_, index, field_name.c_str()) != NULL;
723 }
726 int elementSize() const {
727 return static_cast<int>(mxGetElementSize(array_));
728 }
731 static inline bool IsNaN(double value) { return mxIsNaN(value); }
734 static inline double Inf() { return mxGetInf(); }
737 static inline double NaN() { return mxGetNaN(); }
740 static inline double Eps() { return mxGetEps(); }
741
742 private:
745 MxArray(const MxArray& array);
746 // MxArray(const MxArray& array) = delete;
750 // MxArray& operator=(const MxArray& rhs) = delete;
751
752 /*************************************************************/
754 /*************************************************************/
755
758 template <typename T>
759 static mxArray* fromInternal(const typename std::enable_if<
760 MxArithmeticType<T>::value, T>::type& value);
763 template <typename T>
764 static mxArray* fromInternal(const typename std::enable_if<
765 MxComplexType<T>::value, T>::type& value);
768 template <typename Container>
769 static mxArray* fromInternal(const typename std::enable_if<
771 Container>::type& value);
774 template <typename Container>
775 static mxArray* fromInternal(const typename std::enable_if<
776 MxComplexCompound<Container>::value, Container>::type& value);
778 template <typename T>
779 static mxArray* fromInternal(const typename std::enable_if<
780 MxCharType<T>::value, T>::type& value);
783 template <typename Container>
784 static mxArray* fromInternal(const typename std::enable_if<
786 (std::is_signed<typename Container::value_type>::value),
787 Container>::type& value);
790 template <typename Container>
791 static mxArray* fromInternal(const typename std::enable_if<
793 !(std::is_signed<typename Container::value_type>::value),
794 Container>::type& value);
797 template <typename T>
798 static mxArray* fromInternal(const typename std::enable_if<
799 MxLogicalType<T>::value, T>::type& value);
802 template <typename Container>
803 static mxArray* fromInternal(const typename std::enable_if<
804 MxLogicalCompound<Container>::value, Container>::type& value);
807 template <typename Container>
808 static mxArray* fromInternal(const typename std::enable_if<
809 MxCellCompound<Container>::value, Container>::type& value);
810
811 /*************************************************************/
813 /*************************************************************/
814
817 template <typename T>
818 static void toInternal(const mxArray* array,
819 typename std::enable_if<
824 T
825 >::type* value) {
826 atInternal<T>(array, 0, value);
827 }
830 template <typename T>
831 static void toInternal(const mxArray* array,
832 typename std::enable_if<
836 T
837 >::type* value);
840 template <typename T>
841 static void toInternal(const mxArray* array,
842 typename std::enable_if<
844 (!std::is_compound<T>::value ||
846 T
847 >::type* value);
848
849 /*************************************************************/
851 /*************************************************************/
852
855 template <typename T>
856 static void atInternal(const mxArray* array, mwIndex index,
857 typename std::enable_if<
861 T>::type* value);
864 template <typename T>
865 static void atInternal(const mxArray* array, mwIndex index,
866 typename std::enable_if<
867 std::is_compound<T>::value &&
869 T
870 >::type* value);
873 template <typename T>
874 static void atInternal(const mxArray* array,
875 const std::string& field,
876 mwIndex index, T* value);
877
878 /*************************************************************/
880 /*************************************************************/
881
884 template <typename T>
885 static void setInternal(mxArray* array, mwIndex index,
886 const typename std::enable_if<
887 !std::is_compound<T>::value ||
889 T
890 >::type& value);
893 template <typename T>
894 static void setInternal(mxArray* array, mwIndex index,
895 const typename std::enable_if<
897 T
898 >::type& value);
901 template <typename T>
902 static void setInternal(mxArray* array, const std::string& field,
903 mwIndex index, const T& value);
904
905 /*************************************************************/
907 /*************************************************************/
908
911 template <typename T, typename R>
912 static void assignTo(const mxArray* array,
913 mwIndex index, typename std::enable_if<
914 std::is_integral<R>::value,
915 R
916 >::type* value) {
917 MEXPLUS_ASSERT(!mxIsComplex(array), "Non-complex array expected!");
918 *value = (R)*(reinterpret_cast<T*>(mxGetData(array)) + index);
919 }
922 #pragma warning( push )
923 #ifdef _MSC_VER
924 #pragma warning( disable: 4244 )
925 #endif
926 template <typename T, typename R>
927 static void assignTo(const mxArray* array,
928 mwIndex index,
929 typename std::enable_if<
930 std::is_floating_point<R>::value,
931 R
932 >::type* value) {
933 if (mxIsComplex(array)) {
934 T real_part = *(reinterpret_cast<T*>(mxGetPr(array)) + index);
935 T imag_part = *(reinterpret_cast<T*>(mxGetPi(array)) + index);
936 *value = std::abs(std::complex<R>(real_part, imag_part));
937 } else {
938 *value = *(reinterpret_cast<T*>(mxGetData(array)) + index);
939 }
940 }
941 #pragma warning( pop )
944 template <typename T, typename R>
945 static void assignTo(const mxArray* array,
946 mwIndex index,
947 typename std::enable_if<
949 R
950 >::type* value) {
951 typename R::value_type real_part, imag_part;
952 if (mxIsComplex(array)) {
953 real_part = *(reinterpret_cast<T*>(mxGetPr(array)) + index);
954 imag_part = *(reinterpret_cast<T*>(mxGetPi(array)) + index);
955 } else {
956 real_part = *(reinterpret_cast<T*>(mxGetData(array)) + index);
957 imag_part = 0.0;
958 }
959 *value = std::complex<typename R::value_type>(real_part, imag_part);
960 }
963 template <typename R>
964 static void assignCharTo(const mxArray* array,
965 mwIndex index,
966 typename std::enable_if<
967 std::is_signed<R>::value,
968 R
969 >::type* value) {
970 typedef typename std::make_signed<mxChar>::type SignedMxChar;
971 *value = static_cast<R>(
972 *(reinterpret_cast<SignedMxChar*>(mxGetChars(array)) + index));
973 }
976 template <typename R>
977 static void assignCharTo(const mxArray* array,
978 mwIndex index,
979 typename std::enable_if<
980 !std::is_signed<R>::value,
981 R
982 >::type* value) {
983 *value = *(mxGetChars(array) + index);
984 }
987 template <typename T>
988 static void assignCellTo(const mxArray* array, mwIndex index, T* value) {
989 const mxArray* element = mxGetCell(array, index);
990 MEXPLUS_CHECK_NOTNULL(element);
991 toInternal<T>(element, value); // Recursion for nested types.
992 }
995 #pragma warning( push )
996 #ifdef _MSC_VER
997 #pragma warning( disable: 4244 4800 )
998 #endif
999 template <typename T, typename R>
1000 static void assignTo(const mxArray* array,
1001 typename std::enable_if<
1005 R
1006 >::type* value) {
1007 mwSize array_size = static_cast<mwSize>(mxGetNumberOfElements(array));
1008 if (!mxIsComplex(array)) {
1009 T* data_pointer = reinterpret_cast<T*>(mxGetData(array));
1010 value->assign(data_pointer, data_pointer + array_size);
1011 } else {
1012 T* real_part = reinterpret_cast<T*>(mxGetPr(array));
1013 T* imag_part = reinterpret_cast<T*>(mxGetPi(array));
1014 value->resize(array_size);
1015 for (mwSize i = 0; i < array_size; ++i) {
1016 double mag = std::abs(std::complex<double>(
1017 static_cast<double>(*(real_part++)),
1018 static_cast<double>(*(imag_part++))));
1019 (*value)[i] = static_cast<T>(mag);
1020 }
1021 }
1022 }
1023 #pragma warning( pop )
1026 template <typename T, typename R>
1027 static void assignTo(const mxArray* array,
1028 typename std::enable_if<
1030 R
1031 >::type* value) {
1032 mwSize array_size = mxGetNumberOfElements(array);
1033 value->resize(array_size);
1034 if (!mxIsComplex(array)) {
1035 T* data_pointer = reinterpret_cast<T*>(mxGetData(array));
1036 for (mwSize i = 0; i < array_size; ++i) {
1037 (*value)[i] = typename R::value_type(*(data_pointer++), 0.0f);
1038 }
1039 } else {
1040 T* real_part = reinterpret_cast<T*>(mxGetPr(array));
1041 T* imag_part = reinterpret_cast<T*>(mxGetPi(array));
1042 for (mwSize i = 0; i < array_size; ++i) {
1043 (*value)[i] = typename R::value_type(*(real_part++), *(imag_part++));
1044 }
1045 }
1046 }
1049 template <typename R>
1050 static void assignStringTo(const mxArray* array,
1051 typename std::enable_if<
1052 std::is_signed<typename R::value_type>::value,
1053 R
1054 >::type* value) {
1055 typedef typename std::make_signed<mxChar>::type SignedMxChar;
1056 SignedMxChar* data_pointer = reinterpret_cast<SignedMxChar*>(
1057 mxGetChars(array));
1058 value->assign(data_pointer, data_pointer + mxGetNumberOfElements(array));
1059 }
1062 template <typename R>
1063 static void assignStringTo(const mxArray* array,
1064 typename std::enable_if<
1065 !std::is_signed<typename R::value_type>::value,
1066 R>::type* value) {
1067 mxChar* data_pointer = mxGetChars(array);
1068 value->assign(data_pointer, data_pointer + mxGetNumberOfElements(array));
1069 }
1072 template <typename T>
1073 static void assignCellTo(const mxArray* array, T* value) {
1074 mwSize array_size = static_cast<mwSize>(mxGetNumberOfElements(array));
1075 value->resize(array_size);
1076 for (size_t i = 0; i < array_size; ++i) {
1077 const mxArray* element = mxGetCell(array, static_cast<int>(i));
1078 MEXPLUS_CHECK_NOTNULL(element);
1079 (*value)[i] = to<typename T::value_type>(element);
1080 }
1081 }
1082
1083 /*************************************************************/
1085 /*************************************************************/
1086
1089 #pragma warning( push )
1090 #ifdef _MSC_VER
1091 #pragma warning( disable: 4244 4800 )
1092 #endif
1093 template <typename R, typename T>
1094 static void assignFrom(mxArray* array,
1095 mwIndex index,
1096 const typename std::enable_if<
1098 T
1099 >::type& value) {
1100 if (mxIsComplex(array)) {
1101 *(reinterpret_cast<R*>(mxGetPr(array)) + index) = value;
1102 *(reinterpret_cast<R*>(mxGetPi(array)) + index) = 0.0;
1103 } else {
1104 *(reinterpret_cast<R*>(mxGetData(array)) + index) = value;
1105 }
1106 }
1107 #pragma warning( pop )
1110 template <typename R, typename T>
1111 static void assignFrom(mxArray* array,
1112 mwIndex index,
1113 const typename std::enable_if<
1115 T
1116 >::type& value) {
1117 if (mxIsComplex(array)) {
1118 *(reinterpret_cast<R*>(mxGetPr(array)) + index) = value.real();
1119 *(reinterpret_cast<R*>(mxGetPi(array)) + index) = value.imag();
1120 } else {
1121 *(reinterpret_cast<R*>(mxGetData(array)) + index) = std::abs(value);
1122 }
1123 }
1124 #pragma warning( push )
1125 #ifdef _MSC_VER
1126 #pragma warning( disable: 4244 )
1127 #endif
1128 template <typename T>
1129 static void assignCharFrom(mxArray* array,
1130 mwIndex index,
1131 const typename std::enable_if<
1132 std::is_floating_point<T>::value,
1133 T
1134 >::type& value) {
1135 *(mxGetChars(array) + index) = value; // whoever needs this...
1136 }
1137 #pragma warning( pop )
1138 template <typename T>
1139 static void assignCharFrom(mxArray* array,
1140 mwIndex index,
1141 const typename std::enable_if<
1142 std::is_integral<T>::value &&
1143 std::is_signed<T>::value,
1144 T
1145 >::type& value) {
1146 *(mxGetChars(array) + index) = reinterpret_cast<const typename
1147 std::make_unsigned<T>::type&>(value);
1148 }
1149 template <typename T>
1150 static void assignCharFrom(mxArray* array,
1151 mwIndex index,
1152 const typename std::enable_if<
1153 std::is_integral<T>::value &&
1154 !std::is_signed<T>::value,
1155 T
1156 >::type& value) {
1157 *(mxGetChars(array) + index) = value;
1158 }
1159
1160 template <typename T>
1161 static void assignCharFrom(mxArray* array,
1162 mwIndex index,
1163 const typename std::enable_if<
1165 T
1166 >::type& value) {
1167 *(mxGetChars(array) + index) = std::abs(value); // whoever needs it...
1168 }
1169
1172 mxArray* array_;
1176};
1177
1178/*************************************************************/
1180/*************************************************************/
1181
1184template <typename T>
1185mxArray* MxArray::fromInternal(const typename std::enable_if<
1186 MxArithmeticType<T>::value, T>::type& value) {
1187 mxArray* array = mxCreateNumericMatrix(1,
1188 1,
1191 MEXPLUS_CHECK_NOTNULL(array);
1192 *reinterpret_cast<T*>(mxGetData(array)) = value;
1193 return array;
1194}
1195
1198template <typename T>
1199mxArray* MxArray::fromInternal(const typename std::enable_if<
1200 MxComplexType<T>::value, T>::type& value) {
1201 mxArray* array = mxCreateNumericMatrix(1, 1,
1204 MEXPLUS_CHECK_NOTNULL(array);
1205 *reinterpret_cast<typename T::value_type*>(mxGetPr(array)) = value.real();
1206 *reinterpret_cast<typename T::value_type*>(mxGetPi(array)) = value.imag();
1207
1208 return array;
1209}
1210
1213template <typename Container>
1214mxArray* MxArray::fromInternal(const typename std::enable_if<
1215 MxArithmeticCompound<Container>::value, Container>::type& value) {
1216 typedef typename Container::value_type ValueType;
1217 mxArray* array = mxCreateNumericMatrix(1,
1218 static_cast<int>(value.size()),
1221 MEXPLUS_CHECK_NOTNULL(array);
1222 std::copy(value.begin(),
1223 value.end(),
1224 reinterpret_cast<ValueType*>(mxGetData(array)));
1225 return array;
1226}
1227
1230template <typename Container>
1231mxArray* MxArray::fromInternal(const typename std::enable_if<
1232 MxComplexCompound<Container>::value, Container>::type& value) {
1233 typedef typename Container::value_type ContainerValueType;
1234 typedef typename ContainerValueType::value_type ValueType;
1235 mxArray* array = mxCreateNumericMatrix(1,
1236 static_cast<int>(value.size()),
1238 mxCOMPLEX);
1239 MEXPLUS_CHECK_NOTNULL(array);
1240 ValueType* real = reinterpret_cast<ValueType*>(mxGetPr(array));
1241 ValueType* imag = reinterpret_cast<ValueType*>(mxGetPi(array));
1242 typename Container::const_iterator it;
1243 for (it = value.begin(); it != value.end(); it++) {
1244 *real++ = (*it).real();
1245 *imag++ = (*it).imag();
1246 }
1247 return array;
1248}
1249
1250template <typename T>
1251mxArray* MxArray::fromInternal(const typename std::enable_if<
1252 MxCharType<T>::value, T>::type& value) {
1253 const char char_array[] = {static_cast<char>(value), 0};
1254 mxArray* array = mxCreateString(char_array);
1255 MEXPLUS_CHECK_NOTNULL(array);
1256 return array;
1257}
1258
1259template <typename Container>
1260mxArray* MxArray::fromInternal(const typename std::enable_if<
1262 (std::is_signed<typename Container::value_type>::value),
1263 Container>::type& value) {
1264 typedef typename std::make_unsigned<typename Container::value_type>::type
1265 UnsignedValue;
1266 const mwSize dimensions[] = {1, static_cast<mwSize>(value.size())};
1267 mxArray* array = mxCreateCharArray(2, dimensions);
1268 MEXPLUS_CHECK_NOTNULL(array);
1269 mxChar* array_data = mxGetChars(array);
1270 for (typename Container::const_iterator it = value.begin();
1271 it != value.end();
1272 ++it) {
1273 *(array_data++) = reinterpret_cast<const UnsignedValue&>(*it);
1274 }
1275 return array;
1276}
1277
1278template <typename Container>
1279mxArray* MxArray::fromInternal(const typename std::enable_if<
1281 !(std::is_signed<typename Container::value_type>::value),
1282 Container>::type& value) {
1283 const mwSize dimensions[] = {1, static_cast<mwSize>(value.size())};
1284 mxArray* array = mxCreateCharArray(2, dimensions);
1285 MEXPLUS_CHECK_NOTNULL(array);
1286 std::copy(value.begin(), value.end(), mxGetChars(array));
1287 return array;
1288}
1289
1290template <typename T>
1291mxArray* MxArray::fromInternal(const typename std::enable_if<
1292 MxLogicalType<T>::value, T>::type& value) {
1293 mxArray* array = mxCreateLogicalScalar(value);
1294 MEXPLUS_CHECK_NOTNULL(array);
1295 return array;
1296}
1297
1298template <typename Container>
1299mxArray* MxArray::fromInternal(const typename std::enable_if<
1300 MxLogicalCompound<Container>::value, Container>::type& value) {
1301 mxArray* array = mxCreateLogicalMatrix(1, static_cast<int>(value.size()));
1302 MEXPLUS_CHECK_NOTNULL(array);
1303 std::copy(value.begin(), value.end(), mxGetLogicals(array));
1304 return array;
1305}
1306
1307template <typename Container>
1308mxArray* MxArray::fromInternal(const typename std::enable_if<
1309 MxCellCompound<Container>::value, Container>::type& value) {
1310 mxArray* array = mxCreateCellMatrix(1, static_cast<int>(value.size()));
1311 MEXPLUS_CHECK_NOTNULL(array);
1312 mwIndex index = 0;
1313 for (typename Container::const_iterator it = value.begin();
1314 it != value.end();
1315 ++it) {
1316 mxArray* new_item = from(*it); // Safe in case if from() fails.
1317 mxDestroyArray(mxGetCell(array, index));
1318 mxSetCell(array, index++, new_item);
1319 }
1320 return array;
1321}
1322
1323/*************************************************************/
1325/*************************************************************/
1326
1329template <typename T>
1330void MxArray::toInternal(const mxArray* array, typename std::enable_if<
1333 MxCharCompound<T>::value, T>::type* value) {
1334 MEXPLUS_CHECK_NOTNULL(array);
1335 MEXPLUS_CHECK_NOTNULL(value);
1336 switch (mxGetClassID(array)) {
1337 case mxINT8_CLASS: assignTo<int8_t, T>(array, value); break;
1338 case mxUINT8_CLASS: assignTo<uint8_t, T>(array, value); break;
1339 case mxINT16_CLASS: assignTo<int16_t, T>(array, value); break;
1340 case mxUINT16_CLASS: assignTo<uint16_t, T>(array, value); break;
1341 case mxINT32_CLASS: assignTo<int32_t, T>(array, value); break;
1342 case mxUINT32_CLASS: assignTo<uint32_t, T>(array, value); break;
1343 case mxINT64_CLASS: assignTo<int64_t, T>(array, value); break;
1344 case mxUINT64_CLASS: assignTo<uint64_t, T>(array, value); break;
1345 case mxSINGLE_CLASS: assignTo<float, T>(array, value); break;
1346 case mxDOUBLE_CLASS: assignTo<double, T>(array, value); break;
1347 case mxLOGICAL_CLASS: assignTo<mxLogical, T>(array, value); break;
1348 case mxCHAR_CLASS: assignStringTo<T>(array, value); break;
1349 case mxCELL_CLASS: assignCellTo<T>(array, value); break;
1350 // case mxSPARSE_CLASS:
1351 default:
1352 MEXPLUS_ERROR("Cannot convert %s.", mxGetClassName(array));
1353 }
1354}
1355
1358template <typename T>
1359void MxArray::toInternal(const mxArray* array,
1360 typename std::enable_if<
1362 (!std::is_compound<T>::value ||
1364 T
1365 >::type* value) {
1366 MEXPLUS_CHECK_NOTNULL(value);
1367 MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
1368 mwSize array_size = static_cast<mwSize>(mxGetNumberOfElements(array));
1369 value->resize(array_size);
1370 for (size_t i = 0; i < array_size; ++i) {
1371 const mxArray* element = mxGetCell(array, i);
1372 (*value)[i] = to<typename T::value_type>(element);
1373 }
1374}
1375
1376/*************************************************************/
1378/*************************************************************/
1379
1382template <typename T>
1383void MxArray::atInternal(const mxArray* array, mwIndex index,
1384 typename std::enable_if<
1387 MxCharType<T>::value, T>::type* value) {
1388 MEXPLUS_CHECK_NOTNULL(array);
1389 MEXPLUS_CHECK_NOTNULL(value);
1390 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1391 "Index out of range: %u.",
1392 index);
1393 switch (mxGetClassID(array)) {
1394 case mxINT8_CLASS: assignTo<int8_t, T>(array, index, value); break;
1395 case mxUINT8_CLASS: assignTo<uint8_t, T>(array, index, value); break;
1396 case mxINT16_CLASS: assignTo<int16_t, T>(array, index, value); break;
1397 case mxUINT16_CLASS: assignTo<uint16_t, T>(array, index, value); break;
1398 case mxINT32_CLASS: assignTo<int32_t, T>(array, index, value); break;
1399 case mxUINT32_CLASS: assignTo<uint32_t, T>(array, index, value); break;
1400 case mxINT64_CLASS: assignTo<int64_t, T>(array, index, value); break;
1401 case mxUINT64_CLASS: assignTo<uint64_t, T>(array, index, value); break;
1402 case mxSINGLE_CLASS: assignTo<float, T>(array, index, value); break;
1403 case mxDOUBLE_CLASS: assignTo<double, T>(array, index, value); break;
1404 case mxLOGICAL_CLASS: assignTo<mxLogical, T>(array, index, value); break;
1405 case mxCHAR_CLASS: assignCharTo<T>(array, index, value); break;
1406 case mxCELL_CLASS: assignCellTo<T>(array, index, value); break;
1407 // case mxSPARSE_CLASS:
1408 default:
1409 MEXPLUS_ASSERT(true, "Cannot convert %s", mxGetClassName(array));
1410 }
1411}
1412
1413template <typename T>
1414void MxArray::atInternal(const mxArray* array, mwIndex index,
1415 typename std::enable_if<
1416 std::is_compound<T>::value &&
1417 !MxComplexType<T>::value, T>::type* value) {
1418 MEXPLUS_CHECK_NOTNULL(array);
1419 MEXPLUS_CHECK_NOTNULL(value);
1420 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1421 "Index out of range: %u.",
1422 index);
1423 MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
1424 const mxArray* element = mxGetCell(array, index);
1425 to<T>(element, value);
1426}
1427
1428template <typename T>
1429void MxArray::atInternal(const mxArray* array,
1430 const std::string& field,
1431 mwIndex index,
1432 T* value) {
1433 MEXPLUS_CHECK_NOTNULL(array);
1434 MEXPLUS_CHECK_NOTNULL(value);
1435 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1436 "Index out of range: %u.",
1437 index);
1438 MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
1439 const mxArray* element = mxGetField(array, index, field.c_str());
1440 MEXPLUS_ASSERT(element, "Invalid field name %s.", field.c_str());
1441 to<T>(element, value);
1442}
1443
1444/*************************************************************/
1446/*************************************************************/
1447
1450template <typename T>
1451void MxArray::setInternal(mxArray* array,
1452 mwIndex index,
1453 const typename std::enable_if<
1454 !std::is_compound<T>::value ||
1455 MxComplexType<T>::value, T>::type& value) {
1456 MEXPLUS_CHECK_NOTNULL(array);
1457 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1458 "Index out of range: %u.",
1459 index);
1460 switch (mxGetClassID(array)) {
1461 case mxINT8_CLASS: assignFrom<int8_t, T>(array, index, value); break;
1462 case mxUINT8_CLASS: assignFrom<uint8_t, T>(array, index, value); break;
1463 case mxINT16_CLASS: assignFrom<int16_t, T>(array, index, value); break;
1464 case mxUINT16_CLASS: assignFrom<uint16_t, T>(array, index, value); break;
1465 case mxINT32_CLASS: assignFrom<int32_t, T>(array, index, value); break;
1466 case mxUINT32_CLASS: assignFrom<uint32_t, T>(array, index, value); break;
1467 case mxINT64_CLASS: assignFrom<int64_t, T>(array, index, value); break;
1468 case mxUINT64_CLASS: assignFrom<uint64_t, T>(array, index, value); break;
1469 case mxSINGLE_CLASS: assignFrom<float, T>(array, index, value); break;
1470 case mxDOUBLE_CLASS: assignFrom<double, T>(array, index, value); break;
1471 case mxCHAR_CLASS: assignCharFrom<T>(array, index, value); break;
1472 case mxLOGICAL_CLASS: assignFrom<mxLogical, T>(array, index, value); break;
1473 case mxCELL_CLASS: {
1474 mxArray* new_item = from(value); // Safe in case if from() fails.
1475
1476 mxDestroyArray(mxGetCell(array, index));
1477 mxSetCell(array, index, new_item);
1478 break;
1479 }
1480 default:
1481 MEXPLUS_ERROR("Cannot assign to %s array.", mxGetClassName(array));
1482 }
1483}
1484
1487template <typename T>
1488void MxArray::setInternal(mxArray* array,
1489 mwIndex index,
1490 const typename std::enable_if<
1491 MxCellType<T>::value, T>::type& value) {
1492 MEXPLUS_CHECK_NOTNULL(array);
1493 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1494 "Index out of range: %u.",
1495 index);
1496 MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
1497 mxArray* new_item = from(value); // Safe in case if from() fails.
1498 mxDestroyArray(mxGetCell(array, index));
1499 mxSetCell(array, index, new_item);
1500}
1501
1502template <typename T>
1503void MxArray::setInternal(mxArray* array,
1504 const std::string& field,
1505 mwIndex index,
1506 const T& value) {
1507 MEXPLUS_CHECK_NOTNULL(array);
1508 MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
1509 "Index out of range: %u.",
1510 index);
1511 MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
1512 int field_number = mxGetFieldNumber(array, field.c_str());
1513 if (field_number < 0) {
1514 field_number = mxAddField(array, field.c_str());
1515 MEXPLUS_ASSERT(field_number >= 0,
1516 "Failed to create a field '%s'",
1517 field.c_str());
1518 }
1519 mxArray* new_item = from(value);
1520 mxDestroyArray(mxGetFieldByNumber(array, index, field_number));
1521 mxSetFieldByNumber(array, index, field_number, new_item);
1522}
1523
1524template <typename T>
1525mxArray* MxArray::Numeric(int rows, int columns) {
1526 typedef typename std::enable_if<
1527 MxComplexOrArithmeticType<T>::value, T>::type Scalar;
1528 mxArray* numeric = mxCreateNumericMatrix(rows,
1529 columns,
1532 MEXPLUS_CHECK_NOTNULL(numeric);
1533 return numeric;
1534}
1535
1536template <typename T>
1537mxArray* MxArray::Numeric(std::vector<std::size_t> dims) {
1538 typedef typename std::enable_if<
1539 MxComplexOrArithmeticType<T>::value, T>::type Scalar;
1540 mxArray* numeric = mxCreateNumericArray(dims.size(),
1541 &dims[0],
1544 MEXPLUS_CHECK_NOTNULL(numeric);
1545 return numeric;
1546}
1547
1548template <typename T>
1552 "Expected a %s array.",
1553 typeid(T).name());
1554 return reinterpret_cast<T*>(mxGetData(array_));
1555}
1556
1557template <typename T>
1561 "Expected a %s array.",
1562 typeid(T).name());
1563 return reinterpret_cast<T*>(mxGetPi(array_));
1564}
1565
1566template <typename T>
1567T MxArray::at(mwIndex row, mwIndex column) const {
1568 return at<T>(subscriptIndex(row, column));
1569}
1570
1571template <typename T>
1572T MxArray::at(const std::vector<mwIndex>& subscripts) const {
1573 return at<T>(subscriptIndex(subscripts));
1574}
1575
1576template <typename T>
1577void MxArray::set(mwIndex row, mwIndex column, const T& value) {
1578 set<T>(subscriptIndex(row, column), value);
1579}
1580
1581template <typename T>
1582void MxArray::set(const std::vector<mwIndex>& subscripts, const T& value) {
1583 set<T>(subscriptIndex(subscripts), value);
1584}
1585
1586} // namespace mexplus
1587
1588#endif // INCLUDE_MEXPLUS_MXARRAY_H_
mxArray object wrapper for data conversion and manipulation.
Definition mxarray.h:101
std::vector< std::string > fieldNames() const
Get field names of a struct array.
Definition mxarray.h:599
MxArray()
Empty MxArray constructor.
Definition mxarray.h:105
bool isOwner() const
Return true if owner.
Definition mxarray.h:231
T * getImagData() const
Get raw data pointer to imaginary part.
Definition mxarray.h:1558
mwSize size() const
Number of elements in an array.
Definition mxarray.h:564
void set(const std::string &field, mxArray *value, mwIndex index=0)
Struct element write accessor.
Definition mxarray.h:526
static void to(const mxArray *array, T *value)
mxArray* exporter methods.
Definition mxarray.h:315
void reset(mxArray *array)
Reset an mxArray.
Definition mxarray.h:193
mxArray * clone() const
Clone mxArray.
Definition mxarray.h:212
static void assignCharTo(const mxArray *array, mwIndex index, typename std::enable_if< !std::is_signed< R >::value, R >::type *value)
Explicit char (unsigned) element assignment.
Definition mxarray.h:977
static void assignTo(const mxArray *array, mwIndex index, typename std::enable_if< MxComplexType< R >::value, R >::type *value)
Explicit complex element assignment.
Definition mxarray.h:945
mxChar * getChars() const
Definition mxarray.h:547
static void assignStringTo(const mxArray *array, typename std::enable_if< !std::is_signed< typename R::value_type >::value, R >::type *value)
Explicit char (unsigned) array assignment.
Definition mxarray.h:1063
bool isInt8() const
Determine whether array represents data as signed 8-bit integers.
Definition mxarray.h:672
bool isFromGlobalWS() const
Determine whether array was copied from MATLAB global workspace.
Definition mxarray.h:666
static bool IsFinite(double value)
Determine whether input is finite.
Definition mxarray.h:663
static mxArray * Logical(int rows=1, int columns=1)
Create a new logical matrix.
Definition mxarray.h:249
T at(mwIndex index) const
Template for element accessor.
Definition mxarray.h:421
static void assignStringTo(const mxArray *array, typename std::enable_if< std::is_signed< typename R::value_type >::value, R >::type *value)
Explicit char (signed) array assignment.
Definition mxarray.h:1050
mwIndex subscriptIndex(mwIndex row, mwIndex column) const
Offset from first element to desired element.
Definition mxarray.h:614
static T at(const mxArray *array, mwIndex index)
mxArray* element reader methods.
Definition mxarray.h:327
static void at(const mxArray *array, const std::string &field, T *value, mwIndex index=0)
Definition mxarray.h:342
const mxArray * at(mwIndex index) const
Definition mxarray.h:430
static mxArray * from(const T &value)
mxArray* importer methods.
Definition mxarray.h:300
bool isNumeric() const
Determine whether array is numeric.
Definition mxarray.h:695
static void assignCharTo(const mxArray *array, mwIndex index, typename std::enable_if< std::is_signed< R >::value, R >::type *value)
Explicit char (signed) element assignment.
Definition mxarray.h:964
bool isLogical() const
Determine whether array is of type mxLogical.
Definition mxarray.h:684
static void assignCharFrom(mxArray *array, mwIndex index, const typename std::enable_if< MxComplexType< T >::value, T >::type &value)
Definition mxarray.h:1161
static void atInternal(const mxArray *array, mwIndex index, typename std::enable_if< MxComplexOrArithmeticType< T >::value||MxLogicalType< T >::value||MxCharType< T >::value, T >::type *value)
Templated mxArray getters
Definition mxarray.h:1383
static void toInternal(const mxArray *array, typename std::enable_if< MxArithmeticType< T >::value||MxComplexType< T >::value||MxLogicalType< T >::value||MxCharType< T >::value, T >::type *value)
Templated mxArray exporters
Definition mxarray.h:818
static void assignFrom(mxArray *array, mwIndex index, const typename std::enable_if< MxComplexType< T >::value, T >::type &value)
Explicit complex element assignment.
Definition mxarray.h:1111
static void set(mxArray *array, const std::string &field, const T &value, mwIndex index=0)
Definition mxarray.h:372
T to() const
Convert MxArray to a specified type.
Definition mxarray.h:402
bool isVector() const
Determine whether input is vector array.
Definition mxarray.h:637
mwSize dimensionSize() const
Number of dimensions.
Definition mxarray.h:569
bool isInt16() const
Determine whether array represents data as signed 16-bit integers.
Definition mxarray.h:675
static void assignCellTo(const mxArray *array, mwIndex index, T *value)
Explicit cell element assignment.
Definition mxarray.h:988
bool hasField(const std::string &field_name, mwIndex index=0) const
Determine whether a struct array has a specified field.
Definition mxarray.h:720
MxArray(const mxArray *array)
MxArray constructor from const mxArray*.
Definition mxarray.h:131
static double Eps()
Value of EPS.
Definition mxarray.h:740
void set(const std::string &field, const T &value, mwIndex index=0)
Struct element write accessor.
Definition mxarray.h:517
std::vector< mwSize > dimensions() const
Array of each dimension.
Definition mxarray.h:574
static void assignCellTo(const mxArray *array, T *value)
Explicit cell array assignment.
Definition mxarray.h:1073
static void setInternal(mxArray *array, mwIndex index, const typename std::enable_if< !std::is_compound< T >::value||MxComplexType< T >::value, T >::type &value)
Templated mxArray element setters
Definition mxarray.h:1451
static T to(const mxArray *array)
Definition mxarray.h:319
MxArray(mxArray *array)
MxArray constructor from mutable mxArray*.
Definition mxarray.h:137
MxArray(const T &value)
MxArray constructor from scalar.
Definition mxarray.h:153
mxArray * getMutable()
Get raw mxArray*.
Definition mxarray.h:225
bool owner_
Flag to enable resource management.
Definition mxarray.h:1175
const mxArray * get() const
Conversion to const mxArray*.
Definition mxarray.h:221
static void assignTo(const mxArray *array, mwIndex index, typename std::enable_if< std::is_floating_point< R >::value, R >::type *value)
Explicit floating point element assignment.
Definition mxarray.h:927
mwSize cols() const
Number of columns in an array.
Definition mxarray.h:583
static mxArray * from(const char *value)
Definition mxarray.h:301
int elementSize() const
Element size.
Definition mxarray.h:726
MxArray & operator=(const MxArray &rhs)
Copy assignment operator is prohibited.
std::string fieldName(int index) const
Get field name of a struct array.
Definition mxarray.h:591
static const mxArray * at(const mxArray *array, mwIndex index)
Definition mxarray.h:336
static bool IsInf(double value)
Determine whether input is infinite.
Definition mxarray.h:669
mwSize nonZeroMax() const
Number of elements in IR, PR, and PI arrays.
Definition mxarray.h:608
const mxArray * at(const std::string &field, mwIndex index=0) const
Definition mxarray.h:461
mxClassID classID() const
Class ID of mxArray.
Definition mxarray.h:556
mxLogical * getLogicals() const
Definition mxarray.h:540
bool isInt64() const
Determine whether array represents data as signed 64-bit integers.
Definition mxarray.h:681
bool isDouble() const
Determine whether mxArray represents data as double-precision, floating-point numbers.
Definition mxarray.h:657
bool isStruct() const
Determine whether input is structure array.
Definition mxarray.h:705
bool isUint8() const
Determine whether array represents data as unsigned 8-bit integers.
Definition mxarray.h:708
void set(const std::vector< mwIndex > &subscripts, mxArray *value)
Cell element write accessor.
Definition mxarray.h:507
mwIndex subscriptIndex(const std::vector< mwIndex > &subscripts) const
Offset from first element to desired element.
Definition mxarray.h:624
static void assignTo(const mxArray *array, mwIndex index, typename std::enable_if< std::is_integral< R >::value, R >::type *value)
Assignment helpers (for MxArray.to<type>(value))
Definition mxarray.h:912
T at(const std::string &field, mwIndex index=0) const
Struct element accessor.
Definition mxarray.h:452
int fieldSize() const
Number of fields in a struct array.
Definition mxarray.h:586
static const mxArray * at(const mxArray *array, const std::string &field, mwIndex index=0)
Definition mxarray.h:348
bool isInt32() const
Determine whether array represents data as signed 32-bit integers.
Definition mxarray.h:678
static void at(const mxArray *array, mwIndex index, T *value)
Definition mxarray.h:333
void to(T *value) const
Definition mxarray.h:408
static void assignTo(const mxArray *array, typename std::enable_if< MxArithmeticCompound< R >::value||MxLogicalCompound< R >::value||MxCharCompound< R >::value, R >::type *value)
Explicit numeric array assignment.
Definition mxarray.h:1000
void set(mwIndex row, mwIndex column, mxArray *value)
Cell element write accessor.
Definition mxarray.h:499
const std::string className() const
Class name of mxArray.
Definition mxarray.h:559
bool isUint16() const
Determine whether array represents data as unsigned 16-bit integers.
Definition mxarray.h:711
static void assignTo(const mxArray *array, typename std::enable_if< MxComplexCompound< R >::value, R >::type *value)
Explicit complex array assigment.
Definition mxarray.h:1027
void set(mwIndex index, const T &value)
Template for element write accessor.
Definition mxarray.h:470
mxArray * release()
Release managed mxArray* pointer, or clone if not owner.
Definition mxarray.h:202
static double Inf()
Value of infinity.
Definition mxarray.h:734
static void assignCharFrom(mxArray *array, mwIndex index, const typename std::enable_if< std::is_integral< T >::value &&!std::is_signed< T >::value, T >::type &value)
Definition mxarray.h:1150
static double NaN()
Value of NaN (Not-a-Number).
Definition mxarray.h:737
void set(mwIndex index, mxArray *value)
Cell element write accessor.
Definition mxarray.h:490
static mxArray * fromInternal(const typename std::enable_if< MxArithmeticType< T >::value, T >::type &value)
Templated mxArray importers
Definition mxarray.h:1185
static void set(mxArray *array, mwIndex index, mxArray *value)
Definition mxarray.h:361
static mxArray * Struct(int nfields=0, const char **fields=NULL, int rows=1, int columns=1)
Generic constructor for a struct matrix.
Definition mxarray.h:286
MxArray(const MxArray &array)
Copy constructor is prohibited except internally.
bool isChar() const
Determine whether input is string array.
Definition mxarray.h:634
static void assignCharFrom(mxArray *array, mwIndex index, const typename std::enable_if< std::is_integral< T >::value &&std::is_signed< T >::value, T >::type &value)
Definition mxarray.h:1139
void at(const std::string &field, T *value, mwIndex index=0) const
Definition mxarray.h:458
bool isUint64() const
Determine whether array represents data as unsigned 64-bit integers.
Definition mxarray.h:717
bool isUint32() const
Determine whether array represents data as unsigned 32-bit integers.
Definition mxarray.h:714
void reset(const mxArray *array=NULL)
Reset an mxArray to a const mxArray*.
Definition mxarray.h:185
static mxArray * Cell(int rows=1, int columns=1)
Create a new cell matrix.
Definition mxarray.h:266
bool isSparse() const
Determine whether input is sparse array.
Definition mxarray.h:702
bool isIntegral(const char *name) const
Determine whether array is integral type.
Definition mxarray.h:643
static bool IsNaN(double value)
Determine whether input is NaN (Not-a-Number).
Definition mxarray.h:731
bool isLogicalScalarTrue() const
Determine whether scalar array of type mxLogical is true.
Definition mxarray.h:690
bool isEmpty() const
Determine whether array is empty.
Definition mxarray.h:660
MxArray & operator=(std::nullptr_t)
NULL assignment.
Definition mxarray.h:108
static void assignCharFrom(mxArray *array, mwIndex index, const typename std::enable_if< std::is_floating_point< T >::value, T >::type &value)
Definition mxarray.h:1129
virtual ~MxArray()
Destructor.
Definition mxarray.h:156
bool isComplex() const
Determine whether data is complex.
Definition mxarray.h:653
mwSize rows() const
Number of rows in an array.
Definition mxarray.h:580
static void set(mxArray *array, const std::string &field, mxArray *value, mwIndex index=0)
Definition mxarray.h:378
static mxArray * Numeric(int rows=1, int columns=1)
Create a new numeric (real or complex) matrix.
Definition mxarray.h:1525
static mxArray * from(int32_t value)
Definition mxarray.h:306
MxArray(MxArray &&array) NOEXCEPT
Move constructor.
Definition mxarray.h:114
void swap(MxArray &rhs)
Swap operation.
Definition mxarray.h:162
static void assignFrom(mxArray *array, mwIndex index, const typename std::enable_if< MxArithmeticType< T >::value||MxCharType< T >::value, T >::type &value)
Assignment helpers (for MxArray.set<type>(i, value))
Definition mxarray.h:1094
bool isCell() const
Determine whether input is cell array.
Definition mxarray.h:631
mxArray * array_
Pointer to the mxArray C object.
Definition mxarray.h:1172
bool isClass(const char *name) const
Determine whether array is member of specified class.
Definition mxarray.h:648
bool isSingle() const
Determine whether array represents data as single-precision, floating-point numbers.
Definition mxarray.h:699
static void set(mxArray *array, mwIndex index, const T &value)
mxArray* element writer methods.
Definition mxarray.h:358
T * getData() const
Get raw data pointer.
Definition mxarray.h:1549
bool isLogicalScalar() const
Determine whether scalar array is of type mxLogical.
Definition mxarray.h:687
void at(mwIndex index, T *value) const
Definition mxarray.h:427
#define NOEXCEPT
Definition mxarray.h:87
#define MEXPLUS_ASSERT(condition,...)
Definition mxarray.h:76
#define MEXPLUS_CHECK_NOTNULL(pointer)
MxArray data conversion library.
Definition mxarray.h:66
#define MEXPLUS_ERROR(...)
Definition mxarray.h:74
MEX function arguments helper library.
Definition arguments.h:40
Definition mxtypes.h:308
Definition mxtypes.h:250
Definition mxtypes.h:337
Definition mxtypes.h:281
Definition mxtypes.h:299
Definition mxtypes.h:241
Definition mxtypes.h:318
Definition mxtypes.h:268
Definition mxtypes.h:259
Definition mxtypes.h:290
Definition mxtypes.h:232
Traits for mxArray.
Definition mxtypes.h:82