2017-02-16 11:20:40 +01:00
|
|
|
// -*- C++ -*-
|
|
|
|
|
|
|
|
#ifndef __multi_array_operation_h__
|
|
|
|
#define __multi_array_operation_h__
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <tuple>
|
2017-03-22 21:51:54 +01:00
|
|
|
#include <cmath>
|
2017-08-30 17:56:38 +02:00
|
|
|
#include <map>
|
|
|
|
#include <utility>
|
2021-02-03 14:30:25 +01:00
|
|
|
#include <type_traits>
|
2017-02-16 11:20:40 +01:00
|
|
|
|
|
|
|
#include "base_def.h"
|
2017-12-18 11:19:04 +01:00
|
|
|
#include "mbase_def.h"
|
|
|
|
|
2017-12-18 13:13:13 +01:00
|
|
|
#include "ranges/rheader.h"
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2018-01-15 18:31:47 +01:00
|
|
|
#include "arith.h"
|
2020-07-07 16:42:41 +02:00
|
|
|
#include "xfor/xfor.h"
|
2021-01-14 23:57:06 +01:00
|
|
|
#include "type_operations.h"
|
2020-07-07 16:42:41 +02:00
|
|
|
|
2021-04-10 16:06:02 +02:00
|
|
|
#include "statics/static_for.h"
|
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
|
2017-08-26 22:53:02 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace MultiArrayHelper;
|
|
|
|
}
|
2018-05-15 21:18:21 +02:00
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
2018-05-18 17:45:40 +02:00
|
|
|
class OperationBase
|
2017-08-11 11:30:27 +02:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
|
|
|
|
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2019-07-24 18:49:53 +02:00
|
|
|
template <typename U, class Second>
|
|
|
|
auto operator+(const OperationBase<U,Second>& in) const;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
2019-07-24 18:49:53 +02:00
|
|
|
template <typename U, class Second>
|
|
|
|
auto operator-(const OperationBase<U,Second>& in) const;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
2019-07-24 18:49:53 +02:00
|
|
|
template <typename U, class Second>
|
|
|
|
auto operator*(const OperationBase<U,Second>& in) const;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
2019-07-24 18:49:53 +02:00
|
|
|
template <typename U, class Second>
|
|
|
|
auto operator/(const OperationBase<U,Second>& in) const;
|
2017-11-05 18:46:38 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <class IndexType>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto c(const std::shared_ptr<IndexType>& ind) const;
|
2018-07-19 19:29:52 +02:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto sl(const std::shared_ptr<Indices>&... inds) const;
|
2018-09-11 18:38:30 +02:00
|
|
|
|
2018-12-02 17:40:50 +01:00
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto p(const std::shared_ptr<Indices>&... inds) const;
|
2018-12-02 17:40:50 +01:00
|
|
|
|
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto to(const std::shared_ptr<Indices>&... inds) const;
|
2018-12-02 17:40:50 +01:00
|
|
|
|
2019-02-19 16:35:01 +01:00
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto addto(const std::shared_ptr<Indices>&... inds) const;
|
2019-02-19 16:20:38 +01:00
|
|
|
|
2019-05-24 13:55:07 +02:00
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto pto(const std::shared_ptr<Indices>&... inds) const;
|
2019-05-24 13:55:07 +02:00
|
|
|
|
|
|
|
template <class... Indices>
|
2021-07-01 17:55:46 +02:00
|
|
|
auto paddto(const std::shared_ptr<Indices>&... inds) const;
|
2019-05-24 13:55:07 +02:00
|
|
|
|
2018-11-26 12:10:38 +01:00
|
|
|
template <typename R, class... Args> // Args = Operation Classes
|
2021-07-01 17:55:46 +02:00
|
|
|
auto a(const std::shared_ptr<function<R,T,typename Args::value_type...>>& ll, const Args&... args) const;
|
2021-03-17 20:09:43 +01:00
|
|
|
|
2021-07-01 17:55:46 +02:00
|
|
|
auto ptr() const;
|
2021-03-17 20:09:43 +01:00
|
|
|
|
2018-07-19 19:29:52 +02:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
friend OperationClass;
|
2018-05-18 20:23:21 +02:00
|
|
|
friend OperationTemplate<T,OperationClass>;
|
|
|
|
OperationBase() = default;
|
2017-08-11 11:30:27 +02:00
|
|
|
};
|
2018-05-18 17:45:40 +02:00
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
class OperationTemplate : public OperationBase<T,OperationClass>
|
2018-05-18 20:23:21 +02:00
|
|
|
{
|
|
|
|
/* empty per default; specialize if needed */
|
|
|
|
private:
|
|
|
|
OperationTemplate() = default;
|
|
|
|
friend OperationClass;
|
|
|
|
};
|
|
|
|
|
2020-09-02 18:35:20 +02:00
|
|
|
|
2019-01-15 14:34:59 +01:00
|
|
|
template <typename T>
|
|
|
|
struct SelfIdentity
|
|
|
|
{
|
2019-02-26 18:56:57 +01:00
|
|
|
static inline T& sapply(T& a, T b)
|
2019-01-15 14:34:59 +01:00
|
|
|
{
|
2019-02-14 14:39:59 +01:00
|
|
|
return a = b;
|
2019-01-15 14:34:59 +01:00
|
|
|
}
|
|
|
|
};
|
2019-01-15 17:41:43 +01:00
|
|
|
|
2020-07-09 11:52:40 +02:00
|
|
|
enum class OpIndexAff {
|
|
|
|
EXTERN = 0,
|
|
|
|
TARGET = 1
|
|
|
|
};
|
2021-01-14 14:43:09 +01:00
|
|
|
|
2021-01-18 19:00:12 +01:00
|
|
|
template <class T>
|
|
|
|
struct VType
|
|
|
|
{
|
|
|
|
typedef T type;
|
|
|
|
static constexpr size_t MULT = sizeof(type)/sizeof(T);
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct VType<double>
|
|
|
|
{
|
|
|
|
typedef v256 type;
|
|
|
|
static constexpr size_t MULT = sizeof(type)/sizeof(double);
|
|
|
|
};
|
|
|
|
|
|
|
|
template <template <typename...> class F,typename... Ts>
|
|
|
|
inline auto mkVFuncPtr(const std::shared_ptr<F<Ts...>>& f)
|
|
|
|
{
|
|
|
|
return std::shared_ptr<F<typename VType<Ts>::type...>>();
|
|
|
|
// empty, implement corresponding constructors...!!!
|
|
|
|
}
|
|
|
|
|
|
|
|
template <template <typename...> class F,typename... Ts>
|
|
|
|
inline auto mkVFunc(const F<Ts...>& f)
|
|
|
|
{
|
|
|
|
return F<typename VType<Ts>::type...>();
|
|
|
|
// empty, implement corresponding constructors...!!!
|
|
|
|
}
|
|
|
|
|
2021-07-09 16:54:30 +02:00
|
|
|
/*
|
2021-01-18 19:00:12 +01:00
|
|
|
template <class F>
|
|
|
|
using VFunc = decltype(mkVFunc(std::declval<F>()));
|
2021-07-09 16:54:30 +02:00
|
|
|
*/
|
|
|
|
template <class F>
|
|
|
|
using VFunc = F;
|
2021-07-01 01:51:10 +02:00
|
|
|
|
|
|
|
template <typename T, class F, class... Indices>
|
|
|
|
class OpAccess
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
std::tuple<std::shared_ptr<Indices>...> mInds;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static constexpr bool ISSTATIC = false;
|
|
|
|
|
|
|
|
template <typename Op, class ExtType>
|
|
|
|
inline void operator()(T*& t, size_t pos, const Op& op, ExtType e)
|
|
|
|
{
|
|
|
|
F::selfApply(t[pos](mInds), op.get(e)); // s.th. like that
|
|
|
|
// TODO for classes related to the r.h.s.:
|
|
|
|
// forward get(e) to elements returned by get(e) until basic types are reached
|
|
|
|
// (also same for rootSteps etc...) !!!!
|
|
|
|
// introduce traits !!!!
|
|
|
|
// !!!!
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-01-23 19:40:15 +01:00
|
|
|
template <typename T, class F>
|
2021-01-18 19:00:12 +01:00
|
|
|
struct IAccess
|
|
|
|
{
|
2021-07-01 01:51:10 +02:00
|
|
|
static constexpr bool ISSTATIC = true;
|
2021-01-23 19:40:15 +01:00
|
|
|
typedef T value_type;
|
|
|
|
typedef T in_type;
|
2021-07-09 16:54:30 +02:00
|
|
|
typedef F Func;
|
2021-01-23 19:40:15 +01:00
|
|
|
static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type);
|
|
|
|
|
|
|
|
template <typename Op, class ExtType>
|
2021-07-09 16:54:30 +02:00
|
|
|
static inline void f(T* t, size_t pos, const Op& op, ExtType e)
|
2021-01-18 19:00:12 +01:00
|
|
|
{
|
|
|
|
F::selfApply(t[pos],op.get(e));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-07-09 16:54:30 +02:00
|
|
|
template <typename T, class F>
|
|
|
|
using IVAccess = IAccess<T,F>;
|
|
|
|
/*
|
2021-01-23 19:40:15 +01:00
|
|
|
template <typename T, class F>
|
2021-01-18 19:00:12 +01:00
|
|
|
struct IVAccess
|
|
|
|
{
|
2021-07-01 01:51:10 +02:00
|
|
|
static constexpr bool ISSTATIC = true;
|
2021-01-23 19:40:15 +01:00
|
|
|
typedef typename VType<T>::type value_type;
|
|
|
|
typedef T in_type;
|
2021-07-09 16:54:30 +02:00
|
|
|
typedef VFunc<F> Func;
|
2021-01-23 19:40:15 +01:00
|
|
|
static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type);
|
|
|
|
|
|
|
|
template <typename Op, class ExtType>
|
2021-01-18 19:00:12 +01:00
|
|
|
static inline void f(T*& t, size_t pos, const Op& op, ExtType e)
|
|
|
|
{
|
2021-01-24 02:10:06 +01:00
|
|
|
//VCHECK(pos);
|
2021-01-24 00:10:14 +01:00
|
|
|
VFunc<F>::selfApply(*reinterpret_cast<value_type*>(t+pos),op.template vget<value_type>(e));
|
2021-01-18 19:00:12 +01:00
|
|
|
}
|
|
|
|
};
|
2021-07-09 16:54:30 +02:00
|
|
|
*/
|
2021-01-18 19:00:12 +01:00
|
|
|
|
2021-01-21 00:35:13 +01:00
|
|
|
template <typename T>
|
|
|
|
using xxxplus = plus<T>;
|
2020-07-09 11:52:40 +02:00
|
|
|
|
2021-01-18 19:00:12 +01:00
|
|
|
template <typename T>
|
2021-01-23 19:40:15 +01:00
|
|
|
using IAssign = IAccess<T,identity<T>>;
|
2021-01-18 19:00:12 +01:00
|
|
|
|
|
|
|
template <typename T>
|
2021-01-23 19:40:15 +01:00
|
|
|
using IPlus = IAccess<T,plus<T>>;
|
2021-01-18 19:00:12 +01:00
|
|
|
|
2021-01-23 19:40:15 +01:00
|
|
|
template <typename T>
|
|
|
|
using IVAssign = IVAccess<T,identity<T>>;
|
2021-01-18 19:00:12 +01:00
|
|
|
|
2021-01-23 19:40:15 +01:00
|
|
|
template <typename T>
|
|
|
|
using IVPlus = IVAccess<T,plus<T>>;
|
2021-07-01 17:55:46 +02:00
|
|
|
|
|
|
|
// static polymorphism
|
|
|
|
template <class AccessClass>
|
|
|
|
class AccessTemplate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef AccessClass AC;
|
2021-07-14 22:01:07 +02:00
|
|
|
|
|
|
|
AccessTemplate(const AccessTemplate& in) = default;
|
|
|
|
AccessTemplate(AccessTemplate&& in) = default;
|
|
|
|
AccessTemplate& operator=(const AccessTemplate& in) = default;
|
|
|
|
AccessTemplate& operator=(AccessTemplate&& in) = default;
|
|
|
|
|
2021-07-01 17:55:46 +02:00
|
|
|
AccessClass& THIS() { return static_cast<AccessClass&>(*this); }
|
|
|
|
const AccessClass& THIS() const { return static_cast<const AccessClass&>(*this); }
|
|
|
|
|
|
|
|
inline auto get(size_t pos);
|
|
|
|
inline auto get(size_t pos) const;
|
2021-07-09 16:54:30 +02:00
|
|
|
inline auto oget(size_t pos) const;
|
2021-07-01 17:55:46 +02:00
|
|
|
|
|
|
|
template <class F, typename Op, class ExtType>
|
|
|
|
inline void exec(size_t pos, const Op& op, ExtType e) const;
|
2021-07-09 16:54:30 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
AccessTemplate() = default;
|
2021-07-01 17:55:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class PointerAccess : public AccessTemplate<PointerAccess<T>>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef T value_type;
|
|
|
|
typedef T in_type;
|
2021-07-14 22:01:07 +02:00
|
|
|
|
|
|
|
friend class AccessTemplate<PointerAccess<T>>;
|
2021-07-01 17:55:46 +02:00
|
|
|
private:
|
2021-07-09 16:54:30 +02:00
|
|
|
PointerAccess() = default;
|
|
|
|
|
|
|
|
T* mPtr = nullptr;
|
|
|
|
T* mOrigPtr = nullptr;
|
2021-07-01 17:55:46 +02:00
|
|
|
|
|
|
|
public:
|
2021-07-18 18:40:10 +02:00
|
|
|
PointerAccess(T* ptr, T* origPtr) : mPtr(ptr), mOrigPtr(origPtr) {}
|
|
|
|
|
2021-07-09 16:54:30 +02:00
|
|
|
PointerAccess(const PointerAccess& in) = default;
|
|
|
|
PointerAccess(PointerAccess&& in) = default;
|
|
|
|
PointerAccess& operator=(const PointerAccess& in) = default;
|
|
|
|
PointerAccess& operator=(PointerAccess&& in) = default;
|
2021-07-14 22:01:07 +02:00
|
|
|
|
2021-07-01 18:15:12 +02:00
|
|
|
T* get(size_t pos) { return mPtr+pos; }
|
|
|
|
T* get(size_t pos) const { return mPtr+pos; }
|
|
|
|
PointerAccess<T>& set(size_t pos) { mPtr = mOrigPtr + pos; return *this; }
|
2021-07-09 16:54:30 +02:00
|
|
|
T* oget(size_t pos) const { return mOrigPtr+pos; }
|
2021-07-01 17:55:46 +02:00
|
|
|
|
|
|
|
template <class F, typename Op, class ExtType>
|
|
|
|
inline void exec(size_t pos, const Op& op, ExtType e) const
|
|
|
|
{
|
|
|
|
F::selfApply(*get(pos),op.get(e));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-07-09 16:54:30 +02:00
|
|
|
template <typename T, class IOp, class AT, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
2021-01-14 19:20:46 +01:00
|
|
|
class AssignmentExpr : public ExpressionBase
|
2019-03-22 19:07:29 +01:00
|
|
|
{
|
|
|
|
private:
|
2021-01-14 19:20:46 +01:00
|
|
|
AssignmentExpr() = default;
|
2019-03-22 19:07:29 +01:00
|
|
|
|
|
|
|
Target mTar;
|
|
|
|
OpClass mSec;
|
2021-07-14 22:01:07 +02:00
|
|
|
AT mDataAcc;
|
2019-03-22 19:07:29 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
static constexpr size_t LAYER = 0;
|
2021-01-24 02:10:06 +01:00
|
|
|
static constexpr size_t NHLAYER = 0;
|
2019-03-22 19:07:29 +01:00
|
|
|
static constexpr size_t SIZE = Target::SIZE + OpClass::SIZE;
|
|
|
|
typedef decltype(mTar.rootSteps(0).extend( mSec.rootSteps(0) )) ExtType;
|
|
|
|
|
2021-07-18 18:40:10 +02:00
|
|
|
AssignmentExpr(const AccessTemplate<AT>& dataAcc, const Target& tar, const OpClass& sec);
|
2021-01-14 19:20:46 +01:00
|
|
|
AssignmentExpr(const AssignmentExpr& in) = default;
|
|
|
|
AssignmentExpr(AssignmentExpr&& in) = default;
|
|
|
|
AssignmentExpr& operator=(const AssignmentExpr& in) = default;
|
|
|
|
AssignmentExpr& operator=(AssignmentExpr&& in) = default;
|
2020-08-29 21:46:07 +02:00
|
|
|
|
|
|
|
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
|
|
|
{
|
2021-07-09 16:54:30 +02:00
|
|
|
return std::make_shared<AssignmentExpr<T,IOp,PointerAccess<T>,Target,OpClass,OIA>>(*this);
|
2020-08-29 21:46:07 +02:00
|
|
|
}
|
|
|
|
|
2019-03-22 19:07:29 +01:00
|
|
|
inline void operator()(size_t start = 0);
|
|
|
|
inline void operator()(size_t start, ExtType last);
|
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
2020-07-07 16:42:41 +02:00
|
|
|
|
|
|
|
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;
|
2019-03-22 19:07:29 +01:00
|
|
|
};
|
|
|
|
|
2021-01-14 19:20:46 +01:00
|
|
|
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
2021-07-09 16:54:30 +02:00
|
|
|
using AssignmentExpr2 = AssignmentExpr<T,IAssign<T>,PointerAccess<T>,Target,OpClass,OIA>;
|
2021-01-14 19:20:46 +01:00
|
|
|
|
|
|
|
template <typename T, class Target, class OpClass, OpIndexAff OIA=OpIndexAff::EXTERN>
|
2021-07-09 16:54:30 +02:00
|
|
|
using AddExpr = AssignmentExpr<T,IPlus<T>,PointerAccess<T>,Target,OpClass,OIA>;
|
2021-01-14 19:20:46 +01:00
|
|
|
|
2021-04-11 16:34:01 +02:00
|
|
|
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
|
|
|
|
{
|
2021-06-08 16:41:28 +02:00
|
|
|
return sfor_p<0,sizeof...(Ops)>
|
|
|
|
( [&](auto i){ return std::get<i>(mOps).rootSteps(iPtrNum); },
|
|
|
|
[&](auto f, auto next) { return f.extend(next); } );
|
2021-04-11 16:34:01 +02:00
|
|
|
}
|
|
|
|
|
2020-09-02 18:35:20 +02:00
|
|
|
template <typename T, class... Ops>
|
|
|
|
class MOp
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
MOp() = default;
|
2021-04-11 16:34:01 +02:00
|
|
|
OperationTuple<Ops...> mOps;
|
|
|
|
|
2020-09-02 18:35:20 +02:00
|
|
|
public:
|
|
|
|
static constexpr size_t LAYER = 0;
|
2021-01-24 02:10:06 +01:00
|
|
|
static constexpr size_t NHLAYER = 0;
|
2021-04-10 16:06:02 +02:00
|
|
|
static constexpr size_t SIZE = (... + Ops::SIZE);
|
2021-04-11 16:34:01 +02:00
|
|
|
typedef decltype(mOps.rootSteps(0)) ExtType;
|
|
|
|
|
2020-09-02 18:35:20 +02:00
|
|
|
MOp(const Ops&... exprs);
|
|
|
|
|
|
|
|
MOp(const MOp& in) = default;
|
|
|
|
MOp(MOp&& in) = default;
|
|
|
|
MOp& operator=(const MOp& in) = default;
|
|
|
|
MOp& operator=(MOp&& in) = default;
|
|
|
|
|
|
|
|
inline size_t get(ExtType last) const;
|
2021-01-14 14:43:09 +01:00
|
|
|
|
|
|
|
template <typename V>
|
|
|
|
inline size_t vget(ExtType last) const { return get(last); }
|
|
|
|
|
2020-09-02 18:35:20 +02:00
|
|
|
inline MOp& set(ExtType last);
|
2021-04-11 16:34:01 +02:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
2020-09-02 18:35:20 +02:00
|
|
|
|
|
|
|
template <class Expr>
|
2021-04-11 16:34:01 +02:00
|
|
|
auto loop(Expr exp) const;
|
2020-09-02 18:35:20 +02:00
|
|
|
|
|
|
|
T* data() const { assert(0); return nullptr; }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-08-28 17:55:54 +02:00
|
|
|
template <class OpClass, class NextExpr>
|
|
|
|
class GetExpr : public ExpressionBase
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
GetExpr() = default;
|
|
|
|
|
|
|
|
OpClass mSec;
|
|
|
|
NextExpr mNExpr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
static constexpr size_t LAYER = 0;
|
2021-01-24 02:10:06 +01:00
|
|
|
static constexpr size_t NHLAYER = 0;
|
2020-08-28 17:55:54 +02:00
|
|
|
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;
|
2020-08-29 21:46:07 +02:00
|
|
|
GetExpr& operator=(const GetExpr& in) = default;
|
|
|
|
GetExpr& operator=(GetExpr&& in) = default;
|
2020-08-28 17:55:54 +02:00
|
|
|
|
2020-08-29 21:46:07 +02:00
|
|
|
virtual std::shared_ptr<ExpressionBase> deepCopy() const override final
|
|
|
|
{
|
|
|
|
return std::make_shared<GetExpr<OpClass,NextExpr>>(*this);
|
|
|
|
}
|
|
|
|
|
2020-08-28 17:55:54 +02:00
|
|
|
inline void operator()(size_t start = 0);
|
2020-09-02 18:35:20 +02:00
|
|
|
inline void get(ExtType last);
|
2021-01-14 14:43:09 +01:00
|
|
|
|
|
|
|
template <typename V>
|
|
|
|
inline void vget(ExtType last) { get(last); }
|
|
|
|
|
2020-08-28 17:55:54 +02:00
|
|
|
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);
|
|
|
|
}
|
2020-09-02 18:35:20 +02:00
|
|
|
|
|
|
|
template <typename T, class... Ops>
|
|
|
|
auto mkMOp(const Ops&... exprs)
|
|
|
|
{
|
|
|
|
return MOp<T,Ops...>(exprs...);
|
|
|
|
}
|
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2018-05-18 17:45:40 +02:00
|
|
|
class ConstOperationRoot : public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
|
2017-03-16 19:30:43 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,ConstOperationRoot<T,Ranges...> > OT;
|
2021-05-28 19:48:27 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
2021-05-28 17:29:13 +02:00
|
|
|
typedef ConstContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = 1;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = true;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = true;
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2018-03-17 20:25:16 +01:00
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
ConstOperationRoot(const T* data, const IndexType& ind);
|
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2019-02-27 13:37:53 +01:00
|
|
|
inline const T& get(ET pos) const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline const V& vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline ConstOperationRoot& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2020-07-09 17:37:28 +02:00
|
|
|
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2018-09-11 18:38:30 +02:00
|
|
|
|
|
|
|
const T* data() const;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
const T* mDataPtr;
|
2019-02-26 18:56:57 +01:00
|
|
|
const T* mOrigDataPtr;
|
|
|
|
IndexType mIndex;
|
2018-09-16 15:53:56 +02:00
|
|
|
std::shared_ptr<MultiArrayBase<T,Ranges...> > mMaPtr; // never remove this ptr, otherwise we lose temporary container instances!
|
2017-03-16 19:30:43 +01:00
|
|
|
};
|
2018-07-29 19:17:26 +02:00
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
template <typename T, class Op>
|
|
|
|
class StaticCast : public OperationTemplate<T,StaticCast<T,Op> >
|
|
|
|
{
|
|
|
|
private:
|
2019-02-26 18:56:57 +01:00
|
|
|
Op mOp;
|
2018-08-06 12:46:12 +02:00
|
|
|
|
|
|
|
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;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = false;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = false;
|
2018-08-06 12:46:12 +02:00
|
|
|
|
|
|
|
StaticCast(const Op& op);
|
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline T get(ET pos) const;
|
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline V vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline StaticCast& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-11-26 13:13:23 +01:00
|
|
|
template <class Range>
|
|
|
|
class MetaOperationRoot : public OperationTemplate<typename Range::MetaType,
|
|
|
|
MetaOperationRoot<Range> >
|
2018-07-29 19:17:26 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-11-26 13:13:23 +01:00
|
|
|
typedef typename Range::IndexType IndexType;
|
2018-07-29 19:17:26 +02:00
|
|
|
typedef typename IndexType::MetaType value_type;
|
2018-11-26 13:13:23 +01:00
|
|
|
typedef OperationBase<value_type,MetaOperationRoot<Range> > OT;
|
2018-07-29 19:17:26 +02:00
|
|
|
|
|
|
|
static constexpr size_t SIZE = 1;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = false;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = false;
|
2019-02-27 13:37:53 +01:00
|
|
|
|
2018-11-26 13:13:23 +01:00
|
|
|
MetaOperationRoot(const std::shared_ptr<IndexType>& ind);
|
2018-07-29 19:17:26 +02:00
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline value_type get(ET pos) const;
|
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline V vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline MetaOperationRoot& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2020-07-09 17:37:28 +02:00
|
|
|
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-07-29 19:17:26 +02:00
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2018-11-26 18:23:38 +01:00
|
|
|
mutable IndexType mWorkIndex;
|
2018-11-26 13:13:23 +01:00
|
|
|
std::shared_ptr<IndexType> mIndex;
|
2018-07-29 19:17:26 +02:00
|
|
|
};
|
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2018-01-05 13:56:16 +01:00
|
|
|
class OperationRoot : public OperationTemplate<T,OperationRoot<T,Ranges...> >
|
2017-03-26 16:55:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,OperationRoot<T,Ranges...> > OT;
|
2021-05-28 19:48:27 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
2021-05-28 17:29:13 +02:00
|
|
|
typedef ConstContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
2018-01-04 11:43:45 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = 1;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = true;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = true;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2021-07-09 16:54:30 +02:00
|
|
|
T* mDataPtr;
|
|
|
|
T* mOrigDataPtr;
|
2021-07-01 18:15:12 +02:00
|
|
|
PointerAccess<T> mDataAcc;
|
2019-03-06 13:08:33 +01:00
|
|
|
IndexType mIndex;
|
|
|
|
|
|
|
|
public:
|
2017-08-25 17:02:23 +02:00
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2017-08-11 11:30:27 +02:00
|
|
|
|
2020-08-29 23:36:01 +02:00
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::tuple<std::shared_ptr<typename Ranges::IndexType>...>& indices);
|
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
OperationRoot(T* data, const IndexType& ind);
|
2019-01-15 14:34:59 +01:00
|
|
|
|
2021-01-15 01:05:58 +01:00
|
|
|
template <class IOp, class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asx(const OpClass& in) const;
|
2019-01-15 17:41:43 +01:00
|
|
|
|
2021-01-15 01:05:58 +01:00
|
|
|
template <class IOp, class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asxExpr(const OpClass& in) const;
|
2019-09-13 15:08:33 +02:00
|
|
|
|
2021-01-15 01:05:58 +01:00
|
|
|
template <class IOp, class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asx(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2019-03-22 19:07:29 +01:00
|
|
|
|
2019-01-15 14:34:59 +01:00
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assign(const OpClass& in) const;
|
2019-01-15 17:41:43 +01:00
|
|
|
|
2021-01-15 01:05:58 +01:00
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assignExpr(const OpClass& in) const;
|
2021-01-15 01:05:58 +01:00
|
|
|
|
2019-03-22 19:07:29 +01:00
|
|
|
template <class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2021-01-15 01:05:58 +01:00
|
|
|
|
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto plus(const OpClass& in) const;
|
2019-11-13 14:08:15 +01:00
|
|
|
|
|
|
|
template <class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2019-11-13 14:08:15 +01:00
|
|
|
|
2019-02-26 18:56:57 +01:00
|
|
|
template <class OpClass>
|
|
|
|
OperationRoot& operator=(const OpClass& in);
|
|
|
|
|
|
|
|
template <class OpClass>
|
|
|
|
OperationRoot& operator+=(const OpClass& in);
|
|
|
|
|
|
|
|
OperationRoot& operator=(const OperationRoot& in);
|
|
|
|
|
2019-03-06 13:08:33 +01:00
|
|
|
ParallelOperationRoot<T,Ranges...> par();
|
2019-01-15 17:41:43 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2019-02-27 13:37:53 +01:00
|
|
|
inline T& get(ET pos) const;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline V& vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline OperationRoot& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2020-07-09 17:37:28 +02:00
|
|
|
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
2018-03-06 13:58:17 +01:00
|
|
|
T* data() const;
|
2017-05-24 19:01:02 +02:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <class... Indices>
|
|
|
|
auto sl(const std::shared_ptr<Indices>&... inds)
|
|
|
|
-> Slice<T,typename Indices::RangeType...>;
|
|
|
|
|
2019-03-06 13:08:33 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2021-05-28 19:48:27 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
2021-05-28 17:29:13 +02:00
|
|
|
typedef ConstContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
|
|
|
static constexpr size_t SIZE = 1;
|
|
|
|
static constexpr bool CONT = true;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = true;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
T* mDataPtr;
|
2019-02-26 18:56:57 +01:00
|
|
|
T* mOrigDataPtr;
|
2021-07-09 16:54:30 +02:00
|
|
|
PointerAccess<T> mDataAcc;
|
2019-02-26 18:56:57 +01:00
|
|
|
IndexType mIndex;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
ParallelOperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
|
|
|
|
|
|
ParallelOperationRoot(T* data, const IndexType& ind);
|
|
|
|
|
2021-01-21 00:35:13 +01:00
|
|
|
template <class IOp, class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asx(const OpClass& in) const;
|
2021-01-21 00:35:13 +01:00
|
|
|
|
|
|
|
template <class IOp, class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asxExpr(const OpClass& in) const;
|
2021-01-21 00:35:13 +01:00
|
|
|
|
|
|
|
template <class IOp, class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto asx(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2021-01-21 00:35:13 +01:00
|
|
|
|
2019-03-06 13:08:33 +01:00
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assign(const OpClass& in) const;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
2021-01-21 00:35:13 +01:00
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assignExpr(const OpClass& in) const;
|
2021-01-21 00:35:13 +01:00
|
|
|
|
2020-09-16 20:19:21 +02:00
|
|
|
template <class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto assign(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2021-01-21 00:35:13 +01:00
|
|
|
|
2020-09-16 20:19:21 +02:00
|
|
|
template <class OpClass>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto plus(const OpClass& in) const;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
2020-09-16 20:19:21 +02:00
|
|
|
template <class OpClass, class Index>
|
2021-07-09 16:54:30 +02:00
|
|
|
auto plus(const OpClass& in, const std::shared_ptr<Index>& i) const;
|
2020-09-16 20:19:21 +02:00
|
|
|
|
2019-03-06 13:08:33 +01:00
|
|
|
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;
|
2021-01-14 14:43:09 +01:00
|
|
|
|
|
|
|
template <typename V, class ET>
|
|
|
|
inline V& vget(ET pos) const;
|
2019-03-06 13:08:33 +01:00
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline ParallelOperationRoot& set(ET pos);
|
|
|
|
|
2020-07-09 17:37:28 +02:00
|
|
|
MExt<None> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2019-03-06 13:08:33 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
T* data() const;
|
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
};
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-07-17 20:01:25 +02:00
|
|
|
template <typename T>
|
|
|
|
class OperationValue : public OperationTemplate<T,OperationValue<T> >
|
|
|
|
{
|
2018-07-17 22:10:36 +02:00
|
|
|
public:
|
2018-07-17 20:01:25 +02:00
|
|
|
typedef T value_type;
|
|
|
|
typedef OperationBase<T,OperationValue<T> > OT;
|
2021-05-28 19:48:27 +02:00
|
|
|
typedef ContainerRange<NullRange> CRange;
|
2021-05-28 17:29:13 +02:00
|
|
|
typedef ConstContainerIndex<T,NullIndex> IndexType;
|
2018-07-17 20:01:25 +02:00
|
|
|
|
2019-03-12 21:00:15 +01:00
|
|
|
static constexpr size_t SIZE = 0;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = true;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = false;
|
2018-07-17 20:01:25 +02:00
|
|
|
|
|
|
|
OperationValue(const T& val);
|
|
|
|
|
|
|
|
template <class ET>
|
2019-02-27 13:37:53 +01:00
|
|
|
inline const T& get(ET pos) const;
|
2018-07-17 20:01:25 +02:00
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline V vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline OperationValue& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2019-03-12 21:00:15 +01:00
|
|
|
None rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-07-17 20:01:25 +02:00
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
T mVal;
|
|
|
|
};
|
|
|
|
|
2021-03-17 20:09:43 +01:00
|
|
|
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;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2021-03-17 20:09:43 +01:00
|
|
|
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; }
|
|
|
|
};
|
2021-05-04 17:11:53 +02:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-01-05 13:56:16 +01:00
|
|
|
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
2017-03-22 11:44:33 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OpFunction F;
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2021-04-10 16:06:02 +02:00
|
|
|
static constexpr size_t SIZE = (... + Ops::SIZE);
|
2018-03-21 19:18:57 +01:00
|
|
|
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = false;
|
2021-04-10 16:06:02 +02:00
|
|
|
static constexpr bool VABLE =
|
|
|
|
(... and (Ops::VABLE and std::is_same<T,typename Ops::value_type>::value));
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
private:
|
2021-04-11 16:34:01 +02:00
|
|
|
OperationTuple<Ops...> mOps;
|
2018-03-21 19:18:57 +01:00
|
|
|
std::shared_ptr<OpFunction> mF; // only if non-static
|
2021-04-11 16:34:01 +02:00
|
|
|
typedef decltype(mOps.rootSteps(0)) ExtType;
|
2018-03-21 19:18:57 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
public:
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2017-08-11 15:26:10 +02:00
|
|
|
Operation(const Ops&... ops);
|
2018-04-28 17:33:57 +02:00
|
|
|
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
|
2021-04-11 22:11:20 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2019-05-20 18:32:19 +02:00
|
|
|
inline auto get(ET pos) const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline auto vget(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline Operation& set(ET pos);
|
2021-04-11 16:34:01 +02:00
|
|
|
|
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const
|
|
|
|
-> ExtType; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2021-04-10 16:06:02 +02:00
|
|
|
auto loop(Expr exp) const;
|
2020-08-24 17:39:56 +02:00
|
|
|
|
|
|
|
T* data() const { assert(0); return nullptr; }
|
2017-03-22 11:44:33 +01:00
|
|
|
};
|
2018-09-12 20:56:55 +02:00
|
|
|
|
2018-03-21 16:11:05 +01:00
|
|
|
template <class OpFunction, class... Ops>
|
2018-09-12 20:56:55 +02:00
|
|
|
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
2018-03-21 19:18:57 +01:00
|
|
|
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
2018-03-21 16:11:05 +01:00
|
|
|
{
|
2021-04-10 16:06:02 +02:00
|
|
|
if constexpr(OpFunction::FISSTATIC){
|
|
|
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
|
|
|
|
}
|
2018-03-21 16:11:05 +01:00
|
|
|
}
|
2017-11-04 22:49:55 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
2017-11-04 22:49:55 +01:00
|
|
|
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
2017-11-01 21:26:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,Contraction<T,Op,IndexType> > OT;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = Op::SIZE;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = Op::CONT;
|
2021-01-18 19:00:12 +01:00
|
|
|
static constexpr bool VABLE = Op::VABLE;
|
2019-02-27 13:37:53 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
|
|
|
|
2019-02-26 18:56:57 +01:00
|
|
|
Op mOp;
|
2018-01-09 17:24:10 +01:00
|
|
|
std::shared_ptr<IndexType> mInd;
|
|
|
|
|
|
|
|
public:
|
2018-01-14 19:15:05 +01:00
|
|
|
typedef decltype(mOp.rootSteps(0)) ETuple;
|
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
Contraction(const Op& op, std::shared_ptr<IndexType> ind);
|
2017-11-01 21:26:45 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2019-02-27 13:37:53 +01:00
|
|
|
inline auto get(ET pos) const
|
|
|
|
-> decltype(mOp.template get<ET>(pos));
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2021-01-14 14:43:09 +01:00
|
|
|
template <typename V, class ET>
|
|
|
|
inline auto vget(ET pos) const
|
|
|
|
-> decltype(mOp.template vget<V,ET>(pos));
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2019-02-26 18:56:57 +01:00
|
|
|
inline Contraction& set(ET pos);
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2020-08-26 17:05:44 +02:00
|
|
|
T* data() const { assert(0); return nullptr; }
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
2018-12-24 18:55:11 +01:00
|
|
|
auto loop(Expr exp) const
|
|
|
|
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
2017-11-01 21:26:45 +01:00
|
|
|
};
|
2018-05-15 21:18:21 +02:00
|
|
|
|
2021-06-26 00:40:42 +02:00
|
|
|
// for SliceArray
|
2021-07-01 00:42:31 +02:00
|
|
|
/*
|
2021-06-26 00:40:42 +02:00
|
|
|
template <typename T, class Op>
|
|
|
|
class HyperOperation : public OperationTemplate<T,HyperOperation<T,Op> >
|
2018-09-14 17:50:19 +02:00
|
|
|
{
|
|
|
|
public:
|
2021-06-26 00:40:42 +02:00
|
|
|
|
|
|
|
typedef Op value_type;
|
|
|
|
typedef OperationTemplate<T,HyperOperation<T,Op> > OT;
|
2018-09-14 17:50:19 +02:00
|
|
|
|
|
|
|
static constexpr size_t SIZE = Op::SIZE;
|
2019-02-27 13:37:53 +01:00
|
|
|
static constexpr bool CONT = false;
|
2021-06-26 00:40:42 +02:00
|
|
|
static constexpr bool VABLE = false;
|
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
private:
|
|
|
|
|
2021-06-26 00:40:42 +02:00
|
|
|
Op mOp; // proto
|
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
public:
|
2021-06-26 00:40:42 +02:00
|
|
|
//typedef decltype(mOp.rootSteps(0)) ETuple;
|
2018-09-25 14:06:17 +02:00
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
template <class ET>
|
2021-06-26 00:40:42 +02:00
|
|
|
// 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));
|
2018-09-14 17:50:19 +02:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2021-06-26 00:40:42 +02:00
|
|
|
inline HyperOperation& set(ET pos);
|
|
|
|
|
|
|
|
T* data() const { assert(0); return nullptr; }
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
2021-06-26 00:40:42 +02:00
|
|
|
auto loop(Expr exp) const
|
|
|
|
-> decltype(mInd->iforh(1,mOp.loop(exp)));
|
|
|
|
};
|
2021-07-01 00:42:31 +02:00
|
|
|
*/
|
2017-08-11 15:26:10 +02:00
|
|
|
}
|
2017-02-16 11:20:40 +01:00
|
|
|
|
|
|
|
|
2018-05-18 20:23:21 +02:00
|
|
|
#include "type_operations.h"
|
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
#endif
|