diff --git a/CMakeLists.txt b/CMakeLists.txt index 74a0800a..90d8fe7c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,8 @@ set(MATIOCPP_HDR include/matioCpp/Span.h include/matioCpp/Vector.h include/matioCpp/MultiDimensionalArray.h) -set(MATIOCPP_TPP include/matioCpp/impl/Vector.tpp) +set(MATIOCPP_TPP include/matioCpp/impl/Vector.tpp + include/matioCpp/impl/MultiDimensionalArray.tpp) # Define the library target add_library(matioCpp ${MATIOCPP_SRC} ${MATIOCPP_HDR} ${MATIOCPP_TPP}) diff --git a/include/matioCpp/MultiDimensionalArray.h b/include/matioCpp/MultiDimensionalArray.h index e903ebd2..29f45c82 100644 --- a/include/matioCpp/MultiDimensionalArray.h +++ b/include/matioCpp/MultiDimensionalArray.h @@ -210,282 +210,7 @@ class matioCpp::MultiDimensionalArray : public matioCpp::Variable value_type operator[](const std::vector& el) const; }; - -/////////----------------------Implementation - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray() -{ - std::vector empty; - initializeVariable("unnamed_multidimensional_array", - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, {0, 0, 0}, - (void*)empty.data()); -} - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name) -{ - std::vector empty; - initializeVariable(name, - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, {0, 0, 0}, - (void*)empty.data()); -} - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name, const std::vector::index_type> &dimensions) -{ - matioCpp::MultiDimensionalArray::index_type totalElements = 1; - for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) - { - if (dim == 0) - { - std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl; - assert(false); - } - - totalElements *= dim; - } - - std::vector dummy(totalElements); - - initializeVariable(name, - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, dimensions, - (void*)dummy.data()); -} - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name, const std::vector::index_type> &dimensions, matioCpp::MultiDimensionalArray::const_pointer inputVector) -{ - matioCpp::MultiDimensionalArray::index_type totalElements = 1; - for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) - { - if (dim == 0) - { - std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl; - assert(false); - } - - totalElements *= dim; - } - - initializeVariable(name, - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, dimensions, - (void*)inputVector); -} - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray(const MultiDimensionalArray &other) -{ - fromOther(other); -} - -template -matioCpp::MultiDimensionalArray::MultiDimensionalArray(MultiDimensionalArray &&other) -{ - fromOther(other); -} - -template -matioCpp::MultiDimensionalArray::~MultiDimensionalArray() -{ - -} - -template -matioCpp::MultiDimensionalArray &matioCpp::MultiDimensionalArray::operator=(const matioCpp::MultiDimensionalArray &other) -{ - fromOther(other); - return *this; -} - -template -matioCpp::MultiDimensionalArray &matioCpp::MultiDimensionalArray::operator=(matioCpp::MultiDimensionalArray &&other) -{ - fromOther(other); - return *this; -} - -template -bool matioCpp::MultiDimensionalArray::fromVectorizedArray(const std::vector::index_type> &dimensions, matioCpp::MultiDimensionalArray::const_pointer inputVector) -{ - matioCpp::MultiDimensionalArray::index_type totalElements = 1; - for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) - { - if (dim == 0) - { - std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::fromVectorizedArray] Zero dimension detected." << std::endl; - return false; - } - - totalElements *= dim; - } - - return initializeVariable(name(), - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, dimensions, - (void*)inputVector); -} - -template -typename matioCpp::MultiDimensionalArray::index_type matioCpp::MultiDimensionalArray::rawIndexFromIndices(const std::vector::index_type> &el) const -{ - assert(dimensions().size() && numberOfElements() && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The array is empty."); - assert(el.size() == dimensions().size() && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The input vector el should have the same number of dimensions of the array."); - assert(el[0] < dimensions()[0] && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds."); - - typename matioCpp::MultiDimensionalArray::index_type index = 0; - typename matioCpp::MultiDimensionalArray::index_type previousDimensionsFactorial = 1; - - for (size_t i = 0; i < el.size(); ++i) - { - assert(el[i] < dimensions()[i] && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds."); - index += el[i] * previousDimensionsFactorial; - previousDimensionsFactorial *= dimensions()[i]; - } - - return index; -} - -template -bool matioCpp::MultiDimensionalArray::fromOther(const matioCpp::Variable &other) -{ - if (other.variableType() != matioCpp::VariableType::MultiDimensionalArray) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is not a vector." << std::endl; - return false; - } - - if (other.isComplex()) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is complex, this is not." << std::endl; - return false; - } - - if (!matioCpp::is_convertible_to_primitive_type(other.valueType())) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input type is not convertible to " << - typeid(T).name() <<"." << std::endl; - return false; - } - return Variable::fromOther(other); -} - -template -bool matioCpp::MultiDimensionalArray::fromOther(matioCpp::Variable &&other) -{ - if (other.variableType() != matioCpp::VariableType::MultiDimensionalArray) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is not a vector." << std::endl; - return false; - } - - if (other.isComplex()) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is complex, this is not." << std::endl; - return false; - } - - if (!matioCpp::is_convertible_to_primitive_type(other.valueType())) - { - std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input type is not convertible to " << - typeid(T).name() <<"." << std::endl; - return false; - } - return Variable::fromOther(other); -} - -template -bool matioCpp::MultiDimensionalArray::fromMatio(const matvar_t *inputVar) -{ - Variable dummy; - if (!dummy.fromMatio(inputVar)) - { - return false; - } - - return fromOther(dummy); -} - -template -matioCpp::Span matioCpp::MultiDimensionalArray::toSpan() -{ - return matioCpp::make_span(data(), numberOfElements()); -} - -template -const matioCpp::Span matioCpp::MultiDimensionalArray::toSpan() const -{ - return matioCpp::make_span(data(), numberOfElements()); -} - -template -bool matioCpp::MultiDimensionalArray::setName(const std::string &newName) -{ - return initializeVariable(newName, - VariableType::MultiDimensionalArray, - matioCpp::get_type::valueType, dimensions(), - (void*)data()); -} - -template -void matioCpp::MultiDimensionalArray::resize(const std::vector::index_type> &newDimensions) -{ - matioCpp::MultiDimensionalArray newArray(name(), newDimensions); - fromOther(std::move(newArray)); -} - -template -typename matioCpp::MultiDimensionalArray::pointer matioCpp::MultiDimensionalArray::data() -{ - return static_cast::pointer>(toMatio()->data); -} - -template -typename matioCpp::MultiDimensionalArray::const_pointer matioCpp::MultiDimensionalArray::data() const -{ - return static_cast::const_pointer>(toMatio()->data); -} - -template -typename matioCpp::MultiDimensionalArray::index_type matioCpp::MultiDimensionalArray::numberOfElements() const -{ - matioCpp::MultiDimensionalArray::index_type totalElements = 1; - for (matioCpp::MultiDimensionalArray::index_type dim : dimensions()) - { - totalElements *= dim; - } - - return totalElements; -} - -template -typename matioCpp::MultiDimensionalArray::reference matioCpp::MultiDimensionalArray::operator()(const std::vector::index_type> &el) -{ - return data()[rawIndexFromIndices(el)]; -} - -template -typename matioCpp::MultiDimensionalArray::value_type matioCpp::MultiDimensionalArray::operator()(const std::vector::index_type> &el) const -{ - return data()[rawIndexFromIndices(el)]; -} - -template -typename matioCpp::MultiDimensionalArray::reference matioCpp::MultiDimensionalArray::operator[](const std::vector::index_type> &el) -{ - return data()[rawIndexFromIndices(el)]; -} - -template -typename matioCpp::MultiDimensionalArray::value_type matioCpp::MultiDimensionalArray::operator[](const std::vector::index_type> &el) const -{ - return data()[rawIndexFromIndices(el)]; -} - +#include "impl/MultiDimensionalArray.tpp" #endif // MATIOCPP_MULTIDIMENSIONALARRAY_H diff --git a/include/matioCpp/impl/MultiDimensionalArray.tpp b/include/matioCpp/impl/MultiDimensionalArray.tpp new file mode 100644 index 00000000..b9937531 --- /dev/null +++ b/include/matioCpp/impl/MultiDimensionalArray.tpp @@ -0,0 +1,287 @@ +#ifndef MATIOCPP_MULTIDIMENSIONALARRAY_TPP +#define MATIOCPP_MULTIDIMENSIONALARRAY_TPP + +/* + * Copyright (C) 2020 Fondazione Istituto Italiano di Tecnologia + * + * Licensed under either the GNU Lesser General Public License v3.0 : + * https://www.gnu.org/licenses/lgpl-3.0.html + * or the GNU Lesser General Public License v2.1 : + * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + * at your option. + */ + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray() +{ + std::vector empty; + initializeVariable("unnamed_multidimensional_array", + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, {0, 0, 0}, + (void*)empty.data()); +} + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name) +{ + std::vector empty; + initializeVariable(name, + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, {0, 0, 0}, + (void*)empty.data()); +} + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name, const std::vector::index_type> &dimensions) +{ + matioCpp::MultiDimensionalArray::index_type totalElements = 1; + for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) + { + if (dim == 0) + { + std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl; + assert(false); + } + + totalElements *= dim; + } + + std::vector dummy(totalElements); + + initializeVariable(name, + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, dimensions, + (void*)dummy.data()); +} + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray(const std::string &name, const std::vector::index_type> &dimensions, matioCpp::MultiDimensionalArray::const_pointer inputVector) +{ + matioCpp::MultiDimensionalArray::index_type totalElements = 1; + for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) + { + if (dim == 0) + { + std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl; + assert(false); + } + + totalElements *= dim; + } + + initializeVariable(name, + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, dimensions, + (void*)inputVector); +} + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray(const MultiDimensionalArray &other) +{ + fromOther(other); +} + +template +matioCpp::MultiDimensionalArray::MultiDimensionalArray(MultiDimensionalArray &&other) +{ + fromOther(other); +} + +template +matioCpp::MultiDimensionalArray::~MultiDimensionalArray() +{ + +} + +template +matioCpp::MultiDimensionalArray &matioCpp::MultiDimensionalArray::operator=(const matioCpp::MultiDimensionalArray &other) +{ + fromOther(other); + return *this; +} + +template +matioCpp::MultiDimensionalArray &matioCpp::MultiDimensionalArray::operator=(matioCpp::MultiDimensionalArray &&other) +{ + fromOther(other); + return *this; +} + +template +bool matioCpp::MultiDimensionalArray::fromVectorizedArray(const std::vector::index_type> &dimensions, matioCpp::MultiDimensionalArray::const_pointer inputVector) +{ + matioCpp::MultiDimensionalArray::index_type totalElements = 1; + for (matioCpp::MultiDimensionalArray::index_type dim : dimensions) + { + if (dim == 0) + { + std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::fromVectorizedArray] Zero dimension detected." << std::endl; + return false; + } + + totalElements *= dim; + } + + return initializeVariable(name(), + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, dimensions, + (void*)inputVector); +} + +template +typename matioCpp::MultiDimensionalArray::index_type matioCpp::MultiDimensionalArray::rawIndexFromIndices(const std::vector::index_type> &el) const +{ + assert(dimensions().size() && numberOfElements() && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The array is empty."); + assert(el.size() == dimensions().size() && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The input vector el should have the same number of dimensions of the array."); + assert(el[0] < dimensions()[0] && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds."); + + typename matioCpp::MultiDimensionalArray::index_type index = 0; + typename matioCpp::MultiDimensionalArray::index_type previousDimensionsFactorial = 1; + + for (size_t i = 0; i < el.size(); ++i) + { + assert(el[i] < dimensions()[i] && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds."); + index += el[i] * previousDimensionsFactorial; + previousDimensionsFactorial *= dimensions()[i]; + } + + return index; +} + +template +bool matioCpp::MultiDimensionalArray::fromOther(const matioCpp::Variable &other) +{ + if (other.variableType() != matioCpp::VariableType::MultiDimensionalArray) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is not a vector." << std::endl; + return false; + } + + if (other.isComplex()) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is complex, this is not." << std::endl; + return false; + } + + if (!matioCpp::is_convertible_to_primitive_type(other.valueType())) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input type is not convertible to " << + typeid(T).name() <<"." << std::endl; + return false; + } + return Variable::fromOther(other); +} + +template +bool matioCpp::MultiDimensionalArray::fromOther(matioCpp::Variable &&other) +{ + if (other.variableType() != matioCpp::VariableType::MultiDimensionalArray) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is not a vector." << std::endl; + return false; + } + + if (other.isComplex()) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input variable is complex, this is not." << std::endl; + return false; + } + + if (!matioCpp::is_convertible_to_primitive_type(other.valueType())) + { + std::cerr << "[matioCpp::MultiDimensionalArray::fromOther] The input type is not convertible to " << + typeid(T).name() <<"." << std::endl; + return false; + } + return Variable::fromOther(other); +} + +template +bool matioCpp::MultiDimensionalArray::fromMatio(const matvar_t *inputVar) +{ + Variable dummy; + if (!dummy.fromMatio(inputVar)) + { + return false; + } + + return fromOther(dummy); +} + +template +matioCpp::Span matioCpp::MultiDimensionalArray::toSpan() +{ + return matioCpp::make_span(data(), numberOfElements()); +} + +template +const matioCpp::Span matioCpp::MultiDimensionalArray::toSpan() const +{ + return matioCpp::make_span(data(), numberOfElements()); +} + +template +bool matioCpp::MultiDimensionalArray::setName(const std::string &newName) +{ + return initializeVariable(newName, + VariableType::MultiDimensionalArray, + matioCpp::get_type::valueType, dimensions(), + (void*)data()); +} + +template +void matioCpp::MultiDimensionalArray::resize(const std::vector::index_type> &newDimensions) +{ + matioCpp::MultiDimensionalArray newArray(name(), newDimensions); + fromOther(std::move(newArray)); +} + +template +typename matioCpp::MultiDimensionalArray::pointer matioCpp::MultiDimensionalArray::data() +{ + return static_cast::pointer>(toMatio()->data); +} + +template +typename matioCpp::MultiDimensionalArray::const_pointer matioCpp::MultiDimensionalArray::data() const +{ + return static_cast::const_pointer>(toMatio()->data); +} + +template +typename matioCpp::MultiDimensionalArray::index_type matioCpp::MultiDimensionalArray::numberOfElements() const +{ + matioCpp::MultiDimensionalArray::index_type totalElements = 1; + for (matioCpp::MultiDimensionalArray::index_type dim : dimensions()) + { + totalElements *= dim; + } + + return totalElements; +} + +template +typename matioCpp::MultiDimensionalArray::reference matioCpp::MultiDimensionalArray::operator()(const std::vector::index_type> &el) +{ + return data()[rawIndexFromIndices(el)]; +} + +template +typename matioCpp::MultiDimensionalArray::value_type matioCpp::MultiDimensionalArray::operator()(const std::vector::index_type> &el) const +{ + return data()[rawIndexFromIndices(el)]; +} + +template +typename matioCpp::MultiDimensionalArray::reference matioCpp::MultiDimensionalArray::operator[](const std::vector::index_type> &el) +{ + return data()[rawIndexFromIndices(el)]; +} + +template +typename matioCpp::MultiDimensionalArray::value_type matioCpp::MultiDimensionalArray::operator[](const std::vector::index_type> &el) const +{ + return data()[rawIndexFromIndices(el)]; +} + +#endif // MATIOCPP_MULTIDIMENSIONALARRAY_TPP