container range/index + put NumPack stuff into numpack.h

This commit is contained in:
Christian Zimmermann 2017-07-27 14:48:41 +02:00
parent 8db8a07456
commit ccd99aed76
6 changed files with 345 additions and 289 deletions

14
src/container_range.cc Normal file
View 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
View 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

View file

@ -33,7 +33,7 @@ namespace MultiArrayTools
operator IndexBase::size_t() const
{
return mPos;
return pos();
}
/**********************

View file

@ -1,295 +1,19 @@
#include "multi_range.h"
#include "packnum.h"
namespace MultiArrayTools
{
/*******************
* MultiIndexBase *
*******************/
namespace
{
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';
}
};
using namespace MultiArrayHelper;
}
/**********************
* MultiIndexBase *
**********************/
template <class... Indices>
MultiIndex<Indices...>::MultiIndex(const MultiIndex<Indices...>& in) :
IndexInterface<std::tuple<decltype(Indices().meta())...> >(in)

View file

@ -65,12 +65,12 @@ namespace MultiArrayTools
*************************/
template <class... Ranges>
class MultiRangeFactory : public RangeFactory
class MultiRangeFactory : public RangeFactoryBase
{
public:
MultiRangeFactory() = delete;
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;
};
@ -85,8 +85,7 @@ namespace MultiArrayTools
public:
typedef std::tuple<std::shared_ptr<Ranges>...> SpaceType;
typedef typename RangeInterface<MultiIndex<typename Ranges::IndexType...> >::IndexType
IndexType;
typedef typename RangeInterface<MultiIndex<typename Ranges::IndexType...> >::IndexType IndexType;
static const size_t dim = sizeof...(Ranges);
@ -94,8 +93,8 @@ namespace MultiArrayTools
auto get() const ->;
//typename std::tuple_element<N, std::tuple<std::shared_ptr<Ranges>...> >::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;

223
src/pack_num.h Normal file
View 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