#include "map_range.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /************** * OpExpr * **************/ template OpExpr::OpExpr(const MapF& mapf, const IndexPack& ipack, const std::shared_ptr& oind, size_t step, Expr ex) : mIndPtr(oind.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step), mExpr( std::forward(ex) ), mOp(mkMapOp(mapf, ipack)), //mExt(ex.rootSteps( reinterpret_cast( mIndPtr ))) mExt( mOp.rootSteps( reinterpret_cast( mIndPtr ) ).extend ( ex.rootSteps( reinterpret_cast( mIndPtr ) ) ) ) { assert(mIndPtr != nullptr); } template inline void OpExpr::operator()(size_t mlast, ExtType last) const { constexpr size_t NEXT = Op::SIZE; const ExtType nxpos = last; const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) ); //VCHECK(pos); const ExtType npos = last + mExt*pos; //VCHECK(npos.next().next().val()); const size_t mnpos = PosForward::valuex(mlast, mStep, pos); mExpr(mnpos, Getter::template getX( npos ) ); } template inline void OpExpr::operator()(size_t mlast) const { const ExtType last; constexpr size_t NEXT = Op::SIZE; const ExtType nxpos = last; const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) ); 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) ); } // -> 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 MapIndex::MapIndex(const std::shared_ptr& range) : IndexInterface,std::tuple >(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 MapIndex& MapIndex::up() { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos += RPackNum::blockSize( mIPack ); RPackNum::pp( mIPack ); return *this; } template template MapIndex& MapIndex::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 MapIndex::get() const -> decltype( *std::get( mIPack ) )& { return *std::get(mIPack); } template template auto MapIndex::getPtr() const -> decltype( std::get( mIPack ) )& { return std::get(mIPack); } template auto MapIndex::outIndex() const -> std::shared_ptr { return mOutIndex; } template MapIndex& MapIndex::operator()(std::shared_ptr&... indices) { RPackNum::swapIndices(mIPack, indices...); RPackNum::setIndexPack(mIPack, IB::mPos); return *this; } template IndexType MapIndex::type() const { return IndexType::MULTI; } template MapIndex& MapIndex::operator=(size_t pos) { IB::mPos = pos; RPackNum::setIndexPack(mIPack, pos); return *this; } template MapIndex& MapIndex::operator++() { RPackNum::pp( mIPack ); ++IB::mPos; return *this; } template MapIndex& MapIndex::operator--() { RPackNum::mm( mIPack ); --IB::mPos; return *this; } template int MapIndex::pp(std::intptr_t idxPtrNum) { int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); IB::mPos += tmp; return tmp; } template int MapIndex::mm(std::intptr_t idxPtrNum) { int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); IB::mPos -= tmp; return tmp; } template std::string MapIndex::stringMeta() const { return std::dynamic_pointer_cast( IB::mRangePtr )->stringMeta(IB::mPos); } template typename MapIndex::MetaType MapIndex::meta() const { MetaType metaTuple; RPackNum::getMetaPos(metaTuple, mIPack); return metaTuple; } template MapIndex& MapIndex::at(const MetaType& metaPos) { RPackNum::setMeta(mIPack, metaPos); IB::mPos = RPackNum::makePos(mIPack); return *this; } template size_t MapIndex::dim() const { return sizeof...(Indices); } template bool MapIndex::first() const { return IB::mPos == 0; } template bool MapIndex::last() const { return IB::mPos == IB::mMax - 1; } template std::shared_ptr::RangeType> MapIndex::range() const { return std::dynamic_pointer_cast( IB::mRangePtr ); } template template auto MapIndex::getPtr() -> decltype( std::get( mIPack ) )& { return std::get(mIPack); } template size_t MapIndex::getStepSize(size_t n) const { if(n >= sizeof...(Indices)){ assert(0); // throw !! } return mBlockSizes[n+1]; } template std::string MapIndex::id() const { return std::string("mul") + std::to_string(IB::mId); } template void MapIndex::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 MapIndex::ifor(size_t step, Exprs exs) const -> decltype(RPackNum::mkForh (step, mIPack, mBlockSizes, OpExpr ( range()->map(), mIPack, mOutIndex, step, exs ) ) ) { return RPackNum::mkForh (step, mIPack, mBlockSizes, OpExpr ( range()->map(), mIPack, mOutIndex, step, exs ) ); } /* template template auto MapIndex::iforh(Exprs exs) const -> decltype(RPackNum::mkForh(mIPack, exs)) { return RPackNum::mkForh(mIPack, exs); } */ /************************* * MapRangeFactory * *************************/ template MapRangeFactory::MapRangeFactory(const MapF& mapf, const std::shared_ptr&... rs) { mProd = std::shared_ptr< MapRange >( new MapRange( mapf, rs... ) ); } template MapRangeFactory::MapRangeFactory(const MapF& mapf, const typename MapRange::Space& st) { mProd = std::shared_ptr< MapRange >( new MapRange( mapf, st ) ); } template std::shared_ptr MapRangeFactory::create() { mProd = checkIfCreated( std::dynamic_pointer_cast( mProd )->mSpace ); setSelf(); return mProd; } template std::shared_ptr MapRangeFactory::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){ std::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 void MapRange::mkOutRange() { //FunctionalMultiArray fma(mSpace, mMapf); std::map mult; for(auto ii = mMapf.begin(); ii.max() != ii.pos(); ++ii) { mult[mMapf[ii]]++; } std::vector outmeta(mult.size()); std::vector outmult(mult.size()); size_t cnt = 0; for(auto& x: mult){ outmeta[cnt] = x.first; outmult[cnt] = x.second; ++cnt; } ORFType orf(outmeta); mOutRange = std::dynamic_pointer_cast( orf.create() ); mMapMult = MultiArray( mOutRange, outmult ); } template MapRange::MapRange(const MapF& mapf, const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)), mMapf(mapf) { mkOutRange(); } template MapRange::MapRange(const MapF& mapf, const Space& space) : mSpace( space ), mMapf(mapf) { mkOutRange(); } template template auto MapRange::get() const -> decltype( *std::get( mSpace ) )& { return *std::get(mSpace); } template template auto MapRange::getPtr() const -> decltype( std::get( mSpace ) )& { return std::get(mSpace); } template auto MapRange::outRange() const -> std::shared_ptr { return mOutRange; } template const MapF& MapRange::map() const { return mMapf; } template size_t MapRange::dim() const { return sdim; } template size_t MapRange::size() const { return mOutRange->size(); //return RPackNum::getSize(mSpace); } template SpaceType MapRange::spaceType() const { return SpaceType::ANY; } template const typename MapRange::Space& MapRange::space() const { return mSpace; } template std::string MapRange::stringMeta(size_t pos) const { auto i = begin(); i = pos; return "[ " + RPackNum::metaTupleToString(i.meta()) + " ]"; } template std::vector MapRange::data() const { DataHeader h = dataHeader(); std::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 MapRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::ANY ); h.metaSize = sizeof...(Ranges); h.multiple = 1; return h; } template typename MapRange::IndexType MapRange::begin() const { MapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; return i; } template typename MapRange::IndexType MapRange::end() const { MapIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); i = size(); return i; } template auto MapRange::mapMultiplicity() const -> const MultiArray& { return mMapMult; } template auto MapRange::explMapMultiplicity() const -> MultiArray { auto tmp = mMapMult; return tmp.format( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); } template template auto MapRange::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()); } }