// -*- C++ -*- #ifndef __container_range_h__ #define __container_range_h__ #include <cstdlib> #include <tuple> #include <memory> #include "base_def.h" #include "range_base.h" #include "index_base.h" namespace MultiArrayTools { template <class... Indices> class ContainerIndex : public IndexInterface<std::tuple<decltype(Indices().meta())...> > { public: typedef IndexBase IB; typedef std::tuple<decltype(Indices().meta())...> MetaType; typedef std::tuple<std::shared_ptr<Indices>...> IndexPack; typedef IndexInterface<std::tuple<decltype(Indices().meta())...> > IndexI; protected: bool mExternControl = false; IndexPack mIPack; public: ContainerIndex() = default; ContainerIndex(const ContainerIndex& in); ContainerIndex& operator=(const ContainerIndex& in); template <class MRange> ContainerIndex(const std::shared_ptr<MRange>& range); virtual ContainerIndex& operator++() override; virtual ContainerIndex& operator--() override; virtual ContainerIndex& operator=(size_t pos) override; virtual MetaType meta() const override; virtual ContainerIndex& at(const MetaType& metaPos) override; virtual bool first() const override; virtual bool last() const override; virtual size_t dim() const override; ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true template <size_t N> auto get() const -> decltype( *std::get<N>( mIPack ) )&; ContainerIndex& operator()(const std::shared_ptr<Indices>&... inds); // control via external indices ContainerIndex& operator()(); // -> sync; just to shorten the code }; template <class... Ranges> class ContainerRangeFactory : public RangeFactoryBase { public: typedef ContainerRange<Ranges...> oType; ContainerRangeFactory() = delete; ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs); ContainerRangeFactory(const typename ContainerRange<Ranges...>::SpaceType& space); virtual std::shared_ptr<RangeBase> create() override; protected: }; template <class... Ranges> class ContainerRange : public RangeInterface<ContainerIndex<typename Ranges::IndexType...> > { public: typedef RangeBase RB; typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType; typedef typename RangeInterface<ContainerIndex<typename Ranges::IndexType...> >::IndexType IndexType; protected: ContainerRange() = default; ContainerRange(const ContainerRange& in) = delete; ContainerRange& operator=(const ContainerRange& in) = delete; ContainerRange(const std::shared_ptr<Ranges>&... rs); ContainerRange(const SpaceType& space); SpaceType mSpace; public: static const size_t sdim = sizeof...(Ranges); virtual size_t dim() const override; virtual size_t size() const override; template <size_t N> auto get() const -> decltype( *std::get<N>( mSpace ) )&; template <size_t N> auto getPtr() const -> decltype( std::get<N>( mSpace ) )&; virtual IndexType begin() const override; virtual IndexType end() const override; virtual std::shared_ptr<IndexBase> index() const override; friend ContainerRangeFactory<Ranges...>; }; } // end namespace MultiArrayTools #include "container_range.cc" #endif