#ifndef __cxz_array_base_h__ #define __cxz_array_base_h__ #include <cstdlib> #include <vector> #include <memory> #include <algorithm> #include "base_def.h" #include "mbase_def.h" #include "ranges/rheader.h" namespace CNORXZ { template <class IndexType> using IPTR = std::shared_ptr<IndexType>; template <class IndexType1, class IndexType2> inline auto operator|(const IPTR<IndexType1>& i1, const IPTR<IndexType2>& i2) -> decltype(std::make_tuple(i1,i2)) { return std::make_tuple(i1,i2); } template <class IndexType1, class... IndexTypes2> inline auto operator|(const IPTR<IndexType1>& i1, const std::tuple<IPTR<IndexTypes2>...>& i2) -> decltype(std::tuple_cat(std::make_tuple(i1),i2)) { return std::tuple_cat(std::make_tuple(i1),i2); } template <class IndexType2, class... IndexTypes1> inline auto operator|(const std::tuple<IPTR<IndexTypes1>...>& i1, const IPTR<IndexType2>& i2) -> decltype(std::tuple_cat(i1,std::make_tuple(i2))) { return std::tuple_cat(i1,std::make_tuple(i2)); } template <class IndexType> inline auto operator~(const IPTR<IndexType>& i) -> decltype(std::make_tuple(i)) { return std::make_tuple(i); } // Explicitely specify subranges in template argument !!! template <typename T, class... SRanges> class ArrayBase { public: typedef T value_type; typedef ContainerRange<SRanges...> CRange; typedef ConstContainerIndex<T,typename SRanges::IndexType...> CIndexType; typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType; protected: bool mInit = false; std::shared_ptr<CRange> mRange; std::shared_ptr<CIndexType> mProtoI; public: //DEFAULT_MEMBERS(ArrayBase); ArrayBase(const std::shared_ptr<SRanges>&... ranges); ArrayBase(const typename CRange::Space& space); ArrayBase() = default; ArrayBase(const ArrayBase& in); ArrayBase(ArrayBase&& in); ArrayBase& operator=(const ArrayBase& in); ArrayBase& operator=(ArrayBase&& in); virtual ~ArrayBase() = default; template <typename X> const T& operator[](const ConstContainerIndex<X,typename SRanges::IndexType...>& i); const T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is) const; virtual const T& operator[](const CIndexType& 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 CIndexType begin() const; virtual CIndexType end() const; virtual CIndexType cbegin() const; virtual CIndexType cend() const; virtual const std::shared_ptr<CRange>& range() const; virtual bool isConst() const; virtual std::shared_ptr<ArrayBase<T,AnonymousRange> > anonymous(bool slice = false) const = 0; virtual ConstOperationRoot<T,SRanges...> op(const std::shared_ptr<CIndexType>& ind) const; virtual ConstOperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const; template <class... MappedRanges> ConstOperationRoot<T,MappedRanges...> m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const; virtual bool isInit() const; template <size_t N> auto getRangePtr() const -> decltype(mRange->template getPtr<N>()); }; template <typename T, class... SRanges> class MutableArrayBase : public ArrayBase<T,SRanges...> { public: typedef ContainerRange<SRanges...> CRange; typedef ArrayBase<T,SRanges...> MAB; typedef ContainerIndex<T,typename SRanges::IndexType...> IndexType; typedef ConstContainerIndex<T,typename SRanges::IndexType...> CIndexType; using ArrayBase<T,SRanges...>::operator[]; using ArrayBase<T,SRanges...>::at; using ArrayBase<T,SRanges...>::data; using ArrayBase<T,SRanges...>::begin; using ArrayBase<T,SRanges...>::end; using ArrayBase<T,SRanges...>::cbegin; using ArrayBase<T,SRanges...>::cend; DEFAULT_MEMBERS(MutableArrayBase); MutableArrayBase(const std::shared_ptr<SRanges>&... ranges); MutableArrayBase(const typename CRange::Space& space); template <typename X> T& operator[](const ConstContainerIndex<X,typename SRanges::IndexType...>& i); T& operator[](const std::tuple<IPTR<typename SRanges::IndexType>...>& is); virtual T& operator[](const CIndexType& 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 ConstOperationRoot<T,SRanges...> op(const std::shared_ptr<CIndexType>& ind) const override; virtual ConstOperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds) const override; virtual OperationRoot<T,SRanges...> op(const std::shared_ptr<CIndexType>& ind); virtual OperationRoot<T,SRanges...> operator()(const std::shared_ptr<typename SRanges::IndexType>&... inds); template <class... MappedRanges> OperationRoot<T,MappedRanges...> m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds); template <class... MappedRanges> ConstOperationRoot<T,MappedRanges...> m(const std::shared_ptr<typename MappedRanges::IndexType>&... inds) const; }; } // end namespace CNORXZ /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ #endif