container range/index + put NumPack stuff into numpack.h
This commit is contained in:
parent
8db8a07456
commit
ccd99aed76
6 changed files with 345 additions and 289 deletions
14
src/container_range.cc
Normal file
14
src/container_range.cc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
#include "container_range.h"
|
||||||
|
#include "numpack.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace MultiArrayHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace MultiArrayTools
|
96
src/container_range.h
Normal file
96
src/container_range.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
#ifndef __container_range_h__
|
||||||
|
#define __container_range_h__
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "base_def.h"
|
||||||
|
|
||||||
|
namespace MultiArrayTools
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
class ContainerRangeFactory : public RangeFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ContainerRangeFactory() = delete;
|
||||||
|
ContainerRangeFactory(const std::shared_ptr<Ranges...>& rs);
|
||||||
|
ContainerRangeFactory(const ContainerRange<Ranges...>::SpaceType& space);
|
||||||
|
|
||||||
|
virtual std::shared_ptr<RangeBase> create() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Ranges>
|
||||||
|
class ContainerRange : public RangeInterface<ContainerIndex<typename Ranges::IndexType...> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
|
||||||
|
typedef typename RangeInterface<ContainerIndex<typename Ranges::IndexType...> >::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<IndexBase> index() const override;
|
||||||
|
|
||||||
|
friend ContainerRangeFactory<Ranges...>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ContainerRange() = default;
|
||||||
|
ContainerRange(const ContainerRange& in) = delete;
|
||||||
|
|
||||||
|
ContainerRange(const std::shared_ptr<Ranges...>& rs);
|
||||||
|
ContainerRange(const SpaceType& space);
|
||||||
|
|
||||||
|
SpaceType mSpace;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
class ContainerIndex : public IndexInterface<std::tuple<decltype(Indices().meta())...> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::tuple<decltype(Indices().meta())...> MetaType;
|
||||||
|
typedef std::tuple<std::shared_ptr<Indices>...> IndexPack;
|
||||||
|
|
||||||
|
ContainerIndex() = default;
|
||||||
|
|
||||||
|
ContainerIndex(const ContainerIndex& in);
|
||||||
|
ContainerIndex& operator=(const ContainerIndex& in);
|
||||||
|
|
||||||
|
template <class MRange>
|
||||||
|
ContainerIndex(const std::shared_ptr<MRange>& 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<Indices>&... inds); // control via external indices
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool externControl = false;
|
||||||
|
IndexPack mIPack;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace MultiArrayTools
|
||||||
|
|
||||||
|
#include "container_range.cc"
|
||||||
|
|
||||||
|
#endif
|
|
@ -33,7 +33,7 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
operator IndexBase::size_t() const
|
operator IndexBase::size_t() const
|
||||||
{
|
{
|
||||||
return mPos;
|
return pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|
|
@ -1,295 +1,19 @@
|
||||||
|
|
||||||
#include "multi_range.h"
|
#include "multi_range.h"
|
||||||
|
#include "packnum.h"
|
||||||
|
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
/*******************
|
|
||||||
* MultiIndexBase *
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
using namespace MultiArrayHelper;
|
||||||
template <size_t N>
|
|
||||||
struct PackNum
|
|
||||||
{
|
|
||||||
template <class MultiIndex>
|
|
||||||
static IndexBase& getIndex(MultiIndex& in, size_t n)
|
|
||||||
{
|
|
||||||
if(n == N){
|
|
||||||
return in.getIndex<N>();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return PackNum<N-1>::getIndex(in, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MultiIndex>
|
|
||||||
static const IndexBase& getIndex(const MultiIndex& in, size_t n)
|
|
||||||
{
|
|
||||||
if(n == N){
|
|
||||||
return in.getIndex<N>();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return PackNum<N-1>::getIndex(in, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip)
|
|
||||||
{
|
|
||||||
auto& si = *std::get<N>(ip);
|
|
||||||
if(si.pos() == si.last()){
|
|
||||||
si = 0;
|
|
||||||
PackNum<N-1>::pp(index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++si;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip)
|
|
||||||
{
|
|
||||||
auto& si = *std::get<N>(ip);
|
|
||||||
if(si.pos() == si.atEdge()){
|
|
||||||
si = si.max();
|
|
||||||
PackNum<N-1>::mm(index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
--si;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeTuple>
|
|
||||||
static size_t getSize(const RangeTuple& rt)
|
|
||||||
{
|
|
||||||
return std::get<N>(rt).size() * PackNum<N-1>::getSize(rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void setBegin(MultiRange<Ranges...>::IndexType& i, const MultiRange<Ranges...>::SpaceType& r)
|
|
||||||
{
|
|
||||||
*std::get<N>(i) = std::get<N>(r)->begin();
|
|
||||||
PackNum<N-1>::setBegin(i,r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void setEnd(MultiRange<Ranges...>::IndexType& i, const MultiRange<Ranges...>::SpaceType& r)
|
|
||||||
{
|
|
||||||
*std::get<N>(i) = std::get<N>(r)->end();
|
|
||||||
*std::get<N>(i) -= 1;
|
|
||||||
PackNum<N-1>::setEnd(i,r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void buildRangeVec(std::vector<MultiRangeType>& rvec, const MultiRange<Ranges...>::SpaceType& rs)
|
|
||||||
{
|
|
||||||
rvec.push_back(std::get<sizeof...(Ranges)-N-1>(rs)->type());
|
|
||||||
PackNum<N-1>::buildRangeVec(rvec, rs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
|
|
||||||
const typename MultiIndex<Indices...>::IndexPack& source)
|
|
||||||
{
|
|
||||||
std::get<N>(target) = std::get<N>(source)->meta();
|
|
||||||
PackNum<N-1>::getMetaPos(target, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target,
|
|
||||||
const typename MultiIndex<Indices...>::MetaType& source)
|
|
||||||
{
|
|
||||||
std::get<N>(target).atMeta( std::get<N>(source) );
|
|
||||||
PackNum<N-1>::setMeta(target, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class IndexPack>
|
|
||||||
static void setIndexPack(IndexPack& iPack, size_t pos)
|
|
||||||
{
|
|
||||||
auto i = std::get<N>(iPack);
|
|
||||||
const size_t ownPos = pos % i.max();
|
|
||||||
i = ownPos;
|
|
||||||
if(ownPos == pos){
|
|
||||||
PackNum<N-1>::setIndexPack(iPack, (pos - ownPos) / i.max() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class IndexPack, class... Indices>
|
|
||||||
static auto setFromPointerList(IndexPack& ipack,
|
|
||||||
std::vector<std::shared_ptr<IndefinitIndexBase> >& ptrList,
|
|
||||||
std::shared_ptr<Indices>&... inds)
|
|
||||||
-> decltype(PackNum<N-1>::setFromPointerList(ipack,
|
|
||||||
std::shared_ptr<decltype(std::get<N>(ipack))>,
|
|
||||||
newPtr, inds...))
|
|
||||||
{
|
|
||||||
typedef std::shared_ptr<decltype(std::get<N>(ipack))> NewIndexPtrType;
|
|
||||||
NewIndexPtrType newPtr = dynamic_pointer_cast<NewIndexPtrType>(ptrList.at(N));
|
|
||||||
return PackNum<N-1>::setFromPointerList(ipack, ptrList, newPtr, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MRange, class... Indices>
|
|
||||||
static void construct(std::tuple<std::shared_ptr<Indices>...>& ip,
|
|
||||||
const MRange& range)
|
|
||||||
{
|
|
||||||
typedef decltype(range.template get<N>()) SubIndexType;
|
|
||||||
typedef decltype(std::get<N>(ip).get()) TypeFromIndexPack;
|
|
||||||
|
|
||||||
static_assert(std::is_same<SubIndexType,TypeFromIndexPack>::value,
|
|
||||||
"inconsiśtent types");
|
|
||||||
|
|
||||||
std::get<N>(ip).swap( std::make_shared<SubIndexType>( range.template get<N>() ) );
|
|
||||||
PackNum<N-1>::construct(ip, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
|
|
||||||
const MultiIndex<Indices...>& ind)
|
|
||||||
{
|
|
||||||
typedef decltype(ind.template get<N>()) SubIndexType;
|
|
||||||
std::get<N>(ip).swap( std::make_shared<SubIndexType>( ind.template get<N>() ) );
|
|
||||||
PackNum<N-1>::copy(ip, ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
|
|
||||||
{
|
|
||||||
return std::get<N>(iPtrTup)->pos() +
|
|
||||||
PackNum<N-1>::makePos(iPtrTup) * std::get<N-1>(iPtrTup)->max();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
static void print(std::ostream& os, const std::tuple<Ts...>& meta)
|
|
||||||
{
|
|
||||||
PackNum<N-1>::print(os, meta);
|
|
||||||
os << std::get<N>(meta) << '\t';
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct PackNum<0>
|
|
||||||
{
|
|
||||||
template <class MultiIndex>
|
|
||||||
static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
|
|
||||||
{
|
|
||||||
return in.getIndex<0>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MultiIndex>
|
|
||||||
static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n)
|
|
||||||
{
|
|
||||||
return in.getIndex<0>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MultiIndex>
|
|
||||||
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip)
|
|
||||||
{
|
|
||||||
auto& si = *std::get<0>(ip);
|
|
||||||
++si;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MultiIndex>
|
|
||||||
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip)
|
|
||||||
{
|
|
||||||
auto& si = *std::get<0>(ip);
|
|
||||||
--si;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RangeTuple>
|
|
||||||
static size_t getSize(const RangeTuple& rt)
|
|
||||||
{
|
|
||||||
return std::get<0>(rt).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void setBegin(MultiRange<Ranges...>::IndexType& i, const MultiRange<Ranges...>::SpaceType& r)
|
|
||||||
{
|
|
||||||
*std::get<0>(i) = std::get<0>(r)->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void setEnd(MultiRange<Ranges...>::IndexType& i, const MultiRange<Ranges...>::SpaceType& r)
|
|
||||||
{
|
|
||||||
*std::get<0>(i) = std::get<0>(r)->end();
|
|
||||||
*std::get<0>(i) -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ranges>
|
|
||||||
static void buildRangeVec(std::vector<MultiRangeType>& rvec, const MultiRange<Ranges...>::SpaceType& rs)
|
|
||||||
{
|
|
||||||
rvec.push_back(std::get<sizeof...(Ranges)-1>(rs)->type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
|
|
||||||
const typename MultiIndex<Indices...>::IndexPack& source)
|
|
||||||
{
|
|
||||||
std::get<0>(target) = std::get<0>(source)->meta();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target,
|
|
||||||
const typename MultiIndex<Indices...>::MetaType& source)
|
|
||||||
{
|
|
||||||
std::get<0>(target).atMeta( std::get<0>(source) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class IndexPack>
|
|
||||||
static void setIndexPack(IndexPack& iPack, size_t pos)
|
|
||||||
{
|
|
||||||
auto i = std::get<0>(iPack);
|
|
||||||
const size_t ownPos = pos % i.max();
|
|
||||||
i = ownPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class IndexPack, class... Indices>
|
|
||||||
static auto setFromPointerList(IndexPack& ipack,
|
|
||||||
std::vector<std::shared_ptr<IndefinitIndexBase> >& ptrList,
|
|
||||||
std::shared_ptr<Indices>&... inds)
|
|
||||||
-> decltype(std::make_tuple(std::shared_ptr<decltype(std::get<0>(ipack))>, inds...))
|
|
||||||
{
|
|
||||||
typedef std::shared_ptr<decltype(std::get<0>(ipack))> NewIndexPtrType;
|
|
||||||
NewIndexPtrType newPtr = dynamic_pointer_cast<NewIndexPtrType>(ptrList.at(0));
|
|
||||||
return std::make_tuple(newPtr, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MRange, class... Indices>
|
|
||||||
static void construct(std::tuple<std::shared_ptr<Indices>...>& ip,
|
|
||||||
const MRange& range)
|
|
||||||
{
|
|
||||||
typedef decltype(range.template get<0>()) SubIndexType;
|
|
||||||
typedef decltype(std::get<0>(ip).get()) TypeFromIndexPack;
|
|
||||||
|
|
||||||
static_assert(std::is_same<SubIndexType,TypeFromIndexPack>::value,
|
|
||||||
"inconsiśtent types");
|
|
||||||
|
|
||||||
std::get<0>(ip).swap( std::make_shared<SubIndexType>( range.template get<0>() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
|
|
||||||
const MultiIndex<Indices...>& ind)
|
|
||||||
{
|
|
||||||
typedef decltype(ind.template get<0>()) SubIndexType;
|
|
||||||
std::get<0>(ip).swap( std::make_shared<SubIndexType>( ind.template get<0>() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
|
|
||||||
{
|
|
||||||
return std::get<0>(iPtrTup)->pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
static void print(std::ostream& os, const std::tuple<Ts...>& meta)
|
|
||||||
{
|
|
||||||
os << std::get<0>(meta) << '\t';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MultiIndexBase *
|
||||||
|
**********************/
|
||||||
|
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
MultiIndex<Indices...>::MultiIndex(const MultiIndex<Indices...>& in) :
|
MultiIndex<Indices...>::MultiIndex(const MultiIndex<Indices...>& in) :
|
||||||
IndexInterface<std::tuple<decltype(Indices().meta())...> >(in)
|
IndexInterface<std::tuple<decltype(Indices().meta())...> >(in)
|
||||||
|
|
|
@ -65,12 +65,12 @@ namespace MultiArrayTools
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
template <class... Ranges>
|
template <class... Ranges>
|
||||||
class MultiRangeFactory : public RangeFactory
|
class MultiRangeFactory : public RangeFactoryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MultiRangeFactory() = delete;
|
MultiRangeFactory() = delete;
|
||||||
MultiRangeFactory(const std::shared_ptr<Ranges>&... rs);
|
MultiRangeFactory(const std::shared_ptr<Ranges>&... rs);
|
||||||
MultiRangeFactory(const MultiRange<Ranges...>::SpaceType& st);
|
MultiRangeFactory(const MultiRange<Ranges...>::SpaceType& space);
|
||||||
|
|
||||||
virtual std::shared_ptr<RangeBase> create() override;
|
virtual std::shared_ptr<RangeBase> create() override;
|
||||||
};
|
};
|
||||||
|
@ -85,8 +85,7 @@ namespace MultiArrayTools
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
|
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
|
||||||
typedef typename RangeInterface<MultiIndex<typename Ranges::IndexType...> >::IndexType
|
typedef typename RangeInterface<MultiIndex<typename Ranges::IndexType...> >::IndexType IndexType;
|
||||||
IndexType;
|
|
||||||
|
|
||||||
static const size_t dim = sizeof...(Ranges);
|
static const size_t dim = sizeof...(Ranges);
|
||||||
|
|
||||||
|
@ -94,8 +93,8 @@ namespace MultiArrayTools
|
||||||
auto get() const ->;
|
auto get() const ->;
|
||||||
//typename std::tuple_element<N, std::tuple<std::shared_ptr<Ranges>...> >::type const& getRange() const;
|
//typename std::tuple_element<N, std::tuple<std::shared_ptr<Ranges>...> >::type const& getRange() const;
|
||||||
|
|
||||||
size_t dim() const override;
|
virtual size_t dim() const override;
|
||||||
size_t size() const override;
|
virtual size_t size() const override;
|
||||||
|
|
||||||
const SpaceType& space() const;
|
const SpaceType& space() const;
|
||||||
|
|
||||||
|
|
223
src/pack_num.h
Normal file
223
src/pack_num.h
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace MultiArrayHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
struct PackNum
|
||||||
|
{
|
||||||
|
template <class MultiIndex>
|
||||||
|
static IndexBase& getIndex(MultiIndex& in, size_t n)
|
||||||
|
{
|
||||||
|
if(n == N){
|
||||||
|
return in.getIndex<N>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PackNum<N-1>::getIndex(in, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MultiIndex>
|
||||||
|
static const IndexBase& getIndex(const MultiIndex& in, size_t n)
|
||||||
|
{
|
||||||
|
if(n == N){
|
||||||
|
return in.getIndex<N>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PackNum<N-1>::getIndex(in, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip)
|
||||||
|
{
|
||||||
|
auto& si = *std::get<N>(ip);
|
||||||
|
if(si.pos() == si.last()){
|
||||||
|
si = 0;
|
||||||
|
PackNum<N-1>::pp(index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++si;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip)
|
||||||
|
{
|
||||||
|
auto& si = *std::get<N>(ip);
|
||||||
|
if(si.pos() == si.atEdge()){
|
||||||
|
si = si.max();
|
||||||
|
PackNum<N-1>::mm(index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
--si;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeTuple>
|
||||||
|
static size_t getSize(const RangeTuple& rt)
|
||||||
|
{
|
||||||
|
return std::get<N>(rt).size() * PackNum<N-1>::getSize(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
|
||||||
|
const typename MultiIndex<Indices...>::IndexPack& source)
|
||||||
|
{
|
||||||
|
std::get<N>(target) = std::get<N>(source)->meta();
|
||||||
|
PackNum<N-1>::getMetaPos(target, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target,
|
||||||
|
const typename MultiIndex<Indices...>::MetaType& source)
|
||||||
|
{
|
||||||
|
std::get<N>(target).atMeta( std::get<N>(source) );
|
||||||
|
PackNum<N-1>::setMeta(target, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexPack>
|
||||||
|
static void setIndexPack(IndexPack& iPack, size_t pos)
|
||||||
|
{
|
||||||
|
auto i = std::get<N>(iPack);
|
||||||
|
const size_t ownPos = pos % i.max();
|
||||||
|
i = ownPos;
|
||||||
|
if(ownPos == pos){
|
||||||
|
PackNum<N-1>::setIndexPack(iPack, (pos - ownPos) / i.max() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MRange, class... Indices>
|
||||||
|
static void construct(std::tuple<std::shared_ptr<Indices>...>& ip,
|
||||||
|
const MRange& range)
|
||||||
|
{
|
||||||
|
typedef decltype(range.template get<N>()) SubIndexType;
|
||||||
|
typedef decltype(std::get<N>(ip).get()) TypeFromIndexPack;
|
||||||
|
|
||||||
|
static_assert(std::is_same<SubIndexType,TypeFromIndexPack>::value,
|
||||||
|
"inconsiśtent types");
|
||||||
|
|
||||||
|
std::get<N>(ip).swap( std::make_shared<SubIndexType>( range.template get<N>() ) );
|
||||||
|
PackNum<N-1>::construct(ip, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
|
||||||
|
const MultiIndex<Indices...>& ind)
|
||||||
|
{
|
||||||
|
typedef decltype(ind.template get<N>()) SubIndexType;
|
||||||
|
std::get<N>(ip).swap( std::make_shared<SubIndexType>( ind.template get<N>() ) );
|
||||||
|
PackNum<N-1>::copy(ip, ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
|
||||||
|
{
|
||||||
|
return std::get<N>(iPtrTup)->pos() +
|
||||||
|
PackNum<N-1>::makePos(iPtrTup) * std::get<N-1>(iPtrTup)->max();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
static void print(std::ostream& os, const std::tuple<Ts...>& meta)
|
||||||
|
{
|
||||||
|
PackNum<N-1>::print(os, meta);
|
||||||
|
os << std::get<N>(meta) << '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct PackNum<0>
|
||||||
|
{
|
||||||
|
template <class MultiIndex>
|
||||||
|
static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
|
||||||
|
{
|
||||||
|
return in.getIndex<0>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MultiIndex>
|
||||||
|
static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n)
|
||||||
|
{
|
||||||
|
return in.getIndex<0>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MultiIndex>
|
||||||
|
static inline void pp(std::tuple<std::shared_ptr<Indices>...>& ip)
|
||||||
|
{
|
||||||
|
auto& si = *std::get<0>(ip);
|
||||||
|
++si;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MultiIndex>
|
||||||
|
static inline void mm(std::tuple<std::shared_ptr<Indices>...>& ip)
|
||||||
|
{
|
||||||
|
auto& si = *std::get<0>(ip);
|
||||||
|
--si;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class RangeTuple>
|
||||||
|
static size_t getSize(const RangeTuple& rt)
|
||||||
|
{
|
||||||
|
return std::get<0>(rt).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void getMetaPos(std::tuple<decltype(Indices().meta())...>& target,
|
||||||
|
const typename MultiIndex<Indices...>::IndexPack& source)
|
||||||
|
{
|
||||||
|
std::get<0>(target) = std::get<0>(source)->meta();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void setMeta(typename MultiIndex<Indices...>::IndexPack& target,
|
||||||
|
const typename MultiIndex<Indices...>::MetaType& source)
|
||||||
|
{
|
||||||
|
std::get<0>(target).atMeta( std::get<0>(source) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IndexPack>
|
||||||
|
static void setIndexPack(IndexPack& iPack, size_t pos)
|
||||||
|
{
|
||||||
|
auto i = std::get<0>(iPack);
|
||||||
|
const size_t ownPos = pos % i.max();
|
||||||
|
i = ownPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MRange, class... Indices>
|
||||||
|
static void construct(std::tuple<std::shared_ptr<Indices>...>& ip,
|
||||||
|
const MRange& range)
|
||||||
|
{
|
||||||
|
typedef decltype(range.template get<0>()) SubIndexType;
|
||||||
|
typedef decltype(std::get<0>(ip).get()) TypeFromIndexPack;
|
||||||
|
|
||||||
|
static_assert(std::is_same<SubIndexType,TypeFromIndexPack>::value,
|
||||||
|
"inconsiśtent types");
|
||||||
|
|
||||||
|
std::get<0>(ip).swap( std::make_shared<SubIndexType>( range.template get<0>() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static void copy(std::tuple<std::shared_ptr<Indices>...>& ip,
|
||||||
|
const MultiIndex<Indices...>& ind)
|
||||||
|
{
|
||||||
|
typedef decltype(ind.template get<0>()) SubIndexType;
|
||||||
|
std::get<0>(ip).swap( std::make_shared<SubIndexType>( ind.template get<0>() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
static size_t makePos(const std::tuple<std::shared_ptr<Indices>...>& iPtrTup)
|
||||||
|
{
|
||||||
|
return std::get<0>(iPtrTup)->pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
static void print(std::ostream& os, const std::tuple<Ts...>& meta)
|
||||||
|
{
|
||||||
|
os << std::get<0>(meta) << '\t';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace MultiArrayHelper
|
Loading…
Reference in a new issue