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, class... Ops>
|
2018-01-05 13:56:16 +01:00
|
|
|
class For
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
static size_t layer() { return typename Expr::layer() + 1; }
|
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
For(For&& in) = default;
|
|
|
|
For& operator=(For&& in) = default;
|
|
|
|
|
|
|
|
template <typename... Args>
|
2018-01-08 18:38:13 +01:00
|
|
|
For(const std::shared_ptr<IndexClass>& indPtr,
|
|
|
|
std::tuple<to_size_t<Ops>...>&& ext, const Args&... args);
|
2018-01-05 13:56:16 +01:00
|
|
|
|
2018-01-08 18:38:13 +01:00
|
|
|
For(const std::shared_ptr<IndexClass>& indPtr,
|
|
|
|
Expr&& expr, std::tuple<to_size_t<Ops>...>&& ext);
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
template <typename... Args>
|
|
|
|
For(IndexClass* indPtr,
|
|
|
|
std::tuple<to_size_t<Ops>...>&& ext, const Args&... args);
|
|
|
|
|
|
|
|
For(IndexClass* indPtr,
|
|
|
|
Expr&& expr, std::tuple<to_size_t<Ops>...>&& ext);
|
|
|
|
|
2018-01-07 22:33:34 +01:00
|
|
|
|
2018-01-08 18:38:13 +01:00
|
|
|
inline void operator()(size_t mlast, const std::tuple<to_size_t<Ops>...>& last) const;
|
2018-01-09 17:24:10 +01:00
|
|
|
inline void operator()(size_t mlast = 0) const;
|
2018-01-05 13:56:16 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
For() = default;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
IndexClass* mIndPtr;
|
2018-01-08 18:38:13 +01:00
|
|
|
const Expr mExpr;
|
|
|
|
const std::tuple<to_size_t<Ops>...> mExt;
|
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-08 18:38:13 +01:00
|
|
|
|
2018-01-05 13:56:16 +01:00
|
|
|
} // namespace MultiArrayHelper
|
|
|
|
|
|
|
|
/* ========================= *
|
|
|
|
* --- TEMPLATE CODE --- *
|
|
|
|
* ========================= */
|
|
|
|
|
|
|
|
namespace MultiArrayHelper
|
|
|
|
{
|
|
|
|
|
2018-01-08 18:38:13 +01:00
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
2018-01-05 13:56:16 +01:00
|
|
|
template <typename... Args>
|
2018-01-08 18:38:13 +01:00
|
|
|
For<IndexClass,Expr,Ops...>::For(const std::shared_ptr<IndexClass>& indPtr,
|
|
|
|
std::tuple<to_size_t<Ops>...>&& ext,
|
|
|
|
const Args&... args) :
|
2018-01-09 17:24:10 +01:00
|
|
|
mIndPtr(indPtr.get()), mExpr(args...), mExt(ext) {}
|
2018-01-05 13:56:16 +01:00
|
|
|
|
2018-01-08 18:38:13 +01:00
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
|
|
|
For<IndexClass,Expr,Ops...>::For(const std::shared_ptr<IndexClass>& indPtr,
|
|
|
|
Expr&& expr, std::tuple<to_size_t<Ops>...>&& ext) :
|
2018-01-09 17:24:10 +01:00
|
|
|
mIndPtr(indPtr.get()), mExpr(expr), mExt(ext) {}
|
|
|
|
|
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
|
|
|
template <typename... Args>
|
|
|
|
For<IndexClass,Expr,Ops...>::For(IndexClass* indPtr,
|
|
|
|
std::tuple<to_size_t<Ops>...>&& ext,
|
|
|
|
const Args&... args) :
|
|
|
|
mIndPtr(indPtr), mExpr(args...), mExt(ext) {}
|
2018-01-09 22:38:46 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
|
|
|
For<IndexClass,Expr,Ops...>::For(IndexClass* indPtr,
|
|
|
|
Expr&& expr, std::tuple<to_size_t<Ops>...>&& ext) :
|
2018-01-08 18:38:13 +01:00
|
|
|
mIndPtr(indPtr), mExpr(expr), mExt(ext) {}
|
2018-01-07 22:33:34 +01:00
|
|
|
|
2018-01-08 18:38:13 +01:00
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
|
|
|
inline void For<IndexClass,Expr,Ops...>::operator()(size_t mlast,
|
|
|
|
const std::tuple<to_size_t<Ops>...>& last) const
|
2018-01-05 13:56:16 +01:00
|
|
|
{
|
2018-01-08 18:38:13 +01:00
|
|
|
static const size_t opNum = sizeof...(Ops);
|
2018-01-05 13:56:16 +01:00
|
|
|
auto& ind = *mIndPtr;
|
2018-01-09 17:24:10 +01:00
|
|
|
const size_t max = exceptMax<For<IndexClass,Expr,Ops...>::layer()>( ind.max() ); // blocking
|
|
|
|
for(ind = 0; ind.pos() != max; ++ind){
|
|
|
|
const size_t mnpos = mlast * max + ind.pos();
|
|
|
|
const std::tuple<to_size_t<Ops>...> npos = std::move( XFPackNum<opNum-1>::mkPos(ind, mExt, last) );
|
|
|
|
mExpr(mnpos, npos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class IndexClass, class Expr, class... Ops>
|
|
|
|
inline void For<IndexClass,Expr,Ops...>::operator()(size_t mlast) const
|
|
|
|
{
|
|
|
|
static const size_t opNum = sizeof...(Ops);
|
|
|
|
std::tuple<to_size_t<Ops>...> last(to_size_t<Ops>(0)...);
|
|
|
|
auto& ind = *mIndPtr;
|
|
|
|
const size_t max = exceptMax<For<IndexClass,Expr,Ops...>::layer()>( ind.max() ); // blocking
|
2018-01-05 13:56:16 +01:00
|
|
|
for(ind = 0; ind.pos() != max; ++ind){
|
2018-01-08 18:38:13 +01:00
|
|
|
const size_t mnpos = mlast * max + ind.pos();
|
2018-01-09 11:37:26 +01:00
|
|
|
const std::tuple<to_size_t<Ops>...> npos = std::move( XFPackNum<opNum-1>::mkPos(ind, mExt, last) );
|
2018-01-08 18:38:13 +01:00
|
|
|
mExpr(mnpos, npos);
|
2018-01-05 13:56:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace MultiArrayHelper
|
|
|
|
|
|
|
|
#endif
|