2017-07-27 14:48:41 +02:00
|
|
|
// -*- C++ -*-
|
|
|
|
|
2017-08-04 11:27:47 +02:00
|
|
|
#ifndef __pack_num_h__
|
|
|
|
#define __pack_num_h__
|
|
|
|
|
2017-07-27 14:48:41 +02:00
|
|
|
#include <cstdlib>
|
2017-12-18 11:19:04 +01:00
|
|
|
//#include <type_traits>
|
2017-07-27 14:48:41 +02:00
|
|
|
#include <tuple>
|
2017-12-18 11:19:04 +01:00
|
|
|
#include <ostream>
|
2017-07-27 14:48:41 +02:00
|
|
|
|
2017-08-04 11:27:47 +02:00
|
|
|
#include "base_def.h"
|
2018-02-12 18:26:56 +01:00
|
|
|
#include "xfor/exttype.h"
|
2017-08-04 11:27:47 +02:00
|
|
|
|
2017-07-27 14:48:41 +02:00
|
|
|
namespace MultiArrayHelper
|
|
|
|
{
|
2017-12-17 17:40:55 +01:00
|
|
|
|
2017-07-27 14:48:41 +02:00
|
|
|
template <size_t N>
|
|
|
|
struct PackNum
|
|
|
|
{
|
2017-12-18 11:19:04 +01:00
|
|
|
|
2017-08-30 17:56:38 +02:00
|
|
|
template <class... Ops>
|
|
|
|
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
|
|
|
|
const std::tuple<Ops...>& ops,
|
2017-12-22 14:01:26 +01:00
|
|
|
std::shared_ptr<VIWB> idxPtr, bool init)
|
2017-08-30 17:56:38 +02:00
|
|
|
{
|
2017-12-22 14:01:26 +01:00
|
|
|
auto subvec = std::move( std::get<N>(ops).block(idxPtr, init) );
|
2017-08-30 17:56:38 +02:00
|
|
|
btv.insert(btv.end(), subvec.begin(), subvec.end() );
|
2017-12-22 14:01:26 +01:00
|
|
|
PackNum<N-1>::makeBlockTypeVec(btv, ops, idxPtr, init);
|
2017-08-30 17:56:38 +02:00
|
|
|
}
|
2017-09-11 12:54:24 +02:00
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
template <class... Ops>
|
|
|
|
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
|
|
|
|
const std::tuple<Ops...>& ops,
|
|
|
|
const IndexInfo* idxPtr, bool init)
|
|
|
|
{
|
|
|
|
auto subvec = std::move( std::get<N>(ops).block(idxPtr, init) );
|
|
|
|
btv.insert(btv.end(), subvec.begin(), subvec.end() );
|
|
|
|
PackNum<N-1>::makeBlockTypeVec(btv, ops, idxPtr, init);
|
|
|
|
}
|
|
|
|
|
2017-12-17 17:40:55 +01:00
|
|
|
template <typename T, class Func, class ArgTuple, class... Args>
|
2017-12-22 14:15:09 +01:00
|
|
|
static void unpackArgs(BlockResult<T>& res, const ArgTuple& tp, const Args&... args)
|
2017-12-17 17:40:55 +01:00
|
|
|
{
|
2017-12-22 14:15:09 +01:00
|
|
|
PackNum<N-1>::template unpackArgs<T,Func>(res, tp, std::get<N>(tp).get(), args...);
|
2017-12-17 17:40:55 +01:00
|
|
|
}
|
|
|
|
|
2017-09-11 12:54:24 +02:00
|
|
|
template <typename... T>
|
2018-01-09 17:24:10 +01:00
|
|
|
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
|
|
|
{
|
2017-09-11 12:54:24 +02:00
|
|
|
out << std::get<sizeof...(T)-N-1>(tp) << ", ";
|
|
|
|
PackNum<N-1>::printTuple(out, tp);
|
|
|
|
}
|
2017-12-05 17:31:57 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <class... Ops>
|
2018-01-14 19:15:05 +01:00
|
|
|
static auto mkStepTuple(std::intptr_t ii, std::tuple<Ops const&...> otp)
|
2018-01-09 17:24:10 +01:00
|
|
|
-> decltype(std::tuple_cat( PackNum<N-1>::mkStepTuple(ii, otp), std::get<N>(otp).rootSteps(ii) ))
|
|
|
|
{
|
|
|
|
return std::tuple_cat( PackNum<N-1>::mkStepTuple(ii, otp), std::get<N>(otp).rootSteps(ii) );
|
|
|
|
}
|
2018-01-09 22:38:46 +01:00
|
|
|
|
|
|
|
template <class RootStepTuple, class IndexClass, class OpClass>
|
|
|
|
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
|
|
|
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
|
|
|
const OpClass& second)
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-01-09 22:38:46 +01:00
|
|
|
std::get<N>(out) = second.rootSteps( std::get<N>(siar) );
|
|
|
|
PackNum<N-1>::mkExt(out, siar, second);
|
|
|
|
}
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
// call with -2 (instead of -1)
|
2018-02-12 18:26:56 +01:00
|
|
|
template <typename T, class ETuple, class OpTuple, class OpFunction, typename... Args>
|
|
|
|
static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops, const Args&... args)
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 18:26:56 +01:00
|
|
|
|
|
|
|
return PackNum<N-1>::template mkOpExpr<ETuple,OpTuple,OpFunction,decltype(std::get<N>(ops)),Args...>
|
|
|
|
( pos, ops, std::get<N>(ops).get(Getter<>::template get<ETuple>( pos )), args...);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class OpTuple, class Expr>
|
|
|
|
static auto mkLoop( const OpTuple& ot, Expr&& exp )
|
|
|
|
-> decltype(std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) ))&&
|
|
|
|
{
|
|
|
|
return std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) );
|
|
|
|
}
|
2017-07-27 14:48:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PackNum<0>
|
|
|
|
{
|
2017-08-11 15:26:10 +02:00
|
|
|
|
|
|
|
template <typename T, class Func, class ArgTuple, class... Args>
|
2017-12-22 14:15:09 +01:00
|
|
|
static void unpackArgs(BlockResult<T>& res, const ArgTuple& tp, const Args&... args)
|
2017-08-11 15:26:10 +02:00
|
|
|
{
|
|
|
|
static_assert(sizeof...(Args) == std::tuple_size<ArgTuple>::value-1,
|
|
|
|
"inconsistent number of arguments");
|
2017-12-22 14:15:09 +01:00
|
|
|
BlockBinaryOp<T,Func,decltype(std::get<0>(tp).get()), decltype(args)...> f(res);
|
|
|
|
f(std::get<0>(tp).get(), args...);
|
2017-08-11 15:26:10 +02:00
|
|
|
}
|
2017-07-27 20:34:14 +02:00
|
|
|
|
2017-08-30 17:56:38 +02:00
|
|
|
template <class... Ops>
|
|
|
|
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
|
|
|
|
const std::tuple<Ops...>& ops,
|
2017-12-22 14:01:26 +01:00
|
|
|
std::shared_ptr<VIWB> idxPtr, bool init)
|
2017-08-30 17:56:38 +02:00
|
|
|
{
|
2017-12-22 14:01:26 +01:00
|
|
|
auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) );
|
2017-08-30 17:56:38 +02:00
|
|
|
btv.insert(btv.end(), subvec.begin(), subvec.end() );
|
|
|
|
}
|
2017-12-26 15:13:50 +01:00
|
|
|
|
|
|
|
template <class... Ops>
|
|
|
|
static void makeBlockTypeVec(std::vector<std::pair<BlockType,size_t> >& btv,
|
|
|
|
const std::tuple<Ops...>& ops,
|
|
|
|
const IndexInfo* idxPtr, bool init)
|
|
|
|
{
|
|
|
|
auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) );
|
|
|
|
btv.insert(btv.end(), subvec.begin(), subvec.end() );
|
|
|
|
}
|
|
|
|
|
2017-09-11 12:54:24 +02:00
|
|
|
template <typename... T>
|
2018-01-09 17:24:10 +01:00
|
|
|
static void printTuple(std::ostream& out, const std::tuple<T...>& tp)
|
|
|
|
{
|
2017-09-11 12:54:24 +02:00
|
|
|
out << std::get<sizeof...(T)-1>(tp);
|
|
|
|
}
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
template <class... Ops>
|
2018-01-14 19:15:05 +01:00
|
|
|
static auto mkStepTuple(std::intptr_t ii, std::tuple<Ops const&...> otp)
|
2018-01-09 17:24:10 +01:00
|
|
|
-> decltype(std::get<0>(otp).rootSteps(ii))
|
|
|
|
{
|
|
|
|
return std::get<0>(otp).rootSteps(ii);
|
|
|
|
}
|
|
|
|
|
2018-01-09 22:38:46 +01:00
|
|
|
template <class RootStepTuple, class IndexClass, class OpClass>
|
|
|
|
static void mkExt(std::array<RootStepTuple,IndexClass::totalDim()>& out,
|
|
|
|
const std::array<std::intptr_t,IndexClass::totalDim()>& siar,
|
|
|
|
const OpClass& second)
|
|
|
|
{
|
|
|
|
std::get<0>(out) = second.rootSteps( std::get<0>(siar) );
|
|
|
|
}
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class ETuple, class OpTuple, class OpFunction, size_t START>
|
2018-02-12 18:26:56 +01:00
|
|
|
static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops)
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 18:26:56 +01:00
|
|
|
static constexpr size_t NEXT = START - SubOpType::SIZE;
|
2018-01-14 22:41:35 +01:00
|
|
|
return OpFunction::apply( std::get<1>(ops).template get<ETuple,START>(pos),
|
|
|
|
std::get<0>(ops).template get<ETuple,NEXT>(pos) );
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class OpTuple, class Expr>
|
|
|
|
static auto mkLoop( const OpTuple& ot, Expr&& exp )
|
|
|
|
-> decltype(std::get<0>(ot).loop( exp ))&&
|
|
|
|
{
|
|
|
|
return std::get<0>(ot).loop( exp );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-27 14:48:41 +02:00
|
|
|
};
|
2017-09-12 18:36:05 +02:00
|
|
|
|
|
|
|
|
2017-07-27 14:48:41 +02:00
|
|
|
|
|
|
|
} // end namespace MultiArrayHelper
|
2017-08-04 11:27:47 +02:00
|
|
|
|
|
|
|
#endif
|