#include "map_range.h" #include namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /************** * 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, Getter::template 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, Getter::template 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); } // -> define in range_base.cc //std::shared_ptr mkMULTI(const char** dp); /****************** * MapIndex * ******************/ /* template MapIndex::MapIndex(const MapIndex& in) : IndexInterface >(in) { RPackNum::copy(mIPack, in); IB::mPos = RPackNum::makePos(mIPack); } template MapIndex& MapIndex::operator=(const MapIndex& in) { IndexI::operator=(in); RPackNum::copy(mIPack, in); IB::mPos = RPackNum::makePos(mIPack); return *this; } */ template template GenMapIndex::GenMapIndex(const std::shared_ptr& range) : IndexInterface,typename Op::value_type>(range, 0) { RPackNum::construct(mIPack, *range); IB::mPos = RPackNum::makePos(mIPack); std::get(mBlockSizes) = 1; RPackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! 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 += RPackNum::blockSize( mIPack ); RPackNum::pp( mIPack ); return *this; } template template GenMapIndex& GenMapIndex::down() { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos -= RPackNum::blockSize( mIPack ); RPackNum::mm( mIPack ); 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) { RPackNum::swapIndices(mIPack, indices...); RPackNum::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(); //RPackNum::setIndexPack(mIPack, pos); return *this; } template GenMapIndex& GenMapIndex::operator++() { //RPackNum::pp( mIPack ); ++(*mOutIndex); IB::mPos = mOutIndex->pos(); return *this; } template GenMapIndex& GenMapIndex::operator--() { //RPackNum::mm( mIPack ); --(*mOutIndex); IB::mPos = mOutIndex->pos(); return *this; } template int GenMapIndex::pp(std::intptr_t idxPtrNum) { //int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); mOutIndex->pp(idxPtrNum); IB::mPos = mOutIndex->pos(); //IB::mPos += tmp; return 1; } template int GenMapIndex::mm(std::intptr_t idxPtrNum) { //int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); mOutIndex->mm(idxPtrNum); IB::mPos = mOutIndex->pos(); //IB::mPos -= tmp; 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 { //MetaType metaTuple; //RPackNum::getMetaPos(metaTuple, mIPack); //assert(0); return mOutIndex->meta(); } template GenMapIndex& GenMapIndex::at(const MetaType& metaPos) { //RPackNum::setMeta(mIPack, metaPos); //IB::mPos = RPackNum::makePos(mIPack); 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 std::string GenMapIndex::id() const { return std::string("mul") + std::to_string(IB::mId); } template void GenMapIndex::print(size_t offset) const { if(offset == 0){ std::cout << " === " << std::endl; } for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } std::cout << id() << "[" << reinterpret_cast(this) << "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl; RPackNum::printIndex(mIPack, offset+1); } template template auto GenMapIndex::ifor(size_t step, Exprs exs) const -> decltype(RPackNum::mkForh (step, mIPack, mBlockSizes, OpExpr,Exprs,XSTYPE> ( range()->map(), this, step, exs ) ) ) { return RPackNum::mkForh (0, mIPack, mBlockSizes, OpExpr,Exprs,XSTYPE> ( range()->map(), this, step, exs ) ); } template template auto GenMapIndex::pifor(size_t step, Exprs exs) const -> decltype(ifor(step, exs)) { return ifor(step, exs); } template template auto GenMapIndex::iforh(size_t step, Exprs exs) const -> decltype(ifor(step, exs)) { 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 = RPackNum::checkIfCreated(ptp, x.second); if(check){ out = x.first; break; } } } if(not check){ vector pv(sizeof...(Ranges)); RPackNum::RangesToVec(ptp, pv); 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, MultiArray& 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 = MultiArray( outRange, outmult ); } }; template <> struct OutRangeMaker { template static void mk(std::shared_ptr& outRange, MultiArray& 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 = MultiArray( outRange, outmult ); } }; template template void GenMapRange::mkOutRange(const MA& mapf) { //FunctionalMultiArray 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(); //return RPackNum::getSize(mSpace); } 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; RPackNum::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; //return RPackNum::getCMeta(xtarget,pos,mSpace,cmetaSize()); } template size_t GenMapRange::cmetaSize() const { return RPackNum::getCMetaSize(mSpace); } template std::string GenMapRange::stringMeta(size_t pos) const { auto i = begin(); i = pos; return "[ " + RPackNum::getStringMeta(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)); RPackNum::fillRangeDataVec(out, mSpace); 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 MultiArray& { 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()); } */ }