#ifndef __slice_h__ #define __slice_h__ #include "multi_array_base.h" #include "multi_array_operation.h" 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); ConstSlice(const MultiArray& ma, SIZET... sizes); 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; virtual std::shared_ptr > anonymous() const 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 { public: typedef ContainerRange CRange; typedef MultiArrayBase MAB; typedef ContainerIndex IType; DEFAULT_MEMBERS(Slice); Slice(const std::shared_ptr&... ranges, T* data = nullptr); virtual const T& operator[](const IType& i) const override; virtual T& operator[](const IType& i) override; virtual const T& at(const typename IType::MetaType& meta) const override; virtual T& at(const typename IType::MetaType& meta) override; virtual const T* data() const override; virtual T* data() override; virtual bool isSlice() const override; virtual auto begin() const -> IType override; virtual auto end() const -> IType override; virtual std::shared_ptr > anonymous() const override; virtual std::shared_ptr > anonymousMove() override; auto define(const std::shared_ptr&... inds) -> SliceDef; private: friend SliceDef; void format(const std::array& blocks); T* mData; }; template class SliceDef { public: typedef ContainerIndex IType; private: IType mIndex; 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); template SliceDef& operator=(const OperationRoot& op); }; } // end namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /******************* * ConstSlice * *******************/ template void ConstSlice::format(const std::array& blocks) { MAB::mProtoI->format(blocks); } template ConstSlice::ConstSlice(const std::shared_ptr&... ranges, const T* data) : MultiArrayBase(ranges...), mData(data) { MAB::mInit = true; } template ConstSlice::ConstSlice(const MultiArray& ma, SIZET... sizes) : MultiArrayBase ( ma.range()->template get<0>().template scast(sizes...)->space() ), mData( ma.data() ) { MAB::mInit = true; } 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 std::shared_ptr > ConstSlice::anonymous() const { assert(0); // think about carefully!!!! return nullptr; } template auto ConstSlice::define(const std::shared_ptr&... inds) -> SliceDef { return SliceDef(*this, inds...); } /************** * Slice * **************/ template void Slice::format(const std::array& blocks) { MAB::mProtoI->format(blocks); } template Slice::Slice(const std::shared_ptr&... ranges, T* data) : MutableMultiArrayBase(ranges...), mData(data) {} template const T& Slice::operator[](const IType& i) const { //assert(i.sliceMode()); // -> compare objects !!!!! assert(i.container() == reinterpret_cast(this)); return mData[ i.pos() ]; } template T& Slice::operator[](const IType& i) { //assert(i.sliceMode()); assert(i.container() == reinterpret_cast(this)); return mData[ i.pos() ]; } template const T& Slice::at(const typename IType::MetaType& meta) const { //auto x = begin().at(meta); //VCHECK(x.pos()); return mData[ begin().at(meta).pos() ]; } template T& Slice::at(const typename IType::MetaType& meta) { //auto x = begin().at(meta); //VCHECK(x.pos()); return mData[ begin().at(meta).pos() ]; } template const T* Slice::data() const { return mData; } template T* Slice::data() { return mData; } template bool Slice::isSlice() const { return true; } template auto Slice::begin() const -> Slice::IType { IType i(*MAB::mProtoI); i = 0; //i = mStartPos; return i.setData(data()); } template auto Slice::end() const -> Slice::IType { IType i(*MAB::mProtoI); i = i.max(); // CHECK !!! //i = std::get(mBlockSizes); return i.setData(data()); } template std::shared_ptr > Slice::anonymous() const { assert(0); // think about carefully!!!! return nullptr; } template std::shared_ptr > Slice::anonymousMove() { assert(0); // think about carefully!!!! return nullptr; } template auto Slice::define(const std::shared_ptr&... inds) -> SliceDef { 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()), mSlPtr(&sl) { mIndex(inds...); } template template SliceDef& SliceDef::operator=(const OperationRoot& op) { std::array blocks; PackNum:: template mkSliceBlocks,SRanges...>(blocks, mIndex, op); if(mCSlPtr){ mCSlPtr->format(blocks); mCSlPtr->mData = op.data(); } else { mSlPtr->format(blocks); mSlPtr->mData = op.data(); } return *this; } } // end namespace MultiArrayTools #endif