rewrite Operation::get (not final solution)
This commit is contained in:
parent
9d85f8df46
commit
44f6149a23
3 changed files with 85 additions and 57 deletions
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
#include "multi_array_operation.h"
|
#include "multi_array_operation.h"
|
||||||
|
#include "xfor/exttype.h"
|
||||||
|
|
||||||
|
|
||||||
/* ========================= *
|
/* ========================= *
|
||||||
* --- TEMPLATE CODE --- *
|
* --- TEMPLATE CODE --- *
|
||||||
|
@ -978,16 +980,38 @@ namespace MultiArrayTools
|
||||||
mOps(ops...),
|
mOps(ops...),
|
||||||
mF(ff)
|
mF(ff)
|
||||||
{
|
{
|
||||||
static_assert( not FISSTATIC, "using instance of function supposed to be static" );
|
static_assert( not FISSTATIC, "using instance of static function" );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
template <size_t I, size_t J, class ET>
|
||||||
|
inline auto Operation<T,OpFunction,Ops...>::getSubX(ET pos) const
|
||||||
|
{
|
||||||
|
// somehow get rid of the second condition (should NOT be needed if everything is correct)
|
||||||
|
if constexpr(I == J or sizeof...(Ops)-1 == I){
|
||||||
|
return std::get<J>(mOps.mOps).get(pos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typedef typename std::remove_reference<decltype(std::get<I>(mOps.mOps))>::type
|
||||||
|
NextOpType;
|
||||||
|
return getSubX<I+1,J>(getX<NextOpType::SIZE>(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
template <class ET>
|
template <class ET>
|
||||||
inline auto Operation<T,OpFunction,Ops...>::get(ET pos) const
|
inline auto Operation<T,OpFunction,Ops...>::get(ET pos) const
|
||||||
{
|
{
|
||||||
typedef std::tuple<Ops...> OpTuple;
|
auto cre = [&](auto... args)
|
||||||
return PackNum<sizeof...(Ops)-1>::
|
{
|
||||||
template mkOpExpr<SIZE,ET,OpTuple,OpFunction>(mF, pos, mOps.mOps);
|
if constexpr(OpFunction::FISSTATIC){
|
||||||
|
return OpFunction::apply(args...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (*mF)(args...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return MA_CFOR2(i,0,sizeof...(Ops),i+1,return getSub<i>(pos);,cre);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
|
|
|
@ -804,6 +804,12 @@ namespace MultiArrayTools
|
||||||
Operation(const Ops&... ops);
|
Operation(const Ops&... ops);
|
||||||
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
|
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
|
||||||
|
|
||||||
|
template <size_t I, size_t J, class ET>
|
||||||
|
inline auto getSubX(ET pos) const;
|
||||||
|
|
||||||
|
template <size_t J, class ET>
|
||||||
|
inline auto getSub(ET pos) const { return getSubX<0,J>(pos); }
|
||||||
|
|
||||||
template <class ET>
|
template <class ET>
|
||||||
inline auto get(ET pos) const;
|
inline auto get(ET pos) const;
|
||||||
|
|
||||||
|
|
|
@ -6,67 +6,65 @@
|
||||||
|
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
|
template <size_t BEG, size_t END, int OFF, typename Incr, typename F, typename Conc>
|
||||||
template <size_t BEG, size_t END, int OFF>
|
inline auto sfor(Incr incr, F f, Conc conc)
|
||||||
struct sfor
|
|
||||||
{
|
{
|
||||||
template <typename Incr, typename F, typename Conc>
|
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
||||||
static inline auto exec(Incr incr, F f, Conc conc)
|
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
||||||
{
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
// "this turns out to be a static endless loop");
|
||||||
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
auto tmp = f(idxm);
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
if constexpr(incr(idx) == END){
|
||||||
// "this turns out to be a static endless loop");
|
return tmp;
|
||||||
auto tmp = f(idxm);
|
|
||||||
if constexpr(incr(idx) == END){
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return conc(tmp, sfor<incr(idx),END,OFF>::exec(incr,f,conc));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return conc(tmp, sfor<incr(idx),END,OFF>(incr,f,conc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Incr, typename F, typename Conc, typename Arg>
|
template <size_t BEG, size_t END, int OFF, typename Incr, typename F, typename Conc, typename Arg>
|
||||||
static inline auto exec(Incr incr, F f, Conc conc, const Arg& arg)
|
inline auto sfor(Incr incr, F f, Conc conc, const Arg& arg)
|
||||||
{
|
{
|
||||||
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
||||||
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
// "this turns out to be a static endless loop");
|
// "this turns out to be a static endless loop");
|
||||||
auto tmp = f(idxm);
|
auto tmp = f(idxm);
|
||||||
if constexpr(incr(idx) == END){
|
if constexpr(incr(idx) == END){
|
||||||
return conc(tmp, arg);
|
return conc(tmp, arg);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return conc(tmp, sfor<incr(idx),END,OFF>::exec(incr,f,conc,arg));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return conc(tmp, sfor<incr(idx),END,OFF>(incr,f,conc,arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Incr, typename F, typename Create, typename... Args>
|
template <size_t BEG, size_t END, int OFF, typename Incr, typename F, typename Create, typename... Args>
|
||||||
static inline auto unpack(Incr incr, F f, Create create, const Args&... args)
|
inline auto unpack(Incr incr, F f, Create create, const Args&... args)
|
||||||
{
|
{
|
||||||
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
||||||
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
||||||
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
// "this turns out to be a static endless loop");
|
// "this turns out to be a static endless loop");
|
||||||
auto tmp = f(idxm);
|
if constexpr(BEG == END){
|
||||||
if constexpr(BEG == END){
|
return create(args...);
|
||||||
return create(args...);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return sfor<incr(idx),END,OFF>::unpack(incr, f, create, args..., tmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
else {
|
||||||
|
auto tmp = f(idxm);
|
||||||
|
return unpack<incr(idx),END,OFF>(incr, f, create, args..., tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MA_SFOR(i,beg,end,incr,expr) sfor<beg,end,0>::exec([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
#define MA_SFOR(i,beg,end,incr,expr) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
||||||
#define MA_SCFOR(i,beg,end,incr,expr,conc) sfor<beg,end,0>::exec([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
#define MA_SCFOR(i,beg,end,incr,expr,conc) sfor<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
||||||
#define MA_SRFOR(i,beg,end,decr,expr) sfor<beg,end,-1>::exec([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
#define MA_SRFOR(i,beg,end,decr,expr) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
||||||
#define MA_SCRFOR(i,beg,end,decr,expr,conc) sfor<beg,end,-1>::exec([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
#define MA_SCRFOR(i,beg,end,decr,expr,conc) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); })
|
||||||
#define MA_SCRAFOR(i,beg,end,decr,expr,conc,arg) sfor<beg,end,-1>::exec([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }, arg)
|
#define MA_SCRAFOR(i,beg,end,decr,expr,conc,arg) sfor<beg,end,-1>([&](auto i) constexpr { return decr; }, [&](auto i){ return expr; }, [&](auto f, auto next) { return f.conc(next); }, arg)
|
||||||
#define MA_CFOR(i,beg,end,incr,expr,cre) sfor<beg,end,0>::unpack([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, [&](auto... args) { return cre(args...); })
|
#define MA_CFOR(i,beg,end,incr,expr,cre) unpack<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, [&](auto... args) { return cre(args...); })
|
||||||
|
#define MA_CFOR2(i,beg,end,incr,expr,cre) unpack<beg,end,0>([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, cre)
|
||||||
|
|
||||||
#define MA_SCFOR_X(i,beg,end,incr,expr,conc) sfor<beg,end,0>::exec([](auto i) constexpr { return incr; }, [](auto i){ return expr; }, [](auto f, auto next) { return f.conc(next); })
|
#define MA_SCFOR_X(i,beg,end,incr,expr,conc) sfor<beg,end,0>([](auto i) constexpr { return incr; }, [](auto i){ return expr; }, [](auto f, auto next) { return f.conc(next); })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue