start replacement PackNum -> SFOR
This commit is contained in:
parent
64c5c2b4f3
commit
1f663e0b76
3 changed files with 56 additions and 125 deletions
|
@ -245,9 +245,10 @@ namespace MultiArrayTools
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
template <typename T, class... Ops>
|
||||||
auto MOp<T,Ops...>::rootSteps(std::intptr_t iPtrNum) const -> ExtType
|
auto MOp<T,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
{
|
{
|
||||||
return RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,iPtrNum);
|
return MA_SCFOR(i,0,sizeof...(Ops),i+1,std::get<i>(mOps).rootSteps(iPtrNum),extend);
|
||||||
|
//return RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,iPtrNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
template <class OpClass, class NextExpr>
|
||||||
|
@ -1011,17 +1012,15 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps))
|
|
||||||
{
|
{
|
||||||
return PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps);
|
return MA_SCFOR(i,0,sizeof...(Ops),i+1,std::get<i>(mOps).rootSteps(iPtrNum),extend);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp ))
|
|
||||||
{
|
{
|
||||||
return PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp );
|
return MA_SCRAFOR(i,sizeof...(Ops),0,i-1,std::get<i>(mOps),loop,exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "xfor/xfor.h"
|
#include "xfor/xfor.h"
|
||||||
#include "type_operations.h"
|
#include "type_operations.h"
|
||||||
|
|
||||||
|
#include "statics/static_for.h"
|
||||||
|
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -105,11 +107,6 @@ namespace MultiArrayTools
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
struct RootSumN
|
struct RootSumN
|
||||||
{
|
{
|
||||||
template <class Op1, class... Ops>
|
|
||||||
struct rs
|
|
||||||
{
|
|
||||||
static constexpr size_t SIZE = Op1::SIZE + RootSumN<N-1>::template rs<Ops...>::SIZE;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class... Exprs>
|
template <class... Exprs>
|
||||||
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
||||||
|
@ -142,11 +139,6 @@ namespace MultiArrayTools
|
||||||
template <>
|
template <>
|
||||||
struct RootSumN<0>
|
struct RootSumN<0>
|
||||||
{
|
{
|
||||||
template <class Op1>
|
|
||||||
struct rs
|
|
||||||
{
|
|
||||||
static constexpr size_t SIZE = Op1::SIZE;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class... Exprs>
|
template <class... Exprs>
|
||||||
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
static inline auto rootSteps(const std::tuple<Exprs...>& etp, std::intptr_t i)
|
||||||
|
@ -175,14 +167,6 @@ namespace MultiArrayTools
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class... Ops>
|
|
||||||
struct RootSum
|
|
||||||
{
|
|
||||||
//static constexpr size_t SIZE = (... + Ops::SIZE);
|
|
||||||
static constexpr size_t SIZE = RootSumN<sizeof...(Ops)-1>::template rs<Ops...>::SIZE;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct SelfIdentity
|
struct SelfIdentity
|
||||||
{
|
{
|
||||||
|
@ -271,46 +255,6 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using IVPlus = IVAccess<T,plus<T>>;
|
using IVPlus = IVAccess<T,plus<T>>;
|
||||||
/*
|
|
||||||
struct IAssign
|
|
||||||
{
|
|
||||||
template <typename T, typename Op, class ExtType>
|
|
||||||
static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
|
|
||||||
{
|
|
||||||
t[pos] = op.get(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
struct IVAssign
|
|
||||||
{
|
|
||||||
template <typename T, typename Op, class ExtType>
|
|
||||||
static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
|
|
||||||
{
|
|
||||||
reinterpret_cast<V*>(t)[pos] = op.template vget<V>(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IPlus
|
|
||||||
{
|
|
||||||
template <typename T, typename Op, class ExtType>
|
|
||||||
static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
|
|
||||||
{
|
|
||||||
t[pos] += op.get(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
struct IVPlus
|
|
||||||
{
|
|
||||||
template <typename T, typename Op, class ExtType>
|
|
||||||
static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
|
|
||||||
{
|
|
||||||
reinterpret_cast<V*>(t)[pos] += op.template vget<V>(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class IOp, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
template <typename T, class IOp, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
||||||
class AssignmentExpr : public ExpressionBase
|
class AssignmentExpr : public ExpressionBase
|
||||||
|
@ -366,7 +310,7 @@ namespace MultiArrayTools
|
||||||
public:
|
public:
|
||||||
static constexpr size_t LAYER = 0;
|
static constexpr size_t LAYER = 0;
|
||||||
static constexpr size_t NHLAYER = 0;
|
static constexpr size_t NHLAYER = 0;
|
||||||
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
static constexpr size_t SIZE = (... + Ops::SIZE);
|
||||||
typedef decltype(RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,0) ) ExtType;
|
typedef decltype(RootSumN<sizeof...(Ops)-1>::rootSteps(mOps,0) ) ExtType;
|
||||||
|
|
||||||
MOp(const Ops&... exprs);
|
MOp(const Ops&... exprs);
|
||||||
|
@ -382,7 +326,7 @@ namespace MultiArrayTools
|
||||||
inline size_t vget(ExtType last) const { return get(last); }
|
inline size_t vget(ExtType last) const { return get(last); }
|
||||||
|
|
||||||
inline MOp& set(ExtType last);
|
inline MOp& set(ExtType last);
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
auto rootSteps(std::intptr_t iPtrNum = 0) const;
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto loop(Expr exp) const
|
auto loop(Expr exp) const
|
||||||
|
@ -822,18 +766,6 @@ namespace MultiArrayTools
|
||||||
T const** data() const { assert(0); return nullptr; }
|
T const** data() const { assert(0); return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
inline constexpr bool isVAble()
|
|
||||||
{
|
|
||||||
return Op::VABLE and std::is_same<T,typename Op::value_type>::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op1, class Op2, class... Ops>
|
|
||||||
inline constexpr bool isVAble()
|
|
||||||
{
|
|
||||||
return Op1::VABLE and std::is_same<T,typename Op1::value_type>::value and isVAble<T,Op2,Ops...>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
||||||
{
|
{
|
||||||
|
@ -843,17 +775,17 @@ namespace MultiArrayTools
|
||||||
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
|
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
|
||||||
typedef OpFunction F;
|
typedef OpFunction F;
|
||||||
|
|
||||||
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
static constexpr size_t SIZE = (... + Ops::SIZE);
|
||||||
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
|
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
|
||||||
static constexpr bool CONT = false;
|
static constexpr bool CONT = false;
|
||||||
static constexpr bool VABLE = isVAble<T,Ops...>();
|
static constexpr bool VABLE =
|
||||||
|
(... and (Ops::VABLE and std::is_same<T,typename Ops::value_type>::value));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::tuple<Ops...> mOps;
|
std::tuple<Ops...> mOps;
|
||||||
std::shared_ptr<OpFunction> mF; // only if non-static
|
std::shared_ptr<OpFunction> mF; // only if non-static
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef decltype(PackNum<sizeof...(Ops)-1>::template mkSteps<Ops...>(0, mOps)) ETuple;
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -867,49 +799,25 @@ namespace MultiArrayTools
|
||||||
template <class ET>
|
template <class ET>
|
||||||
inline Operation& set(ET pos);
|
inline Operation& set(ET pos);
|
||||||
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
auto rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps));
|
|
||||||
|
|
||||||
template <class Expr>
|
template <class Expr>
|
||||||
auto loop(Expr exp) const
|
auto loop(Expr exp) const;
|
||||||
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
|
|
||||||
|
|
||||||
T* data() const { assert(0); return nullptr; }
|
T* data() const { assert(0); return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template <bool FISSTATIC>
|
|
||||||
struct OpMaker
|
|
||||||
{
|
|
||||||
template <class OpFunction, class... Ops>
|
|
||||||
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
|
||||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
|
||||||
{
|
|
||||||
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct OpMaker<true>
|
|
||||||
{
|
|
||||||
template <class OpFunction, class... Ops>
|
|
||||||
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
|
||||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
|
||||||
{
|
|
||||||
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpFunction, class... Ops>
|
template <class OpFunction, class... Ops>
|
||||||
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
||||||
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
||||||
{
|
{
|
||||||
return OpMaker<OpFunction::FISSTATIC>::mkOperation(f, ops...);
|
if constexpr(OpFunction::FISSTATIC){
|
||||||
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, class Op, class IndexType>
|
template <typename T, class Op, class IndexType>
|
||||||
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace MultiArrayTools
|
namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
|
|
||||||
template <size_t BEG, size_t END, size_t OFF>
|
template <size_t BEG, size_t END, int OFF>
|
||||||
struct sfor
|
struct sfor
|
||||||
{
|
{
|
||||||
template <typename Incr, typename F, typename Conc>
|
template <typename Incr, typename F, typename Conc>
|
||||||
|
@ -15,10 +15,31 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
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);
|
||||||
return conc(tmp, static_for<incr(idx),END,OFF>::exec(incr,f,conc));
|
if constexpr(incr(idx) == END){
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return conc(tmp, sfor<incr(idx),END,OFF>::exec(incr,f,conc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Incr, typename F, typename Conc, typename Arg>
|
||||||
|
static inline auto exec(Incr incr, F f, Conc conc, const Arg& arg)
|
||||||
|
{
|
||||||
|
constexpr auto idx = std::integral_constant<size_t, BEG>{};
|
||||||
|
constexpr auto idxm = std::integral_constant<size_t, BEG+OFF>{};
|
||||||
|
//static_assert(abs(idx.value - END) >= abs(incr(idx) - END),
|
||||||
|
// "this turns out to be a static endless loop");
|
||||||
|
auto tmp = f(idxm);
|
||||||
|
if constexpr(incr(idx) == END){
|
||||||
|
return conc(tmp, arg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return conc(tmp, sfor<incr(idx),END,OFF>::exec(incr,f,conc,arg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Incr, typename F, typename Create, typename... Args>
|
template <typename Incr, typename F, typename Create, typename... Args>
|
||||||
|
@ -26,14 +47,14 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
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);
|
||||||
return static_for<incr(idx),END,OFF>::unpack(incr, f, create, args..., tmp);
|
return sfor<incr(idx),END,OFF>::unpack(incr, f, create, args..., tmp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t END, size_t OFF>
|
template <size_t END, int OFF>
|
||||||
struct sfor<END,END,OFF>
|
struct sfor<END,END,OFF>
|
||||||
{
|
{
|
||||||
template <typename Incr, typename F, typename Conc>
|
template <typename Incr, typename F, typename Conc>
|
||||||
|
@ -50,8 +71,11 @@ namespace MultiArrayTools
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MA_SFOR(i,beg,end,incr,expr) static_for<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>::exec([&](auto i) constexpr { return incr; }, [&](auto i){ expr return 0; }, [&](auto f, auto next) { return 0; })
|
||||||
#define MA_SRFOR(i,beg,end,decr,expr) static_for<beg,end,-1>::exec([&](auto i) constexpr { return decr; }, [&](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_CFOR(i,beg,end,incr,expr,cre) static_for<beg,end,0>::unpack([&](auto i) constexpr { return incr; }, [&](auto i){ expr }, [&](auto... args) { return cre(args...); })
|
#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_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_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_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...); })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue