#include "map_range.h" #include 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) { 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 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 GenMapIndex::GenMapIndex(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 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()(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) { IB::mPos = pos; RPackNum::setIndexPack(mIPack, pos); return *this; } template GenMapIndex& GenMapIndex::operator++() { RPackNum::pp( mIPack ); ++IB::mPos; return *this; } template GenMapIndex& GenMapIndex::operator--() { RPackNum::mm( mIPack ); --IB::mPos; return *this; } template int GenMapIndex::pp(std::intptr_t idxPtrNum) { int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); IB::mPos += tmp; return tmp; } template int GenMapIndex::mm(std::intptr_t idxPtrNum) { int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); IB::mPos -= tmp; return tmp; } 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); return metaTuple; } template GenMapIndex& GenMapIndex::at(const MetaType& metaPos) { RPackNum::setMeta(mIPack, metaPos); IB::mPos = RPackNum::makePos(mIPack); return *this; } 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 ( range()->map(), mIPack, mOutIndex, step, exs ) ) ) { return RPackNum::mkForh (step, mIPack, mBlockSizes, OpExpr ( range()->map(), mIPack, mOutIndex, 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(Exprs exs) const -> decltype(RPackNum::mkForh(mIPack, exs)) { return RPackNum::mkForh(mIPack, exs); } */ /************************* * MapRangeFactory * *************************/ template GenMapRangeFactory::GenMapRangeFactory(const MapF& mapf, const std::shared_ptr&... rs) { mProd = std::shared_ptr< GenMapRange > ( new GenMapRange( mapf, rs... ) ); } template GenMapRangeFactory::GenMapRangeFactory(const MapF& 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 void GenMapRange::mkOutRange() { //FunctionalMultiArray fma(mSpace, mMapf); OutRangeMaker::mk(mOutRange,mMapMult,mMapf); } template GenMapRange::GenMapRange(const MapF& mapf, const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)), mMapf(mapf) { mkOutRange(); } template GenMapRange::GenMapRange(const MapF& mapf, const Space& space) : mSpace( space ), mMapf(mapf) { mkOutRange(); } 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 MapF& 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 std::string GenMapRange::stringMeta(size_t pos) const { auto i = begin(); i = pos; return "[ " + RPackNum::metaTupleToString(i.meta()) + " ]"; } 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 -> MultiArray { auto tmp = mMapMult; return tmp.format( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis )) ); } template vector GenMapRange::mapPos() const { auto i = mMapf.begin(); vector out(i.max()); for(; i.pos() != i.max(); ++i){ out[i.pos()] = mOutRange->getMeta( mMapf[i] ); } return out; } /* 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()); } */ }