diff --git a/src/container_range.cc b/src/container_range.cc new file mode 100644 index 0000000..9e47e97 --- /dev/null +++ b/src/container_range.cc @@ -0,0 +1,14 @@ +// -*- C++ -*- + +#include "container_range.h" +#include "numpack.h" + +namespace MultiArrayTools +{ + namespace + { + using namespace MultiArrayHelper; + } + + +} // end namespace MultiArrayTools diff --git a/src/container_range.h b/src/container_range.h new file mode 100644 index 0000000..c687751 --- /dev/null +++ b/src/container_range.h @@ -0,0 +1,96 @@ +// -*- C++ -*- + +#ifndef __container_range_h__ +#define __container_range_h__ + +#include +#include "base_def.h" + +namespace MultiArrayTools +{ + + template + class ContainerRangeFactory : public RangeFactoryBase + { + public: + + ContainerRangeFactory() = delete; + ContainerRangeFactory(const std::shared_ptr& rs); + ContainerRangeFactory(const ContainerRange::SpaceType& space); + + virtual std::shared_ptr create() override; + + protected: + + }; + + template + class ContainerRange : public RangeInterface > + { + public: + + typedef std::tuple...> SpaceType; + typedef typename RangeInterface >::IndexType IndexType; + + static const size_t dim = sizeof...(Ranges); + + virtual size_t dim() const override; + virtual size_t size() const override; + + virtual typename IndexType begin() const override; + virtual typename IndexType end() const override; + + virtual std::shared_ptr index() const override; + + friend ContainerRangeFactory; + + protected: + + ContainerRange() = default; + ContainerRange(const ContainerRange& in) = delete; + + ContainerRange(const std::shared_ptr& rs); + ContainerRange(const SpaceType& space); + + SpaceType mSpace; + }; + + template + class ContainerIndex : public IndexInterface > + { + public: + + typedef std::tuple MetaType; + typedef std::tuple...> IndexPack; + + ContainerIndex() = default; + + ContainerIndex(const ContainerIndex& in); + ContainerIndex& operator=(const ContainerIndex& in); + + template + ContainerIndex(const std::shared_ptr& 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 size_t dim() const override; + virtual size_t pos() const override; // recalculate when externalControl == true + + ContainerIndex& operator()(const std::shared_ptr&... inds); // control via external indices + + protected: + + bool externControl = false; + IndexPack mIPack; + }; + +} // end namespace MultiArrayTools + +#include "container_range.cc" + +#endif diff --git a/src/index_base.cc b/src/index_base.cc index 457eee6..675728c 100644 --- a/src/index_base.cc +++ b/src/index_base.cc @@ -33,7 +33,7 @@ namespace MultiArrayTools operator IndexBase::size_t() const { - return mPos; + return pos(); } /********************** diff --git a/src/multi_range.cc b/src/multi_range.cc index 59dce8b..f3cab13 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -1,295 +1,19 @@ #include "multi_range.h" +#include "packnum.h" namespace MultiArrayTools { - /******************* - * MultiIndexBase * - *******************/ namespace { - - template - struct PackNum - { - template - static IndexBase& getIndex(MultiIndex& in, size_t n) - { - if(n == N){ - return in.getIndex(); - } - else { - return PackNum::getIndex(in, n); - } - } - - template - static const IndexBase& getIndex(const MultiIndex& in, size_t n) - { - if(n == N){ - return in.getIndex(); - } - else { - return PackNum::getIndex(in, n); - } - } - - template - static inline void pp(std::tuple...>& ip) - { - auto& si = *std::get(ip); - if(si.pos() == si.last()){ - si = 0; - PackNum::pp(index); - } - else { - ++si; - } - } - - template - static inline void mm(std::tuple...>& ip) - { - auto& si = *std::get(ip); - if(si.pos() == si.atEdge()){ - si = si.max(); - PackNum::mm(index); - } - else { - --si; - } - } - - template - static size_t getSize(const RangeTuple& rt) - { - return std::get(rt).size() * PackNum::getSize(rt); - } - - template - static void setBegin(MultiRange::IndexType& i, const MultiRange::SpaceType& r) - { - *std::get(i) = std::get(r)->begin(); - PackNum::setBegin(i,r); - } - - template - static void setEnd(MultiRange::IndexType& i, const MultiRange::SpaceType& r) - { - *std::get(i) = std::get(r)->end(); - *std::get(i) -= 1; - PackNum::setEnd(i,r); - } - - template - static void buildRangeVec(std::vector& rvec, const MultiRange::SpaceType& rs) - { - rvec.push_back(std::get(rs)->type()); - PackNum::buildRangeVec(rvec, rs); - } - - template - static void getMetaPos(std::tuple& target, - const typename MultiIndex::IndexPack& source) - { - std::get(target) = std::get(source)->meta(); - PackNum::getMetaPos(target, source); - } - - template - static void setMeta(typename MultiIndex::IndexPack& target, - const typename MultiIndex::MetaType& source) - { - std::get(target).atMeta( std::get(source) ); - PackNum::setMeta(target, source); - } - - template - static void setIndexPack(IndexPack& iPack, size_t pos) - { - auto i = std::get(iPack); - const size_t ownPos = pos % i.max(); - i = ownPos; - if(ownPos == pos){ - PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); - } - } - - template - static auto setFromPointerList(IndexPack& ipack, - std::vector >& ptrList, - std::shared_ptr&... inds) - -> decltype(PackNum::setFromPointerList(ipack, - std::shared_ptr(ipack))>, - newPtr, inds...)) - { - typedef std::shared_ptr(ipack))> NewIndexPtrType; - NewIndexPtrType newPtr = dynamic_pointer_cast(ptrList.at(N)); - return PackNum::setFromPointerList(ipack, ptrList, newPtr, inds...); - } - - template - static void construct(std::tuple...>& ip, - const MRange& range) - { - typedef decltype(range.template get()) SubIndexType; - typedef decltype(std::get(ip).get()) TypeFromIndexPack; - - static_assert(std::is_same::value, - "inconsiśtent types"); - - std::get(ip).swap( std::make_shared( range.template get() ) ); - PackNum::construct(ip, range); - } - - template - static void copy(std::tuple...>& ip, - const MultiIndex& ind) - { - typedef decltype(ind.template get()) SubIndexType; - std::get(ip).swap( std::make_shared( ind.template get() ) ); - PackNum::copy(ip, ind); - } - - template - static size_t makePos(const std::tuple...>& iPtrTup) - { - return std::get(iPtrTup)->pos() + - PackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); - } - - template - static void print(std::ostream& os, const std::tuple& meta) - { - PackNum::print(os, meta); - os << std::get(meta) << '\t'; - } - - }; - - template<> - struct PackNum<0> - { - template - static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) - { - return in.getIndex<0>(); - } - - template - static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n) - { - return in.getIndex<0>(); - } - - template - static inline void pp(std::tuple...>& ip) - { - auto& si = *std::get<0>(ip); - ++si; - } - - template - static inline void mm(std::tuple...>& ip) - { - auto& si = *std::get<0>(ip); - --si; - } - - template - static size_t getSize(const RangeTuple& rt) - { - return std::get<0>(rt).size(); - } - - template - static void setBegin(MultiRange::IndexType& i, const MultiRange::SpaceType& r) - { - *std::get<0>(i) = std::get<0>(r)->begin(); - } - - template - static void setEnd(MultiRange::IndexType& i, const MultiRange::SpaceType& r) - { - *std::get<0>(i) = std::get<0>(r)->end(); - *std::get<0>(i) -= 1; - } - - template - static void buildRangeVec(std::vector& rvec, const MultiRange::SpaceType& rs) - { - rvec.push_back(std::get(rs)->type()); - } - - template - static void getMetaPos(std::tuple& target, - const typename MultiIndex::IndexPack& source) - { - std::get<0>(target) = std::get<0>(source)->meta(); - } - - template - static void setMeta(typename MultiIndex::IndexPack& target, - const typename MultiIndex::MetaType& source) - { - std::get<0>(target).atMeta( std::get<0>(source) ); - } - - template - static void setIndexPack(IndexPack& iPack, size_t pos) - { - auto i = std::get<0>(iPack); - const size_t ownPos = pos % i.max(); - i = ownPos; - } - - template - static auto setFromPointerList(IndexPack& ipack, - std::vector >& ptrList, - std::shared_ptr&... inds) - -> decltype(std::make_tuple(std::shared_ptr(ipack))>, inds...)) - { - typedef std::shared_ptr(ipack))> NewIndexPtrType; - NewIndexPtrType newPtr = dynamic_pointer_cast(ptrList.at(0)); - return std::make_tuple(newPtr, inds...); - } - - template - static void construct(std::tuple...>& ip, - const MRange& range) - { - typedef decltype(range.template get<0>()) SubIndexType; - typedef decltype(std::get<0>(ip).get()) TypeFromIndexPack; - - static_assert(std::is_same::value, - "inconsiśtent types"); - - std::get<0>(ip).swap( std::make_shared( range.template get<0>() ) ); - } - - template - static void copy(std::tuple...>& ip, - const MultiIndex& ind) - { - typedef decltype(ind.template get<0>()) SubIndexType; - std::get<0>(ip).swap( std::make_shared( ind.template get<0>() ) ); - } - - template - static size_t makePos(const std::tuple...>& iPtrTup) - { - return std::get<0>(iPtrTup)->pos(); - } - - template - static void print(std::ostream& os, const std::tuple& meta) - { - os << std::get<0>(meta) << '\t'; - } - }; + using namespace MultiArrayHelper; } + /********************** + * MultiIndexBase * + **********************/ + template MultiIndex::MultiIndex(const MultiIndex& in) : IndexInterface >(in) diff --git a/src/multi_range.h b/src/multi_range.h index 7670ae7..2de8e70 100644 --- a/src/multi_range.h +++ b/src/multi_range.h @@ -65,12 +65,12 @@ namespace MultiArrayTools *************************/ template - class MultiRangeFactory : public RangeFactory + class MultiRangeFactory : public RangeFactoryBase { public: MultiRangeFactory() = delete; MultiRangeFactory(const std::shared_ptr&... rs); - MultiRangeFactory(const MultiRange::SpaceType& st); + MultiRangeFactory(const MultiRange::SpaceType& space); virtual std::shared_ptr create() override; }; @@ -85,8 +85,7 @@ namespace MultiArrayTools public: typedef std::tuple...> SpaceType; - typedef typename RangeInterface >::IndexType - IndexType; + typedef typename RangeInterface >::IndexType IndexType; static const size_t dim = sizeof...(Ranges); @@ -94,8 +93,8 @@ namespace MultiArrayTools auto get() const ->; //typename std::tuple_element...> >::type const& getRange() const; - size_t dim() const override; - size_t size() const override; + virtual size_t dim() const override; + virtual size_t size() const override; const SpaceType& space() const; diff --git a/src/pack_num.h b/src/pack_num.h new file mode 100644 index 0000000..4236a81 --- /dev/null +++ b/src/pack_num.h @@ -0,0 +1,223 @@ +// -*- C++ -*- + +#include +#include + +namespace MultiArrayHelper +{ + + template + struct PackNum + { + template + static IndexBase& getIndex(MultiIndex& in, size_t n) + { + if(n == N){ + return in.getIndex(); + } + else { + return PackNum::getIndex(in, n); + } + } + + template + static const IndexBase& getIndex(const MultiIndex& in, size_t n) + { + if(n == N){ + return in.getIndex(); + } + else { + return PackNum::getIndex(in, n); + } + } + + template + static inline void pp(std::tuple...>& ip) + { + auto& si = *std::get(ip); + if(si.pos() == si.last()){ + si = 0; + PackNum::pp(index); + } + else { + ++si; + } + } + + template + static inline void mm(std::tuple...>& ip) + { + auto& si = *std::get(ip); + if(si.pos() == si.atEdge()){ + si = si.max(); + PackNum::mm(index); + } + else { + --si; + } + } + + template + static size_t getSize(const RangeTuple& rt) + { + return std::get(rt).size() * PackNum::getSize(rt); + } + + template + static void getMetaPos(std::tuple& target, + const typename MultiIndex::IndexPack& source) + { + std::get(target) = std::get(source)->meta(); + PackNum::getMetaPos(target, source); + } + + template + static void setMeta(typename MultiIndex::IndexPack& target, + const typename MultiIndex::MetaType& source) + { + std::get(target).atMeta( std::get(source) ); + PackNum::setMeta(target, source); + } + + template + static void setIndexPack(IndexPack& iPack, size_t pos) + { + auto i = std::get(iPack); + const size_t ownPos = pos % i.max(); + i = ownPos; + if(ownPos == pos){ + PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); + } + } + + template + static void construct(std::tuple...>& ip, + const MRange& range) + { + typedef decltype(range.template get()) SubIndexType; + typedef decltype(std::get(ip).get()) TypeFromIndexPack; + + static_assert(std::is_same::value, + "inconsiśtent types"); + + std::get(ip).swap( std::make_shared( range.template get() ) ); + PackNum::construct(ip, range); + } + + template + static void copy(std::tuple...>& ip, + const MultiIndex& ind) + { + typedef decltype(ind.template get()) SubIndexType; + std::get(ip).swap( std::make_shared( ind.template get() ) ); + PackNum::copy(ip, ind); + } + + template + static size_t makePos(const std::tuple...>& iPtrTup) + { + return std::get(iPtrTup)->pos() + + PackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); + } + + template + static void print(std::ostream& os, const std::tuple& meta) + { + PackNum::print(os, meta); + os << std::get(meta) << '\t'; + } + + }; + + template<> + struct PackNum<0> + { + template + static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) + { + return in.getIndex<0>(); + } + + template + static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n) + { + return in.getIndex<0>(); + } + + template + static inline void pp(std::tuple...>& ip) + { + auto& si = *std::get<0>(ip); + ++si; + } + + template + static inline void mm(std::tuple...>& ip) + { + auto& si = *std::get<0>(ip); + --si; + } + + template + static size_t getSize(const RangeTuple& rt) + { + return std::get<0>(rt).size(); + } + + template + static void getMetaPos(std::tuple& target, + const typename MultiIndex::IndexPack& source) + { + std::get<0>(target) = std::get<0>(source)->meta(); + } + + template + static void setMeta(typename MultiIndex::IndexPack& target, + const typename MultiIndex::MetaType& source) + { + std::get<0>(target).atMeta( std::get<0>(source) ); + } + + template + static void setIndexPack(IndexPack& iPack, size_t pos) + { + auto i = std::get<0>(iPack); + const size_t ownPos = pos % i.max(); + i = ownPos; + } + + template + static void construct(std::tuple...>& ip, + const MRange& range) + { + typedef decltype(range.template get<0>()) SubIndexType; + typedef decltype(std::get<0>(ip).get()) TypeFromIndexPack; + + static_assert(std::is_same::value, + "inconsiśtent types"); + + std::get<0>(ip).swap( std::make_shared( range.template get<0>() ) ); + } + + template + static void copy(std::tuple...>& ip, + const MultiIndex& ind) + { + typedef decltype(ind.template get<0>()) SubIndexType; + std::get<0>(ip).swap( std::make_shared( ind.template get<0>() ) ); + } + + template + static size_t makePos(const std::tuple...>& iPtrTup) + { + return std::get<0>(iPtrTup)->pos(); + } + + template + static void print(std::ostream& os, const std::tuple& meta) + { + os << std::get<0>(meta) << '\t'; + } + }; + +} // end namespace MultiArrayHelper