container range/index previously finished

This commit is contained in:
Christian Zimmermann 2017-07-27 20:34:14 +02:00
parent ccd99aed76
commit c31eb76981
4 changed files with 214 additions and 28 deletions

View file

@ -10,5 +10,166 @@ namespace MultiArrayTools
using namespace MultiArrayHelper; using namespace MultiArrayHelper;
} }
/*****************************
* ContainerRangeFactory *
*****************************/
template <class... Ranges>
ContainerRangeFactory<Ranges...>::ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs)
{
mProd = std::make_shared<ContainerRange<Ranges...> >( rs... );
}
template <class... Ranges>
ContainerRangeFactory<Ranges...>::ContainerRangeFactory(const ContainerRange<Ranges...>::SpaceType& space)
{
mProd = std::make_shared<ContainerRange<Ranges...> >( space );
}
template <class... Ranges>
std::shared_ptr<RangeBase> ContainerRangeFactory<Ranges...>::create()
{
setSelf();
return mProd;
}
/**********************
* ContainerRange *
**********************/
template <class... Ranges>
ContainerRange<Ranges...>::ContainerRange(const std::shared_ptr<Ranges>&... rs) :
mSpace( std::make_tuple( rs... ) ) {}
template <class... Ranges>
ContainerRange<Ranges...>::ContainerRange(const SpaceType& space) : mSpace( space ) {}
template <class... Ranges>
size_t ContainerRange<Ranges...>::dim() const
{
return sizeof...(Ranges);
}
template <class... Ranges>
size_t ContainerRange<Ranges...>::size() const
{
return PackNum<sizeof...(Ranges)-1>::getSize(mSpace);
}
template <class... Ranges>
typename IndexType ContainerRange<Ranges...>::begin() const
{
ContainerIndex<typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<ContainerRange<Ranges...> >( mThis ) );
return i = 0;
}
template <class... Ranges>
typename IndexType ContainerRange<Ranges...>::end() const
{
ContainerIndex<typename Ranges::IndexType...>
i( std::dynamic_pointer_cast<ContainerRange<Ranges...> >( mThis ) );
return i = size();
}
template <class... Ranges>
std::shared_ptr<IndexBase> ContainerRange<Ranges...>::index() const
{
return std::make_shared<ContainerIndex<typename Ranges::IndexType...> >
( std::dynamic_pointer_cast<ContainerRange<Ranges...> >( mThis ) );
}
/**********************
* ContainerIndex *
**********************/
template <class... Indices>
ContainerIndex<Indices...>::ContainerIndex(const ContainerIndex& in) :
IndexInterface<std::tuple<decltype(Indices().meta())...> >(in)
{
PackNum<sizeof...(Indices)-1>::copy(mIPack, in);
mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator=(const ContainerIndex& in)
{
IndexI::operator=(in);
PackNum<sizeof...(Indices)-1>::copy(mIPack, in);
mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
return *this;
}
template <class... Indices>
template <class MRange>
ContainerIndex<Indices...>::ContainerIndex(const std::shared_ptr<MRange>& range)
{
PackNum<sizeof...(Indices)-1>::construct(mIPack, *range);
mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator++()
{
PackNum<sizeof...(Indices)-1>::pp( mIPack );
++mPos;
return *this;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator--()
{
PackNum<sizeof...(Indices)-1>::mm( mIPack );
--mPos;
return *this;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator=(size_t pos)
{
mPos = pos;
PackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, pos);
return *this;
}
template <class... Indices>
typename ContainerIndex<Indices...>::MetaType ContainerIndex<Indices...>::meta() const
{
MetaType metaTuple;
PackNum<sizeof...(Indices)-1>::getMetaPos(metaTuple, mIPack);
return metaTuple;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::at(const MetaType& metaPos)
{
PackNum<sizeof...(Indices)-1>::setMeta(mIPack, metaPos);
return *this;
}
template <class... Indices>
size_t ContainerIndex<Indices...>::dim() const
{
return sizeof...(Indices);
}
template <class... Indices>
size_t ContainerIndex<Indices...>::pos() const
{
if(mExternControl){
mPos = PackNum<sizeof...(Indices)-1>::makePos(mIPack);
}
return mPos;
}
template <class... Indices>
ContainerIndex<Indices...>& ContainerIndex<Indices...>::operator()(const std::shared_ptr<Indices>&... inds)
{
PackNum<sizeof...(Indices)-1>::swapIndices(mIPack, inds...);
mExternControl = true;
return *this;
}
} // end namespace MultiArrayTools } // end namespace MultiArrayTools

View file

@ -15,7 +15,7 @@ namespace MultiArrayTools
public: public:
ContainerRangeFactory() = delete; ContainerRangeFactory() = delete;
ContainerRangeFactory(const std::shared_ptr<Ranges...>& rs); ContainerRangeFactory(const std::shared_ptr<Ranges>&... rs);
ContainerRangeFactory(const ContainerRange<Ranges...>::SpaceType& space); ContainerRangeFactory(const ContainerRange<Ranges...>::SpaceType& space);
virtual std::shared_ptr<RangeBase> create() override; virtual std::shared_ptr<RangeBase> create() override;
@ -49,7 +49,7 @@ namespace MultiArrayTools
ContainerRange() = default; ContainerRange() = default;
ContainerRange(const ContainerRange& in) = delete; ContainerRange(const ContainerRange& in) = delete;
ContainerRange(const std::shared_ptr<Ranges...>& rs); ContainerRange(const std::shared_ptr<Ranges>&... rs);
ContainerRange(const SpaceType& space); ContainerRange(const SpaceType& space);
SpaceType mSpace; SpaceType mSpace;
@ -85,7 +85,7 @@ namespace MultiArrayTools
protected: protected:
bool externControl = false; bool mExternControl = false;
IndexPack mIPack; IndexPack mIPack;
}; };

View file

@ -69,7 +69,7 @@ namespace MultiArrayTools
MultiIndex<Indices...>& MultiIndex<Indices...>::up() MultiIndex<Indices...>& MultiIndex<Indices...>::up()
{ {
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
mPos += /*!!!*/; mPos += PackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
PackNum<DIR>::pp( mIPack ); PackNum<DIR>::pp( mIPack );
return *this; return *this;
} }
@ -79,7 +79,7 @@ namespace MultiArrayTools
MultiIndex<Indices...>& MultiIndex<Indices...>::down() MultiIndex<Indices...>& MultiIndex<Indices...>::down()
{ {
static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices");
mPos -= /*!!!*/; mPos -= PackNum<sizeof...(Indices)-DIR-1>::blockSize( mIPack );
PackNum<DIR>::mm( mIPack ); PackNum<DIR>::mm( mIPack );
return *this; return *this;
} }

View file

@ -9,8 +9,8 @@ namespace MultiArrayHelper
template <size_t N> template <size_t N>
struct PackNum struct PackNum
{ {
template <class MultiIndex> template <class IndexType>
static IndexBase& getIndex(MultiIndex& in, size_t n) static IndexBase& getIndex(IndexType& in, size_t n)
{ {
if(n == N){ if(n == N){
return in.getIndex<N>(); return in.getIndex<N>();
@ -20,8 +20,8 @@ namespace MultiArrayHelper
} }
} }
template <class MultiIndex> template <class IndexType>
static const IndexBase& getIndex(const MultiIndex& in, size_t n) static const IndexBase& getIndex(const IndexType& in, size_t n)
{ {
if(n == N){ if(n == N){
return in.getIndex<N>(); return in.getIndex<N>();
@ -63,17 +63,16 @@ namespace MultiArrayHelper
return std::get<N>(rt).size() * PackNum<N-1>::getSize(rt); return std::get<N>(rt).size() * PackNum<N-1>::getSize(rt);
} }
template <class... Indices> template <template <class...> IndexType, class... Indices>
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target, static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
const typename MultiIndex<Indices...>::IndexPack& source) const typename IndexType<Indices...>::IndexPack& source)
{ {
std::get<N>(target) = std::get<N>(source)->meta(); std::get<N>(target) = std::get<N>(source)->meta();
PackNum<N-1>::getMetaPos(target, source); PackNum<N-1>::getMetaPos(target, source);
} }
template <class... Indices> template <class IndexPack>
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target, static void setMeta(IndexPack& target, const MetaType& source)
const typename MultiIndex<Indices...>::MetaType& source)
{ {
std::get<N>(target).atMeta( std::get<N>(source) ); std::get<N>(target).atMeta( std::get<N>(source) );
PackNum<N-1>::setMeta(target, source); PackNum<N-1>::setMeta(target, source);
@ -104,9 +103,9 @@ namespace MultiArrayHelper
PackNum<N-1>::construct(ip, range); PackNum<N-1>::construct(ip, range);
} }
template <class... Indices> template <template<class...> IndexType, class... Indices>
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip, static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
const MultiIndex<Indices...>& ind) const IndexType<Indices...>& ind)
{ {
typedef decltype(ind.template get<N>()) SubIndexType; typedef decltype(ind.template get<N>()) SubIndexType;
std::get<N>(ip).swap( std::make_shared<SubIndexType>( ind.template get<N>() ) ); std::get<N>(ip).swap( std::make_shared<SubIndexType>( ind.template get<N>() ) );
@ -127,6 +126,20 @@ namespace MultiArrayHelper
os << std::get<N>(meta) << '\t'; os << std::get<N>(meta) << '\t';
} }
template <class Pack, class IndexType, class... Indices>
static void swapIndices(Pack& ipack, const std::shared_ptr<Indices>&... ninds,
const std::shared_ptr<IndexType>& nind)
{
std::get<N>(ipack).swap( nind );
PackNum<N-1>::swapIndices(ipack, ninds...);
}
template <class... Indices>
static size_t blockSize(const std::tuple<std::shared_ptr<Indices>...>& pack)
{
return std::get<sizeof...(Indices)-N-1>(pack)->size() * PackNum<N-1>::blockSize(pack);
}
}; };
template<> template<>
@ -144,14 +157,14 @@ namespace MultiArrayHelper
return in.getIndex<0>(); return in.getIndex<0>();
} }
template <class MultiIndex> template <class... Indices>
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip) static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip)
{ {
auto& si = *std::get<0>(ip); auto& si = *std::get<0>(ip);
++si; ++si;
} }
template <class MultiIndex> template <class... Indices>
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip) static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip)
{ {
auto& si = *std::get<0>(ip); auto& si = *std::get<0>(ip);
@ -164,16 +177,15 @@ namespace MultiArrayHelper
return std::get<0>(rt).size(); return std::get<0>(rt).size();
} }
template <class... Indices> template <template <class...> IndexType, class... Indices>
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target, static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
const typename MultiIndex<Indices...>::IndexPack& source) const typename IndexType<Indices...>::IndexPack& source)
{ {
std::get<0>(target) = std::get<0>(source)->meta(); std::get<0>(target) = std::get<0>(source)->meta();
} }
template <class... Indices> template <class IndexPack>
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target, static void setMeta(IndexPack& target, const MetaType& source)
const typename MultiIndex<Indices...>::MetaType& source)
{ {
std::get<0>(target).atMeta( std::get<0>(source) ); std::get<0>(target).atMeta( std::get<0>(source) );
} }
@ -199,9 +211,9 @@ namespace MultiArrayHelper
std::get<0>(ip).swap( std::make_shared<SubIndexType>( range.template get<0>() ) ); std::get<0>(ip).swap( std::make_shared<SubIndexType>( range.template get<0>() ) );
} }
template <class... Indices> template <template<class...> IndexType, class... Indices>
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip, static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
const MultiIndex<Indices...>& ind) const IndexType<Indices...>& ind)
{ {
typedef decltype(ind.template get<0>()) SubIndexType; typedef decltype(ind.template get<0>()) SubIndexType;
std::get<0>(ip).swap( std::make_shared<SubIndexType>( ind.template get<0>() ) ); std::get<0>(ip).swap( std::make_shared<SubIndexType>( ind.template get<0>() ) );
@ -218,6 +230,19 @@ namespace MultiArrayHelper
{ {
os << std::get<0>(meta) << '\t'; os << std::get<0>(meta) << '\t';
} }
template <class Pack, class IndexType>
static void swapIndices(Pack& ipack, const std::shared_ptr<IndexType>& nind)
{
std::get<0>(ipack).swap( nind );
}
template <class... Indices>
static size_t blockSize(const std::tuple<std::shared_ptr<Indices>...>& pack)
{
return std::get<sizeof...(Indices)-1>(pack)->size();
}
}; };
} // end namespace MultiArrayHelper } // end namespace MultiArrayHelper