start operation refactoring
This commit is contained in:
parent
7904d77bd8
commit
477ea8d43d
6 changed files with 162 additions and 907 deletions
|
@ -2,255 +2,49 @@
|
||||||
#include "cxz_operation.h"
|
#include "cxz_operation.h"
|
||||||
#include "xpr/pos_type.h"
|
#include "xpr/pos_type.h"
|
||||||
#include "ranges/range_helper.h"
|
#include "ranges/range_helper.h"
|
||||||
|
#include "ranges/xpr/op_xpr.h"
|
||||||
|
|
||||||
|
|
||||||
/* ========================= *
|
|
||||||
* --- TEMPLATE CODE --- *
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
|
/**********************
|
||||||
|
* COpInterface *
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
template <class OpT>
|
||||||
|
template <class IndexT>
|
||||||
|
auto COpInterface<OpT>::c(const std::shared_ptr<IndexT>& ind) const
|
||||||
{
|
{
|
||||||
using namespace CNORXZInternal;
|
return Contraction<T,OpT,IndexT>(THIS(), ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************
|
template <class OpT>
|
||||||
* OperationTemplate *
|
template <class F, class... Args>
|
||||||
***************************/
|
constexpr auto a(F&& f, Args&&... args) const;
|
||||||
|
auto COpInterface<OpT>::o(F&& f, Args&&... args) const
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <typename U, class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator+(const OperationBase<U,Second>& in) const
|
|
||||||
{
|
{
|
||||||
return Operation<plusv<T,U>,plusx<T,U>,OperationClass,Second>(THIS(), in.THIS());
|
return Operation<R,F,OpT,Args...>(f, THIS(), args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
/*********************
|
||||||
template <typename U, class Second>
|
* OpInterface *
|
||||||
auto OperationBase<T,OperationClass>::operator-(const OperationBase<U,Second>& in) const
|
*********************/
|
||||||
|
|
||||||
|
template <class OpT>
|
||||||
|
template <class IndexT, class F, class... Args>
|
||||||
|
constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, Args&&... args)
|
||||||
{
|
{
|
||||||
return Operation<minusv<T,U>,minusx<T,U>,OperationClass,Second>(THIS(), in.THIS());
|
return ind->ifor( SPos<1>(), OpXpr<F,OpT,Args...>(f, THIS(), args...) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
template <class OpT>
|
||||||
template <typename U, class Second>
|
template <class IndexT, class F, class... Args>
|
||||||
auto OperationBase<T,OperationClass>::operator*(const OperationBase<U,Second>& in) const
|
inline SizeT OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, Arg&&... args)
|
||||||
{
|
{
|
||||||
return Operation<multipliesv<T,U>,multipliesx<T,U>,OperationClass,Second>(THIS(), in.THIS());
|
return ax(ind, f, args...)();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <typename U, class Second>
|
|
||||||
auto OperationBase<T,OperationClass>::operator/(const OperationBase<U,Second>& in) const
|
|
||||||
{
|
|
||||||
return Operation<dividesv<T,U>,dividesx<T,U>,OperationClass,Second>(THIS(), in.THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class IndexType>
|
|
||||||
auto OperationBase<T,OperationClass>::c(const std::shared_ptr<IndexType>& ind) const
|
|
||||||
{
|
|
||||||
return Contraction<T,OperationClass,IndexType>(THIS(), ind);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::sl(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
ConstSlice<T,typename Indices::RangeType...> out(inds->range()...);
|
|
||||||
out.define(inds...) = THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::p(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
auto ma = std::make_shared<Array<T,typename Indices::RangeType...>>
|
|
||||||
(inds->range()... , static_cast<T>(0));
|
|
||||||
(*ma)(inds...) = THIS();
|
|
||||||
return ConstOperationRoot<T,typename Indices::RangeType...>(ma, inds...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::to(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
Array<T,typename Indices::RangeType...> out(inds->range()...);
|
|
||||||
out(inds...) = THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::addto(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
Array<T,typename Indices::RangeType...> out(inds->range()...,
|
|
||||||
static_cast<T>(0));
|
|
||||||
out(inds...) += THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::pto(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
Array<T,typename Indices::RangeType...> out(inds->range()...);
|
|
||||||
out(inds...).par() = THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::paddto(const std::shared_ptr<Indices>&... inds) const
|
|
||||||
{
|
|
||||||
Array<T,typename Indices::RangeType...> out(inds->range()...,
|
|
||||||
static_cast<T>(0));
|
|
||||||
out(inds...).par() += THIS();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <typename R, class... Args>
|
|
||||||
auto OperationBase<T,OperationClass>::a(const std::shared_ptr<function<R,T,typename Args::value_type...>>& ll,
|
|
||||||
const Args&... args) const
|
|
||||||
{
|
|
||||||
return Operation<R,function<R,T,typename Args::value_type...>,OperationClass, Args...>(ll, THIS(), args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
auto OperationBase<T,OperationClass>::ptr() const
|
|
||||||
{
|
|
||||||
return OperationPointer<T,OperationClass>(THIS());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template <typename T, class OperationClass>
|
|
||||||
template <class... Indices>
|
|
||||||
auto OperationBase<T,OperationClass>::ho(const std::shared_ptr<Indices>& inds...) const
|
|
||||||
{
|
|
||||||
typedef XX SubOp;
|
|
||||||
return HyperOperation<T,SubOp,Indices...>()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* MOp *
|
|
||||||
******************/
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
MOp<T,Ops...>::MOp(const Ops&... exprs) : mOps(exprs...)
|
|
||||||
{
|
|
||||||
static_assert(SIZE == sizeof...(Ops), "size missmatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N, class ExtType, class... Exprs>
|
|
||||||
inline size_t MOpGetX( ExtType last, const std::tuple<Exprs...>& etp)
|
|
||||||
{
|
|
||||||
if constexpr(N > 0){
|
|
||||||
std::get<sizeof...(Exprs)-N-1>(etp).get(last);
|
|
||||||
return MOpGetX<N-1>(last.next(),etp);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::get<sizeof...(Exprs)-1>(etp).get(last);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N, class ExtType, class... Exprs>
|
|
||||||
inline void MOpSetX( ExtType last, std::tuple<Exprs...>& etp)
|
|
||||||
{
|
|
||||||
if constexpr(N > 0){
|
|
||||||
std::get<sizeof...(Exprs)-N-1>(etp).set(last);
|
|
||||||
MOpSetX<N-1>(last.next(),etp);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::get<sizeof...(Exprs)-1>(etp).set(last);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
inline size_t MOp<T,Ops...>::get(ExtType last) const
|
|
||||||
{
|
|
||||||
return MOpGetX<sizeof...(Ops)-1>(last,mOps.mOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
inline MOp<T,Ops...>& MOp<T,Ops...>::set(ExtType last)
|
|
||||||
{
|
|
||||||
MOpSetX<sizeof...(Ops)-1>(last,mOps.mOps);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
template <class Expr>
|
|
||||||
auto MOp<T,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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
auto MOp<T,Ops...>::rootSteps(std::intptr_t iPtrNum) const -> ExtType
|
|
||||||
{
|
|
||||||
return mOps.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
GetExpr<OpClass,NextExpr>::GetExpr(const OpClass& sec, const NextExpr& nexpr) :
|
|
||||||
mSec(sec), mNExpr(nexpr) {}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline void GetExpr<OpClass,NextExpr>::operator()(size_t start)
|
|
||||||
{
|
|
||||||
ExtType last = rootSteps();
|
|
||||||
last.zero();
|
|
||||||
mSec.get(last);
|
|
||||||
mNExpr(start,last.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline void GetExpr<OpClass,NextExpr>::operator()(size_t start, ExtType last)
|
|
||||||
{
|
|
||||||
mSec.get(last);
|
|
||||||
mNExpr(start,last.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline void GetExpr<OpClass,NextExpr>::get(ExtType last)
|
|
||||||
{
|
|
||||||
(*this)(0,last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
typename GetExpr<OpClass,NextExpr>::ExtType
|
|
||||||
GetExpr<OpClass,NextExpr>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return mSec.rootSteps(iPtrNum).extend( mNExpr.rootSteps(iPtrNum) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline void GetExpr<OpClass,NextExpr>::operator()(size_t mlast, DExt last)
|
|
||||||
{
|
|
||||||
(*this)(mlast, std::dynamic_pointer_cast<ExtT<ExtType>>(last)->ext());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline DExt GetExpr<OpClass,NextExpr>::dRootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return std::make_shared<ExtT<ExtType>>(rootSteps(iPtrNum));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
inline DExt GetExpr<OpClass,NextExpr>::dExtension() const
|
|
||||||
{
|
|
||||||
CHECK;
|
|
||||||
return nullptr; //???!!!
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
* ConstOperationRoot *
|
* ConstOperationRoot *
|
||||||
|
@ -638,238 +432,6 @@ namespace CNORXZ
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* ParallelOperationRoot *
|
|
||||||
******************************
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ParallelOperationRoot<T,Ranges...>::
|
|
||||||
ParallelOperationRoot(MutableArrayBase<T,Ranges...>& ma,
|
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
|
||||||
mDataPtr(ma.data()),
|
|
||||||
mOrigDataPtr(ma.data()),
|
|
||||||
mDataAcc( ma.data(), ma.data() ),
|
|
||||||
mIndex( ma.begin() )
|
|
||||||
{
|
|
||||||
mIndex(indices...);
|
|
||||||
mDataPtr = mOrigDataPtr + mIndex.pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ParallelOperationRoot<T,Ranges...>::
|
|
||||||
ParallelOperationRoot(T* data, const IndexType& ind) :
|
|
||||||
mDataPtr(data),
|
|
||||||
mOrigDataPtr(data),
|
|
||||||
mDataAcc( data, data ),
|
|
||||||
mIndex( ind )
|
|
||||||
{
|
|
||||||
mDataPtr = mOrigDataPtr + mIndex.pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Func, class OpClass>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::asx(const OpClass& in) const
|
|
||||||
{
|
|
||||||
static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" );
|
|
||||||
return mIndex.pifor(1,in.loop(AssignmentExpr<T,Func,PointerAccess<T>,ParallelOperationRoot<T,Ranges...>,OpClass,OpIndexAff::TARGET>
|
|
||||||
(mDataAcc,*this,in))).template vec<Access::VSIZE>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Func, class OpClass>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::asxExpr(const OpClass& in) const
|
|
||||||
{
|
|
||||||
static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" );
|
|
||||||
return in.loop(AssignmentExpr<T,Func,PointerAccess<T>,ParallelOperationRoot<T,Ranges...>,OpClass>
|
|
||||||
(mDataAcc,*this,in));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Func, class OpClass, class Index>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::asx(const OpClass& in, const std::shared_ptr<Index>& i) const
|
|
||||||
{
|
|
||||||
static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" );
|
|
||||||
return i->pifor(1,in.loop(AssignmentExpr<T,Func,PointerAccess<T>,ParallelOperationRoot<T,Ranges...>,OpClass>
|
|
||||||
(mDataAcc,*this,in))).template vec<Access::VSIZE>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::assign(const OpClass& in) const
|
|
||||||
{
|
|
||||||
return this->template asx<IAssign<T>>(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::assignExpr(const OpClass& in) const
|
|
||||||
{
|
|
||||||
return this->template asxExpr<IAssign<T>>(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass, class Index>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::assign(const OpClass& in, const std::shared_ptr<Index>& i) const
|
|
||||||
{
|
|
||||||
return this->template asx<IAssign<T>>(in,i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::plus(const OpClass& in) const
|
|
||||||
{
|
|
||||||
return this->template asx<IPlus<T>>(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass, class Index>
|
|
||||||
auto ParallelOperationRoot<T,Ranges...>::plus(const OpClass& in, const std::shared_ptr<Index>& i) const
|
|
||||||
{
|
|
||||||
return this->template asx<IPlus<T>>(in,i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
ParallelOperationRoot<T,Ranges...>& ParallelOperationRoot<T,Ranges...>::operator=(const OpClass& in)
|
|
||||||
{
|
|
||||||
vexec<OpClass::VABLE,identity>(*this,in);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class OpClass>
|
|
||||||
ParallelOperationRoot<T,Ranges...>& ParallelOperationRoot<T,Ranges...>::operator+=(const OpClass& in)
|
|
||||||
{
|
|
||||||
vexec<OpClass::VABLE,xxxplus>(*this,in);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
ParallelOperationRoot<T,Ranges...>&
|
|
||||||
ParallelOperationRoot<T,Ranges...>::operator=(const ParallelOperationRoot<T,Ranges...>& in)
|
|
||||||
{
|
|
||||||
return operator=<ParallelOperationRoot<T,Ranges...> >(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline T& ParallelOperationRoot<T,Ranges...>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mDataPtr[pos.val()+mOff];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline V& ParallelOperationRoot<T,Ranges...>::vget(ET pos) const
|
|
||||||
{
|
|
||||||
return *(reinterpret_cast<V*>(mDataPtr+pos.val()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class ET>
|
|
||||||
inline ParallelOperationRoot<T,Ranges...>& ParallelOperationRoot<T,Ranges...>::set(ET pos)
|
|
||||||
{
|
|
||||||
mIndex = pos.val();
|
|
||||||
mDataPtr = mOrigDataPtr + mIndex.pos();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
MExt<None> ParallelOperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return MExt<None>(RangeHelper::getStepSize( mIndex, iPtrNum ));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
template <class Expr>
|
|
||||||
Expr ParallelOperationRoot<T,Ranges...>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
T* ParallelOperationRoot<T,Ranges...>::data() const
|
|
||||||
{
|
|
||||||
auto i = mIndex;
|
|
||||||
return mOrigDataPtr + i().pos();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* OperationValue *
|
|
||||||
************************/
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
OperationValue<T>::OperationValue(const T& val) : mVal(val) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class ET>
|
|
||||||
inline const T& OperationValue<T>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return mVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline V OperationValue<T>::vget(ET pos) const
|
|
||||||
{
|
|
||||||
return static_cast<V>(mVal); // implement???!!!
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class ET>
|
|
||||||
inline OperationValue<T>& OperationValue<T>::set(ET pos)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
None OperationValue<T>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return None();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <class Expr>
|
|
||||||
Expr OperationValue<T>::loop(Expr exp) const
|
|
||||||
{
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
* OperationPointer *
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class ET>
|
|
||||||
inline const T* OperationPointer<T,Op>::get(ET pos) const
|
|
||||||
{
|
|
||||||
return &mOp.get(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class ET>
|
|
||||||
inline OperationPointer<T,Op>& OperationPointer<T,Op>::set(ET pos)
|
|
||||||
{
|
|
||||||
mOp.set(pos);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
auto OperationPointer<T,Op>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
-> decltype(mOp.rootSteps(0))
|
|
||||||
{
|
|
||||||
return mOp.rootSteps(iPtrNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
template <class Expr>
|
|
||||||
auto OperationPointer<T,Op>::loop(Expr exp) const
|
|
||||||
-> decltype(mOp.loop(exp))
|
|
||||||
{
|
|
||||||
return mOp.loop(exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* Operation *
|
* Operation *
|
||||||
|
|
|
@ -3,17 +3,7 @@
|
||||||
#ifndef __cxz_operation_h__
|
#ifndef __cxz_operation_h__
|
||||||
#define __cxz_operation_h__
|
#define __cxz_operation_h__
|
||||||
|
|
||||||
#include <cstdlib>
|
#include "base/base.h"
|
||||||
#include <tuple>
|
|
||||||
#include <cmath>
|
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include "base_def.h"
|
|
||||||
#include "mbase_def.h"
|
|
||||||
|
|
||||||
#include "ranges/rheader.h"
|
|
||||||
|
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "type_operations.h"
|
#include "type_operations.h"
|
||||||
|
@ -25,276 +15,85 @@
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
using namespace CNORXZInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
template <class OpT>
|
||||||
class OperationBase
|
class COpInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
|
OpT& THIS() { return static_cast<OpT&>(*this); }
|
||||||
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
|
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
|
||||||
|
|
||||||
template <typename U, class Second>
|
template <class IndexT>
|
||||||
auto operator+(const OperationBase<U,Second>& in) const;
|
constexpr auto c(const Sptr<IndexT>& ind) const;
|
||||||
|
|
||||||
template <typename U, class Second>
|
template <class F, class... Args>
|
||||||
auto operator-(const OperationBase<U,Second>& in) const;
|
constexpr auto o(F&& f, Args&&... args) const;
|
||||||
|
|
||||||
template <typename U, class Second>
|
template <class PosT>
|
||||||
auto operator*(const OperationBase<U,Second>& in) const;
|
constexpr decltype(auto) get(const PosT& pos) const
|
||||||
|
{ return THIS().get(pos); }
|
||||||
|
|
||||||
template <typename U, class Second>
|
template <SizeT I>
|
||||||
auto operator/(const OperationBase<U,Second>& in) const;
|
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const
|
||||||
|
{ return THIS().rootSteps(id); }
|
||||||
|
|
||||||
template <class IndexType>
|
template <class Xpr>
|
||||||
auto c(const std::shared_ptr<IndexType>& ind) const;
|
constexpr decltype(auto) loop(Xpr&& exp) const
|
||||||
|
{ return THIS().loop(exp); }
|
||||||
template <class... Indices>
|
|
||||||
auto sl(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
auto p(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
auto to(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
auto addto(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
auto pto(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <class... Indices>
|
|
||||||
auto paddto(const std::shared_ptr<Indices>&... inds) const;
|
|
||||||
|
|
||||||
template <typename R, class... Args> // Args = Operation Classes
|
|
||||||
auto a(const std::shared_ptr<function<R,T,typename Args::value_type...>>& ll, const Args&... args) const;
|
|
||||||
|
|
||||||
auto ptr() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend OperationClass;
|
|
||||||
friend OperationTemplate<T,OperationClass>;
|
|
||||||
OperationBase() = default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, class OperationClass>
|
template <class OpT>
|
||||||
class OperationTemplate : public OperationBase<T,OperationClass>
|
class OpInterface : public COpInterface<OpT>
|
||||||
{
|
{
|
||||||
/* empty per default; specialize if needed */
|
|
||||||
private:
|
|
||||||
OperationTemplate() = default;
|
|
||||||
friend OperationClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct SelfIdentity
|
|
||||||
{
|
|
||||||
static inline T& sapply(T& a, T b)
|
|
||||||
{
|
|
||||||
return a = b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <class... Ops>
|
|
||||||
struct OperationTuple
|
|
||||||
{
|
|
||||||
OperationTuple(const Ops&... ops) : mOps(ops...) {}
|
|
||||||
std::tuple<Ops...> mOps;
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class... Ops>
|
|
||||||
auto OperationTuple<Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
|
||||||
{
|
|
||||||
return sfor_p<0,sizeof...(Ops)>
|
|
||||||
( [&](auto i){ return std::get<i>(mOps).rootSteps(iPtrNum); },
|
|
||||||
[&](auto f, auto next) { return f.extend(next); } );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
class MOp
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
MOp() = default;
|
|
||||||
OperationTuple<Ops...> mOps;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr size_t LAYER = 0;
|
typedef COpInterface<OpT> OI;
|
||||||
static constexpr size_t NHLAYER = 0;
|
|
||||||
static constexpr size_t SIZE = (... + Ops::SIZE);
|
|
||||||
typedef decltype(mOps.rootSteps(0)) ExtType;
|
|
||||||
|
|
||||||
MOp(const Ops&... exprs);
|
OpT& THIS() { return static_cast<OpT&>(*this); }
|
||||||
|
const OpT& THIS() const { return static_cast<const OpT&>(*this); }
|
||||||
|
|
||||||
MOp(const MOp& in) = default;
|
template <class IndexT, class F, class... Args>
|
||||||
MOp(MOp&& in) = default;
|
constexpr decltype(auto) ax(const Sptr<IndexT>& ind, F&& f, Args&&... args);
|
||||||
MOp& operator=(const MOp& in) = default;
|
|
||||||
MOp& operator=(MOp&& in) = default;
|
|
||||||
|
|
||||||
inline size_t get(ExtType last) const;
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
inline size_t vget(ExtType last) const { return get(last); }
|
|
||||||
|
|
||||||
inline MOp& set(ExtType last);
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
auto loop(Expr exp) const;
|
|
||||||
|
|
||||||
T* data() const { assert(0); return nullptr; }
|
|
||||||
|
|
||||||
|
template <class IndexT, class F, class... Args>
|
||||||
|
inline SizeT a(const Sptr<IndexT>& ind, F&& f, Args&&... args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct is_operation
|
||||||
|
{ static constexpr bool value = std::is_base_of<COpInterface,T>::value };
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
template <class T>
|
||||||
class GetExpr : public ExpressionBase
|
struct is_mutable_operation
|
||||||
{
|
{ static constexpr bool value = std::is_base_of<OpInterface,T>::value };
|
||||||
private:
|
|
||||||
GetExpr() = default;
|
|
||||||
|
|
||||||
OpClass mSec;
|
template <typename T, class IndexT>
|
||||||
NextExpr mNExpr;
|
class COpRoot : public COpInterface<T,COpRoot<T,IndexT>>
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static constexpr size_t LAYER = 0;
|
|
||||||
static constexpr size_t NHLAYER = 0;
|
|
||||||
static constexpr size_t SIZE = OpClass::SIZE + NextExpr::SIZE;
|
|
||||||
typedef decltype(mSec.rootSteps(0).extend( mNExpr.rootSteps(0) ) ) ExtType;
|
|
||||||
|
|
||||||
GetExpr(const OpClass& sec, const NextExpr& nexpr);
|
|
||||||
GetExpr(const GetExpr& in) = default;
|
|
||||||
GetExpr(GetExpr&& in) = default;
|
|
||||||
GetExpr& operator=(const GetExpr& in) = default;
|
|
||||||
GetExpr& operator=(GetExpr&& in) = default;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
|
||||||
{
|
|
||||||
return std::make_shared<GetExpr<OpClass,NextExpr>>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator()(size_t start = 0);
|
|
||||||
inline void get(ExtType last);
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
inline void vget(ExtType last) { get(last); }
|
|
||||||
|
|
||||||
inline void operator()(size_t start, ExtType last);
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
|
||||||
|
|
||||||
inline void operator()(size_t mlast, DExt last) override final;
|
|
||||||
|
|
||||||
inline DExt dRootSteps(std::intptr_t iPtrNum = 0) const override final;
|
|
||||||
inline DExt dExtension() const override final;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class OpClass, class NextExpr>
|
|
||||||
auto mkGetExpr(const OpClass& op, const NextExpr& nexpr)
|
|
||||||
{
|
|
||||||
return GetExpr<OpClass,NextExpr>(op, nexpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ops>
|
|
||||||
auto mkMOp(const Ops&... exprs)
|
|
||||||
{
|
|
||||||
return MOp<T,Ops...>(exprs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
class ConstOperationRoot : public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef OperationBase<T,ConstOperationRoot<T,Ranges...> > OT;
|
typedef OpInterface<T,COpRoot<T,IndexT>> OI;
|
||||||
typedef ContainerRange<Ranges...> CRange;
|
|
||||||
typedef ConstContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = 1;
|
constexpr COpRoot(const DArrayBase<T>& a, const Sptr<IndexT>& ind);
|
||||||
static constexpr bool CONT = true;
|
constexpr COpRoot(const T* data, const Sptr<IndexT>& ind);
|
||||||
static constexpr bool VABLE = true;
|
|
||||||
|
|
||||||
ConstOperationRoot(const ArrayBase<T,Ranges...>& ma,
|
template <class PosT>
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
constexpr decltype(auto) get(const PosT& pos) const;
|
||||||
|
|
||||||
ConstOperationRoot(std::shared_ptr<ArrayBase<T,Ranges...> > maptr,
|
template <SizeT I>
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
|
||||||
|
|
||||||
ConstOperationRoot(const T* data, const IndexType& ind);
|
template <class Xpr>
|
||||||
|
constexpr decltype(auto) loop(Xpr&& exp) const;
|
||||||
template <class ET>
|
|
||||||
inline const T& get(ET pos) const;
|
|
||||||
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline const V& vget(ET pos) const;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline ConstOperationRoot& set(ET pos);
|
|
||||||
|
|
||||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
Expr loop(Expr exp) const;
|
|
||||||
|
|
||||||
const T* data() const;
|
const T* data() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const T* mData;
|
||||||
const T* mDataPtr;
|
Sptr<IndexType> mIndex;
|
||||||
const T* mOrigDataPtr;
|
|
||||||
IndexType mIndex;
|
|
||||||
std::shared_ptr<ArrayBase<T,Ranges...> > mMaPtr; // never remove this ptr, otherwise we lose temporary container instances!
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
class StaticCast : public OperationTemplate<T,StaticCast<T,Op> >
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Op mOp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef T value_type;
|
|
||||||
typedef OperationBase<T,StaticCast<T,Op> > OT;
|
|
||||||
typedef typename Op::CRange CRange;
|
|
||||||
typedef typename Op::IndexType IndexType;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = Op::SIZE;
|
|
||||||
static constexpr bool CONT = false;
|
|
||||||
static constexpr bool VABLE = false;
|
|
||||||
|
|
||||||
StaticCast(const Op& op);
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline T get(ET pos) const;
|
|
||||||
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline V vget(ET pos) const;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline StaticCast& set(ET pos);
|
|
||||||
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const
|
|
||||||
-> decltype(mOp.rootSteps(iPtrNum));
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
Expr loop(Expr exp) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
StaticCast<T,Op> staticcast(const Op& op)
|
|
||||||
{
|
|
||||||
return StaticCast<T,Op>(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Range>
|
template <class Range>
|
||||||
class MetaOperationRoot : public OperationTemplate<typename Range::MetaType,
|
class MetaOperationRoot : public OperationTemplate<typename Range::MetaType,
|
||||||
|
@ -417,153 +216,6 @@ namespace CNORXZ
|
||||||
-> Slice<T,typename Indices::RangeType...>;
|
-> Slice<T,typename Indices::RangeType...>;
|
||||||
|
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
template <typename T, class... Ranges>
|
|
||||||
class ParallelOperationRoot : public OperationTemplate<T,ParallelOperationRoot<T,Ranges...> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef T value_type;
|
|
||||||
typedef OperationBase<T,ParallelOperationRoot<T,Ranges...> > OT;
|
|
||||||
typedef ContainerRange<Ranges...> CRange;
|
|
||||||
typedef ConstContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = 1;
|
|
||||||
static constexpr bool CONT = true;
|
|
||||||
static constexpr bool VABLE = true;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
T* mDataPtr;
|
|
||||||
T* mOrigDataPtr;
|
|
||||||
PointerAccess<T> mDataAcc;
|
|
||||||
IndexType mIndex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ParallelOperationRoot(MutableArrayBase<T,Ranges...>& ma,
|
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
||||||
|
|
||||||
ParallelOperationRoot(T* data, const IndexType& ind);
|
|
||||||
|
|
||||||
template <class Func, class OpClass>
|
|
||||||
auto asx(const OpClass& in) const;
|
|
||||||
|
|
||||||
template <class Func, class OpClass>
|
|
||||||
auto asxExpr(const OpClass& in) const;
|
|
||||||
|
|
||||||
template <class Func, class OpClass, class Index>
|
|
||||||
auto asx(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
|
||||||
|
|
||||||
template <class OpClass>
|
|
||||||
auto assign(const OpClass& in) const;
|
|
||||||
|
|
||||||
template <class OpClass>
|
|
||||||
auto assignExpr(const OpClass& in) const;
|
|
||||||
|
|
||||||
template <class OpClass, class Index>
|
|
||||||
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
|
||||||
|
|
||||||
template <class OpClass>
|
|
||||||
auto plus(const OpClass& in) const;
|
|
||||||
|
|
||||||
template <class OpClass, class Index>
|
|
||||||
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
|
||||||
|
|
||||||
template <class OpClass>
|
|
||||||
ParallelOperationRoot& operator=(const OpClass& in);
|
|
||||||
|
|
||||||
template <class OpClass>
|
|
||||||
ParallelOperationRoot& operator+=(const OpClass& in);
|
|
||||||
|
|
||||||
ParallelOperationRoot& operator=(const ParallelOperationRoot& in);
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline T& get(ET pos) const;
|
|
||||||
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline V& vget(ET pos) const;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline ParallelOperationRoot& set(ET pos);
|
|
||||||
|
|
||||||
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
Expr loop(Expr exp) const;
|
|
||||||
|
|
||||||
T* data() const;
|
|
||||||
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class OperationValue : public OperationTemplate<T,OperationValue<T> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T value_type;
|
|
||||||
typedef OperationBase<T,OperationValue<T> > OT;
|
|
||||||
typedef ContainerRange<NullRange> CRange;
|
|
||||||
typedef ConstContainerIndex<T,NullIndex> IndexType;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = 0;
|
|
||||||
static constexpr bool CONT = true;
|
|
||||||
static constexpr bool VABLE = false;
|
|
||||||
|
|
||||||
OperationValue(const T& val);
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline const T& get(ET pos) const;
|
|
||||||
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline V vget(ET pos) const;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline OperationValue& set(ET pos);
|
|
||||||
|
|
||||||
None rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
Expr loop(Expr exp) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
T mVal;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, class Op>
|
|
||||||
class OperationPointer : public OperationTemplate<const T*,OperationPointer<T,Op>>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T value_type;
|
|
||||||
typedef OperationTemplate<const T*,OperationPointer<T,Op>> OT;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = Op::SIZE;
|
|
||||||
static constexpr bool CONT = false;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Op mOp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
OperationPointer(const Op& op) : mOp(op)
|
|
||||||
{
|
|
||||||
static_assert(Op::CONT,
|
|
||||||
"OperationPointer can only be applied to containing operations");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline const T* get(ET pos) const;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline OperationPointer& set(ET pos);
|
|
||||||
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
||||||
-> decltype(mOp.rootSteps(0));
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
auto loop(Expr exp) const
|
|
||||||
-> decltype(mOp.loop(exp));
|
|
||||||
|
|
||||||
T const** data() const { assert(0); return nullptr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
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...> >
|
||||||
|
@ -662,50 +314,6 @@ namespace CNORXZ
|
||||||
auto loop(Expr exp) const
|
auto loop(Expr exp) const
|
||||||
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
||||||
};
|
};
|
||||||
|
|
||||||
// for SliceArray
|
|
||||||
/*
|
|
||||||
template <typename T, class Op>
|
|
||||||
class HyperOperation : public OperationTemplate<T,HyperOperation<T,Op> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef Op value_type;
|
|
||||||
typedef OperationTemplate<T,HyperOperation<T,Op> > OT;
|
|
||||||
|
|
||||||
static constexpr size_t SIZE = Op::SIZE;
|
|
||||||
static constexpr bool CONT = false;
|
|
||||||
static constexpr bool VABLE = false;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Op mOp; // proto
|
|
||||||
|
|
||||||
public:
|
|
||||||
//typedef decltype(mOp.rootSteps(0)) ETuple;
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
// include ALL indices (external/internal!!!)
|
|
||||||
inline auto get(ET pos) const
|
|
||||||
-> decltype(mOp.template get<ET>(pos));
|
|
||||||
|
|
||||||
template <typename V, class ET>
|
|
||||||
inline auto vget(ET pos) const
|
|
||||||
-> decltype(mOp.template vget<V,ET>(pos));
|
|
||||||
|
|
||||||
template <class ET>
|
|
||||||
inline HyperOperation& set(ET pos);
|
|
||||||
|
|
||||||
T* data() const { assert(0); return nullptr; }
|
|
||||||
|
|
||||||
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
||||||
-> decltype(mOp.rootSteps(iPtrNum));
|
|
||||||
|
|
||||||
template <class Expr>
|
|
||||||
auto loop(Expr exp) const
|
|
||||||
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const int size = static_cast<int>(mSize);
|
const int size = static_cast<int>(mSize);
|
||||||
#pragma omp parallel
|
#pragma omp parallel private(i)
|
||||||
{
|
{
|
||||||
auto xpr = mXpr;
|
auto xpr = mXpr;
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
|
@ -163,7 +163,7 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const int size = static_cast<int>(mSize);
|
const int size = static_cast<int>(mSize);
|
||||||
#pragma omp parallel
|
#pragma omp parallel private(i)
|
||||||
{
|
{
|
||||||
auto xpr = mXpr;
|
auto xpr = mXpr;
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
|
|
48
src/include/ranges/xpr/op_xpr.cc.h
Normal file
48
src/include/ranges/xpr/op_xpr.cc.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
#ifndef __cxz_op_expr_cc_h__
|
||||||
|
#define __cxz_op_expr_cc_h__
|
||||||
|
|
||||||
|
#include "op_expr.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,mOps,last); // 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
|
37
src/include/ranges/xpr/op_xpr.h
Normal file
37
src/include/ranges/xpr/op_xpr.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
#ifndef __cxz_op_expr_h__
|
||||||
|
#define __cxz_op_expr_h__
|
||||||
|
|
||||||
|
#include "base/base.h"
|
||||||
|
#include "operation/operation_base.h"
|
||||||
|
#include "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
|
|
@ -24,7 +24,7 @@ namespace CNORXZ
|
||||||
inline SizeT operator()() const { return THIS()(); }
|
inline SizeT operator()() const { return THIS()(); }
|
||||||
|
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
inline 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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VXprBase
|
class VXprBase
|
||||||
|
|
Loading…
Reference in a new issue