im com
This commit is contained in:
parent
0d2a5e22e2
commit
aa803b81f2
4 changed files with 115 additions and 49 deletions
67
src/block.cc
67
src/block.cc
|
@ -26,11 +26,35 @@ namespace MultiArrayHelper
|
||||||
OpFunction f;
|
OpFunction f;
|
||||||
BlockResult<T> res(mSize);
|
BlockResult<T> res(mSize);
|
||||||
for(size_t i = 0; i != mSize; ++i){
|
for(size_t i = 0; i != mSize; ++i){
|
||||||
res[i] = f(this->operator[](i), in[i]);
|
res[i] = f((*this)[i], in[i]);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockResult<T> BlockBase<T>::operator+(const BlockBase& in)
|
||||||
|
{
|
||||||
|
return operate<std::plus<T> >(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockResult<T> BlockBase<T>::operator-(const BlockBase& in)
|
||||||
|
{
|
||||||
|
return operate<std::minus<T> >(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockResult<T> BlockBase<T>::operator*(const BlockBase& in)
|
||||||
|
{
|
||||||
|
return operate<std::multiplies<T> >(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockResult<T> BlockBase<T>::operator/(const BlockBase& in)
|
||||||
|
{
|
||||||
|
return operate<std::divides<T> >(in);
|
||||||
|
}
|
||||||
|
|
||||||
/*************
|
/*************
|
||||||
* Block *
|
* Block *
|
||||||
*************/
|
*************/
|
||||||
|
@ -52,6 +76,13 @@ namespace MultiArrayHelper
|
||||||
{
|
{
|
||||||
return *(mBegPtr + i);
|
return *(mBegPtr + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Block<T>& Block<T>::set(const T* nbeg)
|
||||||
|
{
|
||||||
|
mBegPtr = nbeg;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
* BlockValue *
|
* BlockValue *
|
||||||
|
@ -73,26 +104,42 @@ namespace MultiArrayHelper
|
||||||
{
|
{
|
||||||
return mVal;
|
return mVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockValue<T>& BlockValue<T>::set(const T* nbeg)
|
||||||
|
{
|
||||||
|
mVal = *nbeg;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
* SplitBlock *
|
* SplitBlock *
|
||||||
******************/
|
******************/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SplitBlock<T>::SplitBlock(std::vector<T*>&& begPtrVec) :
|
SplitBlock<T>::SplitBlock(const std::vector<T>& data, size_t begPos,
|
||||||
BlockBase<T>(begPtrVec.size()),
|
size_t stepSize, size_t size) :
|
||||||
mBegPtr(begPtrVec) {}
|
BlockBase<T>(size),
|
||||||
|
mStepSize(stepSize),
|
||||||
|
mBegPtr(data.data() + begPos) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
BlockType SplitBlock<T>::type() const
|
BlockType SplitBlock<T>::type() const
|
||||||
{
|
{
|
||||||
return BlockType::SPLIT;
|
return BlockType::SPLIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const T& SplitBlock<T>::operator[](size_t pos) const
|
||||||
|
{
|
||||||
|
return *(mBegPtr + pos*mStepSize);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T& SplitBlock<T>::operator[](size_t i) const
|
SplitBlock<T>& SplitBlock<T>::set(const T* nbeg)
|
||||||
{
|
{
|
||||||
return *(mBegPtrVec[i]);
|
mBegPtr = nbeg;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
|
@ -122,6 +169,10 @@ namespace MultiArrayHelper
|
||||||
return mRes[i];
|
return mRes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BlockResult<T>& BlockResult<T>::set(const T* nbeg)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace MultiArrayHelper
|
} // end namespace MultiArrayHelper
|
||||||
|
|
30
src/block.h
30
src/block.h
|
@ -16,7 +16,7 @@ namespace MultiArrayHelper
|
||||||
BLOCK = 1,
|
BLOCK = 1,
|
||||||
VALUE = 2,
|
VALUE = 2,
|
||||||
SPLIT = 3,
|
SPLIT = 3,
|
||||||
RESULT = 4
|
RESULT = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
// manage vectorization in the future !!
|
// manage vectorization in the future !!
|
||||||
|
@ -33,8 +33,15 @@ namespace MultiArrayHelper
|
||||||
virtual size_t size() const;
|
virtual size_t size() const;
|
||||||
virtual const T& operator[](size_t pos) const = 0;
|
virtual const T& operator[](size_t pos) const = 0;
|
||||||
|
|
||||||
|
virtual BlockBase& set(const T* nbeg) = 0;
|
||||||
|
|
||||||
template <class OpFunction>
|
template <class OpFunction>
|
||||||
BlockResult<T> operate(const BlockBase& in);
|
BlockResult<T> operate(const BlockBase& in);
|
||||||
|
|
||||||
|
BlockResult<T> operator+(const BlockBase& in);
|
||||||
|
BlockResult<T> operator-(const BlockBase& in);
|
||||||
|
BlockResult<T> operator*(const BlockBase& in);
|
||||||
|
BlockResult<T> operator/(const BlockBase& in);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t mSize;
|
size_t mSize;
|
||||||
|
@ -49,9 +56,10 @@ namespace MultiArrayHelper
|
||||||
|
|
||||||
virtual BlockType type() const override;
|
virtual BlockType type() const override;
|
||||||
virtual const T& operator[](size_t pos) const override;
|
virtual const T& operator[](size_t pos) const override;
|
||||||
|
virtual Block& set(const T* nbeg) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T* mBegPtr;
|
const T* mBegPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -63,28 +71,29 @@ namespace MultiArrayHelper
|
||||||
|
|
||||||
virtual BlockType type() const override;
|
virtual BlockType type() const override;
|
||||||
virtual const T& operator[](size_t pos) const override;
|
virtual const T& operator[](size_t pos) const override;
|
||||||
|
virtual BlockValue& set(const T* nbeg) override;
|
||||||
virtual BlockBase& set(size_t begPos) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T mVal;
|
T mVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SplitBlock : public BlockBase<T>
|
class SplitBlock : public BlockBase<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SplitBlock() = default;
|
SplitBlock() = default;
|
||||||
SplitBlock(std::vector<T*>&& begPtrVec);
|
SplitBlock(const std::vector<T>& data, size_t begPos,
|
||||||
|
size_t stepSize, size_t size);
|
||||||
|
|
||||||
virtual BlockType type() const override;
|
virtual BlockType type() const override;
|
||||||
virtual const T& operator[](size_t pos) const override;
|
virtual const T& operator[](size_t pos) const override;
|
||||||
|
virtual SplitBlock& set(const T* nbeg) override;
|
||||||
virtual BlockBase& set(size_t begPos) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<T*> mBegPtrVec;
|
size_t mStepSize;
|
||||||
|
const T* mBegPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -97,8 +106,7 @@ namespace MultiArrayHelper
|
||||||
virtual BlockType type() const override;
|
virtual BlockType type() const override;
|
||||||
virtual const T& operator[](size_t pos) const override;
|
virtual const T& operator[](size_t pos) const override;
|
||||||
virtual T& operator[](size_t i);
|
virtual T& operator[](size_t i);
|
||||||
|
virtual BlockResult& set(const T* nbeg) override;
|
||||||
virtual BlockBase& set(size_t begPos) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<T> mRes;
|
std::vector<T> mRes;
|
||||||
|
|
|
@ -26,33 +26,33 @@ namespace MultiArrayTools
|
||||||
template <class OperationClass>
|
template <class OperationClass>
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto OperationTemplate<OperationClass>::operator+(const Second& in) const
|
auto OperationTemplate<OperationClass>::operator+(const Second& in) const
|
||||||
-> Operation<double,std::plus<double>,OperationClass,Second>
|
-> Operation<value_type,std::plus<value_type>,OperationClass,Second>
|
||||||
{
|
{
|
||||||
return Operation<double,std::plus<double>,OperationClass,Second>(*mOc, in);
|
return Operation<value_type,std::plus<value_type>,OperationClass,Second>(*mOc, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OperationClass>
|
template <class OperationClass>
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto OperationTemplate<OperationClass>::operator-(const Second& in) const
|
auto OperationTemplate<OperationClass>::operator-(const Second& in) const
|
||||||
-> Operation<double,std::minus<double>,OperationClass,Second>
|
-> Operation<value_type,std::minus<value_type>,OperationClass,Second>
|
||||||
{
|
{
|
||||||
return Operation<double,std::minus<double>,OperationClass,Second>(*mOc, in);
|
return Operation<value_type,std::minus<value_type>,OperationClass,Second>(*mOc, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OperationClass>
|
template <class OperationClass>
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto OperationTemplate<OperationClass>::operator*(const Second& in) const
|
auto OperationTemplate<OperationClass>::operator*(const Second& in) const
|
||||||
-> Operation<double,std::multiplies<double>,OperationClass,Second>
|
-> Operation<value_type,std::multiplies<value_type>,OperationClass,Second>
|
||||||
{
|
{
|
||||||
return Operation<double,std::multiplies<double>,OperationClass,Second>(*mOc, in);
|
return Operation<value_type,std::multiplies<value_type>,OperationClass,Second>(*mOc, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OperationClass>
|
template <class OperationClass>
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto OperationTemplate<OperationClass>::operator/(const Second& in) const
|
auto OperationTemplate<OperationClass>::operator/(const Second& in) const
|
||||||
-> Operation<double,std::divides<double>,OperationClass,Second>
|
-> Operation<double,std::divides<value_type>,OperationClass,Second>
|
||||||
{
|
{
|
||||||
return Operation<double,std::divides<double>,OperationClass,Second>(*mOc, in);
|
return Operation<value_type,std::divides<value_type>,OperationClass,Second>(*mOc, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
|
@ -76,13 +76,13 @@ namespace MultiArrayTools
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
BlockBase<T>& OperationMaster<T,Ranges...>::get(const IndexBase& ind)
|
BlockBase<T>& OperationMaster<T,Ranges...>::get()
|
||||||
{
|
{
|
||||||
return mArrayRef.data()[ mIndex->pos() ];
|
return mArrayRef.data()[ mIndex->pos() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
const BlockBase<T>& OperationMaster<T,Ranges...>::get(const IndexBase& ind) const
|
const BlockBase<T>& OperationMaster<T,Ranges...>::get() const
|
||||||
{
|
{
|
||||||
return mArrayRef.data()[ mIndex->pos() ];
|
return mArrayRef.data()[ mIndex->pos() ];
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ namespace MultiArrayTools
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
const BlockBase<T>& ConstOperationRoot<T,Ranges...>::get(const IndexBase& ind) const
|
const BlockBase<T>& ConstOperationRoot<T,Ranges...>::get() const
|
||||||
{
|
{
|
||||||
return mArrayRef[ (*mIndex)() ];
|
return mArrayRef[ (*mIndex)() ];
|
||||||
}
|
}
|
||||||
|
@ -128,13 +128,13 @@ namespace MultiArrayTools
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
const BlockBase<T>& OperationRoot<T,Ranges...>::get(const IndexBase& ind) const
|
const BlockBase<T>& OperationRoot<T,Ranges...>::get() const
|
||||||
{
|
{
|
||||||
return mArrayRef[ (*mIndex)() ];
|
return mArrayRef[ (*mIndex)() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class... Ranges>
|
template <typename T, class... Ranges>
|
||||||
BlockBase<T>& OperationRoot<T,Ranges...>::get(const IndexBase& ind)
|
BlockBase<T>& OperationRoot<T,Ranges...>::get()
|
||||||
{
|
{
|
||||||
return mArrayRef[ (*mIndex)() ];
|
return mArrayRef[ (*mIndex)() ];
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ namespace MultiArrayTools
|
||||||
mOps(ops...) {}
|
mOps(ops...) {}
|
||||||
|
|
||||||
template <typename T, class OpFunction, class... Ops>
|
template <typename T, class OpFunction, class... Ops>
|
||||||
const BlockBase<T>& Operation<T,OpFunction,Ops...>::get(const IndexBase& ind) const
|
const BlockBase<T>& Operation<T,OpFunction,Ops...>::get() const
|
||||||
{
|
{
|
||||||
mRes = PackNum<sizeof...(Ops)-1>::template unpackArgs<T,OpFunction>(mOps);
|
mRes = PackNum<sizeof...(Ops)-1>::template unpackArgs<T,OpFunction>(mOps);
|
||||||
return mRes;
|
return mRes;
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace MultiArrayTools
|
||||||
virtual OperationBase& block(const std::shared_ptr<IndexBase>& blockIndex) = 0;
|
virtual OperationBase& block(const std::shared_ptr<IndexBase>& blockIndex) = 0;
|
||||||
|
|
||||||
//virtual size_t argNum() const = 0;
|
//virtual size_t argNum() const = 0;
|
||||||
virtual const BlockBase<T>& get(const IndexBase& ind) const = 0;
|
virtual const BlockBase<T>& get() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable std::shared_ptr<BlockBase> mBlockPtr;
|
mutable std::shared_ptr<BlockBase> mBlockPtr;
|
||||||
|
@ -53,9 +53,10 @@ namespace MultiArrayTools
|
||||||
class MutableOperationBase : public OperationBase<T>
|
class MutableOperationBase : public OperationBase<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
MutableOperationBase() = default;
|
MutableOperationBase() = default;
|
||||||
virtual BlockBase<T>& get(const IndexBase& ind) = 0;
|
virtual BlockBase<T>& get() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class OperationClass>
|
template <class OperationClass>
|
||||||
|
@ -63,23 +64,25 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
typedef typename OperationClass::value_type value_type;
|
||||||
|
|
||||||
OperationTemplate(OperationClass* oc);
|
OperationTemplate(OperationClass* oc);
|
||||||
|
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto operator+(const Second& in) const
|
auto operator+(const Second& in) const
|
||||||
-> Operation<double,std::plus<double>,OperationClass,Second>;
|
-> Operation<value_type,std::plus<value_type>,OperationClass,Second>;
|
||||||
|
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto operator-(const Second& in) const
|
auto operator-(const Second& in) const
|
||||||
-> Operation<double,std::minus<double>,OperationClass,Second>;
|
-> Operation<value_type,std::minus<value_type>,OperationClass,Second>;
|
||||||
|
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto operator*(const Second& in) const
|
auto operator*(const Second& in) const
|
||||||
-> Operation<double,std::multiplies<double>,OperationClass,Second>;
|
-> Operation<value_type,std::multiplies<value_type>,OperationClass,Second>;
|
||||||
|
|
||||||
template <class Second>
|
template <class Second>
|
||||||
auto operator/(const Second& in) const
|
auto operator/(const Second& in) const
|
||||||
-> Operation<double,std::divides<double>,OperationClass,Second>;
|
-> Operation<value_type,std::divides<value_type>,OperationClass,Second>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OperationClass* mOc;
|
OperationClass* mOc;
|
||||||
|
@ -90,6 +93,7 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
typedef OperationBase<T> OB;
|
typedef OperationBase<T> OB;
|
||||||
typedef ContainerRange<Ranges...> CRange;
|
typedef ContainerRange<Ranges...> CRange;
|
||||||
typedef typename MultiRange<Ranges...>::IndexType IndexType;
|
typedef typename MultiRange<Ranges...>::IndexType IndexType;
|
||||||
|
@ -97,8 +101,8 @@ namespace MultiArrayTools
|
||||||
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OperationBase<T>& second,
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OperationBase<T>& second,
|
||||||
std::shared_ptr<typename CRange::IndexType>& index);
|
std::shared_ptr<typename CRange::IndexType>& index);
|
||||||
|
|
||||||
virtual BlockBase<T>& get(const IndexBase& ind) override;
|
virtual BlockBase<T>& get() override;
|
||||||
virtual const BlockBase<T>& get(const IndexBase& ind) const override;
|
virtual const BlockBase<T>& get() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -114,7 +118,8 @@ namespace MultiArrayTools
|
||||||
public OperationTemplate<ConstOperationRoot<T,Ranges...> >
|
public OperationTemplate<ConstOperationRoot<T,Ranges...> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
typedef OperationBase<T> OB;
|
typedef OperationBase<T> OB;
|
||||||
typedef OperationTemplate<ConstOperationRoot<T,Ranges...> > OT;
|
typedef OperationTemplate<ConstOperationRoot<T,Ranges...> > OT;
|
||||||
typedef ContainerRange<Ranges...> CRange;
|
typedef ContainerRange<Ranges...> CRange;
|
||||||
|
@ -123,7 +128,7 @@ namespace MultiArrayTools
|
||||||
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
||||||
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
||||||
|
|
||||||
virtual const BlockBase<T>& get(const IndexBase& ind) const override;
|
virtual const BlockBase<T>& get() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -136,7 +141,8 @@ namespace MultiArrayTools
|
||||||
public OperationTemplate<OperationRoot<T,Ranges...> >
|
public OperationTemplate<OperationRoot<T,Ranges...> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
typedef OperationBase<T> OB;
|
typedef OperationBase<T> OB;
|
||||||
typedef OperationTemplate<OperationRoot<T,Ranges...> > OT;
|
typedef OperationTemplate<OperationRoot<T,Ranges...> > OT;
|
||||||
typedef ContainerRange<Ranges...> CRange;
|
typedef ContainerRange<Ranges...> CRange;
|
||||||
|
@ -147,8 +153,8 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
OperationMaster<T,Ranges...> operator=(const OperationBase<T>& in);
|
OperationMaster<T,Ranges...> operator=(const OperationBase<T>& in);
|
||||||
|
|
||||||
virtual const BlockBase<T>& get(const IndexBase& ind) const override;
|
virtual const BlockBase<T>& get() const override;
|
||||||
virtual BlockBase<T>& get(const IndexBase& ind) override;
|
virtual BlockBase<T>& get() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -161,14 +167,15 @@ namespace MultiArrayTools
|
||||||
public OperationTemplate<Operation<T,OpFunction,Ops...> >
|
public OperationTemplate<Operation<T,OpFunction,Ops...> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
typedef OperationBase<T> OB;
|
typedef OperationBase<T> OB;
|
||||||
typedef OperationTemplate<Operation<T,OpFunction,Ops...> > OT;
|
typedef OperationTemplate<Operation<T,OpFunction,Ops...> > OT;
|
||||||
typedef OpFunction F;
|
typedef OpFunction F;
|
||||||
|
|
||||||
Operation(const Ops&... ops);
|
Operation(const Ops&... ops);
|
||||||
|
|
||||||
virtual const BlockBase<T>& get(const IndexBase& ind) const override;
|
virtual const BlockBase<T>& get() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::tuple<Ops...> mOps;
|
std::tuple<Ops...> mOps;
|
||||||
|
|
Loading…
Reference in a new issue