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>
|
2018-01-15 14:56:22 +01:00
|
|
|
#include "xfor/for_type.h"
|
2018-09-12 17:05:27 +02:00
|
|
|
#include "xfor/for_utils.h"
|
2018-02-12 00:11:24 +01:00
|
|
|
#include "xfor/exttype.h"
|
2018-01-05 13:56:16 +01:00
|
|
|
|
|
|
|
namespace MultiArrayHelper
|
|
|
|
{
|
2018-01-14 22:41:35 +01:00
|
|
|
|
|
|
|
// 'HIDDEN FOR' CLASS for nested for loops in contractions a.s.o.
|
|
|
|
// (NO COUNTING OF MASTER POSITION !!!!!)
|
2018-01-15 14:56:22 +01:00
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
template <class Expr>
|
|
|
|
class ExpressionBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static constexpr size_t LAYER = Expr::LAYER + 1;
|
|
|
|
static constexpr size_t SIZE = Expr::SIZE;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Expr mExpr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef decltype(mExpr.rootSteps()) ExtType;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
ExtType mExt;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
ExpressionBase() = default;
|
|
|
|
ExpressionBase(const ExpressionBase& in) = default;
|
|
|
|
ExpressionBase(ExpressionBase&& in) = default;
|
|
|
|
ExpressionBase& operator=(const ExpressionBase& in) = default;
|
|
|
|
ExpressionBase& operator=(ExpressionBase&& in) = default;
|
|
|
|
|
|
|
|
ExpressionBase(ExtType ext, Expr&& expr);
|
|
|
|
|
|
|
|
virtual void operator()(size_t mlast, ExtType last) const = 0;
|
|
|
|
virtual void operator()(size_t mlast = 0) const = 0;
|
|
|
|
|
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
|
|
|
auto extension() const -> ExtType;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <ForType FT = ForType::DEFAULT>
|
|
|
|
struct PosForward
|
|
|
|
{
|
2018-09-17 16:21:23 +02:00
|
|
|
static inline size_t valuex(size_t last, size_t step, size_t pos)
|
|
|
|
{
|
|
|
|
return last + pos * step;
|
|
|
|
}
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
static inline size_t value(size_t last, size_t max, size_t pos)
|
|
|
|
{
|
|
|
|
return last * max + pos;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct PosForward<ForType::HIDDEN>
|
|
|
|
{
|
2018-09-17 16:21:23 +02:00
|
|
|
static inline size_t valuex(size_t last, size_t step, size_t pos)
|
|
|
|
{
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
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
|
|
|
|
{
|
|
|
|
template <size_t BOUND>
|
|
|
|
static inline size_t bound(size_t bound)
|
|
|
|
{
|
|
|
|
return bound;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct ForBound<1>
|
|
|
|
{
|
|
|
|
template <size_t BOUND>
|
|
|
|
static constexpr size_t bound(size_t bound)
|
|
|
|
{
|
|
|
|
return BOUND;
|
|
|
|
}
|
|
|
|
};
|
2018-08-07 23:15:31 +02:00
|
|
|
|
|
|
|
template <class IndexClass, class Expr>
|
2018-10-21 22:52:01 +02:00
|
|
|
class SingleExpression : public ExpressionBase<Expr>
|
2018-08-07 23:15:31 +02:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
SingleExpression() = default;
|
|
|
|
|
|
|
|
const IndexClass* mIndPtr;
|
|
|
|
size_t mSPos;
|
|
|
|
size_t mMax;
|
|
|
|
|
|
|
|
public:
|
2018-10-21 22:52:01 +02:00
|
|
|
typedef ExpressionBase<Expr> EB;
|
|
|
|
using EB::rootSteps;
|
|
|
|
typedef typename ExpressionBase<Expr>::ExtType ExtType;
|
|
|
|
|
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,
|
2018-10-21 22:52:01 +02:00
|
|
|
Expr expr);
|
2018-08-07 23:15:31 +02:00
|
|
|
|
|
|
|
SingleExpression(const IndexClass* indPtr,
|
2018-10-21 22:52:01 +02:00
|
|
|
Expr expr);
|
2018-08-07 23:15:31 +02:00
|
|
|
|
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
inline void operator()(size_t mlast, ExtType last) const override final;
|
|
|
|
inline void operator()(size_t mlast = 0) const override final;
|
2018-08-07 23:15:31 +02:00
|
|
|
|
|
|
|
};
|
2018-01-08 18:38:13 +01:00
|
|
|
|
2018-09-12 17:05:27 +02:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
2018-10-21 22:52:01 +02:00
|
|
|
class For : public ExpressionBase<Expr>
|
2018-01-05 13:56:16 +01:00
|
|
|
{
|
2018-01-13 18:07:52 +01:00
|
|
|
private:
|
|
|
|
For() = default;
|
|
|
|
|
|
|
|
const IndexClass* mIndPtr;
|
2018-01-18 23:14:49 +01:00
|
|
|
size_t mSPos;
|
|
|
|
size_t mMax;
|
2018-09-17 16:21:23 +02:00
|
|
|
size_t mStep;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
public:
|
2018-10-21 22:52:01 +02:00
|
|
|
typedef ExpressionBase<Expr> EB;
|
|
|
|
using EB::rootSteps;
|
|
|
|
typedef typename ExpressionBase<Expr>::ExtType ExtType;
|
|
|
|
|
2018-02-12 00:11:24 +01:00
|
|
|
static constexpr size_t LAYER = Expr::LAYER + 1;
|
|
|
|
static constexpr size_t SIZE = Expr::SIZE;
|
|
|
|
|
|
|
|
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,
|
2018-09-17 16:21:23 +02:00
|
|
|
size_t step, Expr expr);
|
2018-01-05 13:56:16 +01:00
|
|
|
|
2018-01-13 18:07:52 +01:00
|
|
|
For(const IndexClass* indPtr,
|
2018-09-17 16:21:23 +02:00
|
|
|
size_t step, Expr expr);
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
inline void operator()(size_t mlast, ExtType last) const override final;
|
|
|
|
inline void operator()(size_t mlast = 0) const override final;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-07 16:57:01 +01:00
|
|
|
};
|
2018-01-05 13:56:16 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <size_t N>
|
2018-02-14 18:15:34 +01:00
|
|
|
inline size_t exceptMax(size_t max) { return max; }
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
template <>
|
2018-02-14 18:15:34 +01:00
|
|
|
inline size_t exceptMax<1>(size_t max) { return 1; }
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
template <class Expr>
|
|
|
|
class DynamicalExpression : public ExpressionBase<Expr>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
DynamicalExpression() = default;
|
|
|
|
|
|
|
|
std::shared_ptr<ExpressionBase<Expr>> mNext;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef ExpressionBase<Expr> EB;
|
|
|
|
using EB::rootSteps;
|
|
|
|
typedef typename ExpressionBase<Expr>::ExtType ExtType;
|
|
|
|
|
|
|
|
static constexpr size_t LAYER = Expr::LAYER + 1;
|
|
|
|
static constexpr size_t SIZE = Expr::SIZE;
|
|
|
|
|
|
|
|
DynamicalExpression(const DynamicalExpression& in) = default;
|
|
|
|
DynamicalExpression(DynamicalExpression&& in) = default;
|
|
|
|
DynamicalExpression& operator=(const DynamicalExpression& in) = default;
|
|
|
|
DynamicalExpression& operator=(DynamicalExpression&& in) = default;
|
|
|
|
|
|
|
|
DynamicalExpression(const std::shared_ptr<ExpressionBase<Expr>>& next,
|
|
|
|
Expr expr);
|
|
|
|
|
|
|
|
inline void operator()(size_t mlast, ExtType last) const override final;
|
|
|
|
inline void operator()(size_t mlast = 0) const override final;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
} // namespace MultiArrayHelper
|
|
|
|
|
|
|
|
/* ========================= *
|
|
|
|
* --- TEMPLATE CODE --- *
|
|
|
|
* ========================= */
|
|
|
|
|
2018-01-14 22:41:35 +01:00
|
|
|
#include <iostream>
|
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
namespace MultiArrayHelper
|
|
|
|
{
|
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
/**********************
|
|
|
|
* ExpressionBase *
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
ExpressionBase<Expr>::ExpressionBase(ExtType ext, Expr&& expr) :
|
|
|
|
mExpr(std::forward<Expr>(expr)),
|
|
|
|
mExt(ext)
|
|
|
|
{}
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
auto ExpressionBase<Expr>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
-> ExtType
|
|
|
|
{
|
|
|
|
return mExpr.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
auto ExpressionBase<Expr>::extension() const
|
|
|
|
-> ExtType
|
|
|
|
{
|
|
|
|
return mExt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************
|
|
|
|
* F o r *
|
|
|
|
*****************/
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
|
|
|
For<IndexClass,Expr,FT>::For(const std::shared_ptr<IndexClass>& indPtr,
|
2018-09-17 16:21:23 +02:00
|
|
|
size_t step, Expr expr) :
|
2018-10-21 22:52:01 +02:00
|
|
|
ExpressionBase<Expr>(expr.rootSteps( reinterpret_cast<std::intptr_t>( indPtr.get() )),
|
|
|
|
std::forward<Expr>(expr)),
|
|
|
|
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mStep(step)
|
2018-01-15 14:56:22 +01:00
|
|
|
{
|
|
|
|
assert(mIndPtr != nullptr);
|
|
|
|
//VCHECK(mIndPtr->id());
|
|
|
|
//VCHECK(mIndPtr->max());
|
|
|
|
}
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
|
|
|
For<IndexClass,Expr,FT>::For(const IndexClass* indPtr,
|
2018-09-17 16:21:23 +02:00
|
|
|
size_t step, Expr expr) :
|
2018-10-21 22:52:01 +02:00
|
|
|
ExpressionBase<Expr>(expr.rootSteps( reinterpret_cast<std::intptr_t>( indPtr ) ),
|
|
|
|
std::forward<Expr>(expr)),
|
2018-01-18 23:14:49 +01:00
|
|
|
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
|
2018-10-21 22:52:01 +02:00
|
|
|
mStep(step)
|
2018-01-15 14:56:22 +01:00
|
|
|
{
|
|
|
|
assert(mIndPtr != nullptr);
|
|
|
|
//VCHECK(mIndPtr->id());
|
|
|
|
//VCHECK(mIndPtr->max());
|
|
|
|
}
|
2018-01-07 22:33:34 +01:00
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
|
|
|
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast,
|
2018-02-13 15:38:03 +01:00
|
|
|
ExtType last) const
|
2018-01-05 13:56:16 +01:00
|
|
|
{
|
2018-02-13 16:54:13 +01:00
|
|
|
typedef typename IndexClass::RangeType RangeType;
|
|
|
|
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax); ++pos){
|
|
|
|
//for(size_t pos = mSPos; pos != mMax; ++pos){
|
2018-09-17 16:34:47 +02:00
|
|
|
//const size_t mnpos = PosForward<FT>::value(mlast, mMax, pos);
|
|
|
|
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
|
2018-10-21 22:52:01 +02:00
|
|
|
const ExtType npos = last + EB::mExt*pos;
|
|
|
|
EB::mExpr(mnpos, npos);
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
|
|
|
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast) const
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-13 16:54:13 +01:00
|
|
|
typedef typename IndexClass::RangeType RangeType;
|
2018-02-12 00:11:24 +01:00
|
|
|
const ExtType last;
|
2018-02-13 16:54:13 +01:00
|
|
|
for(size_t pos = 0u; pos != ForBound<RangeType::ISSTATIC>::template bound<RangeType::SIZE>(mMax); ++pos){
|
|
|
|
//for(size_t pos = mSPos; pos != mMax; ++pos){
|
2018-09-17 16:34:47 +02:00
|
|
|
//const size_t mnpos = PosForward<FT>::value(mlast, mMax, pos);
|
|
|
|
const size_t mnpos = PosForward<FT>::valuex(mlast, mStep, pos);
|
2018-10-21 22:52:01 +02:00
|
|
|
const ExtType npos = last + EB::mExt*pos;
|
|
|
|
EB::mExpr(mnpos, npos);
|
2018-01-05 13:56:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-07 23:15:31 +02:00
|
|
|
|
2018-10-21 22:52:01 +02: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,
|
2018-10-21 22:52:01 +02:00
|
|
|
Expr expr) :
|
|
|
|
ExpressionBase<Expr>(expr.rootSteps( reinterpret_cast<std::intptr_t>( indPtr.get() )),
|
|
|
|
std::forward<Expr>(expr)),
|
|
|
|
mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max())
|
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-21 22:52:01 +02:00
|
|
|
ExpressionBase<Expr>(expr.rootSteps( reinterpret_cast<std::intptr_t>( indPtr ) ),
|
|
|
|
std::forward<Expr>(expr)),
|
|
|
|
mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max())
|
2018-08-07 23:15:31 +02:00
|
|
|
{
|
|
|
|
assert(mIndPtr != nullptr);
|
|
|
|
//VCHECK(mIndPtr->id());
|
|
|
|
//VCHECK(mIndPtr->max());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class IndexClass, class Expr>
|
|
|
|
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast,
|
|
|
|
ExtType last) const
|
|
|
|
{
|
|
|
|
//typedef typename IndexClass::RangeType RangeType;
|
|
|
|
const size_t pos = mIndPtr->pos();
|
|
|
|
const size_t mnpos = PosForward<ForType::DEFAULT>::value(mlast, mMax, pos);
|
2018-10-21 22:52:01 +02:00
|
|
|
const ExtType npos = last + EB::mExt*pos;
|
|
|
|
EB::mExpr(mnpos, npos);
|
2018-08-07 23:15:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class IndexClass, class Expr>
|
|
|
|
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast) const
|
|
|
|
{
|
|
|
|
//typedef typename IndexClass::RangeType RangeType;
|
|
|
|
const ExtType last;
|
|
|
|
const size_t pos = mIndPtr->pos();
|
|
|
|
const size_t mnpos = PosForward<ForType::DEFAULT>::value(mlast, mMax, pos);
|
2018-10-21 22:52:01 +02:00
|
|
|
const ExtType npos = last + EB::mExt*pos;
|
|
|
|
EB::mExpr(mlast, last);
|
2018-08-07 23:15:31 +02:00
|
|
|
}
|
2018-10-21 22:52:01 +02:00
|
|
|
|
2018-08-07 23:15:31 +02:00
|
|
|
|
2018-10-21 22:52:01 +02:00
|
|
|
/***************************
|
|
|
|
* DynamicalExpression *
|
|
|
|
***************************/
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
DynamicalExpression<Expr>::
|
|
|
|
DynamicalExpression(const std::shared_ptr<ExpressionBase<Expr>>& next,
|
|
|
|
Expr expr) :
|
|
|
|
ExpressionBase<Expr>(next->extension(), std::forward<Expr>(expr)),
|
|
|
|
mNext(next)
|
|
|
|
{}
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
inline void DynamicalExpression<Expr>::operator()(size_t mlast, ExtType last) const
|
2018-08-07 23:15:31 +02:00
|
|
|
{
|
2018-10-21 22:52:01 +02:00
|
|
|
(*mNext)(mlast,last);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
inline void DynamicalExpression<Expr>::operator()(size_t mlast) const
|
|
|
|
{
|
|
|
|
(*mNext)(mlast);
|
2018-08-07 23:15:31 +02:00
|
|
|
}
|
|
|
|
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
} // namespace MultiArrayHelper
|
|
|
|
|
|
|
|
#endif
|