#include "map_range.h" #include namespace CNORXZ { namespace { using namespace CNORXZInternal; } /************** * OpExpr * **************/ template OpExpr::OpExpr(const Op& mapf, const Index* ind, size_t step, Expr ex) : mIndPtr(ind), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr( ex ), mOp(mapf), //mExt(ex.rootSteps( reinterpret_cast( mIndPtr ))) mExt( mOp.rootSteps( reinterpret_cast( mIndPtr ) ).extend ( ex.rootSteps( reinterpret_cast( mIndPtr ) ) ) ) { assert(mIndPtr != nullptr); } template std::shared_ptr OpExpr::deepCopy() const { return std::make_shared>(*this); } template inline void OpExpr::operator()(size_t mlast, DExt last) { operator()(mlast, std::dynamic_pointer_cast>(last)->ext()); } template inline void OpExpr::operator()(size_t mlast, ExtType last) { constexpr size_t NEXT = Op::SIZE; const ExtType nxpos = last; const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) ); if(pos != mIndPtr->max()){ const ExtType npos = last + mExt*pos; const size_t mnpos = PosForward::valuex(mlast, mStep, pos); mExpr(mnpos, getX( npos ) ); } } template inline void OpExpr::operator()(size_t mlast) { const ExtType last; constexpr size_t NEXT = Op::SIZE; const ExtType nxpos = last; const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) ); if(pos != mIndPtr->max()){ const ExtType npos = last + mExt*pos; const size_t mnpos = PosForward::valuex(mlast, mStep, pos); mExpr(mnpos, getX( npos )); } } template auto OpExpr::rootSteps(std::intptr_t iPtrNum) const -> ExtType { return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) ); //return mExpr.rootSteps(iPtrNum).extend( mOp.rootSteps(iPtrNum) ); } template DExt OpExpr::dRootSteps(std::intptr_t iPtrNum) const { return std::make_shared>(rootSteps(iPtrNum)); } template DExt OpExpr::dExtension() const { return std::make_shared>(mExt); } /****************** * MapIndex * ******************/ template template GenMapIndex::GenMapIndex(const std::shared_ptr& range) : IndexInterface,typename Op::value_type>(range, 0) { std::get(mBlockSizes) = 1; sfor_mn ( [&](auto i) { auto r = range->template getPtr(); std::get(mIPack) = r->beginPtr(); *std::get(mIPack) = 0; std::get(mBlockSizes) = sfor_p ( [&](auto j) { return std::get(mIPack)->max(); } , [&](auto a, auto b) { return a * b; }); return 0; }); IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); mOutIndex = std::make_shared ( std::dynamic_pointer_cast( IB::mRangePtr )->outRange()->begin() ); } template template GenMapIndex& GenMapIndex::up() { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos += sfor_p ( [&](auto i) { return std::get(mIPack)->max(); }, [&](auto a, auto b) { return a * b; } ); sfor_m ( [&](auto i) { auto& si = *std::get( mIPack ); if(si.last() and i != 0) { si = 0; return true; } else { ++si; return false; } return false; } ); return *this; } template template GenMapIndex& GenMapIndex::down() { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos -= sfor_p ( [&](auto i) { return std::get(mIPack)->max(); }, [&](auto a, auto b) { return a * b; } ); sfor_m ( [&](auto i) { auto& si = *std::get( mIPack ); if(si.first() and i != 0) { si = si.max()-1; return true; } else { --si; return false; } return false; } ); return *this; } template template auto GenMapIndex::get() const -> decltype( *std::get( mIPack ) )& { return *std::get(mIPack); } template template auto GenMapIndex::getPtr() const -> decltype( std::get( mIPack ) )& { return std::get(mIPack); } template auto GenMapIndex::outIndex() const -> std::shared_ptr { return mOutIndex; } template GenMapIndex& GenMapIndex::operator()(const std::shared_ptr&... indices) { return (*this)(std::make_tuple(indices...)); } template GenMapIndex& GenMapIndex::operator()(const std::tuple...>& indices) { sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { std::get(mIPack) = std::get(indices); return 0; } ); RangeHelper::setIndexPack(mIPack, IB::mPos); return *this; } template IndexType GenMapIndex::type() const { return IndexType::MULTI; } template GenMapIndex& GenMapIndex::operator=(size_t pos) { (*mOutIndex) = pos; IB::mPos = mOutIndex->pos(); return *this; } template GenMapIndex& GenMapIndex::operator++() { ++(*mOutIndex); IB::mPos = mOutIndex->pos(); return *this; } template GenMapIndex& GenMapIndex::operator--() { --(*mOutIndex); IB::mPos = mOutIndex->pos(); return *this; } template int GenMapIndex::pp(std::intptr_t idxPtrNum) { mOutIndex->pp(idxPtrNum); IB::mPos = mOutIndex->pos(); return 1; } template int GenMapIndex::mm(std::intptr_t idxPtrNum) { mOutIndex->mm(idxPtrNum); IB::mPos = mOutIndex->pos(); return 1; } template std::string GenMapIndex::stringMeta() const { return std::dynamic_pointer_cast( IB::mRangePtr )->stringMeta(IB::mPos); } template typename GenMapIndex::MetaType GenMapIndex::meta() const { return mOutIndex->meta(); } template GenMapIndex& GenMapIndex::at(const MetaType& metaPos) { mOutIndex->at(metaPos); IB::mPos = mOutIndex->pos(); return *this; } template size_t GenMapIndex::posAt(const MetaType& metaPos) const { return range()->outRange()->getMeta(metaPos); } template size_t GenMapIndex::dim() const { return sizeof...(Indices); } template bool GenMapIndex::first() const { return IB::mPos == 0; } template bool GenMapIndex::last() const { return IB::mPos == IB::mMax - 1; } template std::shared_ptr::RangeType> GenMapIndex::range() const { return std::dynamic_pointer_cast( IB::mRangePtr ); } template template auto GenMapIndex::getPtr() -> decltype( std::get( mIPack ) )& { return std::get(mIPack); } template size_t GenMapIndex::getStepSize(size_t n) const { if(n >= sizeof...(Indices)){ assert(0); // throw !! } return mBlockSizes[n+1]; } template template auto GenMapIndex::ifor(size_t step, Exprs exs) const { return RangeHelper::mkFor<0> (0, mIPack, mBlockSizes, OpExpr,Exprs,XSTYPE> ( range()->map(), this, step, exs )); } template template auto GenMapIndex::pifor(size_t step, Exprs exs) const { return ifor(step, exs); } template template auto GenMapIndex::iforh(size_t step, Exprs exs) const { return ifor(step, exs); } /************************* * MapRangeFactory * *************************/ template template GenMapRangeFactory::GenMapRangeFactory(const std::shared_ptr& outr, const std::tuple& mapf, const std::shared_ptr&... rs) { mProd = std::shared_ptr< GenMapRange > ( new GenMapRange( outr, mapf, rs... ) ); } template template GenMapRangeFactory::GenMapRangeFactory(const std::shared_ptr& outr, const std::tuple& mapf, const typename GenMapRange::Space& st) { mProd = std::shared_ptr< GenMapRange > ( new GenMapRange( outr, mapf, st ) ); } template template GenMapRangeFactory::GenMapRangeFactory(const std::tuple& mapf, const std::shared_ptr&... rs) { mProd = std::shared_ptr< GenMapRange > ( new GenMapRange( mapf, rs... ) ); } template template GenMapRangeFactory::GenMapRangeFactory(const std::tuple& mapf, const typename GenMapRange::Space& st) { mProd = std::shared_ptr< GenMapRange > ( new GenMapRange( mapf, st ) ); } template std::shared_ptr GenMapRangeFactory::create() { mProd = checkIfCreated( std::dynamic_pointer_cast( mProd )->mSpace ); setSelf(); return mProd; } template std::shared_ptr GenMapRangeFactory::checkIfCreated(const std::tuple...>& ptp) { std::shared_ptr out; bool check = false; for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){ if(x.second.size() == sizeof...(Ranges)){ check = sfor_p<0,sizeof...(Ranges)> ( [&](auto i) { return reinterpret_cast( std::get(ptp).get() ) == x.second[i]; }, [&](auto a, auto b) { return a and b; } ); if(check){ out = x.first; break; } } } if(not check){ vector pv(sizeof...(Ranges)); sfor_pn<0,sizeof...(Ranges)> ( [&](auto i) { pv[i] = reinterpret_cast( std::get(ptp).get() ); return 0; } ); pv.push_back( reinterpret_cast ( &std::dynamic_pointer_cast( mProd )->mMapf ) ); MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv; out = mProd; } return out; } /****************** * MapRange * ******************/ template struct OutRangeMaker {}; template <> struct OutRangeMaker { template static void mk(std::shared_ptr& outRange, Array& mapMult, const MapF& mapf) { std::map mult; for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) { mult[mapf[ii]]++; } vector outmeta(mult.size()); vector outmult(mult.size()); size_t cnt = 0; for(auto& x: mult){ outmeta[cnt] = x.first; outmult[cnt] = x.second; ++cnt; } typename ORType::FType orf(outmeta); outRange = std::dynamic_pointer_cast( orf.create() ); mapMult = Array( outRange, outmult ); } }; template <> struct OutRangeMaker { template static void mk(std::shared_ptr& outRange, Array& mapMult, const MapF& mapf) { static_assert( std::is_same::value, "out range value type for NONE must be size_t" ); size_t max = 0; for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) { max = mapf[ii]+1 > max ? mapf[ii]+1 : max; } vector mult(max,0); for(auto ii = mapf.begin(); ii.max() != ii.pos(); ++ii) { mult[mapf[ii]]++; } vector outmult(mult.size()); size_t cnt = 0; for(auto& x: mult){ outmult[cnt++] = x; } typename ORType::FType orf(max); outRange = std::dynamic_pointer_cast( orf.create() ); mapMult = Array( outRange, outmult ); } }; template template void GenMapRange::mkOutRange(const MA& mapf) { //FunctionalArray fma(mSpace, mMapf); OutRangeMaker::mk(mOutRange,mMapMult,mapf); auto i = mapf.begin(); mMapPos.resize(i.max()); for(; i.pos() != i.max(); ++i){ mMapPos[i.pos()] = mOutRange->getMeta( mapf[i] ); } } template template GenMapRange::GenMapRange(const std::shared_ptr& outr, const std::tuple& mapf, const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)), mMapf(std::get<0>(mapf)), mOutRange(outr), mMapMult(mOutRange,0), mMapPos(std::get<1>(mapf).size(),mOutRange->size()) { auto& ma = std::get<1>(mapf); auto jj = mMapMult.begin(); for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){ ++mMapMult[jj.at(ma[ii])]; mMapPos[ii.pos()] = jj.pos(); } } template template GenMapRange::GenMapRange(const std::shared_ptr& outr, const std::tuple& mapf, const Space& space) : mSpace(space), mMapf(std::get<0>(mapf)), mOutRange(outr), mMapMult(mOutRange,0), mMapPos(std::get<1>(mapf).size(),mOutRange->size()) { auto& ma = std::get<1>(mapf); auto jj = mMapMult.begin(); for(auto ii = ma.begin(); ii.pos() != ii.max(); ++ii){ ++mMapMult[jj.at(ma[ii])]; mMapPos[ii.pos()] = jj.pos(); } } template template GenMapRange::GenMapRange(const std::tuple& mapf, const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)), mMapf(std::get<0>(mapf)) { mkOutRange(std::get<1>(mapf)); } template template GenMapRange::GenMapRange(const std::tuple& mapf, const Space& space) : mSpace( space ), mMapf(std::get<0>(mapf)) { mkOutRange(std::get<1>(mapf)); } template template auto GenMapRange::get() const -> decltype( *std::get( mSpace ) )& { return *std::get(mSpace); } template template auto GenMapRange::getPtr() const -> decltype( std::get( mSpace ) )& { return std::get(mSpace); } template auto GenMapRange::outRange() const -> std::shared_ptr { return mOutRange; } template const Op& GenMapRange::map() const { return mMapf; } template size_t GenMapRange::dim() const { return sdim; } template size_t GenMapRange::size() const { return mOutRange->size(); } template SpaceType GenMapRange::spaceType() const { return SpaceType::ANY; } template const typename GenMapRange::Space& GenMapRange::space() const { return mSpace; } template vector GenMapRange::typeNum() const { vector o; RangeHelper::getTypeNum(o,mSpace); return o; } template size_t GenMapRange::cmeta(char* target, size_t pos) const { //MetaType* xtarget = reinterpret_cast(target); assert(0); return 0; } template size_t GenMapRange::cmetaSize() const { return RangeHelper::getCMetaSize<0>(mSpace); } template std::string GenMapRange::stringMeta(size_t pos) const { auto i = begin(); i = pos; return "[ " + RangeHelper::getStringMeta<0>(i) + " ]"; } template vector GenMapRange::data() const { DataHeader h = dataHeader(); vector out; //out.reserve(h.metaSize + sizeof(DataHeader)); char* hcp = reinterpret_cast(&h); out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); sfor_pn<0,sizeof...(Ranges)> ( [&](auto i) { vector part = std::get(mSpace)->data(); out.insert(out.end(), part.begin(), part.end()); return 0; } ); return out; } template DataHeader GenMapRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::ANY ); h.metaSize = sizeof...(Ranges); h.multiple = 1; return h; } template typename GenMapRange::IndexType GenMapRange::begin() const { GenMapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; return i; } template typename GenMapRange::IndexType GenMapRange::end() const { GenMapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); i = size(); return i; } template auto GenMapRange::mapMultiplicity() const -> const Array& { return mMapMult; } template auto GenMapRange::explMapMultiplicity() const -> ConstSlice { /* auto tmp = mMapMult; return tmp.format( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); */ return mMapMult.slformat(std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ))); } template vector GenMapRange::mapPos() const { return mMapPos; } /* template template auto GenMapRange::cat(const std::shared_ptr >& erange) -> std::shared_ptr > { auto crange = std::tuple_cat(mSpace, erange->space()); MapRangeFactory rf(crange); return std::dynamic_pointer_cast >(rf.create()); } */ }