start refactoring MIndex
This commit is contained in:
parent
6b2bbc3020
commit
172110c5de
4 changed files with 199 additions and 93 deletions
|
@ -8,41 +8,74 @@
|
|||
|
||||
namespace CNORXZ
|
||||
{
|
||||
/***********************
|
||||
* MIndex (private) *
|
||||
***********************/
|
||||
|
||||
template <class... Indices>
|
||||
template <SizeT P, SizeT... Is>
|
||||
constexpr decltype(auto) MIndex<Indices...>::indexSequencePlus(std::index_sequence<Is...> is) const
|
||||
{
|
||||
return std::index_sequence<P+Is...> {};
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <SizeT B, SizeT E>
|
||||
constexpr decltype(auto) MIndex<Indices...>::mkIndexSequence() const
|
||||
{
|
||||
return indexSequencePlus<B>(std::make_index_sequence<E-B>{});
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <class G, class F, SizeT... Is>
|
||||
constexpr decltype(auto) MIndex<Indices...>::accumulatei(const G& g, const F& f, std::index_sequence<Is...> is) const
|
||||
{
|
||||
return f( g(std::get<Is>(mIPack))... );
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <SizeT B, SizeT E, class G, class F>
|
||||
constexpr decltype(auto) MIndex<Indices...>::accumulate(const G& g, const F& f) const
|
||||
{
|
||||
return accumulatei(g, f, mkIndexSequence<B,E>())
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence<Is...> is) const
|
||||
{
|
||||
static_assert(sizeof...(Is) == sizeof...(Indices),
|
||||
"sequence size does not match number of indices");
|
||||
return std::make_tuple( std::make_shared<Indices>( mRange->sub(Is) )... );
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) mkBlockSizes(std::index_sequence<Is...> is) const
|
||||
{
|
||||
static_assert(sizeof...(Is) == sizeof...(Indices)-1,
|
||||
"set lowest block size manually");
|
||||
return Arr<SizeT,sizeof...(Indices)>
|
||||
{ accumulate<Is,sizeof...(Indices)>( [](const auto& i) { return i->max(); },
|
||||
[](const auto&... as) { return (as * ...); } ),
|
||||
1 };
|
||||
}
|
||||
|
||||
/**************
|
||||
* MIndex *
|
||||
**************/
|
||||
|
||||
template <class... Indices>
|
||||
template <class MRange>
|
||||
MIndex<Indices...>::MIndex(const Sptr<MRange>& range) :
|
||||
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...> >(0)
|
||||
{
|
||||
std::get<sizeof...(Indices)>(mBlockSizes) = 1;
|
||||
sfor_mn<sizeof...(Indices),0>
|
||||
( [&](auto i) {
|
||||
auto r = range->template getPtr<i>();
|
||||
std::get<i>(mIPack) = r->beginPtr();
|
||||
*std::get<i>(mIPack) = 0;
|
||||
|
||||
std::get<i>(mBlockSizes) = sfor_p<i,sizeof...(Indices)>
|
||||
( [&](auto j) { return std::get<j>(mIPack)->max(); } ,
|
||||
[&](auto a, auto b) { return a * b; });
|
||||
return 0;
|
||||
});
|
||||
|
||||
IB::mPos = sfor_m<sizeof...(Indices),0>
|
||||
( [&](auto i) { return std::get<i>(mIPack); },
|
||||
[&](auto a, auto b) {return a->pos() + b*a->max();}, 0 );
|
||||
}
|
||||
MIndex<Indices...>::MIndex(const Sptr<MRange>& range, SizeT pos) :
|
||||
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(pos),
|
||||
mIPack(mkIPack(IB::mPos, std::make_index_sequence<sizeof...(Indices)>{})),
|
||||
mBlockSizes(mkBlockSizes(IB::mPos), std::make_index_sequence<sizeof...(Indices)>{}),
|
||||
mRange(range)
|
||||
{}
|
||||
|
||||
template <class... Indices>
|
||||
MIndex<Indices...>& MIndex<Indices...>::operator()(Sptr<Indices>&... indices)
|
||||
{
|
||||
return (*this)(std::make_tuple(indices...));
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MIndex<Indices...>& MIndex<Indices...>::operator()(const Tuple<Sptr<Indices>...>& indices)
|
||||
MIndex<Indices...>& MIndex<Indices...>::operator()(const Sptr<MIndex>& mi)
|
||||
{
|
||||
sfor_pn<0,sizeof...(Indices)>
|
||||
( [&](auto i) { std::get<i>(mIPack) = std::get<i>(indices); return 0; } );
|
||||
|
@ -158,20 +191,6 @@ namespace CNORXZ
|
|||
{
|
||||
return RangeHelper::mkFor<0>(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <class Exprs>
|
||||
auto MIndex<Indices...>::iforh(SizeT step, Exprs exs) const
|
||||
{
|
||||
return RangeHelper::mkForh<0>(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
template <class Exprs>
|
||||
auto MIndex<Indices...>::pifor(SizeT step, Exprs exs) const
|
||||
{
|
||||
return RangeHelper::mkPFor<0>(step, mIPack, mBlockSizes, exs);
|
||||
}
|
||||
*/
|
||||
|
||||
/*********************
|
||||
|
@ -179,61 +198,113 @@ namespace CNORXZ
|
|||
*********************/
|
||||
|
||||
template <class... Ranges>
|
||||
MRangeFactory<Ranges...>::MRangeFactory(const Sptr<Ranges>&... rs)
|
||||
{
|
||||
mProd = Sptr< MRange<Ranges...> >( new MRange<Ranges...>( rs... ) );
|
||||
}
|
||||
MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs) :
|
||||
mRs(rs)
|
||||
{}
|
||||
|
||||
template <class... Ranges>
|
||||
MRangeFactory<Ranges...>::MRangeFactory(const typename MRange<Ranges...>::Space& st)
|
||||
{
|
||||
mProd = Sptr< MRange<Ranges...> >( new MRange<Ranges...>( st ) );
|
||||
}
|
||||
MRangeFactory<Ranges...>::MRangeFactory(const Tuple<Sptr<Ranges>...>& rs,
|
||||
const RangePtr& ref) :
|
||||
mRs(rs),
|
||||
mRef(ref)
|
||||
{}
|
||||
|
||||
template <class... Ranges>
|
||||
Sptr<RangeBase> MRangeFactory<Ranges...>::create()
|
||||
void MRangeFactory<Ranges...>::make()
|
||||
{
|
||||
mProd = checkIfCreated( std::dynamic_pointer_cast<oType>( mProd )->mSpace );
|
||||
setSelf();
|
||||
return mProd;
|
||||
auto info = typeid(MRange<Ranges...>);
|
||||
if(mRef != nullptr) {
|
||||
mProd = this->fromCreated[info.hash_code()][mRef->id()];
|
||||
}
|
||||
if(mProd == nullptr) {
|
||||
RangePtr key = mProd = std::shared_ptr<MRange<Ranges...>>
|
||||
( new MRange<Ranges...>( mSpace ) );
|
||||
if(mRef != nullptr) { key = mRef }
|
||||
this->addToCreated(info, { key->id() }, mProd);
|
||||
}
|
||||
}
|
||||
|
||||
/******************
|
||||
/**************
|
||||
* MRange *
|
||||
******************/
|
||||
**************/
|
||||
|
||||
template <class... Ranges>
|
||||
MRange<Ranges...>::MRange(const Sptr<Ranges>&... rs) : mSpace(std::make_tuple(rs...)) {}
|
||||
MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
|
||||
mRs(rs),
|
||||
mA( mkA( std::make_index_sequence<sizeof...(Ranges)>{} ) )
|
||||
{}
|
||||
|
||||
template <class... Ranges>
|
||||
MRange<Ranges...>::MRange(const Space& space) : mSpace( space ) {}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::getMeta(const MetaType& metaPos) const
|
||||
RangePtr MRange<Ranges...>::sub(SizeT num) const
|
||||
{
|
||||
return RangeHelper::getMeta<sizeof...(Ranges)-1>(mSpace,metaPos);
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::dim() const
|
||||
{
|
||||
return sdim;
|
||||
CXZ_ASSERT(num < this->dim(), "index out of range");
|
||||
return mA[num];
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::size() const
|
||||
{
|
||||
return sfor_p<0,sizeof...(Ranges)>
|
||||
( [&](auto i) { return std::get<i>(mSpace)->size(); },
|
||||
[&](auto a, auto b) { return a * b; } );
|
||||
return this->sizei(std::make_index_sequence<sizeof...(Ranges)> {});
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::dim() const
|
||||
{
|
||||
return sizeof...(Ranges);
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
String MRange<Ranges...>::stringMeta(SizeT pos) const
|
||||
{
|
||||
auto i = begin();
|
||||
i = pos;
|
||||
return "[" + RangeHelper::getStringMeta<0>(i) + "]";
|
||||
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
IndexType MRange<Ranges...>::begin() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
IndexType MRange<Ranges...>::end() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
decltype(auto) MRange<Ranges...>::space() const
|
||||
{
|
||||
return mRs;
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
const MetaType MRange<Ranges...>::get(SizeT pos) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::getMeta(const MetaType& metaPos) const
|
||||
{
|
||||
assert(0);
|
||||
//return RangeHelper::getMeta<sizeof...(Ranges)-1>(mSpace,metaPos);
|
||||
}
|
||||
|
||||
/************************
|
||||
* MRange (private) *
|
||||
************************/
|
||||
|
||||
template <class... Ranges>
|
||||
template <SizeT... Is>
|
||||
decltype(auto) MRange<Ranges...>::mkA(std::index_sequence<Is...> is) const
|
||||
{
|
||||
return Arr<RangePtr,sizeof...(Ranges)> { std::get<Is>(mRs)... };
|
||||
}
|
||||
|
||||
template <class... Ranges>
|
||||
SizeT MRange<Ranges...>::sizei(std::index_sequence<Is...> is) const
|
||||
{
|
||||
return ( std::get<Is>(mRs)->size() * ... );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,8 +33,7 @@ namespace CNORXZ
|
|||
MIndex(const RangePtr& range, SizeT pos = 0);
|
||||
|
||||
// replace sub-index instances; only use if you know what you are doing!
|
||||
MIndex& operator()(Sptr<Indices>&... indices);
|
||||
MIndex& operator()(const MIndex& indices);
|
||||
MIndex& operator()(const Sptr<MIndex>& mi);
|
||||
|
||||
const IndexPack& pack() const { return mIPack; }
|
||||
const auto& getBlockSizes() const { return mBlockSizes; }
|
||||
|
@ -66,16 +65,36 @@ namespace CNORXZ
|
|||
MetaType meta() const;
|
||||
MIndex& at(const MetaType& metaPos);
|
||||
|
||||
template <class PosT, class Xpr>
|
||||
auto ifor(const PosT& step, const Xpr& xpr) const;
|
||||
template <class Xpr, class F>
|
||||
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
|
||||
|
||||
private:
|
||||
MIndex() = default;
|
||||
|
||||
IndexPack mIPack;
|
||||
Arr<SizeT,sizeof...(Indices)+1> mBlockSizes;
|
||||
Arr<SizeT,sizeof...(Indices)> mBlockSizes;
|
||||
Sptr<RangeType> mRange;
|
||||
|
||||
// shift to utils:
|
||||
template <SizeT P, SizeT... Is>
|
||||
constexpr decltype(auto) indexSequencePlus(std::index_sequence<Is...> is) const;
|
||||
|
||||
// shift to utils:
|
||||
template <SizeT B, SizeT E>
|
||||
constexpr decltype(auto) mkIndexSequence() const;
|
||||
|
||||
|
||||
template <class G, class F, SizeT... Is>
|
||||
constexpr decltype(auto) accumulatei(const G& g, const F& f, std::index_sequence<Is...> is) const;
|
||||
|
||||
template <SizeT B, SizeT E, class G, class F>
|
||||
constexpr decltype(auto) accumulate(const G& g, const F& f) const;
|
||||
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence<Is...> is) const;
|
||||
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) mkBlockSizes(std::index_sequence<Is...> is) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,44 +103,54 @@ namespace CNORXZ
|
|||
class MRangeFactory : public RangeFactoryBase
|
||||
{
|
||||
public:
|
||||
MRangeFactory() = delete;
|
||||
MRangeFactory(const Sptr<Ranges>&... rs);
|
||||
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs);
|
||||
MRangeFactory(const Tuple<Sptr<Ranges>...>& rs, const RangePtr& ref);
|
||||
|
||||
private:
|
||||
MRangeFactory() = default;
|
||||
virtual void make() override final;
|
||||
|
||||
Tuple<Sptr<Ranges>...> mRs;
|
||||
RangePtr mRef;
|
||||
};
|
||||
|
||||
template <class... Ranges>
|
||||
class MRange : public RangeInterface<MIndex<typename Ranges::IndexType...> >
|
||||
class MRange : public RangeInterface<MIndex<typename Ranges::IndexType...>,
|
||||
Tuple<typename Ranges::IndexType::MetaType...>>
|
||||
{
|
||||
public:
|
||||
typedef RangeBase RB;
|
||||
typedef MIndex<typename Ranges::IndexType...> IndexType;
|
||||
typedef Tuple<typename Ranges::IndexType::MetaType...> MetaType;
|
||||
|
||||
const Space& space() const;
|
||||
|
||||
SizeT getMeta(const MetaType& metaPos) const;
|
||||
|
||||
virtual Sptr<RangeBase> sub(SizeT num) const override;
|
||||
|
||||
virtual SizeT dim() const final;
|
||||
virtual SizeT size() const final;
|
||||
|
||||
virtual String stringMeta(SizeT pos) const final;
|
||||
|
||||
friend MRangeFactory<Ranges...>;
|
||||
|
||||
virtual RangePtr sub(SizeT num) const override final;
|
||||
virtual SizeT size() const override final;
|
||||
virtual SizeT dim() const override final;
|
||||
virtual String stringMeta(SizeT pos) const override final;
|
||||
virtual IndexType begin() const override final;
|
||||
virtual IndexType end() const override final;
|
||||
|
||||
decltype(auto) space() const;
|
||||
const MetaType get(SizeT pos) const;
|
||||
SizeT getMeta(const MetaType& metaPos) const;
|
||||
|
||||
protected:
|
||||
MRange() = delete;
|
||||
MRange(const MRange& in) = delete;
|
||||
MRange& operator=(const MRange& in) = delete;
|
||||
MRange(const Tuple<Sptr<Ranges>...>& rs);
|
||||
|
||||
Tuple<Sptr<Ranges>...> mRs;
|
||||
Arr<RangePtr,sizeof...(Ranges)> mA;
|
||||
private:
|
||||
|
||||
template <SizeT... Is>
|
||||
decltype(auto) mkA(std::index_sequence<Is...> is) const;
|
||||
|
||||
template <SizeT... Is>
|
||||
SizeT sizei(std::index_sequence<Is...> is) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace CNORXZ
|
|||
|
||||
virtual ~RangeBase() = default;
|
||||
|
||||
virtual RangePtr sub() const;
|
||||
virtual SizeT size() const = 0;
|
||||
virtual SizeT dim() const = 0;
|
||||
virtual const TypeInfo& type() const = 0;
|
||||
|
|
|
@ -39,6 +39,11 @@ namespace CNORXZ
|
|||
* RangeBase *
|
||||
******************/
|
||||
|
||||
RangePtr RangeBase::sub() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RangeBase::operator==(const RangeBase& in) const
|
||||
{
|
||||
return this == ∈
|
||||
|
|
Loading…
Reference in a new issue