#ifndef __slice_h__ #define __slice_h__ #include "multi_array_base.h" namespace MultiArrayTools { template class Slice : public MutableMultiArrayBase { public: typedef ContainerRange CRange; typedef MultiArrayBase MAB; typedef typename CRange::IndexType IndexType; DEFAULT_MEMBERS(Slice); template // Range / Index <-> open / const Slice(T* data, const RITypes&... ris); virtual const T& operator[](const IndexType& i) const override; virtual T& operator[](const IndexType& i) override; virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override; virtual T& at(const typename CRange::IndexType::MetaType& meta) override; virtual const T* data() const override; virtual T* data() override; virtual bool isSlice() const override; virtual IndexType begin() const override; virtual IndexType end() const override; private: T* mData; size_t mStartPos; std::array mBlockSizes; }; } // end namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { namespace { template struct XX { template static auto ri_to_tuple(const std::shared_ptr& ri) -> std::tuple { return std::make_tuple(ri); } }; template <> struct XX { template static auto ri_to_tuple(const std::shared_ptr& ri) -> std::tuple<> { return std::make_tuple(); } }; template auto mkSliceRange(const std::shared_ptr&... ris) { return std::tuple_cat(XX::ri_to_tuple(ris)...); } } /************* * Slice * *************/ /* template Slice::Slice(T* data, const RITypes&... ris) : MutableMultiArrayBase( mkSliceRange(ris...) ), mData(data), mStartPos(mkSliceStart(ris...)), mBlockSizes(mkSliceBlocks(ris...)) {} */ //!!!!! template const T& Slice::operator[](const IndexType& i) const { assert(i.sliceMode()); // -> compare objects !!!!! return mData[ i.pos() ]; } template T& Slice::operator[](const IndexType& i) { assert(i.sliceMode()); return mData[ i.pos() ]; } template const T& Slice::at(const typename CRange::IndexType::MetaType& meta) const { assert(i.sliceMode()); return mData[ begin().at(meta).pos() ]; } template T& Slice::at(const typename CRange::IndexType::MetaType& meta) { assert(i.sliceMode()); 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 IndexType Slice::begin() const { IndexType i(mRange, mBlockSizes); i = mStartPos; return i.setData(data()); } template IndexType Slice::end() const { IndexType i(mRange, mBlockSizes); i = std::get(mBlockSizes); return i.setData(data()); } } // end namespace MultiArrayTools #endif