diff --git a/src/multi_range.cc b/src/multi_range.cc index 628d2cd..c169934 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -223,6 +223,52 @@ namespace MultiArrayTools rvec.push_back(std::get(rs).type()); } }; + + template + struct MetaPosGetter + { + template + static void getMetaPos(typename MultiIndex::MetaType& target, + const typename MultiIndex::IndexPack& source) + { + std::get(target) = std::get(source).getMetaPos(); + MetaPosGetter::getMetaPos(target, source); + } + }; + + template <> + struct MetaPosGetter<0> + { + template + static void getMetaPos(typename MultiIndex::MetaType& target, + const typename MultiIndex::IndexPack& source) + { + std::get<0>(target) = std::get<0>(source).getMetaPos(); + } + }; + + template + struct MetaSetter + { + template + static void setMeta(typename MultiIndex::IndexPack& target, + const typename MultiIndex::MetaType& source) + { + std::get(target).atMeta( std::get(source) ); + MetaSetter::setMeta(target, source); + } + }; + + template <> + struct MetaSetter<0> + { + template + static void setMeta(typename MultiIndex::IndexPack& target, + const typename MultiIndex::MetaType& source) + { + std::get<0>(target).atMeta( std::get<0>(source) ); + } + }; } @@ -445,6 +491,7 @@ namespace MultiArrayTools IndefinitIndexBase& MultiIndex::get(size_t n) { if(n >= sizeof...(Indices)){ + assert(0); // throw !! } MultiIndex* t = this; @@ -455,12 +502,28 @@ namespace MultiArrayTools const IndefinitIndexBase& MultiIndex::get(size_t n) const { if(n >= sizeof...(Indices)){ + assert(0); // throw !! } MultiIndex const* t = this; return IndexGetter::getIndex(*t, n); } + template + typename MultiIndex::MetaType MultiIndex::getMetaPos() const + { + MetaType metaTuple; + MetaPosGetter::getMetaPos(metaTuple, mIPack); + return metaTuple; + } + + template + MultiIndex& MultiIndex::atMeta(const MultiIndex::MetaType& metaPos) + { + MetaSetter::setMeta(mIPack, metaPos); + return *this; + } + template bool MultiIndex::linkLower(IndefinitIndexBase* toLink) { diff --git a/src/multi_range.h b/src/multi_range.h index 815adc1..e94ec00 100644 --- a/src/multi_range.h +++ b/src/multi_range.h @@ -20,6 +20,7 @@ namespace MultiArrayTools typedef std::tuple IndexPack; typedef IndefinitIndexBase IIB; typedef IndexBase > IB; + typedef std::tuple MetaType; protected: @@ -67,6 +68,9 @@ namespace MultiArrayTools IndefinitIndexBase& get(size_t n); const IndefinitIndexBase& get(size_t n) const; + MetaType getMetaPos() const; + MultiIndex& atMeta(const MetaType& metaPos); + MultiIndex& operator()(Indices&&... inds); MultiIndex& operator()(const Indices&... inds); diff --git a/src/range_base.h b/src/range_base.h index 6c18a18..e93d13c 100644 --- a/src/range_base.h +++ b/src/range_base.h @@ -52,7 +52,7 @@ namespace MultiArrayTools RangeType mType; std::vector* mMultiType; }; - + template class RangeBase { diff --git a/src/single_range.cc b/src/single_range.cc index cd7478d..f8854ee 100644 --- a/src/single_range.cc +++ b/src/single_range.cc @@ -18,7 +18,7 @@ namespace MultiArrayTools } template - size_t SingleRange::get(const U& metaPos) const + size_t SingleRange::getMeta(const U& metaPos) const { size_t cnt = 0; for(auto& x: mSpace){ @@ -131,6 +131,13 @@ namespace MultiArrayTools return dynamic_cast const*>( IB::mRange )->get(IIB::pos()); } + template + SingleIndex& SingleIndex::atMeta(const U& metaPos) + { + operator=( dynamic_cast const*>( IB::mRange )->getMeta(metaPos) ); + return *this; + } + template size_t SingleIndex::dim() const { diff --git a/src/single_range.h b/src/single_range.h index 7ad231f..484dc53 100644 --- a/src/single_range.h +++ b/src/single_range.h @@ -44,7 +44,8 @@ namespace MultiArrayTools virtual MultiRangeType rangeType() const override; virtual const U& getMetaPos() const; - + virtual SingleIndex& atMeta(const U& metaPos); + virtual size_t dim() const override; // = 1 virtual void linkTo(IndefinitIndexBase* target) override; @@ -68,7 +69,7 @@ namespace MultiArrayTools virtual size_t size() const override; const U& get(size_t pos) const; - size_t get(const U& metaPos) const; + size_t getMeta(const U& metaPos) const; virtual MultiRangeType type() const override;