/* 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 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(matlab::data::ExceptionType::InvalidNumberOfElementsProvided), msg); } template ::value_type>::type> typename std::enable_if<(matlab::data::is_complex::value || std::is_arithmetic::value) && !std::is_same::value, TypedArray::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 (FunctionType::CREATE_ARRAY_WITH_DIMS_AND_DATA); throwIfError(fcn(impl, static_cast(GetArrayType::type), &dims[0], dims.size(), &(*(begin)), (end - begin), &aImpl)); return Access::createObj::type>>(aImpl); } template ::value_type>::type> typename std::enable_if::value, TypedArray>::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 (FunctionType::CREATE_ARRAY_WITH_DIMS); throwIfError(fcn(impl, static_cast(GetArrayType::type), &dims[0], dims.size(), &aImpl)); auto retVal = Access::createObj>(aImpl); auto it = begin; for (auto& elem : retVal) { elem = *it; if (++it == end) { break; } } return retVal; } template ::value_type>::type> typename std::enable_if::value || std::is_same::value, TypedArray::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 (FunctionType::CREATE_ARRAY_WITH_DIMS); throwIfError(fcn(impl, static_cast(GetArrayType::type>::type), &dims[0], dims.size(), &aImpl)); auto retVal = Access::createObj::type>>(aImpl); auto it = begin; for (auto elem : retVal) { elem = *it; if (++it == end) { break; } } return retVal; } template ::value_type>::type> typename std::enable_if::value, TypedArray>::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 (FunctionType::CREATE_OBJECT_ARRAY_WITH_OBJ); throwIfError(fcn(impl, &dims[0], dims.size(), Access::getImpl(*begin), &aImpl)); ObjectArray retVal = Access::createObj(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 ::value_type>::type> typename std::enable_if::value, TypedArray>::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 (FunctionType::CREATE_ARRAY_WITH_DIMS); throwIfError(fcn(impl, static_cast(GetArrayType::type), &dims[0], dims.size(), &aImpl)); auto retVal = Access::createObj>(aImpl); auto it = begin; for (auto elem : retVal) { elem = T(*it); if (++it == end) { break; } } return retVal; } template ::value_type>::type> typename std::enable_if::value || std::is_same::value, TypedArray>::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 (FunctionType::CREATE_ARRAY_WITH_DIMS); throwIfError(fcn(impl, static_cast(ArrayType::MATLAB_STRING), &dims[0], dims.size(), &aImpl)); auto retVal = Access::createObj>(aImpl); auto it = begin; for (auto elem : retVal) { elem = *it; if (++it == end) { break; } } return retVal; } template ::value_type>::type> typename std::enable_if::value, TypedArray>::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 (FunctionType::CREATE_ARRAY_WITH_DIMS); throwIfError(fcn(impl, static_cast(ArrayType::MATLAB_STRING), &dims[0], dims.size(), &aImpl)); auto retVal = Access::createObj>(aImpl); auto it = begin; for (auto elem : retVal) { MATLABString x = *it; if (x) { elem = x; } if (++it == end) { break; } } return retVal; } } } } #endif