#include "ranges/anonymous_range.h" namespace MultiArrayTools { /****************************** * AnonymousRangeFactory * ******************************/ AnonymousRangeFactory::AnonymousRangeFactory() { mProd = std::shared_ptr( new AnonymousRange() ); } std::map,vector > AnonymousRangeFactory::mAleadyCreated; AnonymousRangeFactory::AnonymousRangeFactory(const vector>& origs) { mProd = std::shared_ptr( new AnonymousRange( origs ) ); } std::shared_ptr AnonymousRangeFactory::checkIfCreated(const 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){ 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; } std::shared_ptr AnonymousRangeFactory::create() { mProd = checkIfCreated(std::dynamic_pointer_cast(mProd)->mOrig); setSelf(); mProductCreated = true; return mProd; } /*********************** * AnonymousRange * ***********************/ size_t AnonymousRange::get(size_t pos) const { return pos; } size_t AnonymousRange::getMeta(size_t metaPos) const { return metaPos; } size_t AnonymousRange::size() const { return mSize; } size_t AnonymousRange::dim() const { return 1; } SpaceType AnonymousRange::spaceType() const { return SpaceType::ANON; } bool AnonymousRange::isEmpty() const { return mEmpty; } vector AnonymousRange::typeNum() const { vector o; for(auto& x: mOrig){ auto tn = x->typeNum(); o.insert(o.end(), tn.begin(), tn.end()); } return o; } size_t AnonymousRange::cmeta(char* target, size_t pos) const { size_t out = 0; size_t off = cmetaSize(); for(size_t i = mOrig.size(); i != 0; --i) { auto& x = mOrig[i-1]; const size_t redpos = pos % x->size(); const size_t s = x->cmetaSize(); out += s; off -= s; pos -= redpos; pos /= x->size(); x->cmeta(target+off,redpos); } return out; } size_t AnonymousRange::cmetaSize() const { size_t out = 0; for(size_t i = mOrig.size(); i != 0; --i) { auto& x = mOrig[i-1]; out += x->cmetaSize(); } return out; } std::string AnonymousRange::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; } vector AnonymousRange::data() const { DataHeader h = dataHeader(); 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; } DataHeader AnonymousRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::ANON ); h.metaSize = mOrig.size(); h.multiple = 1; return h; } size_t AnonymousRange::anonymousDim() const { return mOrig.size(); } typename AnonymousRange::IndexType AnonymousRange::begin() const { AnonymousIndex i (std::dynamic_pointer_cast ( std::shared_ptr(RB::mThis) ) ); i = 0; return i; } typename AnonymousRange::IndexType AnonymousRange::end() const { AnonymousIndex i (std::dynamic_pointer_cast ( std::shared_ptr(RB::mThis) ) ); i = size(); return i; } std::shared_ptr AnonymousRange::sub(size_t num) const { return mOrig.at(num); } std::shared_ptr AnonymousRange::sreplace(const std::shared_ptr in, size_t num) const { assert(mOrig[num]->size() == in->size()); auto tmp = mOrig; tmp[num] = in; AnonymousRangeFactory arf(tmp); return std::dynamic_pointer_cast(arf.create()); } std::shared_ptr AnonymousRange::sreplace(const vector>& in, size_t num) const { size_t nsize = 1; for(auto& x: in){ nsize *= x->size(); } assert(mOrig[num]->size() == nsize); auto norig = mOrig; norig.resize(mOrig.size() + in.size() - 1); for(size_t i = 0; i != num; ++i){ norig[i] = mOrig[i]; } for(size_t i = 0; i != in.size(); ++i){ norig[num+i] = in[i]; } for(size_t i = num + 1 ; i < mOrig.size(); ++i){ norig[in.size()+i-1] = mOrig[i]; } //mOrig = std::move( norig ); AnonymousRangeFactory arf(norig); return std::dynamic_pointer_cast(arf.create()); } std::shared_ptr AnonymousRange::sreplace(const std::shared_ptr& in, const vector& num) const { if(num.size() != 0){ size_t cnt = num[0]; size_t rep_size = 1; // assert continuous ordering or replaced ranges: for(auto& x: num){ assert(cnt++ == x); rep_size *= mOrig[x]->size(); } assert(rep_size == in->size()); vector> norig; norig.reserve(mOrig.size()-num.size()+1); norig.insert(norig.end(),mOrig.begin(),mOrig.begin()+num[0]); norig.push_back(in); norig.insert(norig.end(),mOrig.begin()+num.back()+1,mOrig.end()); AnonymousRangeFactory arf(norig); return std::dynamic_pointer_cast(arf.create()); } else { return std::dynamic_pointer_cast( std::shared_ptr(RB::mThis) ); } } const vector >& AnonymousRange::orig() const { return mOrig; } GenSingleRange::GenSingleRange(const vector>& origs) : RangeInterface(), mOrig(origs) { mSize = 1; for(auto& x: mOrig){ mSize *= x->size(); } if(mOrig.size()){ mEmpty = false; } } /***************** * Functions * *****************/ std::shared_ptr defaultRange(size_t size ) { AnonymousRangeFactory arf ( std::dynamic_pointer_cast (AnonymousRange::factory().create() ) ); return std::dynamic_pointer_cast( arf.create() ); } } // end namespace MultiArrayTools