#ifndef __multi_array_base_h__ #define __multi_array_base_h__ #include #include #include #include #include #include "base_def.h" #include "mbase_def.h" #include "ranges/rheader.h" namespace MultiArrayTools { // Explicitely specify subranges in template argument !!! template class MultiArrayBase { public: typedef T value_type; typedef ContainerRange CRange; typedef ContainerIndex IndexType; protected: bool mInit = false; std::shared_ptr mRange; std::shared_ptr mProtoI; public: DEFAULT_MEMBERS(MultiArrayBase); MultiArrayBase(const std::shared_ptr&... ranges); MultiArrayBase(const typename CRange::Space& space); virtual ~MultiArrayBase() = default; virtual const T& operator[](const IndexType& i) const = 0; virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0; virtual const T* data() const = 0; virtual size_t size() const; virtual bool isSlice() const = 0; virtual IndexType begin() const; virtual IndexType end() const; virtual IndexType beginIndex() const; virtual IndexType endIndex() const; virtual const std::shared_ptr& range() const; virtual bool isConst() const; virtual std::shared_ptr > anonymous(bool slice = false) const = 0; virtual ConstOperationRoot operator()(const std::shared_ptr&... inds) const; template ConstOperationRoot m(const std::shared_ptr&... inds) const; virtual bool isInit() const; template auto getRangePtr() const -> decltype(mRange->template getPtr()); }; template class MutableMultiArrayBase : public MultiArrayBase { public: typedef ContainerRange CRange; typedef MultiArrayBase MAB; typedef ContainerIndex IndexType; using MultiArrayBase::operator[]; using MultiArrayBase::at; using MultiArrayBase::data; using MultiArrayBase::begin; using MultiArrayBase::end; DEFAULT_MEMBERS(MutableMultiArrayBase); MutableMultiArrayBase(const std::shared_ptr&... ranges); MutableMultiArrayBase(const typename CRange::Space& space); virtual T& operator[](const IndexType& i) = 0; virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0; virtual T* data() = 0; //virtual IndexType begin(); //virtual IndexType end(); virtual bool isConst() const override; virtual std::shared_ptr > anonymousMove() = 0; virtual ConstOperationRoot operator()(const std::shared_ptr&... inds) const override; virtual OperationRoot operator()(const std::shared_ptr&... inds); template OperationRoot m(const std::shared_ptr&... inds); template ConstOperationRoot m(const std::shared_ptr&... inds) const; }; } // end namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /********************** * MultiArrayBase * **********************/ template MultiArrayBase::MultiArrayBase(const std::shared_ptr&... ranges) { ContainerRangeFactory crf(ranges...); mRange = std::dynamic_pointer_cast >( crf.create() ); mProtoI = std::make_shared( mRange, reinterpret_cast(this) ); } template MultiArrayBase::MultiArrayBase(const typename CRange::Space& space) { ContainerRangeFactory crf(space); mRange = std::dynamic_pointer_cast >( crf.create() ); mProtoI = std::make_shared( mRange, reinterpret_cast(this) ); } template size_t MultiArrayBase::size() const { return mRange->size(); } template typename MultiArrayBase::IndexType MultiArrayBase::begin() const { IndexType i(*mProtoI); i = 0; return i.setData(data()); } template typename MultiArrayBase::IndexType MultiArrayBase::end() const { IndexType i(*mProtoI); i = i.max(); //i = mRange->size(); return i.setData(data()); } template typename MultiArrayBase::IndexType MultiArrayBase::beginIndex() const { IndexType i(*mProtoI); i = 0; return i.setData(data()); } template typename MultiArrayBase::IndexType MultiArrayBase::endIndex() const { IndexType i(*mProtoI); i = i.max(); //i = mRange->size(); return i.setData(data()); } template const std::shared_ptr::CRange>& MultiArrayBase::range() const { return mRange; } template bool MultiArrayBase::isConst() const { return true; } template ConstOperationRoot MultiArrayBase::operator()(const std::shared_ptr&... inds) const { return ConstOperationRoot(*this, inds...); } template template ConstOperationRoot MultiArrayBase::m(const std::shared_ptr&... inds) const { static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), "number of mapped ranges must be equal to number of original ranges"); return ConstOperationRoot(*this, inds...); } template bool MultiArrayBase::isInit() const { return mInit; } template template auto MultiArrayBase::getRangePtr() const -> decltype(mRange->template getPtr()) { return mRange->template getPtr(); } /****************************** * MutableMultiArrayBase * ******************************/ template MutableMultiArrayBase::MutableMultiArrayBase(const std::shared_ptr&... ranges) : MultiArrayBase(ranges...) {} template MutableMultiArrayBase::MutableMultiArrayBase(const typename CRange::Space& space) : MultiArrayBase(space) {} /* template typename MutableMultiArrayBase::IndexType MutableMultiArrayBase::begin() { auto i = mRange->begin(); return i.setData(data()); } template typename MutableMultiArrayBase::IndexType MutableMultiArrayBase::end() { auto i = mRange->end(); return i.setData(data()); } */ template bool MutableMultiArrayBase::isConst() const { return false; } template OperationRoot MutableMultiArrayBase::operator()(const std::shared_ptr&... inds) { return OperationRoot(*this, inds...); } template ConstOperationRoot MutableMultiArrayBase::operator()(const std::shared_ptr&... inds) const { return ConstOperationRoot(*this, inds...); } template template OperationRoot MutableMultiArrayBase::m(const std::shared_ptr&... inds) { static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), "number of mapped ranges must be equal to number of original ranges"); return OperationRoot(*this, inds...); } template template ConstOperationRoot MutableMultiArrayBase::m(const std::shared_ptr&... inds) const { static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), "number of mapped ranges must be equal to number of original ranges"); return ConstOperationRoot(*this, inds...); } } // end namespace MultiArrayTools #endif