After a long conversation with Evgeny Panasyuk, I ended up something completely different. Since I wanted to be able to perform some simple arithmetic operations on data structures, I decided to use Eigen::Map rather than Boost::multi_array , as it offers a wide range of operators, as well as clear documentation.
Thus, the higher-level loop is processed by boost::fusion::for_each , and the lower-level loops are processed by Eigen. Arrays are linearly mapped to eigenvectors. Dimensions are passed in the data_eigen constructor.
#include <iostream> #include <boost/fusion/adapted/struct/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/include/for_each.hpp> #include <boost/bind.hpp> #include <Eigen/Core> namespace demo { template<typename T, int SIZE1, int SIZE2> struct data { T ar1[SIZE1][SIZE2]; T ar2[SIZE1][SIZE2]; }; template<typename T> struct EigenMap { typedef Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> > type; }; template<typename T> struct data_eigen { template <int SIZE1, int SIZE2> data_eigen(data<T,SIZE1,SIZE2>& src) : ar1(typename EigenMap<T>::type(&src.ar1[0][0], SIZE1*SIZE2)), ar2(typename EigenMap<T>::type(&src.ar2[0][0], SIZE1*SIZE2)) { } typename EigenMap<T>::type ar1; typename EigenMap<T>::type ar2; }; struct print { template<typename T> void operator()(const Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> >& t) const { std::cout << t.transpose() << std::endl; } }; struct scalarMult { template<typename T, typename U> void operator()(T& t, U& u) const { t *= u; } }; } BOOST_FUSION_ADAPT_TPL_STRUCT ( (T), (demo::data_eigen) (T), (typename demo::EigenMap<T>::type, ar1) (typename demo::EigenMap<T>::type, ar2) ) int main() { typedef float REALTYPE; const int SIZE1 = 2; const int SIZE2 = 2; // Basic data structure with multidimensional arrays demo::data<REALTYPE, SIZE1, SIZE2> d; for (unsigned int i = 0; i < SIZE1; ++i) for (unsigned int j = 0; j < SIZE2; ++j) { d.ar1[i][j] = (i+1)*(j+1); d.ar2[i][j] = i + j; } // Eigen::Map + BOOST_FUSION_ADAPT_TPL_STRUCT demo::data_eigen<REALTYPE> eig_d(d); std::cout << "d:" << std::endl; boost::fusion::for_each(eig_d, demo::print()); std::cout << std::endl; boost::fusion::for_each(eig_d, boost::bind<void>(demo::scalarMult(), _1, 2.0)); std::cout << "2 * d:" << std::endl; boost::fusion::for_each(eig_d, demo::print()); std::cout << std::endl; }
source share