#include "helper_tools.h" namespace CNORXZ { template std::ostream& operator<<(std::ostream& out, const std::tuple& tp) { sfor_pn<0,sizeof...(T)-1>( [&](auto i){ out << std::get(tp) << ", "; return 0; } ); out << std::get(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, "Range 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() ); } namespace { template struct IndexToRangeTuple { template static inline void set(std::tuple...>& out, const std::tuple...>& indices) { std::get(out) = std::get(indices)->range(); IndexToRangeTuple::set(out,indices); } }; template <> struct IndexToRangeTuple<0> { template static inline void set(std::tuple...>& out, const std::tuple...>& indices) { std::get<0>(out) = std::get<0>(indices)->range(); } }; } template auto indexToRangeTuple(const std::tuple...>& indices) -> std::tuple...> { std::tuple...> out; IndexToRangeTuple::set(out, indices); return out; } template auto mkMIndex(std::shared_ptr... indices) -> decltype( getIndex( mkMulti( indices->range()... ) ) ) { auto mi = getIndex( mkMulti( indices->range()... ) ); (*mi)( indices... ); return mi; } template auto mkMIndex(const std::tuple...>& indices) -> decltype( getIndex( mkMulti( indexToRangeTuple(indices) ) ) ) { auto mi = getIndex( mkMulti( indexToRangeTuple(indices) ) ); (*mi)( indices ); return mi; } template auto mkIndexW(const std::shared_ptr& ind) -> std::shared_ptr { return std::make_shared>(ind); } template auto mkGenMapR(const std::tuple& f, std::shared_ptr... ranges) -> std::shared_ptr,Op,STYPE,RangeTypes...> > { GenMapRangeFactory,Op,STYPE,RangeTypes...> mrf(f, ranges... ); return createExplicit( mrf ); } template auto mkGenMapRwith(const std::shared_ptr& outr, const std::tuple& f, std::shared_ptr... ranges) -> std::shared_ptr > { GenMapRangeFactory mrf(outr, f, ranges... ); return createExplicit( mrf ); } template auto mkGenMapI(const std::tuple& f, std::shared_ptr... indices) -> decltype( getIndex( mkGenMapR( f, indices->range()... ) ) ) { auto mi = getIndex( mkGenMapR( f, indices->range()... ) ); (*mi)(indices...); return mi; } template auto mkMapR(const std::tuple& f, std::shared_ptr... ranges) -> decltype( mkGenMapR(f, ranges... ) ) { return mkGenMapR(f, ranges... ); } template auto mkMapRwith(const std::shared_ptr& outr, const std::tuple& f, std::shared_ptr... ranges) -> decltype( mkGenMapRwith(outr, f, ranges... ) ) { return mkGenMapRwith(outr, f, ranges... ); } template auto mkMapR(const std::shared_ptr& func, const std::shared_ptr&... is) -> decltype( mkMapR( mkMapOp( func, is... ), is->range()... ) ) { return mkMapR( mkMapOp( func, is... ), is->range()... ); } template auto mkMapRwith(const std::shared_ptr& outr, const std::shared_ptr& func, const std::shared_ptr&... is) -> decltype( mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ) ) { return mkMapRwith(outr, mkMapOp( func, is... ), is->range()... ); } template auto mkMapI(const std::tuple& f, std::shared_ptr... indices) -> decltype( mkGenMapI(f, indices... ) ) { return mkGenMapI(f, indices... ); } template auto mkMulti(std::tuple...> rangesTuple) -> std::shared_ptr> { 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 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 ); } inline auto createRange(const vector* cvec, int metaType, size_t size) -> std::shared_ptr { auto f = createSingleRangeFactory(cvec, metaType, size); return f->create(); } inline auto createRangeA(const vector* cvec, int metaType, size_t size) -> std::shared_ptr { AnonymousRangeFactory arf(createRange(cvec, metaType, size)); return createExplicit(arf); } inline auto cvecMetaCast(const std::shared_ptr,SpaceType::ANY>>& r, int metaType) -> std::shared_ptr { return createRange(&r->get(0), metaType, r->size()); } inline auto cvecMetaCastA(const std::shared_ptr,SpaceType::ANY>>& r, int metaType) -> std::shared_ptr { return createRangeA(&r->get(0), metaType, r->size()); } template auto createRangeE(Args&&... args) -> std::shared_ptr { typename Range::FType f(args...); return createExplicit(f); } template auto rptr(const MArray& ma) -> decltype(ma.template getRangePtr()) { return ma.template getRangePtr(); } template auto dynamic(const MArray& ma, bool slice) -> std::shared_ptr> { DynamicRangeFactory drf(ma.range()->space()); if(slice){ return std::make_shared> ( std::dynamic_pointer_cast( drf.create() ), ma.data() ); } else { return std::make_shared> ( std::dynamic_pointer_cast( drf.create() ), ma.vdata() ); } } template auto mdynamic(MArray& ma, bool slice) -> std::shared_ptr> { DynamicRangeFactory drf(ma.range()->space()); if(slice){ return std::make_shared> ( std::dynamic_pointer_cast( drf.create() ), ma.data() ); } else { return std::make_shared> ( std::dynamic_pointer_cast( drf.create() ), ma.vdata() ); } } namespace { template struct CopyRanges { template static inline void exec(const Space1& space1, Space2& space2) { std::get(space2) = std::get(space1); CopyRanges::exec(space1,space2); } }; template <> struct CopyRanges<0> { template static inline void exec(const Space1& space1, Space2& space2) { std::get<0>(space2) = std::get<0>(space1); } }; } template auto anonToDynView(const ArrayBase& ma) -> ConstSlice { constexpr size_t LAST = sizeof...(RangeTypes)+1; DynamicRangeFactory drf(rptr(ma)->orig()); std::tuple,std::shared_ptr..., std::shared_ptr> mNSpace; CopyRanges::exec(ma.range()->space(),mNSpace); std::get(mNSpace) = createExplicit( drf ); return ConstSlice(mNSpace, ma.data()); } template auto anonToDynView(MutableArrayBase& ma) -> Slice { constexpr size_t LAST = sizeof...(RangeTypes)+1; DynamicRangeFactory drf(rptr(ma)->orig()); std::tuple,std::shared_ptr..., std::shared_ptr> mNSpace; CopyRanges::exec(ma.range()->space(),mNSpace); std::get(mNSpace) = createExplicit( drf ); return Slice(mNSpace, ma.data()); } template auto dynToAnonMove(Array&& ma) -> Array { constexpr size_t LAST = sizeof...(RangeTypes)+1; AnonymousRangeFactory arf(rptr(ma)->orig()); std::tuple,std::shared_ptr..., std::shared_ptr> mNSpace; CopyRanges::exec(ma.range()->space(),mNSpace); std::get(mNSpace) = createExplicit( arf ); return ma.format(mNSpace); } template auto anonToDynView(const ArrayBase& ma) -> ConstSlice { DynamicRangeFactory drf(rptr<0>(ma)->orig()); auto mNSpace = std::make_tuple( createExplicit( drf ) ); return ConstSlice(mNSpace, ma.data()); } template auto anonToDynView(MutableArrayBase& ma) -> Slice { DynamicRangeFactory drf(rptr<0>(ma)->orig()); auto mNSpace = std::make_tuple( createExplicit( drf ) ); return Slice(mNSpace, ma.data()); } template auto dynToAnonMove(Array&& ma) -> Array { AnonymousRangeFactory arf(rptr<0>(ma)->orig()); auto mNSpace = std::make_tuple( createExplicit( arf ) ); return ma.format(mNSpace); } template auto metaSlice(const std::shared_ptr& r) -> ConstSlice { ClassicRF crf(r->size()); return ConstSlice( createExplicit(crf), &r->get(0) ); } template auto metaSlice(const std::shared_ptr& r, const std::shared_ptr& ro) -> ConstSlice { return ConstSlice( ro, &r->get(0) ); } template auto mkArray(const std::shared_ptr&... rs) -> Array { return Array(rs...); } template auto mkArray(const std::shared_ptr&... rs, const T& val) -> Array { return Array(rs..., val); } template auto mkArrayPtr(const std::shared_ptr&... rs) -> std::shared_ptr> { return std::make_shared>(rs...); } }