im com (block index locking)

This commit is contained in:
Christian Zimmermann 2017-08-29 17:52:08 +02:00
parent fbcdfd7580
commit b985b9c35c
7 changed files with 116 additions and 17 deletions

View file

@ -34,6 +34,18 @@ namespace MultiArrayTools
return mRangePtr->size(); return mRangePtr->size();
} }
bool IndexBase::locked() const
{
return mLocked;
}
IndexBase& IndexBase::lock(std::shared_ptr<const IndexBase>& idx)
{
mLocked = (idx.get() == this);
return *this;
}
IndexBase::operator size_t() const IndexBase::operator size_t() const
{ {
return pos(); return pos();

View file

@ -54,6 +54,9 @@ namespace MultiArrayTools
virtual bool last() const = 0; virtual bool last() const = 0;
virtual bool first() const = 0; virtual bool first() const = 0;
virtual bool locked() const;
virtual IndexBase& lock(std::shared_ptr<const IndexBase>& idx);
virtual std::shared_ptr<const IndexBase> getPtr(size_t n) const = 0; virtual std::shared_ptr<const IndexBase> getPtr(size_t n) const = 0;
virtual operator size_t() const; virtual operator size_t() const;
@ -64,6 +67,7 @@ namespace MultiArrayTools
std::shared_ptr<RangeBase> mRangePtr; std::shared_ptr<RangeBase> mRangePtr;
size_t mPos; size_t mPos;
size_t mId; size_t mId;
bool mLocked = false;
}; };
template <typename MetaType> template <typename MetaType>

View file

@ -106,6 +106,8 @@ namespace MultiArrayTools
std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() ); std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
mIndex = std::make_shared<IndexType>( mr->begin() ); mIndex = std::make_shared<IndexType>( mr->begin() );
(*mIndex) = *index; (*mIndex) = *index;
// -> find optimal block index !!!
// -> lock this index !!!
for(*mIndex = 0; mIndex->pos() != mIndex->max(); ++(*mIndex)){ for(*mIndex = 0; mIndex->pos() != mIndex->max(); ++(*mIndex)){
get() = mSecond.get(); get() = mSecond.get();
} }
@ -114,13 +116,15 @@ namespace MultiArrayTools
template <typename T, class... Ranges> template <typename T, class... Ranges>
BlockBase<T>& OperationMaster<T,Ranges...>::get() BlockBase<T>& OperationMaster<T,Ranges...>::get()
{ {
return mArrayRef.data()[ mIndex->pos() ]; block();
return *mBlockPtr;
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>
const BlockBase<T>& OperationMaster<T,Ranges...>::get() const const BlockBase<T>& OperationMaster<T,Ranges...>::get() const
{ {
return mArrayRef.data()[ mIndex->pos() ]; block();
return *mBlockPtr;
} }
template <typename T, class... Ranges> template <typename T, class... Ranges>

View file

@ -35,6 +35,7 @@ namespace MultiArrayTools
BlockType getBlockType(std::shared_ptr<const IndexBase> i, BlockType getBlockType(std::shared_ptr<const IndexBase> i,
std::shared_ptr<const IndexBase> j, bool first); std::shared_ptr<const IndexBase> j, bool first);
template <typename T> template <typename T>
class OperationBase class OperationBase
{ {
@ -120,6 +121,7 @@ namespace MultiArrayTools
OperationBase<T> const& mSecond; OperationBase<T> const& mSecond;
MutableMultiArrayBase<T,Ranges...>& mArrayRef; MutableMultiArrayBase<T,Ranges...>& mArrayRef;
std::shared_ptr<IndexType> mIndex; std::shared_ptr<IndexType> mIndex;
}; };

View file

@ -47,6 +47,7 @@ namespace MultiArrayTools
{ {
PackNum<sizeof...(Indices)-1>::construct(mIPack, *range); PackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack); IB::mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
PackNum<sizeof...(Indices)>::initBlockSizes(mBlockSizes, mIPack); // has one more element!
} }
template <class... Indices> template <class... Indices>
@ -58,16 +59,15 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++() MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{ {
PackNum<sizeof...(Indices)-1>::pp( mIPack ); // return step size -> add to IB::mPos
++IB::mPos; IB::mPos += PackNum<sizeof...(Indices)-1>::pp( mIPack, mBlockSizes );
return *this; return *this;
} }
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator--() MultiIndex<Indices...>& MultiIndex<Indices...>::operator--()
{ {
PackNum<sizeof...(Indices)-1>::mm( mIPack ); IB::mPos -= PackNum<sizeof...(Indices)-1>::mm( mIPack, mBlockSizes );
--IB::mPos;
return *this; return *this;
} }
@ -175,6 +175,14 @@ namespace MultiArrayTools
return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr ); return std::dynamic_pointer_cast<RangeType>( IB::mRangePtr );
} }
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::lock(std::shared_ptr<const IndexBase>& idx)
{
IB::mLocked = (idx.get() == this);
PackNum<sizeof...(Indices)-1>::lock(mIPack, idx);
return *this;
}
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(std::shared_ptr<Indices>&... indices) MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(std::shared_ptr<Indices>&... indices)
{ {

View file

@ -27,6 +27,7 @@ namespace MultiArrayTools
protected: protected:
IndexPack mIPack; IndexPack mIPack;
std::array<size_t,sizeof...(Indices)+1> mBlockSizes;
public: public:
MultiIndex() = delete; MultiIndex() = delete;
@ -70,6 +71,8 @@ namespace MultiArrayTools
std::shared_ptr<RangeType> range() const; std::shared_ptr<RangeType> range() const;
virtual MultiIndex& lock(std::shared_ptr<const IndexBase>& idx) override;
// raplace instances (in contrast to its analogon in ContainerIndex // raplace instances (in contrast to its analogon in ContainerIndex
// MultiIndices CANNOT be influences be its subindices, so there is // MultiIndices CANNOT be influences be its subindices, so there is
// NO foreign/external controll) // NO foreign/external controll)

View file

@ -51,29 +51,64 @@ namespace MultiArrayHelper
} }
template <class... Indices> template <class... Indices>
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip) static void lock(std::tuple<std::shared_ptr<Indices>...>& ip,
std::shared_ptr<const IndexBase>& toLock)
{
std::get<N>(ip)->lock(toLock);
PackNum<N-1>::lock(ip, toLock);
}
template <class... Indices>
static void initBlockSizes(std::array<size_t,sizeof...(Indices)+1>& bs,
std::tuple<std::shared_ptr<Indices>...>& ip)
{
if(N == sizeof...(Indices)){
std::get<N>(bs) = 1;
}
else {
std::get<N>(bs) = PackNum<sizeof...(Indices)-N-1>::blockSize(ip);
PackNum<N-1>::initBlockSizes(bs, ip);
}
}
template <class... Indices>
static inline size_t pp(std::tuple<std::shared_ptr<Indices>...>& ip,
std::array<size_t,sizeof...(Indices)>& bs)
{ {
auto& si = *std::get<N>(ip); auto& si = *std::get<N>(ip);
if(si.last()){ if(si.last() or si.locked()){
si = 0; si = 0;
PackNum<N-1>::pp(ip); PackNum<N-1>::pp(ip);
} }
else { else {
++si; ++si;
} }
if(si.locked()){
return std::get<N-1>(bs) - std::get<N>(bs) + 1;
}
else {
return 1;
}
} }
template <class... Indices> template <class... Indices>
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip) static inline size_t mm(std::tuple<std::shared_ptr<Indices>...>& ip,
std::array<size_t,sizeof...(Indices)>& bs)
{ {
auto& si = *std::get<N>(ip); auto& si = *std::get<N>(ip);
if(si.first()){ if(si.first() or si.locked()){
si = si.max(); si = si.max();
PackNum<N-1>::mm(ip); PackNum<N-1>::mm(ip);
} }
else { else {
--si; --si;
} }
if(si.locked()){
return std::get<N-1>(bs) - std::get<N>(bs) + 1;
}
else {
return 1;
}
} }
template <class RangeTuple> template <class RangeTuple>
@ -190,17 +225,48 @@ namespace MultiArrayHelper
} }
template <class... Indices> template <class... Indices>
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip) static void lock(std::tuple<std::shared_ptr<Indices>...>& ip,
std::shared_ptr<const IndexBase>& toLock)
{ {
auto& si = *std::get<0>(ip); std::get<0>(ip)->lock(toLock);
++si;
} }
template <class... Indices> template <class... Indices>
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip) static void initBlockSizes(std::array<size_t,sizeof...(Indices)+1>& bs,
std::tuple<std::shared_ptr<Indices>...>& ip)
{
std::get<0>(bs) = PackNum<sizeof...(Indices)-1>::blockSize(ip);
}
template <class... Indices>
static inline size_t pp(std::tuple<std::shared_ptr<Indices>...>& ip,
std::array<size_t,sizeof...(Indices)+1>& bs)
{ {
auto& si = *std::get<0>(ip); auto& si = *std::get<0>(ip);
if(si.locked()){
si = si.max()+1;
return std::get<0>(bs) - std::get<1>(bs) + 1;
}
else {
++si;
return 1;
}
}
template <class... Indices>
static inline size_t mm(std::tuple<std::shared_ptr<Indices>...>& ip,
std::array<size_t,sizeof...(Indices)>& bs)
{
auto& si = *std::get<0>(ip);
if(si.locked()){
si = 0;
--si; --si;
return std::get<0>(bs) - std::get<1>(bs) + 1;
}
else {
--si;
return 1;
}
} }
template <class RangeTuple> template <class RangeTuple>