cnorxz/src/xfor/xfor.h

114 lines
2.8 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>
2018-01-09 11:37:26 +01:00
#include "xfor/for_utils.h"
2018-01-05 13:56:16 +01:00
namespace MultiArrayHelper
{
2018-01-08 18:38:13 +01:00
template <class IndexClass, class Expr>
2018-01-05 13:56:16 +01:00
class For
{
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:
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-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,
Expr&& expr);
2018-01-05 13:56:16 +01:00
For(const IndexClass* indPtr,
Expr&& expr);
inline void operator()(size_t mlast, const ETuple& last) const;
inline void operator()(size_t mlast = 0) const;
ETuple rootSteps(std::intptr_t iPtrNum = 0) const;
2018-01-07 16:57:01 +01:00
};
2018-01-05 13:56:16 +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-08 18:38:13 +01:00
2018-01-05 13:56:16 +01:00
} // namespace MultiArrayHelper
/* ========================= *
* --- TEMPLATE CODE --- *
* ========================= */
namespace MultiArrayHelper
{
template <class IndexClass, class Expr>
For<IndexClass,Expr>::For(const std::shared_ptr<IndexClass>& indPtr,
Expr&& expr) :
mIndPtr(indPtr.get()), mExpr(expr),
mExt(expr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr.get() ))) {}
template <class IndexClass, class Expr>
For<IndexClass,Expr>::For(const IndexClass* indPtr,
Expr&& expr) :
mIndPtr(indPtr), mExpr(std::forward<Expr>( expr )),
mExt(expr.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) )) {}
template <class IndexClass, class Expr>
inline void For<IndexClass,Expr>::operator()(size_t mlast,
const ETuple& last) const
2018-01-05 13:56:16 +01:00
{
auto& ind = *mIndPtr;
const size_t max = ind.max(); // blocking
for(size_t pos = ind.pos(); pos != max; ++pos){
const size_t mnpos = mlast * max + pos;
const ETuple npos = std::move( XFPackNum<SIZE-1>::mkPos(pos, mExt, last) );
mExpr(mnpos, npos);
}
}
template <class IndexClass, class Expr>
inline void For<IndexClass,Expr>::operator()(size_t mlast) const
{
const ETuple last;
auto& ind = *mIndPtr;
const size_t max = ind.max(); // blocking
for(size_t pos = ind.pos(); pos != max; ++pos){
const size_t mnpos = mlast * max + pos;
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
}
}
template <class IndexClass, class Expr>
typename For<IndexClass,Expr>::ETuple For<IndexClass,Expr>::rootSteps(std::intptr_t iPtrNum) const
{
return mExpr.rootSteps(iPtrNum);
}
2018-01-05 13:56:16 +01:00
} // namespace MultiArrayHelper
#endif