#include "container_index.h" namespace MultiArrayTools { template ConstContainerIndex::ConstContainerIndex(const ConstContainerIndex& in, bool copy) : IB(in), mNonTrivialBlocks(in.mNonTrivialBlocks), mExternControl(false), mBlockSizes(in.mBlockSizes), mData(in.mData), mObjPtrNum(in.mObjPtrNum), mCPos(in.mCPos) { sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { typedef typename std::remove_reference(mIPack))>::type SubType; std::get(mIPack) = std::make_shared( in.template get() ) ; return true; }); } template ConstContainerIndex& ConstContainerIndex::copy(const ConstContainerIndex& in) { IB::operator=(in); mNonTrivialBlocks = in.mNonTrivialBlocks; mExternControl = false; mBlockSizes = in.mBlockSizes; mData = in.mData; mObjPtrNum = in.mObjPtrNum; mCPos = in.mCPos; sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { typedef typename std::remove_reference(mIPack))>::type SubType; std::get(mIPack) = std::make_shared( in.template get() ) ; return true; }); return *this; } template template ConstContainerIndex::ConstContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum) : IndexInterface,std::tuple >(range, 0), mObjPtrNum(objPtrNum) { std::get(mBlockSizes) = 1; sfor_mn ( [&](auto i) { auto r = range->template getPtr(); std::get(mIPack) = r->beginPtr(); *std::get(mIPack) = 0; std::get(mBlockSizes) = sfor_p ( [&](auto j) { return std::get(mIPack)->max(); } , [&](auto a, auto b) { return a * b; }); return 0; }); IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); } template template ConstContainerIndex::ConstContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum, const std::array& blockSizes) : IndexInterface,std::tuple >(range, 0), mObjPtrNum(objPtrNum) { sfor_mn ( [&](auto i) { auto r = range->template getPtr(); std::get(mIPack) = r->beginPtr(); *std::get(mIPack) = 0; return 0; }); IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); mNonTrivialBlocks = true; } template template ConstContainerIndex& ConstContainerIndex::operator=(const ConstContainerIndex& in) { mIPack = in.mIPack; return (*this)(); } template ConstContainerIndex& ConstContainerIndex::sync() { if(mExternControl){ IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); } return *this; } template template auto& ConstContainerIndex::get() const { return *std::get( mIPack ); } template template auto ConstContainerIndex::getPtr() const { return std::get( mIPack ); } template ConstContainerIndex& ConstContainerIndex::operator()(const std::shared_ptr&... inds) { return (*this)(std::make_tuple(inds...)); } template ConstContainerIndex& ConstContainerIndex::operator()(const std::tuple...>& inds) { sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { std::get(mIPack) = std::get(inds); return 0; } ); mExternControl = true; return sync(); } template ConstContainerIndex& ConstContainerIndex::operator()() { return sync(); } template IndexType ConstContainerIndex::type() const { return IndexType::CONT; } template ConstContainerIndex& ConstContainerIndex::operator++() { if(mExternControl){ IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); } sfor_m ( [&](auto i) { auto& si = *std::get( mIPack ); if(si.last() and i != 0) { si = 0; return true; } else { ++si; return false; } return false; } ); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); ++IB::mPos; return *this; } template ConstContainerIndex& ConstContainerIndex::operator--() { if(mExternControl){ IB::mPos = sfor_m ( [&](auto i) { return std::get(mIPack); }, [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); } sfor_m ( [&](auto i) { auto& si = *std::get( mIPack ); if(si.first() and i != 0) { si = si.max()-1; return true; } else { --si; return false; } return false; } ); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); --IB::mPos; return *this; } template ConstContainerIndex& ConstContainerIndex::operator=(size_t pos) { IB::mPos = pos; RangeHelper::setIndexPack(mIPack, pos); mCPos = RangeHelper::makePos(mIPack, mBlockSizes); return *this; } template int ConstContainerIndex::pp(std::intptr_t idxPtrNum) { const int tmp = RangeHelper::ppx(mIPack, mBlockSizes, idxPtrNum); IB::mPos += tmp; return tmp; } template int ConstContainerIndex::mm(std::intptr_t idxPtrNum) { const int tmp = RangeHelper::mmx(mIPack, mBlockSizes, idxPtrNum); IB::mPos -= tmp; return tmp; } template std::string ConstContainerIndex::stringMeta() const { return std::dynamic_pointer_cast( IB::mRangePtr )->stringMeta(IB::mPos); } template typename ConstContainerIndex::MetaType ConstContainerIndex::meta() const { MetaType metaTuple; sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { std::get(metaTuple) = std::get(mIPack)->meta(); return 0; } ); return metaTuple; } template ConstContainerIndex& ConstContainerIndex::at(const MetaType& metaPos) { sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { std::get(mIPack)->at( std::get(metaPos) ); return 0; } ); IB::mPos = RangeHelper::makePos(mIPack, mBlockSizes); return *this; } template size_t ConstContainerIndex::dim() const { return sizeof...(Indices); } template bool ConstContainerIndex::first() const { return IB::pos() == 0; } template bool ConstContainerIndex::last() const { return IB::pos() == IB::mMax - 1; } template bool ConstContainerIndex::sliceMode() const { return mNonTrivialBlocks; } template std::shared_ptr::RangeType> ConstContainerIndex::range() { return std::dynamic_pointer_cast( IB::mRangePtr ); } template size_t ConstContainerIndex::getStepSize(size_t n) { if(n >= sizeof...(Indices)){ assert(0); // throw !! } return mBlockSizes[n+1]; } template template auto ConstContainerIndex::ifor(size_t step, Exprs exs) const { return RangeHelper::mkFor<0>(step, mIPack, mBlockSizes, exs); } template template auto ConstContainerIndex::iforh(size_t step, Exprs exs) const { return RangeHelper::mkForh<0>(step, mIPack, mBlockSizes, exs); } template template auto ConstContainerIndex::pifor(size_t step, Exprs exs) const { return RangeHelper::mkPFor<0>(step, mIPack, mBlockSizes, exs); } template std::intptr_t ConstContainerIndex::container() const { return mObjPtrNum; } template ConstContainerIndex& ConstContainerIndex:: format(const std::array& blocks) { mBlockSizes = blocks; mNonTrivialBlocks = true; return *this; } template ConstContainerIndex& ConstContainerIndex::setData(const T* data) { mData = data; return *this; } template const T& ConstContainerIndex::operator*() const { return mData[mCPos]; } template const T* ConstContainerIndex::operator->() const { return &mData[mCPos]; } template ConstContainerIndex ConstContainerIndex::operator++(int) { auto tmp = *this; ++(*this); return tmp; } template ConstContainerIndex ConstContainerIndex::operator--(int) { auto tmp = *this; --(*this); return tmp; } template ConstContainerIndex& ConstContainerIndex::operator+=(int diff) { if(diff < 0){ for(int i = 0; i != diff; ++i){ (*this)--; } } else { for(int i = 0; i != diff; ++i){ (*this)++; } } return *this; } template ConstContainerIndex& ConstContainerIndex::operator-=(int diff) { if(diff < 0){ for(int i = 0; i != diff; ++i){ (*this)++; } } else { for(int i = 0; i != diff; ++i){ (*this)--; } } return *this; } template ConstContainerIndex ConstContainerIndex::operator+(int num) const { auto tmp = *this; return tmp += num; } template ConstContainerIndex ConstContainerIndex::operator-(int num) const { auto tmp = *this; return tmp -= num; } template int ConstContainerIndex::operator-(const ConstContainerIndex& it) const { return static_cast( IB::mPos ) - static_cast( it.pos() ); } template const T& ConstContainerIndex::operator[](int num) const { return mData[IB::mPos + num]; } template bool ConstContainerIndex::operator<(const ConstContainerIndex& it) const { return IB::mPos < it.pos(); } template bool ConstContainerIndex::operator>(const ConstContainerIndex& it) const { return IB::mPos > it.pos(); } template bool ConstContainerIndex::operator<=(const ConstContainerIndex& it) const { return IB::mPos <= it.pos(); } template bool ConstContainerIndex::operator>=(const ConstContainerIndex& it) const { return IB::mPos >= it.pos(); } } // namespace MultiArrayTools