cnorxz/src/include/xfor/xfor.h

511 lines
14 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
namespace MultiArrayHelper
{
// 'HIDDEN FOR' CLASS for nested for loops in contractions a.s.o.
// (NO COUNTING OF MASTER POSITION !!!!!)
2018-10-27 14:58:34 +02:00
typedef std::pair<size_t const*,size_t> DExt;
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;
2018-10-23 20:02:01 +02:00
virtual void operator()(size_t mlast, DExt last) const = 0;
virtual void operator()(size_t mlast = 0) const = 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
{
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
2018-10-27 14:58:34 +02:00
template <class Expr>
class ExpressionHolder : public ExpressionBase
{
private:
ExpressionHolder() = default;
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;
ExpressionHolder(const ExpressionHolder& in) = default;
ExpressionHolder(ExpressionHolder&& in) = default;
ExpressionHolder& operator=(const ExpressionHolder& in) = default;
ExpressionHolder& operator=(ExpressionHolder&& in) = default;
ExpressionHolder(Expr expr);
inline void operator()(size_t mlast, DExt last) const override final;
inline void operator()(size_t mlast, ExtType last) const;
inline void operator()(size_t mlast = 0) const 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-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
2018-10-23 20:02:01 +02:00
inline void operator()(size_t mlast, DExt last) const override final;
inline void operator()(size_t mlast, ExtType last) const;
inline void operator()(size_t mlast = 0) const 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
};
2018-01-08 18:38:13 +01:00
template <class IndexClass, class Expr, ForType FT>
2018-10-23 20:02:01 +02:00
class For : public ExpressionBase
2018-01-05 13:56:16 +01:00
{
private:
For() = default;
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;
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);
2018-10-23 20:02:01 +02:00
inline void operator()(size_t mlast, DExt last) const override final;
inline void operator()(size_t mlast, ExtType last) const;
inline void operator()(size_t mlast = 0) const override final;
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; }
2018-10-23 20:02:01 +02:00
class DynamicalExpression : public ExpressionBase
{
private:
DynamicalExpression() = default;
2018-10-23 20:02:01 +02:00
std::shared_ptr<ExpressionBase> mNext;
public:
DynamicalExpression(const DynamicalExpression& in) = default;
DynamicalExpression(DynamicalExpression&& in) = default;
DynamicalExpression& operator=(const DynamicalExpression& in) = default;
DynamicalExpression& operator=(DynamicalExpression&& in) = default;
2018-10-27 14:58:34 +02:00
DynamicalExpression(const std::shared_ptr<ExpressionBase>& next) :
mNext(next)
{}
2018-10-23 20:02:01 +02:00
inline void operator()(size_t mlast, DExt last) const override final;
inline void operator()(size_t mlast = 0) const 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
};
2018-01-05 13:56:16 +01:00
} // namespace MultiArrayHelper
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
#include <iostream>
2018-01-05 13:56:16 +01:00
namespace MultiArrayHelper
{
/*****************
* F o r *
*****************/
template <class IndexClass, class Expr, ForType FT>
For<IndexClass,Expr,FT>::For(const std::shared_ptr<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 )))
{
assert(mIndPtr != nullptr);
//VCHECK(mIndPtr->id());
//VCHECK(mIndPtr->max());
}
template <class IndexClass, class Expr, ForType FT>
For<IndexClass,Expr,FT>::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 )))
{
assert(mIndPtr != nullptr);
//VCHECK(mIndPtr->id());
//VCHECK(mIndPtr->max());
}
2018-10-23 20:02:01 +02:00
template <class IndexClass, class Expr, ForType FT>
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast, DExt last) const
{
2018-10-27 14:58:34 +02:00
operator()(mlast, *reinterpret_cast<ExtType const*>(last.first));
2018-10-23 20:02:01 +02: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){
//const size_t mnpos = PosForward<FT>::value(mlast, 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);
}
}
template <class IndexClass, class Expr, ForType FT>
inline void For<IndexClass,Expr,FT>::operator()(size_t mlast) const
{
2018-02-13 16:54:13 +01:00
typedef typename IndexClass::RangeType RangeType;
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){
//const size_t mnpos = PosForward<FT>::value(mlast, 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
template <class IndexClass, class Expr, ForType FT>
auto For<IndexClass,Expr,FT>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
return mExpr.rootSteps(iPtrNum);
}
template <class IndexClass, class Expr, ForType FT>
auto For<IndexClass,Expr,FT>::extension() const
-> ExtType
{
return mExt;
}
template <class IndexClass, class Expr, ForType FT>
2018-10-27 14:58:34 +02:00
DExt For<IndexClass,Expr,FT>::dRootSteps(std::intptr_t iPtrNum) const
2018-10-23 20:02:01 +02:00
{
mRootSteps = rootSteps(iPtrNum);
2018-10-27 14:58:34 +02:00
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, ForType FT>
DExt For<IndexClass,Expr,FT>::dExtension() const
{
2018-10-27 14:58:34 +02:00
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
/************************
* 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>
inline void SingleExpression<IndexClass,Expr>::operator()(size_t mlast, DExt last) const
{
2018-10-27 14:58:34 +02:00
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,
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-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>
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-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
{
mRootSteps = rootSteps(iPtrNum);
2018-10-27 14:58:34 +02:00
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
{
2018-10-27 14:58:34 +02:00
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
/***************************
* DynamicalExpression *
***************************/
2018-10-27 14:58:34 +02:00
inline void DynamicalExpression::operator()(size_t mlast, DExt last) const
{
(*mNext)(mlast,last);
}
inline void DynamicalExpression::operator()(size_t mlast) const
{
(*mNext)(mlast);
}
inline DExt DynamicalExpression::dRootSteps(std::intptr_t iPtrNum) const
{
return mNext->dRootSteps(iPtrNum);
}
inline DExt DynamicalExpression::dExtension() const
{
return mNext->dExtension();
}
/************************
* ExpressionHolder *
************************/
template <class Expr>
2018-10-27 14:58:34 +02:00
ExpressionHolder<Expr>::ExpressionHolder(Expr expr) : mExpr(expr) {}
template <class Expr>
2018-10-27 14:58:34 +02:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast, DExt last) const
2018-08-07 23:15:31 +02:00
{
2018-10-27 14:58:34 +02:00
mExpr(mlast,last);
}
template <class Expr>
2018-10-27 14:58:34 +02:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast, ExtType last) const
{
2018-10-27 14:58:34 +02:00
mExpr(mlast,last);
2018-08-07 23:15:31 +02:00
}
2018-10-23 20:02:01 +02:00
template <class Expr>
2018-10-27 14:58:34 +02:00
inline void ExpressionHolder<Expr>::operator()(size_t mlast) const
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 mExpr.rootSteps(iPtrNum);
}
template <class Expr>
auto ExpressionHolder<Expr>::extension() const
-> ExtType
{
return mExpr.extension();
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