cnorxz/src/multi_array_operation.h

144 lines
3.9 KiB
C
Raw Normal View History

2017-02-16 11:20:40 +01:00
// -*- C++ -*-
#ifndef __multi_array_operation_h__
#define __multi_array_operation_h__
#include <cstdlib>
#include <tuple>
#include "base_def.h"
#include "index_base.h"
namespace MultiArrayTools
{
template <typename T>
2017-02-16 11:20:40 +01:00
class MultiArrayOperationBase
{
public:
2017-02-24 20:50:58 +01:00
MultiArrayOperationBase() = default;
virtual ~MultiArrayOperationBase();
virtual size_t argNum() const = 0;
IndefinitIndexBase* index();
virtual void linkIndicesTo(IndefinitIndexBase* target) const = 0;
virtual T& get() = 0;
virtual const T& get() const = 0;
protected:
IndefinitIndexBase* mIibPtr = nullptr;
};
template <typename T, class Range>
class MultiArrayOperationRoot : public MultiArrayOperationBase<T>
{
public:
typedef MultiArrayOperationBase<T> MAOB;
typedef decltype(MultiArray<T,Range>().begin()) IndexType;
2017-02-16 11:20:40 +01:00
MultiArrayOperationRoot(MultiArray<T,Range>& ma, const Name& nm);
2017-02-24 20:50:58 +01:00
MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in);
template <class Operation, class... MAOps>
MultiArrayOperationRoot& operator=(const MultiArrayOperation<T,Operation,MAOps...>& in);
2017-02-22 00:43:38 +01:00
2017-02-24 20:50:58 +01:00
//MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in) = delete;
//MultiArrayOperationRoot(const MultiArrayOperationRoot& in) = default;
2017-02-16 11:20:40 +01:00
// execute AnyOperation
// exception if range types are inconsitent with names
//MultiArrayOperationRoot& operator=(const MultiArrayOperationBase<T>& in);
2017-02-16 11:20:40 +01:00
template <class Operation, class... MAOps>
MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>
operator()(Operation& op, const MAOps&... secs);
template <class Operation, class... MAOps>
MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>
operator()(const Operation& op, const MAOps&... secs);
2017-02-16 11:20:40 +01:00
template <class MAOp>
auto operator+(const MAOp& sec) -> decltype(operator()(std::plus<T>(), sec));
2017-02-16 11:20:40 +01:00
template <class MAOp>
auto operator-(const MAOp& sec) -> decltype(operator()(std::minus<T>(), sec));
2017-02-16 11:20:40 +01:00
template <class MAOp>
auto operator*(const MAOp& sec) -> decltype(operator()(std::multiplies<T>(), sec));
2017-02-16 11:20:40 +01:00
template <class MAOp>
auto operator/(const MAOp& sec) -> decltype(operator()(std::divides<T>(), sec));
2017-02-16 11:20:40 +01:00
virtual size_t argNum() const override;
2017-02-16 11:20:40 +01:00
2017-02-23 19:33:46 +01:00
//IndexType& index() ;
2017-02-16 11:20:40 +01:00
virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
2017-02-22 00:43:38 +01:00
virtual T& get() override;
virtual const T& get() const override;
2017-02-16 11:20:40 +01:00
protected:
2017-02-16 11:20:40 +01:00
MultiArray<T,Range>& mArrayRef;
mutable IndexType mIndex;
Name mNm;
2017-02-16 11:20:40 +01:00
};
template <typename T, class Operation, class... MAOps>
class MultiArrayOperation : public MultiArrayOperationBase<T>
2017-02-16 11:20:40 +01:00
{
public:
typedef MultiArrayOperationBase<T> MAOB;
typedef std::tuple<MAOps...> OBT;
MultiArrayOperation(Operation& op, const MAOps&... secs);
MultiArrayOperation(const Operation& op, const MAOps&... secs);
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
2017-02-26 14:00:47 +01:00
operator()(Operation2& op, const MAOps2&... secs);
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
2017-02-26 14:00:47 +01:00
operator()(const Operation2& op, const MAOps2&... secs);
template <class MAOp2>
auto operator+(const MAOp2& sec) -> decltype(operator()(std::plus<T>(), sec));
template <class MAOp2>
auto operator-(const MAOp2& sec) -> decltype(operator()(std::minus<T>(), sec));
template <class MAOp2>
auto operator*(const MAOp2& sec) -> decltype(operator()(std::multiplies<T>(), sec));
template <class MAOp2>
auto operator/(const MAOp2& sec) -> decltype(operator()(std::divides<T>(), sec));
2017-02-16 11:20:40 +01:00
virtual size_t argNum() const override;
2017-02-22 00:43:38 +01:00
virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
2017-02-16 11:20:40 +01:00
virtual T& get() override;
virtual const T& get() const override;
2017-02-16 11:20:40 +01:00
protected:
2017-02-22 00:43:38 +01:00
mutable T mVal;
2017-02-16 11:20:40 +01:00
Operation mOp;
OBT mArgs; // include first arg also here !!!
2017-02-16 11:20:40 +01:00
};
}
#include "multi_array_operation.cc"
2017-02-16 11:20:40 +01:00
#endif