cnorxz/src/include/xfor/xfor.h

1153 lines
34 KiB
C
Raw Normal View History

2018-01-05 13:56:16 +01:00
#ifndef __xfor_h__
#define __xfor_h__
#include <cstdlib>
#include <memory>
2018-01-08 18:38:13 +01:00
#include <tuple>
#include "xfor/for_type.h"
#include "xfor/for_utils.h"
#include "xfor/exttype.h"
2018-01-05 13:56:16 +01:00
2019-02-13 21:59:13 +01:00
#include "allocator.h"
2019-01-14 18:39:09 +01:00
#include <omp.h>
#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \
<< " in " << __func__ << ": " << #a << " = " << a << std::endl;
2018-01-05 13:56:16 +01:00
namespace MultiArrayHelper
{
2019-02-13 21:59:13 +01:00
using namespace MultiArrayTools;
// 'HIDDEN FOR' CLASS for nested for loops in contractions a.s.o.
// (NO COUNTING OF MASTER POSITION !!!!!)
//typedef std::pair<size_t const*,size_t> DExt;
2018-12-21 23:02:35 +01:00
class ExtBase
{
public:
2020-07-13 01:00:35 +02:00
ExtBase() = default;
ExtBase(const ExtBase& in) = default;
ExtBase(ExtBase&& in) = default;
ExtBase& operator=(const ExtBase& in) = default;
ExtBase& operator=(ExtBase&& in) = default;
2020-07-13 01:00:35 +02:00
virtual size_t size() const = 0;
virtual const size_t& val() const = 0;
//virtual size_t rootSteps() const = 0;
2021-01-15 01:05:58 +01:00
virtual bool operator==(const ExtBase& in) const = 0;
virtual bool operator==(size_t in) const = 0;
2020-07-13 01:00:35 +02:00
virtual std::shared_ptr<ExtBase> operator+(const ExtBase& in) const = 0;
virtual std::shared_ptr<ExtBase> operator*(size_t in) const = 0;
virtual void zero() = 0;
virtual std::shared_ptr<ExtBase> deepCopy() const = 0;
2020-07-10 00:17:38 +02:00
template <class ExtType>
const ExtType& expl() const;
2020-08-24 16:35:14 +02:00
virtual std::string stype() const = 0;
};
typedef std::shared_ptr<ExtBase> DExt;
template <class ExtType>
class ExtT : public ExtBase
{
private:
2020-07-13 01:00:35 +02:00
ExtType mExt;
public:
2020-07-13 01:00:35 +02:00
static constexpr size_t SIZE = ExtType::SIZE;
static constexpr size_t NUM = ExtType::NUM;
ExtT() = default;
ExtT(const ExtT& in) = default;
ExtT(ExtT&& in) = default;
ExtT& operator=(const ExtT& in) = default;
ExtT& operator=(ExtT&& in) = default;
ExtT(const ExtType& in) : mExt(in) {}
virtual std::shared_ptr<ExtBase> deepCopy() const override final { return std::make_shared<ExtT<ExtType>>(mExt); }
2020-07-13 01:00:35 +02:00
virtual size_t size() const override final { return sizeof(ExtType)/sizeof(size_t); }
//virtual size_t size() const override final { return ExtType::MExtSize(); }
//virtual size_t rootSteps() const override final;
const ExtType& ext() const { return mExt; }
virtual const size_t& val() const override final { return mExt.val(); }
virtual void zero() override final { mExt.zero(); }
2020-07-13 01:00:35 +02:00
2021-01-15 01:05:58 +01:00
virtual bool operator==(const ExtBase& in) const override final
{ return mExt == dynamic_cast<const ExtT<ExtType>&>(in).mExt; }
virtual bool operator==(size_t in) const override final
{ return mExt == in; }
2020-07-13 01:00:35 +02:00
virtual DExt operator+(const ExtBase& in) const override final
2020-08-24 16:35:14 +02:00
{ return std::make_shared<ExtT<ExtType>>( mExt + dynamic_cast<const ExtT<ExtType>&>(in).mExt ); }
2020-07-13 01:00:35 +02:00
virtual DExt operator*(size_t in) const override final
2020-08-24 16:35:14 +02:00
{ return std::make_shared<ExtT<ExtType>>( mExt * in ); }
virtual std::string stype() const override final { return std::string("T[") + mExt.stype() + "]"; }
};
2020-07-13 01:00:35 +02:00
//class DExtT;
2020-08-24 16:35:14 +02:00
template <class ExtType>
DExt mkDExt(const ExtT<ExtType>& in)
{
return std::make_shared<ExtT<ExtType>>(in);
}
template <class ExtType>
ExtT<ExtType> mkExtT(const ExtType& in)
{
return ExtT<ExtType>(in);
}
2020-07-13 01:00:35 +02:00
template <class X>
class DExtTX
{
private:
mutable DExt mDExt = nullptr;
2020-07-13 01:00:35 +02:00
X mNext;
template <class Y>
friend class DExtTX;
public:
2020-07-13 01:00:35 +02:00
static constexpr size_t NUM = X::SIZE;
static constexpr size_t SIZE = NUM + 1;
DExtTX() { mDExt = std::make_shared<ExtT<None>>(); }
DExtTX(const DExtTX& in) : mDExt(in.mDExt->deepCopy()), mNext(in.mNext) {}
DExtTX(DExtTX&& in) : mDExt(in.mDExt->deepCopy()), mNext(in.mNext) {}
DExtTX& operator=(const DExtTX& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); return *this; }
DExtTX& operator=(DExtTX&& in) { mNext = in.mNext; mDExt = in.mDExt->deepCopy(); return *this; }
2020-08-24 16:35:14 +02:00
explicit DExtTX(const DExt& in) : mDExt(in) {}
/*
2020-07-13 01:00:35 +02:00
template <class Y>
DExtTX& operator=(const Y& y) { mDExt = std::make_shared<ExtT<Y>>(y); return *this; }
2020-07-13 01:00:35 +02:00
template <class Y>
DExtTX(const Y& y) : mDExt(std::make_shared<ExtT<Y>>(y)) {}
2020-08-24 16:35:14 +02:00
*/
2021-01-15 01:05:58 +01:00
bool operator==(const DExtTX& in) const
{ return *mDExt == *in.mDExt and mNext == in.mNext; }
bool operator==(size_t in) const
{ return *mDExt == in and mNext == in; }
template <class Y>
DExtTX(const DExtTX<Y>& in) : mDExt(in.mDExt), mNext(in.mNext) {}
DExtTX(const DExt& y, const X& x) : mDExt(y->deepCopy()),
mNext(x) {}
2020-07-13 01:00:35 +02:00
virtual size_t size() const { return mDExt->size(); }
inline const DExt& get() const { return mDExt; }
2020-08-24 16:35:14 +02:00
inline DExtTX<None> reduce() const { return DExtTX<None>(mDExt,None(0)); }
2020-07-13 01:00:35 +02:00
inline DExtTX operator+(const DExtTX& in) const
2020-08-24 16:35:14 +02:00
{ if (not mDExt) return in; else return DExtTX( (*mDExt) + (*in.mDExt), mNext + in.mNext ); }
2020-07-13 01:00:35 +02:00
inline DExtTX operator*(size_t in) const
2020-08-24 16:35:14 +02:00
{ if (not mDExt) return *this; else return DExtTX((*mDExt) * in, mNext * in); }
2020-07-13 01:00:35 +02:00
template <class ExtType>
inline const ExtType& expl() const
{ if(mDExt == nullptr) mDExt = std::make_shared<ExtT<ExtType>>(); assert(mDExt != nullptr); return mDExt->expl<ExtType>(); }
2020-07-13 01:00:35 +02:00
template <class Y>
inline auto extend(const Y& y) const -> DExtTX<decltype(mNext.extend(y))>
{ return DExtTX<decltype(mNext.extend(y))>(mDExt, mNext.extend(y)); }
inline const size_t& val() const { return mDExt->val(); }
inline const X& next() const { return mNext; }
inline void zero() { mDExt->zero(); }
2020-07-13 01:00:35 +02:00
template <size_t N>
inline auto nn() const -> decltype(Getter<N>::getX(*this))
{ return Getter<N>::getX(*this); }
2020-08-24 16:35:14 +02:00
std::string stype() const { return std::string("D[") + mDExt->stype() + "," + mNext.stype() + "]"; }
};
2020-07-13 01:00:35 +02:00
typedef DExtTX<None> DExtT;
2020-07-09 17:37:28 +02:00
inline MExt<None> mkExt(size_t s) { return MExt<None>(s); }
2018-10-23 20:02:01 +02:00
class ExpressionBase
{
public:
ExpressionBase() = default;
ExpressionBase(const ExpressionBase& in) = default;
ExpressionBase(ExpressionBase&& in) = default;
ExpressionBase& operator=(const ExpressionBase& in) = default;
ExpressionBase& operator=(ExpressionBase&& in) = default;
//virtual size_t divResid() const { return 1; }
virtual std::intptr_t vI() const { return 0; }
virtual std::shared_ptr<ExpressionBase> deepCopy() const = 0;
2019-02-26 18:56:57 +01:00
virtual void operator()(size_t mlast, DExt last) = 0;
virtual void operator()(size_t mlast = 0) = 0;
2018-10-23 20:02:01 +02:00
virtual DExt dRootSteps(std::intptr_t iPtrNum = 0) const = 0;
virtual DExt dExtension() const = 0;
};
template <ForType FT = ForType::DEFAULT>
struct PosForward
{
static inline size_t valuex(size_t last, size_t step, size_t pos)
{
return last + pos * step;
}
static inline size_t value(size_t last, size_t max, size_t pos)
{
return last * max + pos;
}
};
template <>
struct PosForward<ForType::HIDDEN>
{
static inline size_t valuex(size_t last, size_t step, size_t pos)
{
return last;
}
static inline size_t value(size_t last, size_t max, size_t pos)
{
return last;
}
};
2018-02-13 16:54:13 +01:00
template <size_t ISSTATIC>
struct ForBound
{
2021-01-23 19:40:15 +01:00
template <size_t BOUND, size_t DIV = 1>
2018-02-13 16:54:13 +01:00
static inline size_t bound(size_t bound)
{
2021-01-23 19:40:15 +01:00
return bound / DIV;
2018-02-13 16:54:13 +01:00
}
};
template <>
struct ForBound<1>
{
2021-01-23 19:40:15 +01:00
template <size_t BOUND, size_t DIV = 1>
2018-02-13 16:54:13 +01:00
static constexpr size_t bound(size_t bound)
{
2021-01-23 19:40:15 +01:00
return BOUND / DIV;
2018-02-13 16:54:13 +01:00
}
};
2018-08-07 23:15:31 +02:00
2018-10-27 14:58:34 +02:00
2018-08-07 23:15:31 +02:00
template <class IndexClass, class Expr>
2018-10-23 20:02:01 +02:00
class SingleExpression : public ExpressionBase
2018-08-07 23:15:31 +02:00
{
private:
SingleExpression() = default;
const IndexClass* mIndPtr;
size_t mSPos;
size_t mMax;
2018-10-23 20:02:01 +02:00
Expr mExpr;
typedef decltype(mExpr.rootSteps()) ExtType;
ExtType mExt;
2018-10-27 14:58:34 +02:00
mutable ExtType mRootSteps;
2018-08-07 23:15:31 +02:00
public:
2018-10-23 20:02:01 +02:00
typedef ExpressionBase EB;
2018-08-07 23:15:31 +02:00
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE;
SingleExpression(const SingleExpression& in) = default;
SingleExpression& operator=(const SingleExpression& in) = default;
SingleExpression(SingleExpression&& in) = default;
SingleExpression& operator=(SingleExpression&& in) = default;
SingleExpression(const std::shared_ptr<IndexClass>& indPtr,
Expr expr);
2018-08-07 23:15:31 +02:00
SingleExpression(const IndexClass* indPtr,
Expr expr);
2018-08-07 23:15:31 +02:00
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<SingleExpression<IndexClass,Expr>>(*this);
}
2021-01-23 19:40:15 +01:00
template <size_t VS>
inline auto vec() const { return *this; }
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last);
inline void operator()(size_t mlast = 0) override final;
2018-08-07 23:15:31 +02:00
2018-10-23 20:02:01 +02:00
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final;
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
auto extension() const -> ExtType;
2018-08-07 23:15:31 +02:00
};
template <class IndexClass, class Expr>
class SubExpr : public ExpressionBase
{
private:
SubExpr() = default;
const IndexClass* mIndPtr;
2018-12-21 23:02:35 +01:00
std::intptr_t mSIPtr;
size_t mSPos;
size_t mMax;
Expr mExpr;
2018-12-21 23:02:35 +01:00
typedef decltype(mkExt(0).extend(mExpr.rootSteps())) ExtType;
ExtType mExt;
2019-02-13 21:59:13 +01:00
const vector<size_t>* mSubSet;
mutable ExtType mRootSteps;
public:
typedef ExpressionBase EB;
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE + 1;
SubExpr(const SubExpr& in) = default;
SubExpr& operator=(const SubExpr& in) = default;
SubExpr(SubExpr&& in) = default;
SubExpr& operator=(SubExpr&& in) = default;
SubExpr(const std::shared_ptr<IndexClass>& indPtr,
2018-12-21 23:02:35 +01:00
std::intptr_t siptr,
2019-02-13 21:59:13 +01:00
const vector<size_t>* subset, Expr expr);
2018-12-21 23:41:14 +01:00
SubExpr(const IndexClass* indPtr, std::intptr_t siptr,
2019-02-13 21:59:13 +01:00
const vector<size_t>* subset, Expr expr);
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<SubExpr<IndexClass,Expr>>(*this);
}
2021-01-23 19:40:15 +01:00
template <size_t VS>
inline auto vec() const { return *this; }
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final;
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final;
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
auto extension() const -> ExtType;
};
2021-01-23 19:40:15 +01:00
template <size_t LAYER, bool ISV>
struct MkVFor
{
template <size_t DIV, class IndexClass, class Expr>
using ptype = PFor<IndexClass,Expr,1>;
template <size_t DIV, class IndexClass, class Expr, ForType FT>
using type = For<IndexClass,Expr,FT,1>;
};
template <>
struct MkVFor<1,true>
{
template <size_t DIV, class IndexClass, class Expr>
using ptype = PFor<IndexClass,Expr,DIV>;
template <size_t DIV, class IndexClass, class Expr, ForType FT>
using type = For<IndexClass,Expr,FT,DIV>;
};
template <size_t LAYER>
struct MkVExpr
{
template <size_t VS, class Expr>
static auto mk(const Expr& e)
{
return e.template vec<VS>();
}
template <class Expr>
static inline size_t divResid(const Expr& e)
{
return e.divResid();
}
};
template <>
struct MkVExpr<1>
{
template <size_t VS, class Expr>
static auto mk(const Expr& e)
{
return e; // terminate
}
template <class Expr>
static inline size_t divResid(const Expr& e)
{
return 0;
}
};
template <class IndexClass, class Expr, ForType FT, size_t DIV>
2018-10-23 20:02:01 +02:00
class For : public ExpressionBase
2018-01-05 13:56:16 +01:00
{
private:
For() = default;
2021-01-23 19:40:15 +01:00
typedef typename IndexClass::RangeType RangeType;
const IndexClass* mIndPtr;
2018-01-18 23:14:49 +01:00
size_t mSPos;
size_t mMax;
size_t mStep;
2018-10-23 20:02:01 +02:00
Expr mExpr;
typedef decltype(mExpr.rootSteps()) ExtType;
ExtType mExt;
mutable ExtType mRootSteps;
2018-01-05 13:56:16 +01:00
public:
2018-10-23 20:02:01 +02:00
typedef ExpressionBase EB;
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE;
2021-01-23 19:40:15 +01:00
static constexpr size_t MAX = RangeType::SIZE / DIV;
For(const For& in) = default;
For& operator=(const For& in) = default;
2018-01-05 13:56:16 +01:00
For(For&& in) = default;
For& operator=(For&& in) = default;
2018-01-08 18:38:13 +01:00
For(const std::shared_ptr<IndexClass>& indPtr,
size_t step, Expr expr);
2018-01-05 13:56:16 +01:00
For(const IndexClass* indPtr,
size_t step, Expr expr);
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
2021-01-23 19:40:15 +01:00
return std::make_shared<For<IndexClass,Expr,FT,DIV>>(*this);
}
//virtual size_t divResid() const override final { return mMax % DIV + MkVExpr<LAYER>::divResid(mExpr); }
virtual std::intptr_t vI() const override final
{
if(mStep == 1 and LAYER == 1 and mMax % DIV == 0){
VCHECK(LAYER);
return reinterpret_cast<std::intptr_t>(mIndPtr);
}
return mExpr.vI();
}
2021-01-23 19:40:15 +01:00
template <size_t VS>
auto vec() const
2021-01-14 17:40:08 +01:00
{
2021-01-23 19:40:15 +01:00
typedef typename MkVFor<LAYER,RangeType::SIZE % DIV == 0 or RangeType::SIZE == static_cast<size_t>(-1)>::
template type<VS,IndexClass,decltype(MkVExpr<LAYER>::template mk<VS>(mExpr)),FT> oType;
return oType(mIndPtr,mStep,MkVExpr<LAYER>::template mk<VS>(mExpr));
2021-01-14 17:40:08 +01:00
}
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final;
2018-10-23 20:02:01 +02:00
2021-01-23 19:40:15 +01:00
PFor<IndexClass,Expr,DIV> parallel() const;
2019-01-14 18:39:09 +01:00
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final;
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
auto extension() const -> ExtType;
};
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
2019-01-14 18:39:09 +01:00
class PFor : public ExpressionBase
{
private:
PFor() = default;
2021-01-23 19:40:15 +01:00
typedef typename IndexClass::RangeType RangeType;
2019-01-14 18:39:09 +01:00
const IndexClass* mIndPtr;
size_t mSPos;
size_t mMax;
size_t mStep;
Expr mExpr;
typedef decltype(mExpr.rootSteps()) ExtType;
ExtType mExt;
mutable ExtType mRootSteps;
public:
typedef ExpressionBase EB;
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE;
2021-01-23 19:40:15 +01:00
static constexpr size_t MAX = RangeType::SIZE / DIV;
2019-01-14 18:39:09 +01:00
PFor(const PFor& in) = default;
PFor& operator=(const PFor& in) = default;
PFor(PFor&& in) = default;
PFor& operator=(PFor&& in) = default;
2021-01-23 19:40:15 +01:00
2019-01-14 18:39:09 +01:00
PFor(const std::shared_ptr<IndexClass>& indPtr,
size_t step, Expr expr);
PFor(const IndexClass* indPtr,
size_t step, Expr expr);
//virtual size_t divResid() const override final { return mMax % DIV + MkVExpr<LAYER>::divResid(mExpr); }
virtual std::intptr_t vI() const override final
{
if(mStep == 1 and LAYER == 1 and mMax % DIV == 0){
VCHECK(LAYER);
return reinterpret_cast<std::intptr_t>(mIndPtr);
}
return mExpr.vI();
}
2021-01-23 19:40:15 +01:00
template <size_t VS>
auto vec() const
2021-01-14 17:40:08 +01:00
{
2021-01-23 19:40:15 +01:00
typedef typename MkVFor<LAYER,RangeType::SIZE % DIV == 0 or RangeType::SIZE == static_cast<size_t>(-1)>::
template ptype<VS,IndexClass,decltype(MkVExpr<LAYER>::template mk<VS>(mExpr))> oType;
return oType(mIndPtr,mStep,MkVExpr<LAYER>::template mk<VS>(mExpr));
2021-01-14 17:40:08 +01:00
}
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<PFor<IndexClass,Expr>>(*this);
}
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final;
2019-01-14 18:39:09 +01:00
2018-10-23 20:02:01 +02:00
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final;
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
auto extension() const -> ExtType;
2018-01-07 16:57:01 +01:00
};
2018-01-05 13:56:16 +01:00
template <size_t N>
2018-02-14 18:15:34 +01:00
inline size_t exceptMax(size_t max) { return max; }
template <>
2018-02-14 18:15:34 +01:00
inline size_t exceptMax<1>(size_t max) { return 1; }
class DynamicExpression : public ExpressionBase
{
private:
size_t mThreadId = 0;
2018-10-23 20:02:01 +02:00
std::shared_ptr<ExpressionBase> mNext;
DynamicExpression() : mThreadId(omp_get_thread_num()) {}
public:
2020-08-31 17:28:00 +02:00
static constexpr size_t LAYER = 0;
static constexpr size_t SIZE = 0;
DynamicExpression(const DynamicExpression& in) :
mThreadId(omp_get_thread_num()),
mNext( (static_cast<int>(in.mThreadId) == omp_get_thread_num()) ?
in.mNext : in.mNext->deepCopy()) {}
DynamicExpression(DynamicExpression&& in) :
mThreadId(omp_get_thread_num()),
mNext( (static_cast<int>(in.mThreadId) == omp_get_thread_num()) ?
in.mNext : in.mNext->deepCopy()) {}
DynamicExpression& operator=(const DynamicExpression& in)
{
mThreadId = omp_get_thread_num();
mNext = (static_cast<int>(in.mThreadId) == omp_get_thread_num()) ?
in.mNext : in.mNext->deepCopy();
return *this;
}
DynamicExpression& operator=(DynamicExpression&& in)
{
mThreadId = omp_get_thread_num();
mNext = (static_cast<int>(in.mThreadId) == omp_get_thread_num()) ?
in.mNext : in.mNext->deepCopy();
return *this;
}
DynamicExpression(const std::shared_ptr<ExpressionBase>& next) :
2018-10-27 14:58:34 +02:00
mNext(next)
{}
template <class Expr>
DynamicExpression(const ExpressionBase& next) :
mNext(std::make_shared<Expr>(next))
{}
template <class Expr>
DynamicExpression(Expr ex) : mNext( std::make_shared<Expr>(ex) ) {}
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<DynamicExpression>(*this);
}
2021-01-23 19:40:15 +01:00
template <size_t VS>
inline auto vec() const { return *this; }
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, DExtT last) { (*this)(mlast,last.get()); }
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast = 0) override final;
2018-10-23 20:02:01 +02:00
2018-10-27 14:58:34 +02:00
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
inline DExt dExtension() const override final;
2018-10-23 20:02:01 +02:00
2020-08-24 16:35:14 +02:00
inline DExtT rootSteps(std::intptr_t iPtrNum = 0) const { return DExtT(dRootSteps(iPtrNum)); }
inline DExtT extension() const { return DExtT(dExtension()); }
};
template <class Expr>
class ExpressionHolder : public ExpressionBase
{
private:
ExpressionHolder() = default;
DynamicExpression mExpr;
typedef decltype(std::declval<Expr>().rootSteps()) ExtType;
ExtType mExt;
mutable ExtType mRootSteps;
public:
typedef ExpressionBase EB;
static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE;
ExpressionHolder(const ExpressionHolder& in) = default;
ExpressionHolder(ExpressionHolder&& in) = default;
ExpressionHolder& operator=(const ExpressionHolder& in) = default;
ExpressionHolder& operator=(ExpressionHolder&& in) = default;
ExpressionHolder(DynamicExpression expr);
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
{
return std::make_shared<ExpressionHolder<Expr>>(*this);
}
2019-02-26 18:56:57 +01:00
inline void operator()(size_t mlast, DExt last) override final;
inline void operator()(size_t mlast, ExtType last) ;
inline void operator()(size_t mlast = 0) override final;
DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
DExt dExtension() const override final;
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
auto extension() const -> ExtType;
};
2018-01-05 13:56:16 +01:00
} // namespace MultiArrayHelper
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
#include <iostream>
2018-01-05 13:56:16 +01:00
namespace MultiArrayHelper
{
2020-07-10 00:17:38 +02:00
template <class ExtType>
const ExtType& ExtBase::expl() const
{
return dynamic_cast<const ExtT<ExtType>*>(this)->ext();
2020-07-10 00:17:38 +02:00
}
/*****************
* F o r *
*****************/
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
For<IndexClass,Expr,FT,DIV>::For(const std::shared_ptr<IndexClass>& indPtr,
size_t step, Expr expr) :
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
2018-10-23 20:02:01 +02:00
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{
2021-01-23 19:40:15 +01:00
assert(mMax % DIV == 0);
assert(mIndPtr != nullptr);
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
For<IndexClass,Expr,FT,DIV>::For(const IndexClass* indPtr,
size_t step, Expr expr) :
2018-10-27 14:58:34 +02:00
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
2018-10-23 20:02:01 +02:00
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{
//VCHECK(mMax);
//VCHECK(DIV);
//assert(mMax % DIV == 0);
assert(mIndPtr != nullptr);
}
2018-10-23 20:02:01 +02:00
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast, DExt last)
2018-10-23 20:02:01 +02:00
{
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
2018-10-23 20:02:01 +02:00
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast,
2019-02-26 18:56:57 +01:00
ExtType last)
2018-01-05 13:56:16 +01:00
{
2018-02-13 16:54:13 +01:00
typedef typename IndexClass::RangeType RangeType;
2021-01-23 19:40:15 +01:00
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax); ++pos){
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
2018-10-27 14:58:34 +02:00
const ExtType npos = last + mExt*pos;
mExpr(mnpos, npos);
}
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
inline void For<IndexClass,Expr,FT,DIV>::operator()(size_t mlast)
{
2018-02-13 16:54:13 +01:00
typedef typename IndexClass::RangeType RangeType;
ExtType last = rootSteps();
last.zero();
2021-01-23 19:40:15 +01:00
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax); ++pos){
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
2018-10-27 14:58:34 +02:00
const ExtType npos = last + mExt*pos;
mExpr(mnpos, npos);
2018-01-05 13:56:16 +01:00
}
}
2018-10-23 20:02:01 +02:00
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
auto For<IndexClass,Expr,FT,DIV>::rootSteps(std::intptr_t iPtrNum) const
2018-10-23 20:02:01 +02:00
-> ExtType
{
return mExpr.rootSteps(iPtrNum);
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
auto For<IndexClass,Expr,FT,DIV>::extension() const
2018-10-23 20:02:01 +02:00
-> ExtType
{
return mExt;
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
DExt For<IndexClass,Expr,FT,DIV>::dRootSteps(std::intptr_t iPtrNum) const
2018-10-23 20:02:01 +02:00
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mRootSteps),
// sizeof(ExtType)/sizeof(size_t));
2018-10-23 20:02:01 +02:00
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
DExt For<IndexClass,Expr,FT,DIV>::dExtension() const
2018-10-23 20:02:01 +02:00
{
return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),
// sizeof(ExtType)/sizeof(size_t));
2018-10-23 20:02:01 +02:00
}
2018-08-07 23:15:31 +02:00
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, ForType FT, size_t DIV>
PFor<IndexClass,Expr,DIV> For<IndexClass,Expr,FT,DIV>::parallel() const
2019-01-14 18:39:09 +01:00
{
static_assert(FT == ForType::DEFAULT, "hidden for not parallelizable");
2021-01-23 19:40:15 +01:00
return PFor<IndexClass,Expr,DIV>(mIndPtr, mStep, mExpr);
2019-01-14 18:39:09 +01:00
}
/******************
* P F o r *
******************/
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
PFor<IndexClass,Expr,DIV>::PFor(const std::shared_ptr<IndexClass>& indPtr,
2019-01-14 18:39:09 +01:00
size_t step, Expr expr) :
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{
//assert(mMax % DIV == 0);
2019-01-14 18:39:09 +01:00
assert(mIndPtr != nullptr);
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
PFor<IndexClass,Expr,DIV>::PFor(const IndexClass* indPtr,
2019-01-14 18:39:09 +01:00
size_t step, Expr expr) :
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
{
2021-01-23 19:40:15 +01:00
assert(mMax % DIV == 0);
2019-01-14 18:39:09 +01:00
assert(mIndPtr != nullptr);
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast, DExt last)
2019-01-14 18:39:09 +01:00
{
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
2019-01-14 18:39:09 +01:00
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast,
2019-02-26 18:56:57 +01:00
ExtType last)
2019-01-14 18:39:09 +01:00
{
2019-01-15 17:41:43 +01:00
CHECK;
2019-01-14 18:39:09 +01:00
typedef typename IndexClass::RangeType RangeType;
int pos = 0;
size_t mnpos = 0;
ExtType npos;
#pragma omp parallel shared(mExpr) private(pos,mnpos,npos)
2019-01-14 18:39:09 +01:00
{
auto expr = mExpr;
2019-01-14 18:39:09 +01:00
#pragma omp for nowait
2021-01-23 19:40:15 +01:00
for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax)); pos++){
2019-01-14 18:39:09 +01:00
mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
npos = last + mExt*static_cast<size_t>(pos);
expr(mnpos, npos);
}
}
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
inline void PFor<IndexClass,Expr,DIV>::operator()(size_t mlast)
2019-01-14 18:39:09 +01:00
{
2019-01-15 17:41:43 +01:00
CHECK;
ExtType last = rootSteps();
last.zero();
2019-01-14 18:39:09 +01:00
int pos = 0;
size_t mnpos = 0;
ExtType npos = rootSteps();
npos.zero();
#pragma omp parallel shared(mExpr) private(pos,mnpos,npos)
2019-01-14 18:39:09 +01:00
{
auto expr = mExpr;
2019-01-14 18:39:09 +01:00
#pragma omp for nowait
2021-01-23 19:40:15 +01:00
for(pos = 0; pos < static_cast<int>(ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE,DIV>(mMax)); pos++){
2019-01-14 18:39:09 +01:00
mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
npos = last + mExt*static_cast<size_t>(pos);
expr(mnpos, npos);
}
}
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
auto PFor<IndexClass,Expr,DIV>::rootSteps(std::intptr_t iPtrNum) const
2019-01-14 18:39:09 +01:00
-> ExtType
{
return mExpr.rootSteps(iPtrNum);
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
auto PFor<IndexClass,Expr,DIV>::extension() const
2019-01-14 18:39:09 +01:00
-> ExtType
{
return mExt;
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
DExt PFor<IndexClass,Expr,DIV>::dRootSteps(std::intptr_t iPtrNum) const
2019-01-14 18:39:09 +01:00
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mRootSteps),
// sizeof(ExtType)/sizeof(size_t));
2019-01-14 18:39:09 +01:00
}
2021-01-23 19:40:15 +01:00
template <class IndexClass, class Expr, size_t DIV>
DExt PFor<IndexClass,Expr,DIV>::dExtension() const
2019-01-14 18:39:09 +01:00
{
return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),
// sizeof(ExtType)/sizeof(size_t));
2019-01-14 18:39:09 +01:00
}
/************************
* SingleExpression *
************************/
2018-08-07 23:15:31 +02:00
template <class IndexClass, class Expr>
SingleExpression<IndexClass,Expr>::SingleExpression(const std::shared_ptr<IndexClass>& indPtr,
Expr expr) :
2018-10-23 20:02:01 +02:00
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
2018-08-07 23:15:31 +02:00
{
assert(mIndPtr != nullptr);
//VCHECK(mIndPtr->id());
//VCHECK(mIndPtr->max());
}
template <class IndexClass, class Expr>
SingleExpression<IndexClass,Expr>::SingleExpression(const IndexClass* indPtr,
Expr expr) :
2018-10-23 20:02:01 +02:00
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mExpr(expr), mExt(mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
2018-08-07 23:15:31 +02:00
{
assert(mIndPtr != nullptr);
//VCHECK(mIndPtr->id());
//VCHECK(mIndPtr->max());
}
2018-10-23 20:02:01 +02:00
template <class IndexClass, class Expr>
2019-02-26 18:56:57 +01:00
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast, DExt last)
2018-10-23 20:02:01 +02:00
{
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
2018-10-23 20:02:01 +02:00
}
2018-08-07 23:15:31 +02:00
template <class IndexClass, class Expr>
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast,
2019-02-26 18:56:57 +01:00
ExtType last)
2018-08-07 23:15:31 +02:00
{
//typedef typename IndexClass::RangeType RangeType;
const size_t pos = mIndPtr->pos();
const size_t mnpos = PosForward<ForType::DEFAULT>::value(mlast, mMax, pos);
2018-10-27 14:58:34 +02:00
const ExtType npos = last + mExt*pos;
mExpr(mnpos, npos);
2018-08-07 23:15:31 +02:00
}
template <class IndexClass, class Expr>
2019-02-26 18:56:57 +01:00
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast)
2018-08-07 23:15:31 +02:00
{
//typedef typename IndexClass::RangeType RangeType;
ExtType last = rootSteps();
last.zero();
2018-08-07 23:15:31 +02:00
const size_t pos = mIndPtr->pos();
const size_t mnpos = PosForward<ForType::DEFAULT>::value(mlast, mMax, pos);
2018-10-27 14:58:34 +02:00
const ExtType npos = last + mExt*pos;
mExpr(mlast, last);
2018-08-07 23:15:31 +02:00
}
2018-10-23 20:02:01 +02:00
template <class IndexClass, class Expr>
auto SingleExpression<IndexClass,Expr>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
return mExpr.rootSteps(iPtrNum);
}
template <class IndexClass, class Expr>
auto SingleExpression<IndexClass,Expr>::extension() const
-> ExtType
{
return mExt;
}
template <class IndexClass, class Expr>
2018-10-27 14:58:34 +02:00
DExt SingleExpression<IndexClass,Expr>::dRootSteps(std::intptr_t iPtrNum) const
2018-10-23 20:02:01 +02:00
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mRootSteps),
// sizeof(ExtType)/sizeof(size_t));
2018-10-23 20:02:01 +02:00
}
template <class IndexClass, class Expr>
DExt SingleExpression<IndexClass,Expr>::dExtension() const
{
return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),
// sizeof(ExtType)/sizeof(size_t));
2018-10-23 20:02:01 +02:00
}
2018-08-07 23:15:31 +02:00
/****************
* SubExpr *
****************/
2018-12-21 23:02:35 +01:00
template <class IndexClass, class Expr>
SubExpr<IndexClass,Expr>::SubExpr(const std::shared_ptr<IndexClass>& indPtr,
2018-12-21 23:02:35 +01:00
std::intptr_t siptr,
2019-02-13 21:59:13 +01:00
const vector<size_t>* subset, Expr expr) :
2018-12-21 23:02:35 +01:00
mIndPtr(indPtr.get()), mSIPtr(siptr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mExpr(expr),
mExt( mkExt(0).extend( mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )) ) ),
2018-12-21 23:41:14 +01:00
mSubSet(subset)
{
assert(mIndPtr != nullptr);
}
template <class IndexClass, class Expr>
2018-12-21 23:41:14 +01:00
SubExpr<IndexClass,Expr>::SubExpr(const IndexClass* indPtr, std::intptr_t siptr,
2019-02-13 21:59:13 +01:00
const vector<size_t>* subset, Expr expr) :
2018-12-21 23:02:35 +01:00
mIndPtr(indPtr), mSIPtr(siptr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mExpr(expr),
mExt( mkExt(0).extend( mExpr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )) ) ),
2018-12-21 23:41:14 +01:00
mSubSet(subset)
{
assert(mIndPtr != nullptr);
}
template <class IndexClass, class Expr>
2019-02-26 18:56:57 +01:00
inline void SubExpr<IndexClass,Expr>::operator()(size_t mlast, DExt last)
{
operator()(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
//operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
}
template <class IndexClass, class Expr>
inline void SubExpr<IndexClass,Expr>::operator()(size_t mlast,
2019-02-26 18:56:57 +01:00
ExtType last)
{
2018-12-21 23:02:35 +01:00
const size_t pos = (*mSubSet)[last.val()];
2018-12-21 23:41:14 +01:00
const size_t mnpos = mlast;
const ExtType npos = last + mExt*pos;
2018-12-21 23:02:35 +01:00
mExpr(mnpos, Getter<1>::template getX<ExtType>( npos ));
}
template <class IndexClass, class Expr>
2019-02-26 18:56:57 +01:00
inline void SubExpr<IndexClass,Expr>::operator()(size_t mlast)
{
ExtType last = rootSteps();
last.zero();
2018-12-21 23:02:35 +01:00
const size_t pos = (*mSubSet)[last.val()];
2018-12-21 23:41:14 +01:00
const size_t mnpos = mlast;
const ExtType npos = last + mExt*pos;
2018-12-21 23:02:35 +01:00
mExpr(mnpos, Getter<1>::template getX<ExtType>( npos ));
}
template <class IndexClass, class Expr>
auto SubExpr<IndexClass,Expr>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
2018-12-21 23:02:35 +01:00
return mkExt(iPtrNum == mSIPtr ? 1 : 0).extend(mExpr.rootSteps(iPtrNum));
}
template <class IndexClass, class Expr>
auto SubExpr<IndexClass,Expr>::extension() const
-> ExtType
{
return mExt;
}
template <class IndexClass, class Expr>
DExt SubExpr<IndexClass,Expr>::dRootSteps(std::intptr_t iPtrNum) const
{
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
//mRootSteps = rootSteps(iPtrNum);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mRootSteps),
//sizeof(ExtType)/sizeof(size_t));
}
template <class IndexClass, class Expr>
DExt SubExpr<IndexClass,Expr>::dExtension() const
{
return std::make_shared<ExtT<ExtType>>(mExt);
//return std::make_pair<size_t const*,size_t>(reinterpret_cast<size_t const*>(&mExt),
// sizeof(ExtType)/sizeof(size_t));
}
/***************************
* DynamicExpression *
***************************/
2019-02-26 18:56:57 +01:00
inline void DynamicExpression::operator()(size_t mlast, DExt last)
2018-10-27 14:58:34 +02:00
{
(*mNext)(mlast,last);
}
2019-02-26 18:56:57 +01:00
inline void DynamicExpression::operator()(size_t mlast)
2018-10-27 14:58:34 +02:00
{
(*mNext)(mlast);
}
inline DExt DynamicExpression::dRootSteps(std::intptr_t iPtrNum) const
2018-10-27 14:58:34 +02:00
{
return mNext->dRootSteps(iPtrNum);
}
inline DExt DynamicExpression::dExtension() const
2018-10-27 14:58:34 +02:00
{
return mNext->dExtension();
}
/************************
* ExpressionHolder *
************************/
template <class Expr>
ExpressionHolder<Expr>::ExpressionHolder(DynamicExpression expr) : mExpr(expr) {}
template <class Expr>
2019-02-26 18:56:57 +01:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast, DExt last)
2018-08-07 23:15:31 +02:00
{
2018-10-27 14:58:34 +02:00
mExpr(mlast,last);
}
template <class Expr>
2019-02-26 18:56:57 +01:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast, ExtType last)
{
mExpr(mlast,
std::make_shared<ExtT<ExtType>>(last));
2018-08-07 23:15:31 +02:00
}
2018-10-23 20:02:01 +02:00
template <class Expr>
2019-02-26 18:56:57 +01:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast)
2018-10-23 20:02:01 +02:00
{
2018-10-27 14:58:34 +02:00
mExpr(mlast);
2018-10-23 20:02:01 +02:00
}
template <class Expr>
2018-10-27 14:58:34 +02:00
DExt ExpressionHolder<Expr>::dRootSteps(std::intptr_t iPtrNum) const
2018-10-23 20:02:01 +02:00
{
2018-10-27 14:58:34 +02:00
return mExpr.dRootSteps(iPtrNum);
}
template <class Expr>
DExt ExpressionHolder<Expr>::dExtension() const
{
return mExpr.dExtension();
}
template <class Expr>
auto ExpressionHolder<Expr>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
return std::dynamic_pointer_cast<ExtT<ExtType>>(mExpr.dRootSteps(iPtrNum))->ext();
//return *reinterpret_cast<ExtType const*>( mExpr.dRootSteps(iPtrNum).first );
2018-10-27 14:58:34 +02:00
}
template <class Expr>
auto ExpressionHolder<Expr>::extension() const
-> ExtType
{
return std::dynamic_pointer_cast<ExtT<ExtType>>(mExpr.dExtension())->ext();
//return *reinterpret_cast<ExtType const*>( mExpr.dExtension().first );
2018-10-23 20:02:01 +02:00
}
2018-10-27 14:58:34 +02:00
2018-01-05 13:56:16 +01:00
} // namespace MultiArrayHelper
#endif