#ifndef __helper_tools_h__ #define __helper_tools_h__ #include "base_def.h" #include "slice.h" #include #include "pack_num.h" #include "map_range.h" #include #include "xfor/iloop.h" namespace MultiArrayTools { template std::ostream& operator<<(std::ostream& out, const std::tuple& tp); template auto getIndex(std::shared_ptr range) -> std::shared_ptr; // only if 'RangeType' is defaultable and unique (Singleton) template auto getIndex() -> std::shared_ptr; template auto mkMulti(std::shared_ptr... ranges) -> std::shared_ptr >; template auto mkGenMapR(const std::tuple& f, std::shared_ptr... ranges) -> std::shared_ptr >; template auto mkGenMapI(const std::tuple& f, std::shared_ptr... indices) -> decltype( getIndex( mkGenMapR( f, indices->range()... ) ) ); template auto mkMapR(const std::tuple& f, std::shared_ptr... ranges) -> decltype( mkGenMapR(f, ranges... ) ); template auto mkMapI(const std::tuple& f, std::shared_ptr... indices) -> decltype( mkGenMapI(f, indices... ) ); template auto mkMIndex(std::shared_ptr... indices) -> decltype( getIndex( mkMulti( indices.range()... ) ) ); template auto mkMulti(std::tuple...> rangesTuple) -> MultiRange; template auto createExplicit(RangeFactory& rf) -> std::shared_ptr; template auto createExplicit(std::shared_ptr rfp) -> std::shared_ptr; template auto createRange(const vector& cvec) -> std::shared_ptr; inline auto createRange(const vector* cvec, int metaType, size_t size) -> std::shared_ptr; inline auto createRangeA(const vector* cvec, int metaType, size_t size) -> std::shared_ptr; template auto createRangeE(Args&&... args) -> std::shared_ptr; template auto rptr(const MArray& ma) -> decltype(ma.template getRangePtr()); template auto get(const std::shared_ptr& i) -> decltype(i->template getPtr()) { return i->template getPtr(); } template auto dynamic(const MArray& ma, bool slice = false) -> std::shared_ptr>>; template auto mdynamic(MArray& ma, bool slice) -> std::shared_ptr>>; template auto anonToDynView(const MultiArrayBase& ma) -> ConstSlice>; template auto dynToAnonMove(MultiArray>&& ma) -> MultiArray; template auto anonToDynView(const MultiArrayBase& ma) -> ConstSlice>; template auto dynToAnonMove(MultiArray>&& ma) -> MultiArray; template auto metaSlice(const std::shared_ptr& r) -> ConstSlice; template auto metaSlice(const std::shared_ptr& r, const std::shared_ptr& ro) -> ConstSlice; template auto mkArray(const std::shared_ptr&... rs) -> MultiArray; template auto mkArray(const std::shared_ptr&... rs, const T& val) -> MultiArray; template auto mkILoop(const OpTp& opTp, const IndTp& indTp, const VarTp& varTp, const LTp& lTp, const std::array::value>& umpos, const std::array::value>& setzero) -> MultiArrayHelper::ILoop { return MultiArrayHelper::ILoop(opTp, indTp, varTp, lTp, umpos, setzero); } template auto mkPILoop(const CF& cf) -> MultiArrayHelper::PILoop { return MultiArrayHelper::PILoop(cf); } template inline void For(const std::shared_ptr& ind, const std::function& ll) { for((*ind) = 0; ind->pos() != ind->max(); ++(*ind)){ ll(); } } // parallel: template inline void PFor(const std::shared_ptr& ind, const std::function&)>& ll) { const int max = static_cast(ind->max()); int i = 0; #pragma omp parallel shared(ind,ll) private(i) { #pragma omp for nowait for(i = 0; i < max; i++) { auto ii = getIndex( ind->range() ); ((*ii) = i)(); ll(ii); } } } template inline auto mkOp(const std::shared_ptr& i) -> decltype(std::declval,typename Index::RangeType> > ().exec(i)) { FunctionalMultiArray, typename Index::RangeType> fma(i->range()); return fma.exec(i); } template struct Func { static inline std::shared_ptr> mk(const std::function& ll) { return std::make_shared>(ll); } }; } #endif