diff --git a/src/include/functional_multi_array.h b/src/include/functional_multi_array.h index c7149e1..4719b41 100644 --- a/src/include/functional_multi_array.h +++ b/src/include/functional_multi_array.h @@ -10,7 +10,7 @@ namespace MultiArrayTools template auto indexToSlice(const std::shared_ptr& i) - -> Slice; + -> ConstSlice; template @@ -19,15 +19,18 @@ namespace MultiArrayTools public: typedef ContainerRange CRange; - typedef MultiArrayBase MAB; + typedef MultiArrayBase MAB; //typedef typename MultiArrayBase::const_iterator const_iterator; typedef ContainerIndex IndexType; //typedef typename CRange::IndexType IndexType; - + typedef MultiArray MAType; + private: mutable T mVal; Function mFunc; + mutable std::shared_ptr mMaPtr; + public: DEFAULT_MEMBERS(FunctionalMultiArray); @@ -45,6 +48,9 @@ namespace MultiArrayTools auto exec(std::shared_ptr&... inds) const -> decltype( mkOperation( mFunc, ConstOperationRoot( indexToSlice( inds ), inds) ... ) ); + + virtual ConstOperationRoot + operator()(std::shared_ptr&... inds) const override; }; @@ -60,9 +66,9 @@ namespace MultiArrayTools template auto indexToSlice(const std::shared_ptr& i) - -> Slice + -> ConstSlice { - return Slice( i->range(), i->metaPtr() ); + return ConstSlice( i->range(), i->metaPtr() ); } @@ -136,6 +142,18 @@ namespace MultiArrayTools return false; } + template + ConstOperationRoot FunctionalMultiArray:: + operator()(std::shared_ptr&... inds) const + { + if(not mMaPtr){ + mMaPtr = std::make_shared( MAB::mRange->space() ); + (*mMaPtr)(inds...) = exec(inds...); + } + return ConstOperationRoot( *mMaPtr, inds... ); + } + + template auto FunctionalMultiArray:: exec(std::shared_ptr&... inds) const diff --git a/src/include/multi_array.h b/src/include/multi_array.h index 7fedb46..014976c 100644 --- a/src/include/multi_array.h +++ b/src/include/multi_array.h @@ -22,7 +22,8 @@ namespace MultiArrayTools MultiArray(const std::shared_ptr&... ranges); MultiArray(const std::shared_ptr&... ranges, const std::vector& vec); MultiArray(const std::shared_ptr&... ranges, std::vector&& vec); - + MultiArray(const typename CRange::SpaceType& space); + // Only if ALL ranges have default extensions: //MultiArray(const std::vector& vec); //MultiArray(std::vector&& vec); @@ -70,6 +71,14 @@ namespace MultiArrayTools * MultiArray * *******************/ + template + MultiArray::MultiArray(const typename CRange::SpaceType& space) : + MutableMultiArrayBase(space), + mCont(MAB::mRange->size()) + { + MAB::mInit = true; + } + template MultiArray::MultiArray(const std::shared_ptr&... ranges) : MutableMultiArrayBase(ranges...), diff --git a/src/include/ranges/single_range.h b/src/include/ranges/single_range.h index 8ab53ce..7a4c0b9 100644 --- a/src/include/ranges/single_range.h +++ b/src/include/ranges/single_range.h @@ -48,7 +48,7 @@ namespace MultiArrayTools int mm(std::intptr_t idxPtrNum); U meta(); - U* metaPtr(); + const U* metaPtr() const; SingleIndex& at(const U& metaPos); size_t dim(); // = 1 @@ -213,7 +213,7 @@ namespace MultiArrayTools } template - U* SingleIndex::metaPtr() + const U* SingleIndex::metaPtr() const { return mMetaPtr; } diff --git a/src/include/slice.h b/src/include/slice.h index 43afdd0..2fc81ab 100644 --- a/src/include/slice.h +++ b/src/include/slice.h @@ -7,6 +7,41 @@ namespace MultiArrayTools { + template + class ConstSlice : public MultiArrayBase + { + public: + + typedef ContainerRange CRange; + typedef MultiArrayBase MAB; + typedef ContainerIndex IType; + + DEFAULT_MEMBERS(ConstSlice); + + ConstSlice(const std::shared_ptr&... ranges, const T* data = nullptr); + + virtual const T& operator[](const IType& i) const override; + virtual const T& at(const typename IType::MetaType& meta) const override; + + virtual const T* data() const override; + + virtual bool isSlice() const override; + + virtual auto begin() const -> IType override; + virtual auto end() const -> IType override; + + auto define(const std::shared_ptr&... inds) + -> SliceDef; + + private: + friend SliceDef; + + void format(const std::array& blocks); + + const T* mData; + }; + + template class Slice : public MutableMultiArrayBase { @@ -53,10 +88,14 @@ namespace MultiArrayTools private: IType mIndex; - Slice& mSl; + Slice* mSlPtr = nullptr; + ConstSlice* mCSlPtr = nullptr; SliceDef() = default; public: + SliceDef(ConstSlice& csl, + const std::shared_ptr&... inds); + SliceDef(Slice& sl, const std::shared_ptr&... inds); @@ -72,10 +111,79 @@ namespace MultiArrayTools namespace MultiArrayTools { + + /******************* + * ConstSlice * + *******************/ + + template + void ConstSlice::format(const std::array& blocks) + { + MAB::mProtoI->format(blocks); + } - /************* - * Slice * - *************/ + template + ConstSlice::ConstSlice(const std::shared_ptr&... ranges, const T* data) : + MultiArrayBase(ranges...), + mData(data) {} + + template + const T& ConstSlice::operator[](const IType& i) const + { + //assert(i.sliceMode()); // -> compare objects !!!!! + assert(i.container() == reinterpret_cast(this)); + return mData[ i.pos() ]; + } + + template + const T& ConstSlice::at(const typename IType::MetaType& meta) const + { + //auto x = begin().at(meta); + //VCHECK(x.pos()); + return mData[ begin().at(meta).pos() ]; + } + + template + const T* ConstSlice::data() const + { + return mData; + } + + template + bool ConstSlice::isSlice() const + { + return true; + } + + template + auto ConstSlice::begin() const -> ConstSlice::IType + { + IType i(*MAB::mProtoI); + i = 0; + //i = mStartPos; + return i.setData(data()); + } + + template + auto ConstSlice::end() const -> ConstSlice::IType + { + IType i(*MAB::mProtoI); + i = i.max(); // CHECK !!! + //i = std::get(mBlockSizes); + return i.setData(data()); + } + + template + auto ConstSlice::define(const std::shared_ptr&... inds) + -> SliceDef + { + return SliceDef(*this, inds...); + } + + + /************** + * Slice * + **************/ template void Slice::format(const std::array& blocks) @@ -163,11 +271,20 @@ namespace MultiArrayTools return SliceDef(*this, inds...); } + template + SliceDef::SliceDef(ConstSlice& csl, + const std::shared_ptr&... inds) : + mIndex(csl.begin()), + mCSlPtr(&csl) + { + mIndex(inds...); + } + template SliceDef::SliceDef(Slice& sl, const std::shared_ptr&... inds) : mIndex(sl.begin()), - mSl(sl) + mSlPtr(&sl) { mIndex(inds...); } @@ -179,10 +296,14 @@ namespace MultiArrayTools std::array blocks; PackNum:: template mkSliceBlocks,SRanges...>(blocks, mIndex, op); - mSl.format(blocks); - //VCHECK(blocks[0]); - //VCHECK(blocks[1]); - mSl.mData = op.data(); + if(mCSlPtr){ + mCSlPtr->format(blocks); + mCSlPtr->mData = op.data(); + } + else { + mSlPtr->format(blocks); + mSlPtr->mData = op.data(); + } return *this; }