// -*- C++ -*- #ifndef __map_range_h__ #define __map_range_h__ #include #include #include #include #include "mbase_def.h" #include "ranges/range_base.h" #include "ranges/index_base.h" #include "ranges/rpack_num.h" #include "map_range_factory_product_map.h" #include "ranges/x_to_string.h" #include "ranges/type_map.h" #include "xfor/xfor.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } template auto mkMapOp(const MA& ma, const std::tuple...>& itp) -> decltype(PackNum::mkMapOp(ma, itp)) { return PackNum::mkMapOp(ma, itp); } template class OpExpr { public: typedef SingleIndex OIType; //typedef typename MapF::IndexPack IndexPack; static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t SIZE = Expr::SIZE; private: OpExpr() = default; const OIType* mIndPtr; size_t mSPos; size_t mMax; size_t mStep; Expr mExpr; typedef decltype(mkMapOp(std::declval(), std::declval())) Op; Op mOp; typedef decltype(mOp.rootSteps(std::declval()).extend( mExpr.rootSteps(std::declval()) )) ExtType; ExtType mExt; public: OpExpr(const OpExpr& in) = default; OpExpr(OpExpr&& in) = default; OpExpr& operator=(const OpExpr& in) = default; OpExpr& operator=(OpExpr&& in) = default; OpExpr(const MapF& mapf, const IndexPack& ipack, const std::shared_ptr& oind, size_t step, Expr ex); inline void operator()(size_t mlast, ExtType last) const; inline void operator()(size_t mlast = 0) const; auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; }; template class GenMapIndex : public IndexInterface, std::tuple > { public: typedef IndexInterface, std::tuple > IB; typedef std::tuple...> IndexPack; typedef std::tuple MetaType; typedef GenMapRange RangeType; typedef GenMapIndex IType; typedef SingleIndex OIType; static constexpr IndexType sType() { return IndexType::MULTI; } static constexpr size_t sDim() { return sizeof...(Indices); } static constexpr size_t totalDim() { return mkTotalDim(); } static constexpr SpaceType STYPE = XSTYPE; static constexpr bool PARALLEL = false; private: IndexPack mIPack; std::array mBlockSizes; std::shared_ptr mOutIndex; public: const IndexPack& pack() const { return mIPack; } GenMapIndex() = delete; // NO DEFAULT HERE !!! // ( have to assign sub-indices (ptr!) correctly ) //MapIndex(const MapIndex& in); //MapIndex& operator=(const MapIndex& in); template GenMapIndex(const std::shared_ptr& range); template GenMapIndex& up(); template GenMapIndex& down(); template auto get() const -> decltype( *std::get( mIPack ) )&; template auto getPtr() const -> decltype( std::get( mIPack ) )&; template size_t getBlockSize() const { return std::get(mBlockSizes); } std::shared_ptr outIndex() const; // raplace instances (in contrast to its analogon in ContainerIndex // MultiIndices CANNOT be influences be its subindices, so there is // NO foreign/external controll) // Do NOT share index instances between two or more MapIndex instances GenMapIndex& operator()(std::shared_ptr&... indices); // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== IndexType type() const; GenMapIndex& operator=(size_t pos); GenMapIndex& operator++(); GenMapIndex& operator--(); int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; MetaType meta() const; GenMapIndex& at(const MetaType& metaPos); size_t dim() const; bool first() const; bool last() const; std::shared_ptr range() const; template auto getPtr() -> decltype( std::get( mIPack ) )&; size_t getStepSize(size_t n) const; std::string id() const; void print(size_t offset) const; template auto ifor(size_t step, Exprs exs) const -> decltype(RPackNum::mkForh (step, mIPack, mBlockSizes, OpExpr( range()->map(), mIPack, mOutIndex, step, exs ) ) ); // first step arg not used! template auto pifor(size_t step, Exprs exs) const -> decltype(ifor(step, exs)); // NO MULTITHREADING /* template auto iforh(Exprs exs) const -> decltype(RPackNum::mkForh(mIPack, exs)); */ }; /************************* * MapRangeFactory * *************************/ // NOT THREAD SAVE template class GenMapRangeFactory : public RangeFactoryBase { public: typedef GenMapRange oType; GenMapRangeFactory() = delete; GenMapRangeFactory(const MapF& mapf, const std::shared_ptr&... rs); GenMapRangeFactory(const MapF& mapf, const typename GenMapRange::Space& space); virtual std::shared_ptr create() override; private: std::shared_ptr checkIfCreated(const std::tuple...>& ptp); }; /****************** * MapRange * ******************/ template class GenMapRange : public RangeInterface > { public: typedef RangeBase RB; typedef std::tuple...> Space; typedef GenMapIndex IndexType; typedef GenMapRange RangeType; typedef SingleRange ORType; typedef SingleRangeFactory ORFType; //typedef typename RangeInterface >::IndexType IndexType; protected: GenMapRange() = delete; GenMapRange(const GenMapRange& in) = delete; GenMapRange& operator=(const GenMapRange& in) = delete; GenMapRange(const MapF& mapf, const std::shared_ptr&... rs); GenMapRange(const MapF& mapf, const Space& space); Space mSpace; const MapF& mMapf; std::shared_ptr mOutRange; MultiArray mMapMult; private: void mkOutRange(); public: static constexpr size_t sdim = sizeof...(Ranges); template auto get() const -> decltype( *std::get( mSpace ) )&; template auto getPtr() const -> decltype( std::get( mSpace ) )&; std::shared_ptr outRange() const; const MapF& map() const; virtual size_t dim() const final; virtual size_t size() const final; virtual SpaceType spaceType() const final; virtual DataHeader dataHeader() const final; virtual std::string stringMeta(size_t pos) const final; virtual std::vector data() const final; const Space& space() const; virtual IndexType begin() const final; virtual IndexType end() const final; const MultiArray& mapMultiplicity() const; MultiArray explMapMultiplicity() const; /* template auto cat(const std::shared_ptr >& erange) -> std::shared_ptr >; */ friend GenMapRangeFactory; static constexpr bool HASMETACONT = false; static constexpr bool defaultable = false; static constexpr size_t ISSTATIC = SubProp::ISSTATIC; static constexpr size_t SIZE = SubProp::SIZE; }; // for legacy template using MapIndex = GenMapIndex; template using MapRangeFactory = GenMapRangeFactory; template using MapRange = GenMapRange; template auto mapResult/* >*/(const std::shared_ptr >& ind) -> decltype(ind->outIndex()) { return ind->outIndex(); } } #endif