diff --git a/src/include/functional_multi_array.h b/src/include/functional_multi_array.h new file mode 100644 index 0000000..3d5cde1 --- /dev/null +++ b/src/include/functional_multi_array.h @@ -0,0 +1,79 @@ + +#ifndef __functional_multi_array__ +#define __functional_multi_array__ + +#include "multi_array_base.h" + +namespace MultiArrayTools +{ + + template <typename T, class Function, class... SRanges> + class FunctionalMultiArray : public MultiArrayBase<T,SRanges...> + { + public: + + typedef ContainerRange<T,SRanges...> CRange; + typedef MultiArrayBase<T,CRange> MAB; + typedef typename MultiArrayBase<T,CRange>::const_iterator const_iterator; + typedef typename CRange::IndexType IndexType; + + DEFAULT_MEMBERS(FunctionalMultiArray); + FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, const Function& func); + + virtual const T& operator[](const IndexType& i) const override; + + virtual bool isConst() const override; + virtual bool isSlice() const override; + + private: + mutable T mVal; + Function mFunc; + }; + + +} // namespace MultiArrayTools + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + /**************************** + * FunctionalMultiArray * + ****************************/ + + /* + template <typename T, class Range, class Function> + FunctionalMultiArray<T,Range,Function>::FunctionalMultiArray(const Range& range) : + MultiArrayBase<T,SRanges...>(range), mFunc() {} + */ + template <typename T, class Function, class... SRanges> + FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, + const Function& func) : + MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {} + + template <typename T, class Function, class... SRanges> + const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const typename CRange::IndexType& i) const + { + mVal = mFunc(i); + return mVal; + } + + template <typename T, class Function, class... SRanges> + bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const + { + return true; + } + + template <typename T, class Function, class... SRanges> + bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const + { + return false; + } + + +} // namespace MultiArrayTools + +#endif diff --git a/src/include/multi_array.h b/src/include/multi_array.h index 5a92811..c7e07de 100644 --- a/src/include/multi_array.h +++ b/src/include/multi_array.h @@ -3,101 +3,11 @@ #ifndef __multi_array_h__ #define __multi_array_h__ -#include <cstdlib> -#include <vector> -#include <memory> -#include <iterator> -#include <algorithm> - -#include "base_def.h" -#include "mbase_def.h" - -#include "ranges/rheader.h" +#include "multi_array_base.h" namespace MultiArrayTools { - // Explicitely specify subranges in template argument !!! - template <typename T, class... SRanges> - class MultiArrayBase - { - public: - - typedef T value_type; - typedef ContainerRange<T,SRanges...> CRange; - typedef typename CRange::IndexType IndexType; - - DEFAULT_MEMBERS(MultiArrayBase); - MultiArrayBase(const std::shared_ptr<SRanges>&... ranges); - - virtual ~MultiArrayBase() = default; - - virtual const T& operator[](const IndexType& i) const = 0; - //virtual const T& operator[](const typename CRange::IndexType& i) const = 0; - virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0; - - virtual const T* data() const = 0; - virtual const std::vector<T>& datav() 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<CRange>& range() const; - - virtual bool isConst() const; - - virtual ConstOperationRoot<T,SRanges...> - operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const; - - virtual bool isInit() const; - - protected: - bool mInit = false; - std::shared_ptr<CRange> mRange; - - }; - - template <typename T, class... SRanges> - class MutableMultiArrayBase : public MultiArrayBase<T,SRanges...> - { - public: - - typedef ContainerRange<T,SRanges...> CRange; - //typedef typename MultiArrayBase<T,SRanges...>::const_iterator const_iterator; - typedef MultiArrayBase<T,SRanges...> MAB; - typedef typename CRange::IndexType IndexType; - - using MultiArrayBase<T,SRanges...>::operator[]; - using MultiArrayBase<T,SRanges...>::at; - using MultiArrayBase<T,SRanges...>::data; - using MultiArrayBase<T,SRanges...>::datav; - using MultiArrayBase<T,SRanges...>::begin; - using MultiArrayBase<T,SRanges...>::end; - - DEFAULT_MEMBERS(MutableMultiArrayBase); - MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges); - - virtual T& operator[](const IndexType& i) = 0; - virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0; - - virtual T* data() = 0; - virtual std::vector<T>& datav() = 0; - - //virtual IndexType begin(); - //virtual IndexType end(); - - virtual bool isConst() const override; - - virtual ConstOperationRoot<T,SRanges...> - operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const override; - virtual OperationRoot<T,SRanges...> operator()(std::shared_ptr<typename SRanges::IndexType>&... inds); - }; template <typename T, class... SRanges> class MultiArray : public MutableMultiArrayBase<T,SRanges...> @@ -106,8 +16,6 @@ namespace MultiArrayTools typedef ContainerRange<T,SRanges...> CRange; typedef MultiArrayBase<T,SRanges...> MAB; - //typedef typename MultiArrayBase<T,SRanges...>::const_iterator const_iterator; - //typedef typename MutableMultiArrayBase<T,SRanges...>::iterator iterator; typedef typename CRange::IndexType IndexType; DEFAULT_MEMBERS(MultiArray); @@ -141,13 +49,6 @@ namespace MultiArrayTools virtual const T* data() const override; virtual T* data() override; - - virtual const std::vector<T>& datav() const override; - virtual std::vector<T>& datav() override; - - // virtual void manipulate(ManipulatorBase<T>& mb, - // const typename CRange::IndexType& manBegin, - // const typename CRange::IndexType& manEnd); template <typename U, class... SRanges2> friend class MultiArray; @@ -155,30 +56,6 @@ namespace MultiArrayTools private: std::vector<T> mCont; }; - - template <typename T, class Function, class... SRanges> - class FunctionalMultiArray : public MultiArrayBase<T,SRanges...> - { - public: - - typedef ContainerRange<T,SRanges...> CRange; - typedef MultiArrayBase<T,CRange> MAB; - typedef typename MultiArrayBase<T,CRange>::const_iterator const_iterator; - typedef typename CRange::IndexType IndexType; - - DEFAULT_MEMBERS(FunctionalMultiArray); - //FunctionalMultiArray(const CRange& range); - FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, const Function& func); - - virtual const T& operator[](const IndexType& i) const override; - - virtual bool isConst() const override; - virtual bool isSlice() const override; - - protected: - mutable T mVal; - Function mFunc; - }; } @@ -189,122 +66,6 @@ namespace MultiArrayTools namespace MultiArrayTools { - /********************** - * MultiArrayBase * - **********************/ - - template <typename T, class... SRanges> - MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges) - { - ContainerRangeFactory<T,SRanges...> crf(ranges...); - mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() ); - } - - template <typename T, class... SRanges> - size_t MultiArrayBase<T,SRanges...>::size() const - { - return mRange->size(); - } - - template <typename T, class... SRanges> - typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const - { - auto i = mRange->begin(); - return i.setData(data()); - } - - template <typename T, class... SRanges> - typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const - { - auto i = mRange->end(); - return i.setData(data()); - } - - template <typename T, class... SRanges> - typename MultiArrayBase<T,SRanges...>::IndexType - MultiArrayBase<T,SRanges...>::beginIndex() const - { - auto i = mRange->begin(); - return i.setData(data()); - } - - template <typename T, class... SRanges> - typename MultiArrayBase<T,SRanges...>::IndexType - MultiArrayBase<T,SRanges...>::endIndex() const - { - auto i = mRange->end(); - return i.setData(data()); - } - - template <typename T, class... SRanges> - const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>& - MultiArrayBase<T,SRanges...>::range() const - { - return mRange; - } - - template <typename T, class... SRanges> - bool MultiArrayBase<T,SRanges...>::isConst() const - { - return true; - } - - template <typename T, class... SRanges> - ConstOperationRoot<T,SRanges...> - MultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const - { - return ConstOperationRoot<T,SRanges...>(*this, inds...); - } - - template <typename T, class... SRanges> - bool MultiArrayBase<T,SRanges...>::isInit() const - { - return mInit; - } - - /****************************** - * MutableMultiArrayBase * - ******************************/ - - template <typename T, class... SRanges> - MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) : - MultiArrayBase<T,SRanges...>(ranges...) {} - /* - template <typename T, class... SRanges> - typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin() - { - auto i = mRange->begin(); - return i.setData(data()); - } - - template <typename T, class... SRanges> - typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end() - { - auto i = mRange->end(); - return i.setData(data()); - } - */ - template <typename T, class... SRanges> - bool MutableMultiArrayBase<T,SRanges...>::isConst() const - { - return false; - } - - template <typename T, class... SRanges> - OperationRoot<T,SRanges...> - MutableMultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) - { - return OperationRoot<T,SRanges...>(*this, inds...); - } - - template <typename T, class... SRanges> - ConstOperationRoot<T,SRanges...> - MutableMultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const - { - return ConstOperationRoot<T,SRanges...>(*this, inds...); - } - - /******************* * MultiArray * *******************/ @@ -423,65 +184,6 @@ namespace MultiArrayTools { return mCont.data(); } - - template <typename T, class... SRanges> - const std::vector<T>& MultiArray<T,SRanges...>::datav() const - { - return mCont; - } - - template <typename T, class... SRanges> - std::vector<T>& MultiArray<T,SRanges...>::datav() - { - return mCont; - } - - - /* - template <typename T, class... SRanges> - void MultiArray<T,SRanges...>::manipulate(ManipulatorBase<T>& mb, - const typename Range::IndexType& manBegin, - const typename Range::IndexType& manEnd) - { - mb.setup(mCont, manBegin.pos(), manEnd.pos()); - mb.execute(); - } - */ - - - /**************************** - * FunctionalMultiArray * - ****************************/ - - /* - template <typename T, class Range, class Function> - FunctionalMultiArray<T,Range,Function>::FunctionalMultiArray(const Range& range) : - MultiArrayBase<T,SRanges...>(range), mFunc() {} - */ - template <typename T, class Function, class... SRanges> - FunctionalMultiArray<T,Function,SRanges...>::FunctionalMultiArray(const std::shared_ptr<SRanges>&... ranges, - const Function& func) : - MultiArrayBase<T,SRanges...>(ranges...), mFunc(func) {} - - template <typename T, class Function, class... SRanges> - const T& FunctionalMultiArray<T,Function,SRanges...>::operator[](const typename CRange::IndexType& i) const - { - mVal = mFunc(i); - return mVal; - } - - template <typename T, class Function, class... SRanges> - bool FunctionalMultiArray<T,Function,SRanges...>::isConst() const - { - return true; - } - - template <typename T, class Function, class... SRanges> - bool FunctionalMultiArray<T,Function,SRanges...>::isSlice() const - { - return false; - } - } #endif diff --git a/src/include/multi_array_base.h b/src/include/multi_array_base.h new file mode 100644 index 0000000..a96b21b --- /dev/null +++ b/src/include/multi_array_base.h @@ -0,0 +1,239 @@ + +#ifndef __multi_array_base_h__ +#define __multi_array_base_h__ + +#include <cstdlib> +#include <vector> +#include <memory> +#include <iterator> +#include <algorithm> + +#include "base_def.h" +#include "mbase_def.h" + +#include "ranges/rheader.h" + +namespace MultiArrayTools +{ + + // Explicitely specify subranges in template argument !!! + template <typename T, class... SRanges> + class MultiArrayBase + { + public: + + typedef T value_type; + typedef ContainerRange<T,SRanges...> CRange; + typedef typename CRange::IndexType IndexType; + + DEFAULT_MEMBERS(MultiArrayBase); + MultiArrayBase(const std::shared_ptr<SRanges>&... ranges); + MultiArrayBase(const typename CRange::SpaceType& 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<CRange>& range() const; + + virtual bool isConst() const; + + virtual ConstOperationRoot<T,SRanges...> + operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const; + + virtual bool isInit() const; + + // slice function !!!!! + + protected: + bool mInit = false; + std::shared_ptr<CRange> mRange; + + }; + + template <typename T, class... SRanges> + class MutableMultiArrayBase : public MultiArrayBase<T,SRanges...> + { + public: + + typedef ContainerRange<T,SRanges...> CRange; + typedef MultiArrayBase<T,SRanges...> MAB; + typedef typename CRange::IndexType IndexType; + + using MultiArrayBase<T,SRanges...>::operator[]; + using MultiArrayBase<T,SRanges...>::at; + using MultiArrayBase<T,SRanges...>::data; + using MultiArrayBase<T,SRanges...>::begin; + using MultiArrayBase<T,SRanges...>::end; + + DEFAULT_MEMBERS(MutableMultiArrayBase); + MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges); + MutableMultiArrayBase(const typename CRange::SpaceType& 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 ConstOperationRoot<T,SRanges...> + operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const override; + virtual OperationRoot<T,SRanges...> operator()(std::shared_ptr<typename SRanges::IndexType>&... inds); + }; + + +} // end namespace MultiArrayTools + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + /********************** + * MultiArrayBase * + **********************/ + + template <typename T, class... SRanges> + MultiArrayBase<T,SRanges...>::MultiArrayBase(const std::shared_ptr<SRanges>&... ranges) + { + ContainerRangeFactory<T,SRanges...> crf(ranges...); + mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() ); + } + + template <typename T, class... SRanges> + MultiArrayBase<T,SRanges...>::MultiArrayBase(const typename CRange::SpaceType& space) + { + ContainerRangeFactory<T,SRanges...> crf(space); + mRange = std::dynamic_pointer_cast<ContainerRange<T,SRanges...> >( crf.create() ); + } + + template <typename T, class... SRanges> + size_t MultiArrayBase<T,SRanges...>::size() const + { + return mRange->size(); + } + + template <typename T, class... SRanges> + typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::begin() const + { + auto i = mRange->begin(); + return i.setData(data()); + } + + template <typename T, class... SRanges> + typename MultiArrayBase<T,SRanges...>::IndexType MultiArrayBase<T,SRanges...>::end() const + { + auto i = mRange->end(); + return i.setData(data()); + } + + template <typename T, class... SRanges> + typename MultiArrayBase<T,SRanges...>::IndexType + MultiArrayBase<T,SRanges...>::beginIndex() const + { + auto i = mRange->begin(); + return i.setData(data()); + } + + template <typename T, class... SRanges> + typename MultiArrayBase<T,SRanges...>::IndexType + MultiArrayBase<T,SRanges...>::endIndex() const + { + auto i = mRange->end(); + return i.setData(data()); + } + + template <typename T, class... SRanges> + const std::shared_ptr<typename MultiArrayBase<T,SRanges...>::CRange>& + MultiArrayBase<T,SRanges...>::range() const + { + return mRange; + } + + template <typename T, class... SRanges> + bool MultiArrayBase<T,SRanges...>::isConst() const + { + return true; + } + + template <typename T, class... SRanges> + ConstOperationRoot<T,SRanges...> + MultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const + { + return ConstOperationRoot<T,SRanges...>(*this, inds...); + } + + template <typename T, class... SRanges> + bool MultiArrayBase<T,SRanges...>::isInit() const + { + return mInit; + } + + + /****************************** + * MutableMultiArrayBase * + ******************************/ + + template <typename T, class... SRanges> + MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const std::shared_ptr<SRanges>&... ranges) : + MultiArrayBase<T,SRanges...>(ranges...) {} + + template <typename T, class... SRanges> + MutableMultiArrayBase<T,SRanges...>::MutableMultiArrayBase(const typename CRange::SpaceType& space) : + MultiArrayBase<T,SRanges...>(space) {} + /* + template <typename T, class... SRanges> + typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::begin() + { + auto i = mRange->begin(); + return i.setData(data()); + } + + template <typename T, class... SRanges> + typename MutableMultiArrayBase<T,SRanges...>::IndexType MutableMultiArrayBase<T,SRanges...>::end() + { + auto i = mRange->end(); + return i.setData(data()); + } + */ + template <typename T, class... SRanges> + bool MutableMultiArrayBase<T,SRanges...>::isConst() const + { + return false; + } + + template <typename T, class... SRanges> + OperationRoot<T,SRanges...> + MutableMultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) + { + return OperationRoot<T,SRanges...>(*this, inds...); + } + + template <typename T, class... SRanges> + ConstOperationRoot<T,SRanges...> + MutableMultiArrayBase<T,SRanges...>::operator()(std::shared_ptr<typename SRanges::IndexType>&... inds) const + { + return ConstOperationRoot<T,SRanges...>(*this, inds...); + } + +} // end namespace MultiArrayTools + +#endif diff --git a/src/include/multi_array_header.h b/src/include/multi_array_header.h index 9dd1e2b..ab6021d 100644 --- a/src/include/multi_array_header.h +++ b/src/include/multi_array_header.h @@ -12,7 +12,9 @@ //#include "container_range.h" //#include "block.h" #include "multi_array_operation.h" +#include "multi_array_base.h" #include "multi_array.h" +#include "functional_multi_array.h" #include "helper_tools.h" //#include "slice.h" //#include "manipulator.h" diff --git a/src/include/pack_num.h b/src/include/pack_num.h index 9631565..eed17c4 100644 --- a/src/include/pack_num.h +++ b/src/include/pack_num.h @@ -13,7 +13,7 @@ namespace MultiArrayHelper { - + template <size_t N> struct PackNum { diff --git a/src/include/ranges/container_range.h b/src/include/ranges/container_range.h index e0d9713..6e8dd0d 100644 --- a/src/include/ranges/container_range.h +++ b/src/include/ranges/container_range.h @@ -7,7 +7,6 @@ #include <tuple> #include <memory> -//#include "base_def.h" #include "ranges/range_base.h" #include "ranges/index_base.h" @@ -32,9 +31,10 @@ namespace MultiArrayTools static IndexType sType() { return IndexType::CONT; } static size_t sDim() { return sizeof...(Indices); } static size_t totalDim() { return mkTotalDim<Indices...>(); } - + private: + bool mNonTrivialBlocks = false; bool mExternControl = false; IndexPack mIPack; std::array<size_t,sizeof...(Indices)+1> mBlockSizes; @@ -46,6 +46,10 @@ namespace MultiArrayTools template <class MRange> ContainerIndex(const std::shared_ptr<MRange>& range); + + template <class MRange> + ContainerIndex(const std::shared_ptr<MRange>& range, + const std::array<size_t,sizeof...(Indices)+1>& blockSizes); template <size_t N> auto get() const -> decltype( *std::get<N>( mIPack ) )&; @@ -71,13 +75,14 @@ namespace MultiArrayTools int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); - MetaType meta(); + MetaType meta() const; ContainerIndex& at(const MetaType& metaPos); - size_t dim(); - bool first(); - bool last(); - + size_t dim() const; + bool first() const; + bool last() const; + bool sliceMode() const; + std::shared_ptr<RangeType> range(); template <size_t N> @@ -148,7 +153,6 @@ namespace MultiArrayTools typedef RangeBase RB; typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType; typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType; - //typedef typename RangeInterface<ContainerIndex<typename Ranges::IndexType...> >::IndexType IndexType; protected: ContainerRange() = default; @@ -207,11 +211,24 @@ namespace MultiArrayTools IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0) { RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range); - IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack); std::get<sizeof...(Indices)>(mBlockSizes) = 1; RPackNum<sizeof...(Indices)-1>::initBlockSizes(mBlockSizes, mIPack); + IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes); } + template <typename T, class... Indices> + template <class MRange> + ContainerIndex<T,Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range, + const std::array<size_t,sizeof...(Indices)+1>& blockSizes) : + IndexInterface<ContainerIndex<T,Indices...>,std::tuple<typename Indices::MetaType...> >(range, 0) + { + RPackNum<sizeof...(Indices)-1>::construct(mIPack, *range); + mBlockSizes = blockSizes; + IB::mPos = RPackNum<sizeof...(Indices)-1>::makePos(mIPack, mBlockSizes); + mNonTrivialBlocks = true; + } + + template <typename T, class... Indices> ContainerIndex<T,Indices...>& ContainerIndex<T,Indices...>::sync() { @@ -303,7 +320,7 @@ namespace MultiArrayTools } template <typename T, class... Indices> - typename ContainerIndex<T,Indices...>::MetaType ContainerIndex<T,Indices...>::meta() + typename ContainerIndex<T,Indices...>::MetaType ContainerIndex<T,Indices...>::meta() const { MetaType metaTuple; RPackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack); @@ -319,23 +336,29 @@ namespace MultiArrayTools } template <typename T, class... Indices> - size_t ContainerIndex<T,Indices...>::dim() + size_t ContainerIndex<T,Indices...>::dim() const { return sizeof...(Indices); } template <typename T, class... Indices> - bool ContainerIndex<T,Indices...>::first() + bool ContainerIndex<T,Indices...>::first() const { return IB::pos() == 0; } template <typename T, class... Indices> - bool ContainerIndex<T,Indices...>::last() + bool ContainerIndex<T,Indices...>::last() const { return IB::pos() == IB::mMax - 1; } + template <typename T, class... Indices> + bool ContainerIndex<T,Indices...>::sliceMode() const + { + return mNonTrivialBlocks; + } + template <typename T, class... Indices> std::shared_ptr<typename ContainerIndex<T,Indices...>::RangeType> ContainerIndex<T,Indices...>::range() diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index 0fc2b2e..38c552c 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -27,6 +27,8 @@ namespace MultiArrayTools I& THIS() { return static_cast<I&>(*this); } I const& THIS() const { return static_cast<I const&>(*this); } + + static constexpr bool ISINDEX = true; ~IndexInterface() = default; diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index e10f847..d8e3c32 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -50,6 +50,8 @@ namespace MultiArrayTools { public: + static constexpr bool ISINDEX = false; + virtual ~RangeBase() = default; virtual size_t size() const = 0; diff --git a/src/include/ranges/rpack_num.h b/src/include/ranges/rpack_num.h index c547e2e..b765ab4 100644 --- a/src/include/ranges/rpack_num.h +++ b/src/include/ranges/rpack_num.h @@ -177,6 +177,13 @@ namespace MultiArrayHelper return std::get<N>(iPtrTup)->pos() + RPackNum<N-1>::makePos(iPtrTup) * std::get<N>(iPtrTup)->max(); } + template <class... Indices> + static inline size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup, + const std::array<size_t,sizeof...(Indices)+1>& blockSize) + { + return RPackNum<N-1>::makePos(iPtrTup, blockSize) + std::get<N>(iPtrTup)->pos() * std::get<N>(blockSize); + } + template <class Pack, class IndexType, class... Indices> static void swapIndices(Pack& ipack, const std::shared_ptr<IndexType>& nind, const std::shared_ptr<Indices>&... ninds) @@ -353,7 +360,14 @@ namespace MultiArrayHelper { return std::get<0>(iPtrTup)->pos(); } - + + template <class... Indices> + static inline size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup, + const std::array<size_t,sizeof...(Indices)+1>& blockSize) + { + return std::get<0>(iPtrTup)->pos() * std::get<0>(blockSize); + } + template <class Pack, class IndexType> static void swapIndices(Pack& ipack, const std::shared_ptr<IndexType>& nind) { diff --git a/src/include/slice.h b/src/include/slice.h new file mode 100644 index 0000000..de6bfa0 --- /dev/null +++ b/src/include/slice.h @@ -0,0 +1,162 @@ + +#ifndef __slice_h__ +#define __slice_h__ + +#include "multi_array_base.h" + +namespace MultiArrayTools +{ + + template <typename T, class... SRanges> + class Slice : public MutableMultiArrayBase<T,SRanges...> + { + public: + + typedef ContainerRange<T,SRanges...> CRange; + typedef MultiArrayBase<T,SRanges...> MAB; + typedef typename CRange::IndexType IndexType; + + DEFAULT_MEMBERS(Slice); + + template <class... RITypes> // 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<size_t,sizeof...(SRange)+1> mBlockSizes; + }; + +} // end namespace MultiArrayTools + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + namespace + { + + template <bool ISINDEX> + struct XX + { + template <class RI> + static auto ri_to_tuple(const std::shared_ptr<RI>& ri) + -> std::tuple<RI> + { + return std::make_tuple(ri); + } + }; + + template <> + struct XX<true> + { + template <class RI> + static auto ri_to_tuple(const std::shared_ptr<RI>& ri) + -> std::tuple<> + { + return std::make_tuple(); + } + }; + + template <class... RITypes> + auto mkSliceRange(const std::shared_ptr<RITypes>&... ris) + { + return std::tuple_cat(XX<RITypes::ISINDEX>::ri_to_tuple(ris)...); + } + + } + + /************* + * Slice * + *************/ + /* + template <typename T, class... SRanges> + Slice<T,SRanges...>::Slice(T* data, const RITypes&... ris) : + MutableMultiArrayBase<T,SRanges...>( mkSliceRange(ris...) ), + mData(data), + mStartPos(mkSliceStart(ris...)), + mBlockSizes(mkSliceBlocks(ris...)) {} + */ //!!!!! + template <typename T, class... SRanges> + const T& Slice<T,SRanges...>::operator[](const IndexType& i) const + { + assert(i.sliceMode()); // -> compare objects !!!!! + return mData[ i.pos() ]; + } + + template <typename T, class... SRanges> + T& Slice<T,SRanges...>::operator[](const IndexType& i) + { + assert(i.sliceMode()); + return mData[ i.pos() ]; + } + + template <typename T, class... SRanges> + const T& Slice<T,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) const + { + assert(i.sliceMode()); + return mData[ begin().at(meta).pos() ]; + } + + template <typename T, class... SRanges> + T& Slice<T,SRanges...>::at(const typename CRange::IndexType::MetaType& meta) + { + assert(i.sliceMode()); + return mData[ begin().at(meta).pos() ]; + } + + template <typename T, class... SRanges> + const T* Slice<T,SRanges...>::data() const + { + return mData; + } + + template <typename T, class... SRanges> + T* Slice<T,SRanges...>::data() + { + return mData; + } + + template <typename T, class... SRanges> + bool Slice<T,SRanges...>::isSlice() const + { + return true; + } + + template <typename T, class... SRanges> + IndexType Slice<T,SRanges...>::begin() const + { + IndexType i(mRange, mBlockSizes); + i = mStartPos; + return i.setData(data()); + } + + template <typename T, class... SRanges> + IndexType Slice<T,SRanges...>::end() const + { + IndexType i(mRange, mBlockSizes); + i = std::get<sizeof...(SRanges)>(mBlockSizes); + return i.setData(data()); + } + + + +} // end namespace MultiArrayTools + +#endif