261 lines
13 KiB
C++
261 lines
13 KiB
C++
|
/* Copyright 2016-2020 The MathWorks, Inc. */
|
||
|
|
||
|
#ifndef ARRAY_FACTORY_HELPERS_HPP_
|
||
|
#define ARRAY_FACTORY_HELPERS_HPP_
|
||
|
|
||
|
#include "FunctionType.hpp"
|
||
|
#include "publish_util.hpp"
|
||
|
#include "ExceptionHelpers.hpp"
|
||
|
|
||
|
namespace matlab {
|
||
|
namespace data {
|
||
|
namespace impl {
|
||
|
class ArrayFactoryImpl;
|
||
|
class ArrayImpl;
|
||
|
}
|
||
|
namespace detail {
|
||
|
class NameListImpl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace matlab {
|
||
|
namespace data {
|
||
|
namespace detail {
|
||
|
template <typename ItType>
|
||
|
void throwWrongNumberOfElementsException(ItType begin, ItType end, const ArrayDimensions& dims) {
|
||
|
auto numel = (end - begin);
|
||
|
std::string msg = std::string("Exactly ") +
|
||
|
std::to_string(dims[0]*dims[1]) +
|
||
|
std::string(" elements required to create ") +
|
||
|
std::to_string(dims[0]) +
|
||
|
std::string("x") +
|
||
|
std::to_string(dims[1]) +
|
||
|
std::string(" ObjectArray, but ") +
|
||
|
std::to_string(numel) +
|
||
|
std::string(" elements provided.");
|
||
|
throwIfError(static_cast<int>(matlab::data::ExceptionType::InvalidNumberOfElementsProvided), msg);
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<(matlab::data::is_complex<T>::value || std::is_arithmetic<T>::value) && !std::is_same<T, bool>::value, TypedArray<typename GetReturnType<T>::type>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsAndDataFcnPtr)(matlab::data::impl::ArrayFactoryImpl* impl,
|
||
|
int arrayType,
|
||
|
size_t* dims,
|
||
|
size_t numDims,
|
||
|
const void* const dataStart,
|
||
|
size_t numEl,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsAndDataFcnPtr fcn = resolveFunction<CreateArrayWithDimsAndDataFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS_AND_DATA);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(GetArrayType<T>::type),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&(*(begin)),
|
||
|
(end - begin),
|
||
|
&aImpl));
|
||
|
return Access::createObj<TypedArray<typename GetReturnType<T>::type>>(aImpl);
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, bool>::value, TypedArray<bool>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
int,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsFcnPtr fcn = resolveFunction<CreateArrayWithDimsFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(GetArrayType<T>::type),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&aImpl));
|
||
|
auto retVal = Access::createObj<TypedArray<T>>(aImpl);
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto& elem : retVal) {
|
||
|
elem = *it;
|
||
|
if (++it == end) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, String>::value || std::is_same<T, const char16_t*>::value, TypedArray<typename GetReturnType<T>::type>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
int,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsFcnPtr fcn = resolveFunction<CreateArrayWithDimsFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(GetArrayType<typename GetReturnType<T>::type>::type),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&aImpl));
|
||
|
auto retVal = Access::createObj<TypedArray<typename GetReturnType<T>::type>>(aImpl);
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto elem : retVal) {
|
||
|
elem = *it;
|
||
|
if (++it == end) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, Object>::value, TypedArray<T>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
|
||
|
typedef int(*CreateObjectArrayWithObjsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ObjectImpl*,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
|
||
|
static const CreateObjectArrayWithObjsFcnPtr fcn = resolveFunction<CreateObjectArrayWithObjsFcnPtr>
|
||
|
(FunctionType::CREATE_OBJECT_ARRAY_WITH_OBJ);
|
||
|
throwIfError(fcn(impl,
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
Access::getImpl<matlab::data::impl::ObjectImpl>(*begin),
|
||
|
&aImpl));
|
||
|
|
||
|
ObjectArray retVal = Access::createObj<ObjectArray>(aImpl);
|
||
|
auto temp = retVal.getDimensions();
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto elem : retVal) {
|
||
|
if (it == end) {
|
||
|
throwWrongNumberOfElementsException(begin, end, dims);
|
||
|
}
|
||
|
elem = T(*it);
|
||
|
++it;
|
||
|
}
|
||
|
if (it != end) {
|
||
|
throwWrongNumberOfElementsException(begin, end, dims);
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, Array>::value, TypedArray<T>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
int,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsFcnPtr fcn = resolveFunction<CreateArrayWithDimsFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(GetArrayType<T>::type),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&aImpl));
|
||
|
|
||
|
auto retVal = Access::createObj<TypedArray<T>>(aImpl);
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto elem : retVal) {
|
||
|
elem = T(*it);
|
||
|
if (++it == end) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, const char *>::value || std::is_same<T, std::string>::value, TypedArray<MATLABString>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
if (std::find_if(begin, end, [](std::string str) {return (isAscii7(str) == false); }) != end) {
|
||
|
throw NonAsciiCharInInputDataException(std::string("Input data can only contain ASCII characters"));
|
||
|
}
|
||
|
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
int,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsFcnPtr fcn = resolveFunction<CreateArrayWithDimsFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(ArrayType::MATLAB_STRING),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&aImpl));
|
||
|
auto retVal = Access::createObj<TypedArray<MATLABString>>(aImpl);
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto elem : retVal) {
|
||
|
elem = *it;
|
||
|
if (++it == end) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <typename ItType,
|
||
|
typename T = typename std::remove_cv<typename std::iterator_traits<ItType>::value_type>::type>
|
||
|
typename std::enable_if<std::is_same<T, MATLABString>::value, TypedArray<MATLABString>>::type
|
||
|
createArrayWithIterator(matlab::data::impl::ArrayFactoryImpl* impl, ArrayDimensions dims, ItType begin, ItType end) {
|
||
|
|
||
|
matlab::data::impl::ArrayImpl* aImpl = nullptr;
|
||
|
typedef int(*CreateArrayWithDimsFcnPtr)(matlab::data::impl::ArrayFactoryImpl*,
|
||
|
int,
|
||
|
size_t*,
|
||
|
size_t,
|
||
|
matlab::data::impl::ArrayImpl**);
|
||
|
static const CreateArrayWithDimsFcnPtr fcn = resolveFunction<CreateArrayWithDimsFcnPtr>
|
||
|
(FunctionType::CREATE_ARRAY_WITH_DIMS);
|
||
|
throwIfError(fcn(impl,
|
||
|
static_cast<int>(ArrayType::MATLAB_STRING),
|
||
|
&dims[0],
|
||
|
dims.size(),
|
||
|
&aImpl));
|
||
|
auto retVal = Access::createObj<TypedArray<MATLABString>>(aImpl);
|
||
|
|
||
|
auto it = begin;
|
||
|
for (auto elem : retVal) {
|
||
|
MATLABString x = *it;
|
||
|
if (x) {
|
||
|
elem = x;
|
||
|
}
|
||
|
if (++it == end) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|