#ifndef __helper_tools_h__ #define __helper_tools_h__ #include "base_def.h" #include "slice.h" #include #include "pack_num.h" #include 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 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 std::vector& cvec) -> std::shared_ptr; template auto prtr(const MArray& ma) -> decltype(ma.template getRangePtr()); template inline void For(const std::shared_ptr& ind, const std::function& ll); template inline auto mkOp(const std::shared_ptr& i) -> decltype(std::declval,typename Index::RangeType> > ().exec(i)); } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { template std::ostream& operator<<(std::ostream& out, const std::tuple& tp) { PackNum::printTuple(out, tp); return out; } template auto getIndex(std::shared_ptr range) -> std::shared_ptr { return std::make_shared(range); } template auto getIndex() -> std::shared_ptr { static_assert( RangeType::defaultable, /*typeid(typename RangeType).name() + */" is not defaultable" ); static auto f = RangeType::factory(); static auto r = std::dynamic_pointer_cast( f.create() ); return std::make_shared(r); } template auto mkMulti(std::shared_ptr... ranges) -> std::shared_ptr > { MultiRangeFactory mrf( ranges... ); return std::dynamic_pointer_cast >( mrf.create() ); } template auto mkMIndex(std::shared_ptr... indices) -> decltype( getIndex( mkMulti( indices->range()... ) ) ) { auto mi = getIndex( mkMulti( indices->range()... ) ); (*mi)( indices... ); return mi; } template auto mkMulti(std::tuple...> rangesTuple) -> MultiRange { MultiRangeFactory mrf( rangesTuple ); return std::dynamic_pointer_cast >( mrf.create() ); } template auto createExplicit(RangeFactory& rf) -> std::shared_ptr { return std::dynamic_pointer_cast( rf.create() ); } template auto createExplicit(std::shared_ptr rfp) -> std::shared_ptr { return std::dynamic_pointer_cast( rfp->create() ); } template auto createRange(const std::vector& cvec) -> std::shared_ptr { const char* dp = cvec.data(); auto ff = createRangeFactory(&dp); auto rbptr = ff->create(); assert(rbptr->spaceType() == Range::STYPE); // CATCH CAST ERROR HERE !!! return std::dynamic_pointer_cast( rbptr ); } template auto rptr(const MArray& ma) -> decltype(ma.template getRangePtr()) { return ma.template getRangePtr(); } template inline void For(const std::shared_ptr& ind, const std::function& ll) { for((*ind) = 0; ind->pos() != ind->max(); ++(*ind)){ ll(); } } 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); } } #endif