derive COpInterface : XprInterface; allow return values for Xpr (VXpr+DXpr -> templates)

This commit is contained in:
Christian Zimmermann 2022-10-23 18:29:07 +02:00
parent fa1ea56d51
commit e2405738c1
16 changed files with 262 additions and 356 deletions

View file

@ -4,10 +4,8 @@
#include "op_types.h" #include "op_types.h"
#include "xpr/pos_type.h" #include "xpr/pos_type.h"
#include "ranges/range_helper.h"
#include "xpr/op_xpr.h" #include "xpr/op_xpr.h"
#include "statics/static_for.h" #include "op_utility.h"
namespace CNORXZ namespace CNORXZ
{ {
@ -17,20 +15,29 @@ namespace CNORXZ
**********************/ **********************/
template <class OpT> template <class OpT>
template <class IndexT> template <class F, class IndexT>
auto COpInterface<OpT>::c(const std::shared_ptr<IndexT>& ind) const decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
{ {
return Contraction<T,OpT,IndexT>(THIS(), ind); return mkContraction(std::forward<F>(f), THIS(), ind);
}
template <class OpT>
template <class IndexT>
decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
{
return mkContraction([](auto& a, const auto& b) { a += b; },
THIS(), ind);
} }
template <class OpT> template <class OpT>
template <class F, class... Args> template <class F, class... Args>
constexpr auto a(F&& f, Args&&... args) const; constexpr auto a(F&& f, Args&&... args) const;
auto COpInterface<OpT>::o(F&& f, Args&&... args) const decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
{ {
return Operation<R,F,OpT,Args...>(f, THIS(), args...); return Operation<F,OpT,Args...>(std::forward<F>(f), THIS(), args...);
} }
/********************* /*********************
* OpInterface * * OpInterface *
*********************/ *********************/
@ -39,7 +46,7 @@ namespace CNORXZ
template <class IndexT, class F, class... Args> template <class IndexT, class F, class... Args>
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, Args&&... args) constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, Args&&... args)
{ {
return ind->ifor( SPos<1>(), OpXpr<F,OpT,Args...>(f, THIS(), args...) ); return ind->ifor( Operation<F,OpT,Args...>(f, THIS(), args...) );
} }
template <class OpT> template <class OpT>
@ -68,7 +75,7 @@ namespace CNORXZ
template <typename T, class IndexT> template <typename T, class IndexT>
template <class PosT> template <class PosT>
constexpr decltype(auto) COpRoot<T,IndexT>::get(const PosT& pos) const constexpr decltype(auto) COpRoot<T,IndexT>::operator()(const PosT& pos) const
{ {
if constexpr(is_epos_type<PosT>::value){ if constexpr(is_epos_type<PosT>::value){
return vreg(mData,pos); // distinguish between consecutive/non-consecutive return vreg(mData,pos); // distinguish between consecutive/non-consecutive
@ -78,6 +85,12 @@ namespace CNORXZ
} }
} }
template <typename T, class IndexT>
constexpr decltype(auto) COpRoot<T,IndexT>::operator()() const
{
return mData[0];
}
template <typename T, class IndexT> template <typename T, class IndexT>
template <SizeT I> template <SizeT I>
constexpr decltype(auto) COpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const constexpr decltype(auto) COpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
@ -85,13 +98,6 @@ namespace CNORXZ
return mIndex->stepSize(id); return mIndex->stepSize(id);
} }
template <typename T, class IndexT>
template <class Expr>
constexpr decltype(auto) COpRoot<T,IndexT>::loop(Xpr&& xpr) const
{
return xpr;
}
template <typename T, class IndexT> template <typename T, class IndexT>
const T* COpRoot<T,IndexT>::data() const const T* COpRoot<T,IndexT>::data() const
{ {
@ -140,7 +146,7 @@ namespace CNORXZ
template <typename T, class IndexT> template <typename T, class IndexT>
template <class PosT> template <class PosT>
constexpr decltype(auto) OpRoot<T,IndexT>::get(const PosT& pos) const constexpr decltype(auto) OpRoot<T,IndexT>::operator()(const PosT& pos) const
{ {
if constexpr(is_epos_type<PosT>::value){ if constexpr(is_epos_type<PosT>::value){
return vreg(mData,pos); // distinguish between consecutive/non-consecutive return vreg(mData,pos); // distinguish between consecutive/non-consecutive
@ -150,6 +156,12 @@ namespace CNORXZ
} }
} }
template <typename T, class IndexT>
constexpr decltype(auto) OpRoot<T,IndexT>::operator()() const
{
return mData[0];
}
template <typename T, class IndexT> template <typename T, class IndexT>
template <SizeT I> template <SizeT I>
constexpr decltype(auto) OpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const constexpr decltype(auto) OpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
@ -157,100 +169,41 @@ namespace CNORXZ
return mIndex->stepSize(id); return mIndex->stepSize(id);
} }
template <typename T, class IndexT>
template <class Expr>
constexpr decltype(auto) OpRoot<T,IndexT>::loop(Xpr&& xpr) const;
{
return xpr;
}
/******************* /*******************
* Operation * * Operation *
*******************/ *******************/
template <typename T, class OpFunction, class... Ops> template <class F, class... Ops>
Operation<T,OpFunction,Ops...>::Operation(const Ops&... ops) : Operation<F,Ops...>::Operation(F&& f, Ops&&... ops) :
mOps(ops...)
{
static_assert( FISSTATIC, "need function instance for non-static function" );
}
template <typename T, class OpFunction, class... Ops>
Operation<T,OpFunction,Ops...>::Operation(std::shared_ptr<OpFunction> ff,
const Ops&... ops) :
mOps(ops...), mOps(ops...),
mF(ff) mF(ff)
{}
template <class F, class... Ops>
template <class PosT>
inline decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
{ {
static_assert( not FISSTATIC, "using instance of static function" ); return pos_unpack_args(mF, pos, mOps);
} }
template <size_t I, class OpFunction, class ETuple, class OpTuple, typename... Args> template <class F, class... Ops>
inline auto template <class PosT>
mkOpExpr(std::shared_ptr<OpFunction> f, const ETuple& pos, const OpTuple& ops, Args... args) inline decltype(auto) Operation<F,Ops...>::operator()() const
{ {
if constexpr(I == std::tuple_size<OpTuple>{}){ return exec(std::make_index_sequence<sizeof...(Ops)>{});
if constexpr(OpFunction::FISSTATIC){
return OpFunction::apply(args...);
}
else {
(*f)(args...);
}
}
else {
typedef typename std::remove_reference<decltype(std::get<I>(ops))>::type NextOpType;
return mkOpExpr<I+1>
( f, getX<NextOpType::SIZE>(pos), ops, args..., std::get<I>(ops).get(pos));
}
} }
template <typename T, class OpFunction, class... Ops> template <class F, class... Ops>
template <class ET> constexpr decltype(auto) Operation<F,Ops...>::rootSteps(const IndexId<I>& id) const
inline auto Operation<T,OpFunction,Ops...>::get(ET pos) const
{ {
return mkOpExpr<0>(mF, pos, mOps.mOps); return mOps.rootSteps(id);
} }
template <typename T, class OpFunction, class... Ops> template <class F, class... Ops>
template <typename V, class ET> constexpr decltype(auto) Operation<F,Ops...>::exec(std::index_sequence<Is...> is) const
inline auto Operation<T,OpFunction,Ops...>::vget(ET pos) const
{ {
return mkVOpExpr<0,V>(mF, pos, mOps.mOps); return mF( std::get<Is>(mOps)() ... );
}
template <size_t I, class OpTuple, class ETuple>
static inline void setOpPos(OpTuple& ot, const ETuple& et)
{
if constexpr(I != std::tuple_size<OpTuple>{}){
typedef typename std::remove_reference<decltype(std::get<I>(ot))>::type NextOpType;
std::get<I>( ot ).set( et );
setOpPos<I+1>(ot, getX<NextOpType::SIZE>(et));
}
}
template <typename T, class OpFunction, class... Ops>
template <class ET>
inline Operation<T,OpFunction,Ops...>& Operation<T,OpFunction,Ops...>::set(ET pos)
{
setOpPos<0>(mOps.mOps,pos);
return *this;
}
template <typename T, class OpFunction, class... Ops>
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType
{
return mOps.rootSteps(iPtrNum);
}
template <typename T, class OpFunction, class... Ops>
template <class Expr>
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
{
return sfor_m<sizeof...(Ops),0>
( [&](auto i){ return std::get<i>(mOps.mOps); },
[&](auto f, auto next) { return f.loop(next); },
exp );
} }
@ -265,11 +218,17 @@ namespace CNORXZ
template <class CXpr> template <class CXpr>
template <class PosT> template <class PosT>
constexpr decltype(auto) Contraction<CXpr>::get(const PosT& pos) const constexpr decltype(auto) Contraction<CXpr>::operator()(const PosT& pos) const
{ {
return mCXpr(pos); return mCXpr(pos);
} }
template <class CXpr>
constexpr decltype(auto) Contraction<CXpr>::operator()() const
{
return mCXpr();
}
template <class CXpr> template <class CXpr>
template <SizeT I> template <SizeT I>
constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const;
@ -277,18 +236,11 @@ namespace CNORXZ
return mCXpr.stepSize(id); return mCXpr.stepSize(id);
} }
template <class CXpr>
template <class Expr>
constexpr decltype(auto) Contraction<CXpr>::loop(Xpr&& xpr) const
{
return xpr;
}
template <class F, class Op, class IndexT> template <class F, class Op, class IndexT>
constexpr decltype(auto) mkContracion(F&& f, Op&& op, const Sptr<IndexT>& i) constexpr decltype(auto) mkContracion(F&& f, Op&& op, const Sptr<IndexT>& i)
{ {
typedef decltype(i->ifor( mkOpXpr( f, op ) )) CXprT; typedef decltype(i->ifor( op, f )) CXprT; // TODO: implement ifor with func arg!!!
return Contraction<CXprT>( i->ifor( mkOpXpr( f, op ) ) ); return Contraction<CXprT>( i->ifor( op, f ) );
} }
} }

View file

@ -10,30 +10,22 @@ namespace CNORXZ
template <class OpT> template <class OpT>
class COpInterface class COpInterface : public XprInterface<OpT>
{ {
public: public:
OpT& THIS() { return static_cast<OpT&>(*this); } OpT& THIS() { return static_cast<OpT&>(*this); }
const OpT& THIS() const { return static_cast<const OpT&>(*this); } const OpT& THIS() const { return static_cast<const OpT&>(*this); }
template <class F, class IndexT>
constexpr decltype(auto) c(F&& f, const Sptr<IndexT>& ind) const;
template <class IndexT> template <class IndexT>
constexpr auto c(const Sptr<IndexT>& ind) const; constexpr decltype(auto) c(const Sptr<IndexT>& ind) const;
template <class F, class... Args> template <class F, class... Args>
constexpr auto o(F&& f, Args&&... args) const; constexpr decltype(auto) o(F&& f, Args&&... args) const;
template <class PosT>
constexpr decltype(auto) get(const PosT& pos) const
{ return THIS().get(pos); }
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const
{ return THIS().rootSteps(id); }
template <class Xpr>
constexpr decltype(auto) loop(Xpr&& exp) const
{ return THIS().loop(exp); }
}; };
template <class OpT> template <class OpT>
@ -72,14 +64,13 @@ namespace CNORXZ
constexpr COpRoot(const T* data, const Sptr<IndexT>& ind); constexpr COpRoot(const T* data, const Sptr<IndexT>& ind);
template <class PosT> template <class PosT>
constexpr decltype(auto) get(const PosT& pos) const; constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
template <class Xpr>
constexpr decltype(auto) loop(Xpr&& xpr) const;
const T* data() const; const T* data() const;
private: private:
@ -114,14 +105,13 @@ namespace CNORXZ
constexpr OpRoot& operator=(const OpRoot& in); constexpr OpRoot& operator=(const OpRoot& in);
template <class PosT> template <class PosT>
constexpr decltype(auto) get(const PosT& pos) const; constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
template <class Xpr>
constexpr decltype(auto) loop(Xpr&& exp) const;
T* data() const; T* data() const;
private: private:
@ -140,15 +130,17 @@ namespace CNORXZ
constexpr Operation(F&& f, Ops&&... ops); constexpr Operation(F&& f, Ops&&... ops);
template <class PosT> template <class PosT>
constexpr decltype(auto) get(const PosT& pos) const; constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
template <class Xpr>
constexpr decltype(auto) loop(Xpr&& xpr) const;
private: private:
template <SizeT... Is>
constexpr decltype(auto) exec(std::index_sequence<Is...> is) const;
Tuple<Ops...> mOps; Tuple<Ops...> mOps;
F mF; F mF;
@ -163,14 +155,13 @@ namespace CNORXZ
constexpr Contraction(CXpr&& cxpr); constexpr Contraction(CXpr&& cxpr);
template <class PosT> template <class PosT>
constexpr decltype(auto) get(const PosT& pos) const; constexpr decltype(auto) operator()(const PosT& pos) const;
constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
template <class Xpr>
constexpr decltype(auto) loop(Xpr&& xpr) const;
private: private:
CXpr mCXpr; CXpr mCXpr;
Sptr<IndexType> mInd; Sptr<IndexType> mInd;

View file

@ -1,49 +0,0 @@
#ifndef __cxz_op_expr_cc_h__
#define __cxz_op_expr_cc_h__
#include "op_expr.h"
#include "op_utility.h"
namespace CNORXZ
{
template <class F, class... Ops>
constexpr OpXpr<F,Ops...>::OpXpr(F&& f, Ops&&... ops) :
mF(std::forward<F>(f)),
mOps(ops...)
{
static_assert((is_operation<Ops>::value and ...), "got non-op type");
}
template <class F, class... Ops>
template <class PosT1, class PosT2>
inline SizeT OpXpr<F,Ops...>::operator()(const PosT& last) const
{
pos_unpack_args(mF,last,mOps); // utility function (to be implemented)
// depending on whether Ops[N] is static or not call statically or dynamically .next()
return 0;
}
template <class F, class... Ops>
inline SizeT OpXpr<F,Ops...>::operator()() const
{
return 0;
}
template <class F, class... Ops>
template <SizeT I>
constexpr decltype(auto) OpXpr<F,Ops...>::rootSteps(const IndexId<I>& id) const
{
return rootStepsI(id, std::make_index_sequence<sizeof...(Ops)>{});
}
template <class F, class... Ops>
template <SizeT I, SizeT... Js>
constexpr decltype(auto) OpXpr<F,Ops...>::rootStepsI(const IndexId<I>& id, std::index_sequence<Js...> is) const
{
return (std::get<Js>(mOps).rootSteps(id) << ...);
// TODO: implement a << b which is a.extend(b)!!
}
}
#endif

View file

@ -1,37 +0,0 @@
#ifndef __cxz_op_expr_h__
#define __cxz_op_expr_h__
#include "base/base.h"
#include "operation/operation_base.h"
#include "xpr/xpr_base.h"
namespace CNORXZ
{
template <class F, class... Ops>
class OpXpr
{
private:
F mF;
Tuple<Ops...> mOps;
template <SizeT I, SizeT... Js>
constexpr decltype(auto) rootStepsI(const IndexId<I>& id, std::index_sequence<Js...> is) const;
public:
DEFAULT_MEMBERS(OpXpr);
constexpr OpXpr(F&& f, Ops&&... ops);
template <class PosT>
inline SizeT operator()(const PosT& last) const;
inline SizeT operator()() const;
template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
};
}
#endif

View file

@ -9,7 +9,7 @@ namespace CNORXZ
template <class Xpr> template <class Xpr>
decltype(auto) CIndex::ifor(const Xpr& xpr) const decltype(auto) CIndex::ifor(const Xpr& xpr) const
{ {
return For<0,Xpr>(this->max(), this->id(), xpr); return For<0,Xpr>(this->max(), this->id(), xpr, NoF());
} }
} }

View file

@ -50,7 +50,7 @@ namespace CNORXZ
DType meta() const; DType meta() const;
DIndex& at(const DType& meta); DIndex& at(const DType& meta);
DXpr ifor(const DXpr& xpr) const; DXpr<SizeT> ifor(const DXpr<SizeT>& xpr) const;
private: private:
XIndexPtr mI; XIndexPtr mI;

View file

@ -155,9 +155,9 @@ namespace CNORXZ
} }
template <class Index, typename Meta> template <class Index, typename Meta>
DXpr XIndex<Index,Meta>::ifor(const DXpr& xpr) const DXpr<SizeT> XIndex<Index,Meta>::ifor(const DXpr<SizeT>& xpr) const
{ {
return DXpr(mI->ifor(xpr)); return DXpr<SizeT>(mI->ifor(xpr));
} }
} }

View file

@ -42,7 +42,7 @@ namespace CNORXZ
virtual DType meta() const = 0; virtual DType meta() const = 0;
virtual XIndexBase& at(const DType& meta) = 0; virtual XIndexBase& at(const DType& meta) = 0;
virtual DXpr ifor(const DXpr& xpr) const = 0; virtual DXpr<SizeT> ifor(const DXpr<SizeT>& xpr) const = 0;
}; };
//Sptr<XIndexBase>& operator++(Sptr<XIndexBase>& i); //Sptr<XIndexBase>& operator++(Sptr<XIndexBase>& i);
@ -91,7 +91,7 @@ namespace CNORXZ
virtual DType meta() const override final; virtual DType meta() const override final;
virtual XIndexBase& at(const DType& meta) override final; virtual XIndexBase& at(const DType& meta) override final;
virtual DXpr ifor(const DXpr& xpr) const override final; virtual DXpr<SizeT> ifor(const DXpr<SizeT>& xpr) const override final;
private: private:
IndexPtr<Index,Meta> mI; IndexPtr<Index,Meta> mI;

View file

@ -51,7 +51,7 @@ namespace CNORXZ
DType meta() const; DType meta() const;
YIndex& at(const DType& meta); YIndex& at(const DType& meta);
DXpr ifor(const DXpr& xpr) const; DXpr<SizeT> ifor(const DXpr<SizeT>& xpr) const;
private: private:

View file

@ -8,42 +8,63 @@
namespace CNORXZ namespace CNORXZ
{ {
/*************
* ZeroF *
*************/
template <typename... T>
constexpr decltype(auto) ZeroF::operator()(const T&... as) const
{
return 0;
}
template <typename... T>
constexpr decltype(auto) NoF::operator()(const T&... as) const
{
return;
}
/*********** /***********
* For * * For *
***********/ ***********/
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
constexpr For<L,Xpr>::For(SizeT size, const IndexId<L>& id, const Xpr& xpr) : constexpr For<L,Xpr,F>::For(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f) :
mSize(size), mSize(size),
mId(id), mId(id),
mXpr(xpr), mXpr(xpr),
mExt(mXpr.rootSteps(mId)) mExt(mXpr.rootSteps(mId)),
mF(f)
{} {}
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
template <class PosT> template <class PosT>
inline SizeT For<L,Xpr>::operator()(const PosT& last) const inline decltype(auto) For<L,Xpr,F>::operator()(const PosT& last) const
{ {
typedef typename std::remove_reference<decltype(mXpr(last + mExt * UPos(0)))>::type OutT;
auto o = OutT();
for(SizeT i = 0; i != mSize; ++i){ for(SizeT i = 0; i != mSize; ++i){
const auto pos = last + mExt * UPos(i); const auto pos = last + mExt * UPos(i);
mXpr(pos); mF(o, mXpr(pos));
} }
return 0; return o;
} }
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
inline SizeT For<L,Xpr>::operator()() const inline decltype(auto) For<L,Xpr,F>::operator()() const
{ {
typedef typename std::remove_reference<decltype(mXpr(mExt * UPos(0)))>::type OutT;
auto o = OutT();
for(SizeT i = 0; i != mSize; ++i){ for(SizeT i = 0; i != mSize; ++i){
const auto pos = mExt * UPos(i); const auto pos = mExt * UPos(i);
mXpr(pos); mF(o, mXpr(pos));
} }
return 0; return o;
} }
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
template <SizeT I> template <SizeT I>
inline decltype(auto) For<L,Xpr>::rootSteps(const IndexId<I>& id) const inline decltype(auto) For<L,Xpr,F>::rootSteps(const IndexId<I>& id) const
{ {
return mXpr.rootSteps(id); return mXpr.rootSteps(id);
} }
@ -53,60 +74,61 @@ namespace CNORXZ
* SFor * * SFor *
************/ ************/
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
constexpr SFor<N,L,Xpr>::SFor(const IndexId<L>& id, const Xpr& xpr) : constexpr SFor<N,L,Xpr,F>::SFor(const IndexId<L>& id, const Xpr& xpr, F&& f) :
mId(id), mId(id),
mXpr(xpr), mXpr(xpr),
mExt(mXpr.RootSteps(mId)) mExt(mXpr.RootSteps(mId)),
mF(f)
{} {}
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
template <class PosT> template <class PosT>
constexpr SizeT SFor<N,L,Xpr>::operator()(const PosT& last) const constexpr decltype(auto) SFor<N,L,Xpr,F>::operator()(const PosT& last) const
{ {
return exec<0>(last); return exec<0>(last);
} }
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
constexpr SizeT SFor<N,L,Xpr>::operator()() const constexpr decltype(auto) SFor<N,L,Xpr,F>::operator()() const
{ {
return exec<0>(); return exec<0>();
} }
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
template <SizeT I> template <SizeT I>
constexpr decltype(auto) SFor<N,L,Xpr>::rootSteps(const IndexId<I>& id) const constexpr decltype(auto) SFor<N,L,Xpr,F>::rootSteps(const IndexId<I>& id) const
{ {
return mXpr.rootSteps(id); return mXpr.rootSteps(id);
} }
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
template <SizeT I, class PosT> template <SizeT I, class PosT>
constexpr SizeT SFor<N,L,Xpr>::exec(const PosT& last) const constexpr decltype(auto) SFor<N,L,Xpr,F>::exec(const PosT& last) const
{ {
constexpr SPos<I> i; constexpr SPos<I> i;
const auto pos = last + mExt * i; const auto pos = last + mExt * i;
mXpr(pos); auto o = mXpr(pos);
if constexpr(I < N-1){ if constexpr(I < N-1){
return exec<I+1>(last); return mF(o,exec<I+1>(last));
} }
else { else {
return 0; return o;
} }
} }
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F>
template <SizeT I> template <SizeT I>
constexpr SizeT SFor<N,L,Xpr>::exec() const constexpr decltype(auto) SFor<N,L,Xpr,F>::exec() const
{ {
constexpr SPos<I> i; constexpr SPos<I> i;
const auto pos = mExt * i; const auto pos = mExt * i;
mXpr(pos); auto o = mXpr(pos);
if constexpr(I < N-1){ if constexpr(I < N-1){
return exec<I+1>(); return mF(o,exec<I+1>());
} }
else { else {
return 0; return o;
} }
} }
@ -114,12 +136,13 @@ namespace CNORXZ
* TFor * * TFor *
************/ ************/
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
constexpr TFor<L,Xpr>::TFor(SizeT size, const IndexId<L>& id, const Xpr& xpr) : constexpr TFor<L,Xpr,F>::TFor(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f) :
mSize(size), mSize(size),
mId(id), mId(id),
mXpr(xpr), mXpr(xpr),
mExt(mXpr.rootSteps(mId)) mExt(mXpr.rootSteps(mId)),
mF(f)
{ {
// check for write access!!! // check for write access!!!
/* /*
@ -130,12 +153,18 @@ namespace CNORXZ
*/ */
} }
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
template <class PosT> template <class PosT>
inline SizeT TFor<L,Xpr>::operator()(const PosT& last) const inline decltype(auto) TFor<L,Xpr,F>::operator()(const PosT& last) const
{ {
typedef typename std::remove_reference<decltype(mXpr(last + mExt * UPos(0)))>::type OutT;
int i = 0; int i = 0;
const int size = static_cast<int>(mSize); const int size = static_cast<int>(mSize);
Vector<OutT> ov;
if constexpr(not std::is_same<F,ZeroF>::value){
// replace if statement by "does s.th. non-trivial"
ov.resize(mSize);
}
#pragma omp parallel private(i) #pragma omp parallel private(i)
{ {
auto xpr = mXpr; auto xpr = mXpr;
@ -145,14 +174,27 @@ namespace CNORXZ
xpr(pos); xpr(pos);
} }
} }
return 0; OutT o;
if constexpr(not std::is_same<F,ZeroF>::value){
// replace if statement by "does s.th. non-trivial"
for(SizeT i = 0; i != mSize; ++i){
mF(o, ov[i]);
}
}
return o;
} }
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
inline SizeT TFor<L,Xpr>::operator()() const inline decltype(auto) TFor<L,Xpr,F>::operator()() const
{ {
typedef typename std::remove_reference<decltype(mXpr(mExt * UPos(0)))>::type OutT;
int i = 0; int i = 0;
const int size = static_cast<int>(mSize); const int size = static_cast<int>(mSize);
Vector<OutT> ov;
if constexpr(not std::is_same<F,ZeroF>::value){
// replace if statement by "does s.th. non-trivial"
ov.resize(mSize);
}
#pragma omp parallel private(i) #pragma omp parallel private(i)
{ {
auto xpr = mXpr; auto xpr = mXpr;
@ -162,12 +204,19 @@ namespace CNORXZ
xpr(pos); xpr(pos);
} }
} }
return 0; OutT o;
if constexpr(not std::is_same<F,ZeroF>::value){
// replace if statement by "does s.th. non-trivial"
for(SizeT i = 0; i != mSize; ++i){
mF(o, ov[i]);
}
}
return o;
} }
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F>
template <SizeT I> template <SizeT I>
inline decltype(auto) TFor<L,Xpr>::rootSteps(const IndexId<I>& id) const inline decltype(auto) TFor<L,Xpr,F>::rootSteps(const IndexId<I>& id) const
{ {
return mXpr.rootSteps(id); return mXpr.rootSteps(id);
} }
@ -186,14 +235,14 @@ namespace CNORXZ
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr>
template <class PosT> template <class PosT>
constexpr SizeT EFor<N,L,Xpr>::operator()(const PosT& last) const constexpr decltype(auto) EFor<N,L,Xpr>::operator()(const PosT& last) const
{ {
auto pos = mkEPos<N>(last, mExt); auto pos = mkEPos<N>(last, mExt);
return mXpr(pos); return mXpr(pos);
} }
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr>
constexpr SizeT EFor<N,L,Xpr>::operator()() const constexpr decltype(auto) EFor<N,L,Xpr>::operator()() const
{ {
auto pos = mkEPos<N>(SPos<0>(), mExt); auto pos = mkEPos<N>(SPos<0>(), mExt);
return mXpr(pos); return mXpr(pos);

View file

@ -7,19 +7,32 @@
namespace CNORXZ namespace CNORXZ
{ {
class ZeroF
{
public:
template <typename... T>
constexpr decltype(auto) operator()(const T&... as) const;
};
template <SizeT L, class Xpr> class NoF
class For : public XprInterface<For<L,Xpr>> {
public:
template <typename... T>
constexpr decltype(auto) operator()(const T&... as) const;
};
template <SizeT L, class Xpr, class F = NoF>
class For : public XprInterface<For<L,Xpr,F>>
{ {
public: public:
DEFAULT_MEMBERS(For); DEFAULT_MEMBERS(For);
constexpr For(SizeT size, const IndexId<L>& id, const Xpr& xpr); constexpr For(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f);
template <class PosT> template <class PosT>
inline SizeT operator()(const PosT& last) const; inline decltype(auto) operator()(const PosT& last) const;
inline SizeT operator()() const; inline decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
inline decltype(auto) rootSteps(const IndexId<I>& id) const; inline decltype(auto) rootSteps(const IndexId<I>& id) const;
@ -30,22 +43,23 @@ namespace CNORXZ
Xpr mXpr; Xpr mXpr;
typedef decltype(mXpr.rootSteps(mId)) XPosT; typedef decltype(mXpr.rootSteps(mId)) XPosT;
XPosT mExt; XPosT mExt;
F mF;
}; };
// unrolled loop: // unrolled loop:
template <SizeT N, SizeT L, class Xpr> template <SizeT N, SizeT L, class Xpr, class F = NoF>
class SFor : public XprInterface<SFor<N,L,Xpr>> class SFor : public XprInterface<SFor<N,L,Xpr,F>>
{ {
public: public:
DEFAULT_MEMBERS(SFor); DEFAULT_MEMBERS(SFor);
constexpr SFor(const IndexId<L>& id, const Xpr& xpr); constexpr SFor(const IndexId<L>& id, const Xpr& xpr, F&& f);
template <class PosT> template <class PosT>
constexpr SizeT operator()(const PosT& last) const; constexpr decltype(auto) operator()(const PosT& last) const;
constexpr SizeT operator()() const; constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
@ -53,32 +67,33 @@ namespace CNORXZ
private: private:
template <SizeT I, class PosT> template <SizeT I, class PosT>
constexpr SizeT exec(const PosT& last) const; constexpr decltype(auto) exec(const PosT& last) const;
template <SizeT I> template <SizeT I>
constexpr SizeT exec() const; constexpr decltype(auto) exec() const;
IndexId<L> mId; IndexId<L> mId;
Xpr mXpr; Xpr mXpr;
typedef decltype(mXpr.RootSteps(mId)) XPosT; typedef decltype(mXpr.RootSteps(mId)) XPosT;
XPosT mExt; XPosT mExt;
F mF;
}; };
// multi-threading // multi-threading
template <SizeT L, class Xpr> template <SizeT L, class Xpr, class F = NoF>
class TFor : public XprInterface<TFor<L,Xpr>> class TFor : public XprInterface<TFor<L,Xpr,F>>
{ {
public: public:
DEFAULT_MEMBERS(TFor); DEFAULT_MEMBERS(TFor);
constexpr TFor(SizeT size, const IndexId<L>& id, const Xpr& xpr); constexpr TFor(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f);
template <class PosT> template <class PosT>
inline SizeT operator()(const PosT& last) const; inline decltype(auto) operator()(const PosT& last) const;
inline SizeT operator()() const; inline decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
inline decltype(auto) rootSteps(const IndexId<I>& id) const; inline decltype(auto) rootSteps(const IndexId<I>& id) const;
@ -89,7 +104,7 @@ namespace CNORXZ
Xpr mXpr; Xpr mXpr;
typedef decltype(mXpr.rootSteps(mId)) XPosT; typedef decltype(mXpr.rootSteps(mId)) XPosT;
XPosT mExt; XPosT mExt;
F mF;
}; };
// Extension For (Vectorization) // Extension For (Vectorization)
@ -102,9 +117,9 @@ namespace CNORXZ
constexpr EFor(const IndexId<L>& id, const Xpr& xpr); constexpr EFor(const IndexId<L>& id, const Xpr& xpr);
template <class PosT> template <class PosT>
constexpr SizeT operator()(const PosT& last) const; constexpr decltype(auto) operator()(const PosT& last) const;
constexpr SizeT operator()() const; constexpr decltype(auto) operator()() const;
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const; constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;

View file

@ -1,23 +0,0 @@
#ifndef __cxz_for_type_h__
#define __cxz_for_type_h__
namespace CNORXZInternal
{
enum class ForType {
DEFAULT = 0,
HIDDEN = 1
};
template <class IndexClass, class Expr, ForType FT = ForType::DEFAULT, size_t DIV = 1>
class For;
template <class IndexClass, class Expr, size_t DIV = 1>
class PFor;
} // end namespace CNORXZInternal
#endif

View file

@ -11,31 +11,31 @@ namespace CNORXZ
* VXpr * * VXpr *
************/ ************/
template <class Xpr> template <typename T, class Xpr>
VXpr<Xpr>::VXpr(const XprInterface<Xpr>& a) : VXpr<T,Xpr>::VXpr(const XprInterface<Xpr>& a) :
Xpr(a.THIS()) Xpr(a.THIS())
{} {}
template <class Xpr> template <typename T, class Xpr>
Uptr<VXprBase> VXpr<Xpr>::copy() const Uptr<VXprBase<T>> VXpr<T,Xpr>::copy() const
{ {
return std::make_unique<VXpr<Xpr>>(*this); return std::make_unique<VXpr<T,Xpr>>(*this);
} }
template <class Xpr> template <typename T, class Xpr>
SizeT VXpr<Xpr>::vexec(const DPos& last) const T VXpr<T,Xpr>::vexec(const DPos& last) const
{ {
return (*this)(last); return (*this)(last);
} }
template <class Xpr> template <typename T, class Xpr>
SizeT VXpr<Xpr>::vexec() const T VXpr<T,Xpr>::vexec() const
{ {
return (*this)(); return (*this)();
} }
template <class Xpr> template <typename T, class Xpr>
DPos VXpr<Xpr>::vrootSteps(const IndexId<0>& id) const DPos VXpr<T,Xpr>::vrootSteps(const IndexId<0>& id) const
{ {
return DPos(this->rootSteps(id)); return DPos(this->rootSteps(id));
} }
@ -44,25 +44,29 @@ namespace CNORXZ
* DXpr * * DXpr *
************/ ************/
template <typename T>
template <class Xpr> template <class Xpr>
DXpr::DXpr(const Xpr& a) : DXpr<T>::DXpr(const Xpr& a) :
ObjHandle<VXprBase>(std::make_unique<VXpr<Xpr>>(a)) ObjHandle<VXprBase<T>>(std::make_unique<VXpr<T,Xpr>>(a))
{} {}
inline SizeT DXpr::operator()(const DPos& last) const template <typename T>
inline T DXpr<T>::operator()(const DPos& last) const
{ {
return mC->vexec(last); return VB::mC->vexec(last);
} }
inline SizeT DXpr::operator()() const template <typename T>
inline T DXpr<T>::operator()() const
{ {
return mC->vexec(); return VB::mC->vexec();
} }
template <typename T>
template <SizeT I> template <SizeT I>
inline DPos DXpr::rootSteps(const IndexId<I>& id) const inline DPos DXpr<T>::rootSteps(const IndexId<I>& id) const
{ {
return mC->vrootSteps(IndexId<0>(id.id())); return VB::mC->vrootSteps(IndexId<0>(id.id()));
} }
} }

View file

@ -19,53 +19,57 @@ namespace CNORXZ
inline const Xpr& THIS() const { return static_cast<const Xpr&>(*this); } inline const Xpr& THIS() const { return static_cast<const Xpr&>(*this); }
template <class PosT> template <class PosT>
inline SizeT operator()(const PosT& last) const { return THIS()(last); } constexpr decltype(auto) operator()(const PosT& last) const { return THIS()(last); }
inline SizeT operator()() const { return THIS()(); } constexpr decltype(auto) operator()() const { return THIS()(); }
template <SizeT I> template <SizeT I>
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const { return THIS().rootSteps(id); } constexpr decltype(auto) rootSteps(const IndexId<I>& id) const { return THIS().rootSteps(id); }
}; };
template <typename T>
class VXprBase class VXprBase
{ {
public: public:
DEFAULT_MEMBERS(VXprBase); DEFAULT_MEMBERS(VXprBase);
virtual Uptr<VXprBase> copy() const = 0; virtual Uptr<VXprBase<T>> copy() const = 0;
virtual SizeT vexec(const DPos& last) const = 0; virtual T vexec(const DPos& last) const = 0;
virtual SizeT vexec() const = 0; virtual T vexec() const = 0;
virtual DPos vrootSteps(const IndexId<0>& id) const = 0; virtual DPos vrootSteps(const IndexId<0>& id) const = 0;
}; };
template <class Xpr> template <typename T, class Xpr>
class VXpr : public VXprBase, public Xpr class VXpr : public VXprBase<T>, public Xpr
{ {
public: public:
DEFAULT_MEMBERS(VXpr); DEFAULT_MEMBERS(VXpr);
VXpr(const XprInterface<Xpr>& a); VXpr(const XprInterface<Xpr>& a);
virtual Uptr<VXprBase> copy() const override final; virtual Uptr<VXprBase<T>> copy() const override final;
virtual SizeT vexec(const DPos& last) const override final; virtual T vexec(const DPos& last) const override final;
virtual SizeT vexec() const override final; virtual T vexec() const override final;
virtual DPos vrootSteps(const IndexId<0>& id) const override final; virtual DPos vrootSteps(const IndexId<0>& id) const override final;
}; };
class DXpr : public ObjHandle<VXprBase>, template <typename T>
public XprInterface<DXpr> class DXpr : public ObjHandle<VXprBase<T>>,
public XprInterface<DXpr<T>>
{ {
public: public:
typedef ObjHandle<VXprBase<T>> VB;
DEFAULT_MEMBERS(DXpr); DEFAULT_MEMBERS(DXpr);
template <class Xpr> template <class Xpr>
explicit DXpr(const Xpr& a); explicit DXpr(const Xpr& a);
inline SizeT operator()(const DPos& last) const; inline T operator()(const DPos& last) const;
inline SizeT operator()() const; inline T operator()() const;
template <SizeT I> template <SizeT I>
inline DPos rootSteps(const IndexId<I>& id) const; inline DPos rootSteps(const IndexId<I>& id) const;

View file

@ -138,9 +138,9 @@ namespace CNORXZ
return *this; return *this;
} }
DXpr DIndex::ifor(const DXpr& xpr) const DXpr<SizeT> DIndex::ifor(const DXpr<SizeT>& xpr) const
{ {
return DXpr(mI->ifor(xpr)); return DXpr<SizeT>(mI->ifor(xpr));
} }
} }

View file

@ -171,10 +171,10 @@ namespace CNORXZ
return *this; return *this;
} }
DXpr YIndex::ifor(const DXpr& xpr) const DXpr<SizeT> YIndex::ifor(const DXpr<SizeT>& xpr) const
{ {
assert(0); assert(0);
return DXpr(); return DXpr<SizeT>();
} }
/********************** /**********************