//#include "ranges/dynamic_range.h" //#include "ranges/dynamic_meta.h" #include "rpack_num.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /************************* * IndexWrapperBase * *************************/ template template ExpressionHolder IndexWrapperBase::ifor(size_t step, ExpressionHolder ex) const { return mEc->ifor(step, ex); } template template ExpressionHolder IndexWrapperBase::iforh(size_t step, ExpressionHolder ex) const { return mEc->iforh(step, ex); } template template ExpressionHolder IndexWrapperBase::ifori(size_t step, Expr ex) const { return mEc->ifori(step, ex); } template template ExpressionHolder IndexWrapperBase::iforhi(size_t step, Expr ex) const { return mEc->iforhi(step, ex); } template size_t IndexWrapper::getStepSizeComp(std::intptr_t j) const { return MultiArrayHelper::getStepSize(*mI, j); } /**************************** * DynamicRangeFactory * ****************************/ template template DynamicRangeFactory::DynamicRangeFactory(const std::tuple...>& origs) { mProd = std::shared_ptr( new DynamicRange( origs ) ); } template template DynamicRangeFactory::DynamicRangeFactory(std::shared_ptr... origs) { mProd = std::shared_ptr( new DynamicRange( origs... ) ); } template DynamicRangeFactory::DynamicRangeFactory(const std::vector>& origs) { mProd = std::shared_ptr( new DynamicRange( origs ) ); } template template void DynamicRangeFactory::append(std::shared_ptr r) { if(mProductCreated){ mProd = std::shared_ptr( new DynamicRange( *std::dynamic_pointer_cast(mProd) ) ); mProductCreated = false; } std::dynamic_pointer_cast(mProd)->mOrig.push_back(r); std::dynamic_pointer_cast(mProd)->mSize *= r->size(); std::dynamic_pointer_cast(mProd)->mEmpty = false; } template DynamicRangeFactory::DynamicRangeFactory() { mProd = std::shared_ptr( new DynamicRange() ); } // INSTANCIATE IF NEEDED!! template std::map,std::vector > DynamicRangeFactory::mAleadyCreated; template std::shared_ptr DynamicRangeFactory::checkIfCreated(const std::vector >& pvec) { std::shared_ptr out; bool check = false; for(auto& x: mAleadyCreated){ if(x.second.size() == pvec.size()){ check = true; for(size_t i = 0; i != x.second.size(); ++i){ if(x.second[i] != reinterpret_cast( pvec[i].get() ) ){ check = false; break; } } if(check == true){ out = x.first; break; } } } if(not check){ std::vector app(pvec.size()); for(size_t i = 0; i != app.size(); ++i){ app[i] = reinterpret_cast( pvec[i].get() ); } mAleadyCreated[mProd] = app; out = mProd; } return out; } template std::shared_ptr DynamicRangeFactory::create() { mProd = checkIfCreated(std::dynamic_pointer_cast>(mProd)->mOrig); setSelf(); mProductCreated = true; return mProd; } /********************* * DynamicIndex * *********************/ template DynamicIndex::DynamicIndex(const std::shared_ptr >& range) : IndexInterface(range, 0), mIVec(range->dim()) { size_t xx = 1; for(size_t i = mIVec.size()-1; i != 0; --i){ mIVec[i].second = xx; xx *= range->sub(i)->size(); } mIVec[0].second = xx; } template IndexType DynamicIndex::type() const { return IndexType::SINGLE; } template DynamicIndex& DynamicIndex::operator=(size_t pos) { IB::mPos = pos; return *this; } template DynamicIndex& DynamicIndex::operator++() { size_t ipos = mIVec.size()-1; auto& ii = mIVec[ipos].first; auto& jj = mIVec[ipos-1].first; while(ii->pos() == ii->max()-1 and ipos != 0) { (*ii) = 0; ++(*jj); --ipos; } return *this; } template DynamicIndex& DynamicIndex::operator--() { size_t ipos = mIVec.size()-1; auto& ii = mIVec[ipos].first; auto& jj = mIVec[ipos-1].first; while(ii->pos() == 0 and ipos != 0) { (*ii) = ii->max()-1; --(*jj); --ipos; } return *this; } template DynamicIndex& DynamicIndex::operator()(const IVecT& ivec) { mIVec = ivec; return *this; } template DynamicIndex& DynamicIndex::operator()(const std::vector>>& ivec) { assert(mIVec.size() == ivec.size()); for(size_t i = 0; i != mIVec.size(); ++i){ mIVec[i].first = ivec[i]; } return *this; } template template DynamicIndex& DynamicIndex::operator()(const std::shared_ptr&... is) { std::vector>> tmp = { std::make_shared>(is)... }; assert(mIVec.size() == tmp.size()); for(size_t i = 0; i != mIVec.size(); ++i){ mIVec[i].first = tmp[i]; } return *this; } template int DynamicIndex::pp(std::intptr_t idxPtrNum) { ++(*this); return 1; } template int DynamicIndex::mm(std::intptr_t idxPtrNum) { --(*this); return 1; } template std::string DynamicIndex::stringMeta() const { return std::dynamic_pointer_cast const>( IB::mRangePtr )->stringMeta(IB::mPos); } template typename DynamicIndex::MetaType DynamicIndex::meta() const { return std::dynamic_pointer_cast const>( IB::mRangePtr )->get(IB::mPos); } template const typename DynamicIndex::MetaType* DynamicIndex::metaPtr() const { return nullptr; } /* bool DynamicIndex::isMeta(const MetaType& metaPos) const { return mExplicitRangePtr->isMeta(metaPos); }*/ template DynamicIndex& DynamicIndex::at(const MetaType& metaPos) { (*this) = std::dynamic_pointer_cast const>( IB::mRangePtr )->getMeta( metaPos ); return *this; } template size_t DynamicIndex::posAt(const MetaType& metaPos) const { return std::dynamic_pointer_cast const>( IB::mRangePtr )->getMeta( metaPos ); } template size_t DynamicIndex::dim() const // = 1 { return mIVec.size(); } template bool DynamicIndex::last() const { return IB::mPos == IB::mMax - 1; } template bool DynamicIndex::first() const { return IB::mPos == 0; } template const IndexW& DynamicIndex::get(size_t n) const { return *mIVec[n].first; } template std::shared_ptr::RangeType> DynamicIndex::range() { return std::dynamic_pointer_cast( IB::mRangePtr ); } template template void DynamicIndex::getPtr() {} template size_t DynamicIndex::getStepSize(size_t n) const { return mIVec[n].second; } template std::string DynamicIndex::id() const { return std::string("dyn") + std::to_string(IB::mId); } template void DynamicIndex::print(size_t offset) { 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().first*/ << std::endl; } template struct ForMaker { template static inline auto mk(size_t i, size_t step, ExpressionHolder ex, const IVecT& ivec, bool hidden = false) -> ExpressionHolder { if(i != 0){ auto& ii = *ivec[i].first; return mk(i-1, step, (hidden ? ii.iforh(step*ivec[i].second, ex) : ii.ifor(step*ivec[i].second, ex)), ivec, hidden); } else { auto& ii = *ivec[0].first; return hidden ? ii.iforh(step*ivec[i].second, ex) : ii.ifor(step*ivec[i].second, ex); } } }; /* template template inline auto DynamicIndex::mkFor(size_t i, size_t step, ExpressionHolder ex, bool hidden) const -> ExpressionHolder { if(i != 0){ auto& ii = *mIVec[i].first; return mkFor(i-1, step, hidden ? ii.iforh(step, ex) : ii.ifor(step, ex)); } else { auto& ii = *mIVec[0].first; return hidden ? ii.iforh(step, ex) : ii.ifor(step, ex); } } */ template template ExpressionHolder DynamicIndex::ifor(size_t step, Expr ex) const { return ForMaker::mk(mIVec.size()-2, step, mIVec.back().first->ifori(step,ex), mIVec); } template template ExpressionHolder DynamicIndex::iforh(size_t step, Expr ex) const { return ForMaker::mk(mIVec.size()-2, step, mIVec.back().first->iforhi(step,ex), mIVec, true); } /*********************** * DynamicRange * ***********************/ template typename DynamicRange::MetaType DynamicRange::get(size_t pos) const { return MetaType(); // !!! } template size_t DynamicRange::getMeta(const MetaType& metaPos) const { return 0; // !!! } template size_t DynamicRange::size() const { return mSize; } template size_t DynamicRange::dim() const { return mOrig.size(); } template SpaceType DynamicRange::spaceType() const { return SpaceType::DYN; } template bool DynamicRange::isEmpty() const { return mEmpty; } template std::string DynamicRange::stringMeta(size_t pos) const { std::string out = "[ "; //size_t xpos = pos; for(size_t i = mOrig.size(); i != 0; --i) { auto& x = mOrig[i-1]; const size_t redpos = pos % x->size(); out = ( (i == mOrig.size()) ? out : out + " , " ) + x->stringMeta(redpos); pos -= redpos; pos /= x->size(); } out += " ]"; return out; } template std::vector DynamicRange::data() const { DataHeader h = dataHeader(); std::vector out; char* hcp = reinterpret_cast(&h); out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); for(auto& x: mOrig){ auto part = x->data(); out.insert(out.end(), part.begin(), part.end()); } return out; } template DataHeader DynamicRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::DYN ); h.metaSize = mOrig.size(); h.multiple = 1; return h; } template typename DynamicRange::IndexType DynamicRange::begin() const { DynamicIndex i (std::dynamic_pointer_cast ( std::shared_ptr(RB::mThis) ) ); i = 0; return i; } template typename DynamicRange::IndexType DynamicRange::end() const { DynamicIndex i (std::dynamic_pointer_cast ( std::shared_ptr(RB::mThis) ) ); i = size(); return i; } template std::shared_ptr DynamicRange::sub(size_t num) const { return mOrig.at(num); } template void DynamicRange::sreplace(const std::shared_ptr in, size_t num) { assert(mOrig[num]->size() == in->size()); mOrig[num] = in; } template template DynamicRange::DynamicRange(const std::tuple...>& origs) : RangeInterface>() { RPackNum::RangesToVec( origs, mOrig ); mSize = RPackNum::getSize( origs ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template template DynamicRange::DynamicRange(std::shared_ptr... origs) : RangeInterface>() { auto rst = std::make_tuple(origs...); RPackNum::RangesToVec( rst, mOrig ); mSize = RPackNum::getSize( rst ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template DynamicRange::DynamicRange(const std::vector>& origs) : RangeInterface>(), mOrig(origs) { mSize = 1; for(auto& x: mOrig){ mSize *= x->size(); } if(mOrig.size()){ mEmpty = false; } } template template std::shared_ptr DynamicRange::fullsub(size_t num) const { return std::dynamic_pointer_cast( mOrig.at(num) ); } template template std::shared_ptr > DynamicRange::scast(SIZET... sizes) const { std::tuple...> rtp; RPackNum::resolveRangeType(mOrig, rtp, 0, sizes...); MultiRangeFactory mrf(rtp); return std::dynamic_pointer_cast >( mrf.create() ); } template const std::vector >& DynamicRange::orig() const { return mOrig; } } // end namespace MultiArrayTools