diff --git a/src/index_base.cc b/src/index_base.cc index 1b47e70..352cc52 100644 --- a/src/index_base.cc +++ b/src/index_base.cc @@ -34,6 +34,18 @@ namespace MultiArrayTools return mRangePtr->size(); } + bool IndexBase::locked() const + { + return mLocked; + } + + IndexBase& IndexBase::lock(std::shared_ptr& idx) + { + mLocked = (idx.get() == this); + return *this; + } + + IndexBase::operator size_t() const { return pos(); diff --git a/src/index_base.h b/src/index_base.h index a0278f8..27a40ac 100644 --- a/src/index_base.h +++ b/src/index_base.h @@ -54,6 +54,9 @@ namespace MultiArrayTools virtual bool last() const = 0; virtual bool first() const = 0; + virtual bool locked() const; + virtual IndexBase& lock(std::shared_ptr& idx); + virtual std::shared_ptr getPtr(size_t n) const = 0; virtual operator size_t() const; @@ -64,6 +67,7 @@ namespace MultiArrayTools std::shared_ptr mRangePtr; size_t mPos; size_t mId; + bool mLocked = false; }; template diff --git a/src/multi_array_operation.cc b/src/multi_array_operation.cc index ea825c1..0589bb7 100644 --- a/src/multi_array_operation.cc +++ b/src/multi_array_operation.cc @@ -106,6 +106,8 @@ namespace MultiArrayTools std::dynamic_pointer_cast >( mrf.create() ); mIndex = std::make_shared( mr->begin() ); (*mIndex) = *index; + // -> find optimal block index !!! + // -> lock this index !!! for(*mIndex = 0; mIndex->pos() != mIndex->max(); ++(*mIndex)){ get() = mSecond.get(); } @@ -114,13 +116,15 @@ namespace MultiArrayTools template BlockBase& OperationMaster::get() { - return mArrayRef.data()[ mIndex->pos() ]; + block(); + return *mBlockPtr; } template const BlockBase& OperationMaster::get() const { - return mArrayRef.data()[ mIndex->pos() ]; + block(); + return *mBlockPtr; } template diff --git a/src/multi_array_operation.h b/src/multi_array_operation.h index 9e8fc69..80d1830 100644 --- a/src/multi_array_operation.h +++ b/src/multi_array_operation.h @@ -34,6 +34,7 @@ namespace MultiArrayTools BlockType getBlockType(std::shared_ptr i, std::shared_ptr j, bool first); + template class OperationBase @@ -120,6 +121,7 @@ namespace MultiArrayTools OperationBase const& mSecond; MutableMultiArrayBase& mArrayRef; std::shared_ptr mIndex; + }; diff --git a/src/multi_range.cc b/src/multi_range.cc index 3fe6107..71ee330 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -47,6 +47,7 @@ namespace MultiArrayTools { PackNum::construct(mIPack, *range); IB::mPos = PackNum::makePos(mIPack); + PackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! } template @@ -58,16 +59,15 @@ namespace MultiArrayTools template MultiIndex& MultiIndex::operator++() { - PackNum::pp( mIPack ); - ++IB::mPos; + // return step size -> add to IB::mPos + IB::mPos += PackNum::pp( mIPack, mBlockSizes ); return *this; } template MultiIndex& MultiIndex::operator--() { - PackNum::mm( mIPack ); - --IB::mPos; + IB::mPos -= PackNum::mm( mIPack, mBlockSizes ); return *this; } @@ -175,6 +175,14 @@ namespace MultiArrayTools return std::dynamic_pointer_cast( IB::mRangePtr ); } + template + MultiIndex& MultiIndex::lock(std::shared_ptr& idx) + { + IB::mLocked = (idx.get() == this); + PackNum::lock(mIPack, idx); + return *this; + } + template MultiIndex& MultiIndex::operator()(std::shared_ptr&... indices) { diff --git a/src/multi_range.h b/src/multi_range.h index 4aca29b..61c507e 100644 --- a/src/multi_range.h +++ b/src/multi_range.h @@ -27,7 +27,8 @@ namespace MultiArrayTools protected: IndexPack mIPack; - + std::array mBlockSizes; + public: MultiIndex() = delete; // NO DEFAULT HERE !!! @@ -70,6 +71,8 @@ namespace MultiArrayTools std::shared_ptr range() const; + virtual MultiIndex& lock(std::shared_ptr& idx) override; + // raplace instances (in contrast to its analogon in ContainerIndex // MultiIndices CANNOT be influences be its subindices, so there is // NO foreign/external controll) diff --git a/src/pack_num.h b/src/pack_num.h index f3d292f..6348cf7 100644 --- a/src/pack_num.h +++ b/src/pack_num.h @@ -49,31 +49,66 @@ namespace MultiArrayHelper return PackNum::getIndexPtr(in, n); } } + + template + static void lock(std::tuple...>& ip, + std::shared_ptr& toLock) + { + std::get(ip)->lock(toLock); + PackNum::lock(ip, toLock); + } template - static inline void pp(std::tuple...>& ip) + static void initBlockSizes(std::array& bs, + std::tuple...>& ip) + { + if(N == sizeof...(Indices)){ + std::get(bs) = 1; + } + else { + std::get(bs) = PackNum::blockSize(ip); + PackNum::initBlockSizes(bs, ip); + } + } + + template + static inline size_t pp(std::tuple...>& ip, + std::array& bs) { auto& si = *std::get(ip); - if(si.last()){ + if(si.last() or si.locked()){ si = 0; PackNum::pp(ip); } else { ++si; } + if(si.locked()){ + return std::get(bs) - std::get(bs) + 1; + } + else { + return 1; + } } template - static inline void mm(std::tuple...>& ip) + static inline size_t mm(std::tuple...>& ip, + std::array& bs) { auto& si = *std::get(ip); - if(si.first()){ + if(si.first() or si.locked()){ si = si.max(); PackNum::mm(ip); } else { --si; } + if(si.locked()){ + return std::get(bs) - std::get(bs) + 1; + } + else { + return 1; + } } template @@ -188,19 +223,50 @@ namespace MultiArrayHelper { return in.template getPtr<0>(); } - + template - static inline void pp(std::tuple...>& ip) + static void lock(std::tuple...>& ip, + std::shared_ptr& toLock) { - auto& si = *std::get<0>(ip); - ++si; + std::get<0>(ip)->lock(toLock); } template - static inline void mm(std::tuple...>& ip) + static void initBlockSizes(std::array& bs, + std::tuple...>& ip) + { + std::get<0>(bs) = PackNum::blockSize(ip); + } + + template + static inline size_t pp(std::tuple...>& ip, + std::array& bs) { auto& si = *std::get<0>(ip); - --si; + if(si.locked()){ + si = si.max()+1; + return std::get<0>(bs) - std::get<1>(bs) + 1; + } + else { + ++si; + return 1; + } + } + + template + static inline size_t mm(std::tuple...>& ip, + std::array& bs) + { + auto& si = *std::get<0>(ip); + if(si.locked()){ + si = 0; + --si; + return std::get<0>(bs) - std::get<1>(bs) + 1; + } + else { + --si; + return 1; + } } template