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-09 11:37:26 +01:00
|
|
|
#include "xfor/for_utils.h"
|
2018-01-15 14:56:22 +01:00
|
|
|
#include "xfor/for_type.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
|
|
|
|
|
|
|
template <ForType FT = ForType::DEFAULT>
|
|
|
|
struct PosForward
|
|
|
|
{
|
|
|
|
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 value(size_t last, size_t max, size_t pos)
|
|
|
|
{
|
|
|
|
return last;
|
|
|
|
}
|
|
|
|
};
|
2018-01-08 18:38:13 +01:00
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT = ForType::DEFAULT>
|
2018-01-05 13:56:16 +01:00
|
|
|
class For
|
|
|
|
{
|
2018-01-13 18:07:52 +01:00
|
|
|
private:
|
|
|
|
For() = default;
|
|
|
|
//For(const For& in) = default;
|
|
|
|
//For& operator=(const For& in) = default;
|
|
|
|
|
|
|
|
const IndexClass* mIndPtr;
|
|
|
|
Expr mExpr;
|
|
|
|
decltype(mExpr.rootSteps()) mExt;
|
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
public:
|
|
|
|
|
2018-01-13 18:07:52 +01:00
|
|
|
static size_t layer() { return Expr::layer() + 1; }
|
|
|
|
static const size_t LAYER = Expr::LAYER + 1;
|
|
|
|
static const size_t SIZE = std::remove_reference<Expr>::type::SIZE;
|
|
|
|
|
|
|
|
typedef decltype(mExpr.rootSteps()) ETuple;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
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-01-13 18:07:52 +01:00
|
|
|
Expr&& expr);
|
2018-01-05 13:56:16 +01:00
|
|
|
|
2018-01-13 18:07:52 +01:00
|
|
|
For(const IndexClass* indPtr,
|
|
|
|
Expr&& expr);
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-01-07 22:33:34 +01:00
|
|
|
|
2018-01-13 18:07:52 +01:00
|
|
|
inline void operator()(size_t mlast, const ETuple& last) const;
|
2018-01-09 17:24:10 +01:00
|
|
|
inline void operator()(size_t mlast = 0) const;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
|
|
|
ETuple rootSteps(std::intptr_t iPtrNum = 0) const;
|
|
|
|
|
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>
|
|
|
|
size_t exceptMax(size_t max) { return max; }
|
|
|
|
|
|
|
|
template <>
|
|
|
|
size_t exceptMax<1>(size_t max) { return 1; }
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
|
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-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-01-13 18:07:52 +01:00
|
|
|
Expr&& expr) :
|
2018-01-14 19:15:05 +01:00
|
|
|
mIndPtr(indPtr.get()), mExpr(expr),
|
2018-01-15 14:56:22 +01:00
|
|
|
mExt(expr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr.get() )))
|
|
|
|
{
|
|
|
|
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-01-13 18:07:52 +01:00
|
|
|
Expr&& expr) :
|
2018-01-14 19:15:05 +01:00
|
|
|
mIndPtr(indPtr), mExpr(std::forward<Expr>( expr )),
|
2018-01-15 14:56:22 +01:00
|
|
|
mExt(expr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ))
|
|
|
|
{
|
|
|
|
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,
|
|
|
|
const ETuple& last) const
|
2018-01-05 13:56:16 +01:00
|
|
|
{
|
|
|
|
auto& ind = *mIndPtr;
|
2018-01-15 14:56:22 +01:00
|
|
|
//std::cout << mIndPtr << std::endl;
|
2018-01-13 18:07:52 +01:00
|
|
|
const size_t max = ind.max(); // blocking
|
|
|
|
for(size_t pos = ind.pos(); pos != max; ++pos){
|
2018-01-15 14:56:22 +01:00
|
|
|
//const size_t mnpos = mlast * max + pos;
|
|
|
|
const size_t mnpos = PosForward<FT>::value(mlast, max, pos);
|
2018-01-13 18:07:52 +01:00
|
|
|
const ETuple npos = std::move( XFPackNum<SIZE-1>::mkPos(pos, mExt, last) );
|
2018-01-09 17:24:10 +01:00
|
|
|
mExpr(mnpos, npos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-01-13 18:07:52 +01:00
|
|
|
const ETuple last;
|
2018-01-09 17:24:10 +01:00
|
|
|
auto& ind = *mIndPtr;
|
2018-01-15 14:56:22 +01:00
|
|
|
//std::cout << mIndPtr << std::endl;
|
2018-01-13 18:07:52 +01:00
|
|
|
const size_t max = ind.max(); // blocking
|
|
|
|
for(size_t pos = ind.pos(); pos != max; ++pos){
|
2018-01-15 14:56:22 +01:00
|
|
|
//const size_t mnpos = mlast * max + pos;
|
|
|
|
const size_t mnpos = PosForward<FT>::value(mlast, max, pos);
|
2018-01-13 18:07:52 +01:00
|
|
|
const ETuple npos = std::move( XFPackNum<SIZE-1>::mkPos(pos, mExt, last) );
|
2018-01-08 18:38:13 +01:00
|
|
|
mExpr(mnpos, npos);
|
2018-01-05 13:56:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 14:56:22 +01:00
|
|
|
template <class IndexClass, class Expr, ForType FT>
|
|
|
|
typename For<IndexClass,Expr,FT>::ETuple For<IndexClass,Expr,FT>::rootSteps(std::intptr_t iPtrNum) const
|
2018-01-13 18:07:52 +01:00
|
|
|
{
|
|
|
|
return mExpr.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
} // namespace MultiArrayHelper
|
|
|
|
|
|
|
|
#endif
|