From f5cf35ae696df402737cb065923dd9286cfbd57b Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Tue, 7 Aug 2018 21:49:21 +0200 Subject: [PATCH] start with map range (not finished) --- src/include/multi_array_base.h | 30 +- src/include/ranges/index_base.h | 6 + src/include/ranges/map_range.h | 643 ++++++++++++++++++++++++++++++++ 3 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 src/include/ranges/map_range.h diff --git a/src/include/multi_array_base.h b/src/include/multi_array_base.h index 2ffb133..15a8e2f 100644 --- a/src/include/multi_array_base.h +++ b/src/include/multi_array_base.h @@ -61,7 +61,11 @@ namespace MultiArrayTools virtual ConstOperationRoot operator()(const std::shared_ptr&... inds) const; - + + template + ConstOperationRoot + operator()(const std::shared_ptr&... inds) const; + virtual bool isInit() const; template @@ -103,7 +107,13 @@ namespace MultiArrayTools virtual ConstOperationRoot operator()(const std::shared_ptr&... inds) const override; + virtual OperationRoot operator()(const std::shared_ptr&... inds); + + template + ConstOperationRoot + operator()(const std::shared_ptr&... inds); + }; @@ -197,6 +207,15 @@ namespace MultiArrayTools { return ConstOperationRoot(*this, inds...); } + + template + ConstOperationRoot + MultiArrayBase::operator()(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 (*this)(MapResult(inds)...); + } template bool MultiArrayBase::isInit() const @@ -259,6 +278,15 @@ namespace MultiArrayTools return ConstOperationRoot(*this, inds...); } + template + ConstOperationRoot + MultiArrayBase::operator()(const std::shared_ptr&... inds) + { + static_assert(sizeof...(SRanges) == sizeof...(MappedRanges), + "number of mapped ranges must be equal to number of original ranges"); + return (*this)(MapResult(inds)...); + } + } // end namespace MultiArrayTools #endif diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index 9fbf80d..f10d285 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -97,6 +97,12 @@ namespace MultiArrayTools std::intptr_t mPtrNum; }; + template + std::shared_ptr mapResult(const std::shared_ptr& iptr) + { + return iptr; + } + } /* ========================= * diff --git a/src/include/ranges/map_range.h b/src/include/ranges/map_range.h new file mode 100644 index 0000000..59ee61e --- /dev/null +++ b/src/include/ranges/map_range.h @@ -0,0 +1,643 @@ +// -*- C++ -*- + +#ifndef __map_range_h__ +#define __map_range_h__ + +#include +#include +#include +#include + +//#include "base_def.h" +#include "ranges/range_base.h" +#include "ranges/index_base.h" + +#include "ranges/rpack_num.h" +#include "ranges/multi_range_factory_product_map.h" +#include "ranges/x_to_string.h" +#include "ranges/type_map.h" + +namespace MultiArrayTools +{ + namespace + { + using namespace MultiArrayHelper; + } + + template + class MapIndex : public IndexInterface, + std::tuple > + { + public: + + typedef IndexInterface, + std::tuple > IB; + typedef std::tuple...> IndexPack; + typedef std::tuple MetaType; + typedef MapRange RangeType; + typedef MapIndex 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 = SpaceType::ANY; + + private: + + IndexPack mIPack; + std::array mBlockSizes; + std::shared_ptr mOutIndex; + + public: + + const IndexPack& pack() const { return mIPack; } + + MapIndex() = delete; + + // NO DEFAULT HERE !!! + // ( have to assign sub-indices (ptr!) correctly ) + //MapIndex(const MapIndex& in); + //MapIndex& operator=(const MapIndex& in); + + template + MapIndex(const std::shared_ptr& range); + + template + MapIndex& up(); + + template + MapIndex& down(); + + template + auto get() const -> decltype( *std::get( mIPack ) )&; + + template + auto getPtr() const -> decltype( std::get( mIPack ) )&; + + 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 + MapIndex& operator()(std::shared_ptr&... indices); + + // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== + + IndexType type() const; + + MapIndex& operator=(size_t pos); + + MapIndex& operator++(); + MapIndex& operator--(); + + int pp(std::intptr_t idxPtrNum); + int mm(std::intptr_t idxPtrNum); + + std::string stringMeta() const; + MetaType meta() const; + MapIndex& at(const MetaType& metaPos); + + size_t dim(); + bool first(); + bool last(); + std::shared_ptr range(); + + template + auto getPtr() -> decltype( std::get( mIPack ) )&; + + size_t getStepSize(size_t n); + + std::string id() const; + void print(size_t offset); + + template + auto ifor(Exprs exs) const + -> decltype(RPackNum::mkFors(mIPack, mOutIndex, exs)); + + /* + template + auto iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)); + */ + }; + + template + auto mapResult >(const std::shared_ptr >& ind) + -> decltype(ind->outIndex()) + { + return ind->outIndex(); + } + + /************************* + * MapRangeFactory * + *************************/ + + // NOT THREAD SAVE + template + class MapRangeFactory : public RangeFactoryBase + { + public: + typedef MapRange oType; + + MapRangeFactory() = delete; + MapRangeFactory(const std::shared_ptr&... rs); + MapRangeFactory(const typename MapRange::Space& space); + + template + MapRangeFactory(const std::shared_ptr >& cr); + + virtual std::shared_ptr create() override; + + private: + + std::shared_ptr checkIfCreated(const std::tuple...>& ptp); + + }; + + /****************** + * MapRange * + ******************/ + + template + class MapRange : public RangeInterface > + { + public: + typedef RangeBase RB; + typedef std::tuple...> Space; + typedef MapIndex IndexType; + typedef MapRange RangeType; + typedef SingleRange ORType; + typedef SingleRangeFactory ORFType; + //typedef typename RangeInterface >::IndexType IndexType; + + protected: + MapRange() = delete; + MapRange(const MapRange& in) = delete; + MapRange& operator=(const MapRange& in) = delete; + + MapRange(const MapF& mapf, const std::shared_ptr&... rs); + MapRange(const MapF& mapf, const Space& space); + + Space mSpace; + shred_ptr mOutRange; + + public: + + static const size_t sdim = sizeof...(Ranges); + + template + auto get() const -> decltype( *std::get( mSpace ) )&; + + template + auto getPtr() const -> decltype( std::get( mSpace ) )&; + + shred_ptr outRange() const; + + virtual size_t dim() const final; + virtual size_t size() const final; + + virtual SpaceType spaceType() 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; + + template + auto cat(const std::shared_ptr >& erange) + -> std::shared_ptr >; + + friend MapRangeFactory; + + static constexpr bool HASMETACONT = false; + static constexpr bool defaultable = false; + static constexpr size_t ISSTATIC = SubProp::ISSTATIC; + static constexpr size_t SIZE = SubProp::SIZE; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + namespace + { + using namespace MultiArrayHelper; + } + + // -> define in range_base.cc + std::shared_ptr mkMULTI(const char** dp); + + /****************** + * MapIndex * + ******************/ + + /* + template + MapIndex::MapIndex(const MapIndex& in) : + IndexInterface >(in) + { + RPackNum::copy(mIPack, in); + IB::mPos = RPackNum::makePos(mIPack); + } + + template + MapIndex& MapIndex::operator=(const MapIndex& in) + { + IndexI::operator=(in); + RPackNum::copy(mIPack, in); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + */ + + template + template + MapIndex::MapIndex(const std::shared_ptr& range) : + IndexInterface,std::tuple >(range, 0) + { + RPackNum::construct(mIPack, *range); + IB::mPos = RPackNum::makePos(mIPack); + std::get(mBlockSizes) = 1; + RPackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! + mOutIndex = std::dynamic_pointer_cast( IB::mRangePtr )->outRange()->begin(); + } + + template + template + MapIndex& MapIndex::up() + { + static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); + IB::mPos += RPackNum::blockSize( mIPack ); + RPackNum::pp( mIPack ); + return *this; + } + + template + template + MapIndex& MapIndex::down() + { + static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); + IB::mPos -= RPackNum::blockSize( mIPack ); + RPackNum::mm( mIPack ); + return *this; + } + + template + template + auto MapIndex::get() const -> decltype( *std::get( mIPack ) )& + { + return *std::get(mIPack); + } + + template + template + auto MapIndex::getPtr() const -> decltype( std::get( mIPack ) )& + { + return std::get(mIPack); + } + + template + std::shared_ptr MapIndex::outIndex() const + { + return mOutIndex; + } + + template + MapIndex& MapIndex::operator()(std::shared_ptr&... indices) + { + RPackNum::swapIndices(mIPack, indices...); + RPackNum::setIndexPack(mIPack, IB::mPos); + return *this; + } + + template + IndexType MapIndex::type() const + { + return IndexType::MULTI; + } + + template + MapIndex& MapIndex::operator=(size_t pos) + { + IB::mPos = pos; + RPackNum::setIndexPack(mIPack, pos); + return *this; + } + + template + MapIndex& MapIndex::operator++() + { + RPackNum::pp( mIPack ); + ++IB::mPos; + return *this; + } + + template + MapIndex& MapIndex::operator--() + { + RPackNum::mm( mIPack ); + --IB::mPos; + return *this; + } + + template + int MapIndex::pp(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); + IB::mPos += tmp; + return tmp; + } + + template + int MapIndex::mm(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); + IB::mPos -= tmp; + return tmp; + } + + template + std::string MapIndex::stringMeta() const + { + return std::dynamic_pointer_cast( IB::mRangePtr )->stringMeta(IB::mPos); + } + + template + typename MapIndex::MetaType MapIndex::meta() const + { + MetaType metaTuple; + RPackNum::getMetaPos(metaTuple, mIPack); + return metaTuple; + } + + template + MapIndex& MapIndex::at(const MetaType& metaPos) + { + RPackNum::setMeta(mIPack, metaPos); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + + template + size_t MapIndex::dim() + { + return sizeof...(Indices); + } + + template + bool MapIndex::first() + { + return IB::mPos == 0; + } + + template + bool MapIndex::last() + { + return IB::mPos == IB::mMax - 1; + } + + template + std::shared_ptr::RangeType> + MapIndex::range() + { + return std::dynamic_pointer_cast( IB::mRangePtr ); + } + + template + template + auto MapIndex::getPtr() -> decltype( std::get( mIPack ) )& + { + return std::get(mIPack); + } + + template + size_t MapIndex::getStepSize(size_t n) + { + if(n >= sizeof...(Indices)){ + assert(0); + // throw !! + } + return mBlockSizes[n+1]; + } + + template + std::string MapIndex::id() const + { + return std::string("mul") + std::to_string(IB::mId); + } + + template + void MapIndex::print(size_t offset) + { + if(offset == 0){ + std::cout << " === " << std::endl; + } + for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } + std::cout << id() << "[" << reinterpret_cast(this) + << "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl; + RPackNum::printIndex(mIPack, offset+1); + } + + template + template + auto MapIndex::ifor(Exprs exs) const + -> decltype(RPackNum::mkFor(mIPack, exs)) + { + return RPackNum::mkFor(mIPack, exs); + } + + template + template + auto MapIndex::iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)) + { + return RPackNum::mkForh(mIPack, exs); + } + + /************************* + * MapRangeFactory * + *************************/ + + template + MapRangeFactory::MapRangeFactory(const std::shared_ptr&... rs) + { + mProd = std::shared_ptr< MapRange >( new MapRange( rs... ) ); + } + + template + MapRangeFactory::MapRangeFactory(const typename MapRange::Space& st) + { + mProd = std::shared_ptr< MapRange >( new MapRange( st ) ); + } + + template + template + MapRangeFactory::MapRangeFactory(const std::shared_ptr >& cr) + { + mProd = std::shared_ptr< MapRange >( new MapRange( cr->space() ) ); + } + + template + std::shared_ptr MapRangeFactory::create() + { + mProd = checkIfCreated( std::dynamic_pointer_cast( mProd )->mSpace ); + setSelf(); + return mProd; + } + + template + std::shared_ptr MapRangeFactory::checkIfCreated(const std::tuple...>& ptp) + { + std::shared_ptr out; + bool check = false; + for(auto& x: MapRangeFactoryProductMap::mAleadyCreated){ + if(x.second.size() == sizeof...(Ranges)){ + check = RPackNum::checkIfCreated(ptp, x.second); + if(check){ + out = x.first; + break; + } + } + } + if(not check){ + std::vector pv(sizeof...(Ranges)); + RPackNum::RangesToVec(ptp, pv); + MapRangeFactoryProductMap::mAleadyCreated[mProd] = pv; + out = mProd; + } + return out; + } + + /****************** + * MapRange * + ******************/ + + template + MapRange::MapRange(const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)) + { + std::vector outmeta; + // set !!!! + ORFType orf(outmeta); + mOutRange = std::dynamic_pointer_cast( orf.create() ); + } + + template + MapRange::MapRange(const Space& space) : mSpace( space ) + { + std::vector outmeta; + // set !!!! + ORFType orf(outmeta); + mOutRange = std::dynamic_pointer_cast( orf.create() ); + } + + template + template + auto MapRange::get() const -> decltype( *std::get( mSpace ) )& + { + return *std::get(mSpace); + } + + template + template + auto MapRange::getPtr() const -> decltype( std::get( mSpace ) )& + { + return std::get(mSpace); + } + + template + shred_ptr MapRange::outRange() const + { + return mOutRange; + } + + template + size_t MapRange::dim() const + { + return sdim; + } + + template + size_t MapRange::size() const + { + return RPackNum::getSize(mSpace); + } + + template + SpaceType MapRange::spaceType() const + { + return SpaceType::ANY; + } + + template + const typename MapRange::Space& MapRange::space() const + { + return mSpace; + } + + template + std::string MapRange::stringMeta(size_t pos) const + { + auto i = begin(); + i = pos; + return "[ " + RPackNum::metaTupleToString(i.meta()) + " ]"; + } + + template + std::vector MapRange::data() const + { + DataHeader h; + h.spaceType = static_cast( SpaceType::ANY ); + h.metaSize = sizeof...(Ranges); + h.multiple = 1; + std::vector out; + //out.reserve(h.metaSize + sizeof(DataHeader)); + char* hcp = reinterpret_cast(&h); + out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); + RPackNum::fillRangeDataVec(out, mSpace); + return out; + } + + template + typename MapRange::IndexType MapRange::begin() const + { + MapIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + template + typename MapRange::IndexType MapRange::end() const + { + MapIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis )) ); + i = size(); + return i; + } + + template + template + auto MapRange::cat(const std::shared_ptr >& erange) + -> std::shared_ptr > + { + auto crange = std::tuple_cat(mSpace, erange->space()); + MapRangeFactory rf(crange); + return std::dynamic_pointer_cast >(rf.create()); + } + +} + +#endif