cnorxz/src/include/pack_num.h

155 lines
4.9 KiB
C
Raw Normal View History

// -*- C++ -*-
2017-08-04 11:27:47 +02:00
#ifndef __pack_num_h__
#define __pack_num_h__
#include <cstdlib>
2017-12-18 11:19:04 +01:00
//#include <type_traits>
#include <tuple>
2017-12-18 11:19:04 +01:00
#include <ostream>
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
namespace MultiArrayHelper
{
template <bool ISSTATIC>
struct Application
{
template <class OpFunction, typename T, typename... Ts>
static inline T apply(std::shared_ptr<OpFunction> f, T a, Ts... as)
{
return (*f)(a, as...);
}
};
template <>
struct Application<true>
{
template <class OpFunction, typename T, typename... Ts>
static inline T apply(std::shared_ptr<OpFunction> f, T a, Ts... as)
{
return OpFunction::apply(a, as...);
}
};
template <size_t N>
struct PackNum
{
2017-09-11 12:54:24 +02:00
template <typename... T>
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
template <class... Ops>
2018-02-13 21:36:41 +01:00
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
2018-02-14 00:38:44 +01:00
-> decltype(PackNum<N-1>::mkSteps(ii, otp).extend( std::get<N>(otp).rootSteps(ii)) )
{
2018-02-14 00:38:44 +01:00
return PackNum<N-1>::mkSteps(ii, otp).extend( 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 22:38:46 +01:00
std::get<N>(out) = second.rootSteps( std::get<N>(siar) );
PackNum<N-1>::mkExt(out, siar, second);
}
2018-02-13 15:38:03 +01:00
template <size_t LAST, typename T, class ETuple, class OpTuple, class OpFunction, typename... Args>
static inline T mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
{
2018-02-13 15:38:03 +01:00
typedef typename std::remove_reference<decltype(std::get<N>(ops))>::type NextOpType;
static_assert(LAST > NextOpType::SIZE, "inconsistent array positions");
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
2018-02-14 00:38:44 +01:00
return PackNum<N-1>::template mkOpExpr<NEXT,T,ETuple,OpTuple,OpFunction,T,Args...>
( f, pos, ops, std::get<N>(ops).get(Getter<NEXT>::template getX<ETuple>( pos )), args...);
}
template <class OpTuple, class Expr>
2018-03-05 21:52:12 +01:00
static auto mkLoop( const OpTuple& ot, Expr exp )
2018-02-14 00:38:44 +01:00
-> decltype(std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) ))
{
return std::get<N>(ot).loop( PackNum<N-1>::mkLoop(ot,exp) );
}
template <typename T, class Op, class... SRanges>
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
const ContainerIndex<T,typename SRanges::IndexType...>& index,
const Op& op, size_t total = 1)
{
const size_t tmp =
op.rootSteps(reinterpret_cast<std::intptr_t>
( index.template getPtr<N>().get() ) )
.val();
std::get<N+1>(blocks) = tmp;
PackNum<N-1>::template mkSliceBlocks<T,Op,SRanges...>(blocks, index, op, total * tmp);
}
};
template<>
struct PackNum<0>
{
2017-09-11 12:54:24 +02:00
template <typename... T>
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);
}
template <class... Ops>
2018-02-13 21:36:41 +01:00
static auto mkSteps(std::intptr_t ii, const std::tuple<Ops...>& otp)
-> 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-02-13 15:38:03 +01:00
template <size_t LAST, typename T, class ETuple, class OpTuple, class OpFunction, typename... Args>
static inline T mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, const Args&... args)
{
2018-02-14 00:38:44 +01:00
typedef typename std::remove_reference<decltype(std::get<0>(ops))>::type NextOpType;
static constexpr size_t NEXT = LAST - NextOpType::SIZE;
static_assert(NEXT == 0, "inconsistent array positions");
return Application<OpFunction::FISSTATIC>::apply(f, std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
//return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX<ETuple>( pos )), args...);
}
template <class OpTuple, class Expr>
2018-03-05 21:52:12 +01:00
static auto mkLoop( const OpTuple& ot, Expr exp )
2018-02-14 00:38:44 +01:00
-> decltype(std::get<0>(ot).loop( exp ))
{
return std::get<0>(ot).loop( exp );
}
template <typename T, class Op, class... SRanges>
static void mkSliceBlocks(std::array<size_t, sizeof...(SRanges)+1>& blocks,
const ContainerIndex<T,typename SRanges::IndexType...>& index,
const Op& op, size_t total = 1)
{
const size_t tmp =
op.rootSteps(reinterpret_cast<std::intptr_t>
( index.template getPtr<0>().get() ) )
.val();
std::get<1>(blocks) = tmp;
std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!!
}
};
} // end namespace MultiArrayHelper
2017-08-04 11:27:47 +02:00
#endif