diff --git a/src/base_def.h b/src/base_def.h index e5cdf67..e1d8d57 100644 --- a/src/base_def.h +++ b/src/base_def.h @@ -188,6 +188,10 @@ namespace MultiArrayTools namespace MultiArrayHelper { + // block.h + template + class BlockBinaryOp; + // block.h enum class BlockType; diff --git a/src/block.cc b/src/block.cc index 7d8dfc9..ba255b7 100644 --- a/src/block.cc +++ b/src/block.cc @@ -5,6 +5,23 @@ namespace MultiArrayHelper { + /********************* + * BlockBinaryOp * + *********************/ + + template + BlockResult BlockBinaryOp::operator()(const BlockBase& arg1, + const BlockBase& arg2) + { + static OpFunc f; + BlockResult res(arg1.size()); + assert(arg1.size() == arg2.size()); + for(size_t i = 0; i != arg1.size(); ++i){ + res[i] = f(arg1[i], arg2[i]); + } + return res; + } + /***************** * BlockBase * *****************/ @@ -80,6 +97,7 @@ namespace MultiArrayHelper Block::Block(const std::vector& data, size_t begPos, size_t size) : BlockBase(size), + mData(&data), mBegPtr(data.data() + begPos) {} template @@ -91,13 +109,14 @@ namespace MultiArrayHelper template const T& Block::operator[](size_t i) const { + return *(mBegPtr + i); } template - Block& Block::set(const T* nbeg) + Block& Block::set(size_t npos) { - mBegPtr = nbeg; + mBegPtr = &(*mData)[npos]; return *this; } @@ -109,6 +128,7 @@ namespace MultiArrayHelper MBlock::MBlock(std::vector& data, size_t begPos, size_t size) : MutableBlockBase(size), + mData(&data), mBegPtr(data.data() + begPos) {} template @@ -120,19 +140,21 @@ namespace MultiArrayHelper template const T& MBlock::operator[](size_t i) const { + return *(mBegPtr + i); } template T& MBlock::operator[](size_t i) { + return *(mBegPtr + i); } template - MBlock& MBlock::set(const T* nbeg) + MBlock& MBlock::set(size_t npos) { - mBegPtr = nbeg; + mBegPtr = &(*mData)[npos]; return *this; } @@ -141,9 +163,11 @@ namespace MultiArrayHelper ******************/ template - BlockValue::BlockValue(const T& val, size_t size) : + BlockValue::BlockValue(const std::vector& data, + size_t pos, size_t size) : BlockBase(size), - mVal(val) {} + mData(&data), + mVal(data[pos]) {} template BlockType BlockValue::type() const @@ -154,13 +178,14 @@ namespace MultiArrayHelper template const T& BlockValue::operator[](size_t i) const { + return mVal; } template - BlockValue& BlockValue::set(const T* nbeg) + BlockValue& BlockValue::set(size_t npos) { - mVal = *nbeg; + mVal = (*mData)[npos]; return *this; } @@ -169,9 +194,11 @@ namespace MultiArrayHelper *******************/ template - MBlockValue::MBlockValue(T& val, size_t size) : - BlockBase(size), - mVal(val) {} + MBlockValue::MBlockValue(std::vector& data, + size_t pos, size_t size) : + MutableBlockBase(size), + mData(&data), + mVal(data[pos]) {} template BlockType MBlockValue::type() const @@ -182,19 +209,21 @@ namespace MultiArrayHelper template const T& MBlockValue::operator[](size_t i) const { + return mVal; } template T& MBlockValue::operator[](size_t i) { + return mVal; } template - MBlockValue& MBlockValue::set(const T* nbeg) + MBlockValue& MBlockValue::set(size_t npos) { - mVal = *nbeg; + mVal = (*mData)[npos]; return *this; } @@ -206,6 +235,7 @@ namespace MultiArrayHelper SplitBlock::SplitBlock(const std::vector& data, size_t begPos, size_t stepSize, size_t size) : BlockBase(size), + mData(data), mStepSize(stepSize), mBegPtr(data.data() + begPos) {} @@ -218,13 +248,14 @@ namespace MultiArrayHelper template const T& SplitBlock::operator[](size_t pos) const { + return *(mBegPtr + pos*mStepSize); } template - SplitBlock& SplitBlock::set(const T* nbeg) + SplitBlock& SplitBlock::set(size_t npos) { - mBegPtr = nbeg; + mBegPtr = &(*mData)[npos]; return *this; } @@ -235,7 +266,7 @@ namespace MultiArrayHelper template MSplitBlock::MSplitBlock(std::vector& data, size_t begPos, size_t stepSize, size_t size) : - BlockBase(size), + MutableBlockBase(size), mStepSize(stepSize), mBegPtr(data.data() + begPos) {} @@ -248,19 +279,21 @@ namespace MultiArrayHelper template const T& MSplitBlock::operator[](size_t pos) const { + return *(mBegPtr + pos*mStepSize); } template T& MSplitBlock::operator[](size_t pos) { + return *(mBegPtr + pos*mStepSize); } template - MSplitBlock& MSplitBlock::set(const T* nbeg) + MSplitBlock& MSplitBlock::set(size_t npos) { - mBegPtr = nbeg; + mBegPtr = &(*mData)[npos]; return *this; } @@ -270,7 +303,7 @@ namespace MultiArrayHelper template BlockResult::BlockResult(size_t size) : - BlockBase(size), + MutableBlockBase(size), mRes(size) {} template @@ -282,17 +315,19 @@ namespace MultiArrayHelper template const T& BlockResult::operator[](size_t i) const { + return mRes[i]; } template T& BlockResult::operator[](size_t i) { + return mRes[i]; } template - BlockResult& BlockResult::set(const T* nbeg) + BlockResult& BlockResult::set(size_t npos) { return *this; } diff --git a/src/block.h b/src/block.h index 174b009..c129402 100644 --- a/src/block.h +++ b/src/block.h @@ -20,6 +20,14 @@ namespace MultiArrayHelper }; // manage vectorization in the future !! + + template + class BlockBinaryOp + { + public: + BlockBinaryOp() = default; + BlockResult operator()(const BlockBase& arg1, const BlockBase& arg2); + }; template class BlockBase @@ -36,7 +44,7 @@ namespace MultiArrayHelper virtual size_t size() const; virtual const T& operator[](size_t pos) const = 0; - virtual BlockBase& set(const T* nbeg) = 0; + virtual BlockBase& set(size_t npos) = 0; template BlockResult operate(const BlockBase& in); @@ -62,7 +70,7 @@ namespace MultiArrayHelper MutableBlockBase(MutableBlockBase&& res) = default; MutableBlockBase& operator=(MutableBlockBase&& res) = default; - + virtual T& operator[](size_t pos) = 0; }; @@ -76,9 +84,10 @@ namespace MultiArrayHelper virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; - virtual Block& set(const T* nbeg) override; + virtual Block& set(size_t npos) override; protected: + const std::vector* mData; const T* mBegPtr; }; @@ -92,9 +101,10 @@ namespace MultiArrayHelper virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; virtual T& operator[](size_t pos) override; - virtual MBlock& set(const T* nbeg) override; + virtual MBlock& set(size_t npos) override; protected: + std::vector* mData; T* mBegPtr; }; @@ -103,14 +113,16 @@ namespace MultiArrayHelper { public: BlockValue() = default; - BlockValue(const T& val, size_t size); + BlockValue(const std::vector& data, + size_t pos, size_t size); virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; - virtual BlockValue& set(const T* nbeg) override; + virtual BlockValue& set(size_t npos) override; protected: - T mVal; + const std::vector* mData; + T& mVal; }; template @@ -118,14 +130,16 @@ namespace MultiArrayHelper { public: MBlockValue() = default; - MBlockValue(T& val, size_t size); + MBlockValue(std::vector& data, + size_t pos, size_t size); virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; virtual T& operator[](size_t pos) override; - virtual MBlockValue& set(const T* nbeg) override; + virtual MBlockValue& set(size_t npos) override; protected: + std::vector* mData; T& mVal; }; @@ -140,9 +154,10 @@ namespace MultiArrayHelper virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; - virtual SplitBlock& set(const T* nbeg) override; + virtual SplitBlock& set(size_t npos) override; protected: + const std::vector* mData; size_t mStepSize; const T* mBegPtr; }; @@ -159,9 +174,10 @@ namespace MultiArrayHelper virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; virtual T& operator[](size_t pos) override; - virtual MSplitBlock& set(const T* nbeg) override; + virtual MSplitBlock& set(size_t npos) override; protected: + std::vector* mData; size_t mStepSize; T* mBegPtr; }; @@ -180,7 +196,7 @@ namespace MultiArrayHelper virtual BlockType type() const override; virtual const T& operator[](size_t pos) const override; virtual T& operator[](size_t i) override; - virtual BlockResult& set(const T* nbeg) override; + virtual BlockResult& set(size_t npos) override; protected: std::vector mRes; diff --git a/src/multi_array.cc b/src/multi_array.cc index e631a90..8da67ff 100644 --- a/src/multi_array.cc +++ b/src/multi_array.cc @@ -525,6 +525,19 @@ namespace MultiArrayTools { return mCont.data(); } + + template + const std::vector& MultiArray::datav() const + { + return mCont; + } + + template + std::vector& MultiArray::datav() + { + return mCont; + } + /* template diff --git a/src/multi_array.h b/src/multi_array.h index 203f0d3..973ff12 100644 --- a/src/multi_array.h +++ b/src/multi_array.h @@ -81,6 +81,7 @@ namespace MultiArrayTools virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0; virtual const T* data() const = 0; + virtual const std::vector& datav() const = 0; virtual size_t size() const; virtual bool isSlice() const = 0; @@ -171,6 +172,7 @@ namespace MultiArrayTools virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0; virtual T* data() = 0; + virtual std::vector& datav() = 0; virtual iterator begin(); virtual iterator end(); @@ -216,9 +218,12 @@ namespace MultiArrayTools MultiArray format(const std::shared_ptr&... nrs); // reformat array using 'nr' which in // total must have the same size as mRange - const T* data() const override; - T* data() override; + virtual const T* data() const override; + virtual T* data() override; + virtual const std::vector& datav() const override; + virtual std::vector& datav() override; + // virtual void manipulate(ManipulatorBase& mb, // const typename CRange::IndexType& manBegin, // const typename CRange::IndexType& manEnd); diff --git a/src/multi_array_operation.cc b/src/multi_array_operation.cc index a48568b..0e30e72 100644 --- a/src/multi_array_operation.cc +++ b/src/multi_array_operation.cc @@ -55,7 +55,7 @@ namespace MultiArrayTools std::shared_ptr > makeBlock(const std::vector& vec, size_t stepSize, size_t blockSize) { if(stepSize == 0){ - return std::make_shared >(vec[0], blockSize); + return std::make_shared >(vec, 0, blockSize); } else if(stepSize == 1){ return std::make_shared >(vec, 0, blockSize); @@ -69,7 +69,7 @@ namespace MultiArrayTools std::shared_ptr > makeBlock(std::vector& vec, size_t stepSize, size_t blockSize) { if(stepSize == 0){ - return std::make_shared >(vec[0], blockSize); + return std::make_shared >(vec, 0, blockSize); } else if(stepSize == 1){ return std::make_shared >(vec, 0, blockSize); @@ -223,14 +223,14 @@ namespace MultiArrayTools std::vector OperationMaster::block(const std::shared_ptr blockIndex) const { std::vector btv(1, getBlockType(mIndex, blockIndex, true) ); - mBlockPtr = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); return btv; } template - OperationMaster& OperationMaster::block() const + const OperationMaster& OperationMaster::block() const { - mBlockPtr->set( &mArrayRef[ (*mIndex) ] ); + mBlockPtr->set( mIndex->pos() ); // containerRange <-> multiRange !!! return *this; } @@ -259,14 +259,14 @@ namespace MultiArrayTools std::vector ConstOperationRoot::block(const std::shared_ptr blockIndex) const { std::vector btv(1, getBlockType(mIndex, blockIndex, true) ); - mBlockPtr = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); return btv; } template - ConstOperationRoot& ConstOperationRoot::block() const + const ConstOperationRoot& ConstOperationRoot::block() const { - mBlockPtr->set( &mArrayRef[ (*mIndex)() ] ); + mBlockPtr->set( mIndex->pos() ); return *this; } @@ -308,14 +308,14 @@ namespace MultiArrayTools std::vector OperationRoot::block(const std::shared_ptr blockIndex) const { std::vector btv(1, getBlockType(mIndex, blockIndex, true) ); - mBlockPtr = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + mBlockPtr = makeBlock(mArrayRef.datav(), btv[0].second, blockIndex->max()); return btv; } template - OperationRoot& OperationRoot::block() const + const OperationRoot& OperationRoot::block() const { - mBlockPtr->set( &mArrayRef[ (*mIndex)() ] ); + mBlockPtr->set( mIndex->pos() ); return *this; } @@ -331,7 +331,7 @@ namespace MultiArrayTools template const BlockBase& Operation::get() const { - mRes = PackNum::template unpackArgs(mOps); + mRes = std::move( PackNum::template unpackArgs(mOps) ); return mRes; } @@ -344,9 +344,9 @@ namespace MultiArrayTools } template - Operation& Operation::block() const + const Operation& Operation::block() const { - //mBlockPtr->set( &mArrayRef[ (*mIndex)() ] ); + //mBlockPtr->set( mIndex->pos() ); return *this; } diff --git a/src/multi_array_operation.h b/src/multi_array_operation.h index 0c50527..276a755 100644 --- a/src/multi_array_operation.h +++ b/src/multi_array_operation.h @@ -67,7 +67,7 @@ namespace MultiArrayTools // init block, return resulting type (BLOCK, VALUE, SPLIT) virtual std::vector block(const std::shared_ptr blockIndex) const = 0; - virtual OperationBase& block() const = 0; // update block + virtual const OperationBase& block() const = 0; // update block //virtual size_t argNum() const = 0; virtual const BlockBase& get() const = 0; @@ -129,7 +129,7 @@ namespace MultiArrayTools virtual const BlockBase& get() const override; virtual std::vector block(const std::shared_ptr blockIndex) const override; - virtual OperationMaster& block() const override; + virtual const OperationMaster& block() const override; protected: @@ -159,7 +159,7 @@ namespace MultiArrayTools virtual const BlockBase& get() const override; virtual std::vector block(const std::shared_ptr blockIndex) const override; - virtual ConstOperationRoot& block() const override; + virtual const ConstOperationRoot& block() const override; protected: @@ -189,7 +189,7 @@ namespace MultiArrayTools virtual MutableBlockBase& get() override; virtual std::vector block(const std::shared_ptr blockIndex) const override; - virtual OperationRoot& block() const override; + virtual const OperationRoot& block() const override; protected: @@ -214,7 +214,7 @@ namespace MultiArrayTools virtual const BlockBase& get() const override; virtual std::vector block(const std::shared_ptr blockIndex) const override; - virtual Operation& block() const override; + virtual const Operation& block() const override; protected: std::tuple mOps; diff --git a/src/multi_range.cc b/src/multi_range.cc index 13aa158..9bf7f94 100644 --- a/src/multi_range.cc +++ b/src/multi_range.cc @@ -47,7 +47,8 @@ namespace MultiArrayTools { PackNum::construct(mIPack, *range); IB::mPos = PackNum::makePos(mIPack); - PackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! + std::get(mBlockSizes) = 1; + PackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! } template @@ -102,7 +103,7 @@ namespace MultiArrayTools { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos += PackNum::blockSize( mIPack ); - PackNum::pp( mIPack ); + PackNum::pp( mIPack ); return *this; } @@ -112,7 +113,7 @@ namespace MultiArrayTools { static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); IB::mPos -= PackNum::blockSize( mIPack ); - PackNum::mm( mIPack ); + PackNum::mm( mIPack ); return *this; } diff --git a/src/op_unit_test.cc b/src/op_unit_test.cc index d75c70b..2f2e797 100644 --- a/src/op_unit_test.cc +++ b/src/op_unit_test.cc @@ -110,7 +110,7 @@ namespace { EXPECT_EQ( fabs( res.at('f') - (0.373+8.215) ) < 0.0001, true ); EXPECT_EQ( fabs( res.at('g') - (7.192+5.063) ) < 0.0001, true ); } - + /* TEST_F(OpTest_MDim, ExecOp1) { MultiArray res(sr2ptr,sr4ptr); @@ -191,7 +191,7 @@ namespace { EXPECT_EQ( fabs( res.at(mkt(mkt('3','b'),'A')) - (2.911 + 0.373 + 1.470) ) < 0.0001, true ); EXPECT_EQ( fabs( res.at(mkt(mkt('3','b'),'B')) - (2.911 + 0.373 + 2.210) ) < 0.0001, true ); } - + */ } // anonymous namspace int main(int argc, char** argv) diff --git a/src/pack_num.h b/src/pack_num.h index 4d888fb..ba91b6b 100644 --- a/src/pack_num.h +++ b/src/pack_num.h @@ -40,7 +40,7 @@ namespace MultiArrayHelper } template - static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) + static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) { if(n == N){ return in.template getPtr(); @@ -62,13 +62,8 @@ namespace MultiArrayHelper static void initBlockSizes(std::array& bs, std::tuple...>& ip) { - if(N == sizeof...(Indices)+1){ - std::get(bs) = 1; - } - else { - std::get(bs) = PackNum::blockSize(ip); - PackNum::initBlockSizes(bs, ip); - } + std::get(bs) = PackNum::blockSize(ip); + PackNum::initBlockSizes(bs, ip); } template @@ -86,17 +81,17 @@ namespace MultiArrayHelper template static inline size_t pp(std::tuple...>& ip, - std::array& bs, + std::array& bs, std::shared_ptr idxPtr) { auto siPtr = std::get(ip); if(siPtr.get() == idxPtr.get()){ - return std::get(bs) + PackNum::pp(ip); + return std::get(bs) + PackNum::pp(ip, bs, idxPtr); } else { if(siPtr->last()){ (*siPtr) = 0; - return PackNum::pp(ip, bs) - siPtr->max() + 1; + return PackNum::pp(ip, bs, idxPtr) - siPtr->max() + 1; } else { return siPtr->pp(idxPtr); @@ -119,17 +114,17 @@ namespace MultiArrayHelper template static inline size_t mm(std::tuple...>& ip, - std::array& bs, + std::array& bs, std::shared_ptr idxPtr) { auto siPtr = std::get(ip); if(siPtr.get() == idxPtr.get()){ - return std::get(bs) + PackNum::mm(ip); + return std::get(bs) + PackNum::mm(ip, bs, idxPtr); } else { if(siPtr->first()){ (*siPtr) = siPtr->max() - 1; - return PackNum::mm(ip, bs) - siPtr->max() + 1; + return PackNum::mm(ip, bs, idxPtr) - siPtr->max() + 1; } else { return siPtr->mm(idxPtr); @@ -222,7 +217,7 @@ namespace MultiArrayHelper } template - static T unpackArgs(const ArgTuple& tp, const Args&... args) + static BlockResult unpackArgs(const ArgTuple& tp, const Args&... args) { return PackNum::template unpackArgs(tp, std::get(tp).get(), args...); } @@ -232,7 +227,7 @@ namespace MultiArrayHelper const std::tuple& ops, std::shared_ptr idxPtr) { - auto& subvec = std::get(ops).block(idxPtr); + auto subvec = std::move( std::get(ops).block(idxPtr) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); PackNum::makeBlockTypeVec(btv, ops, idxPtr); } @@ -255,7 +250,7 @@ namespace MultiArrayHelper } template - static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) + static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) { return in.template getPtr<0>(); } @@ -283,7 +278,7 @@ namespace MultiArrayHelper template static inline size_t pp(std::tuple...>& ip, - std::array& bs, + std::array& bs, std::shared_ptr idxPtr) { auto siPtr = std::get<0>(ip); @@ -304,7 +299,7 @@ namespace MultiArrayHelper template static inline size_t mm(std::tuple...>& ip, - std::array& bs, + std::array& bs, std::shared_ptr idxPtr) { auto siPtr = std::get<0>(ip); @@ -392,11 +387,11 @@ namespace MultiArrayHelper } template - static T unpackArgs(const ArgTuple& tp, const Args&... args) + static BlockResult unpackArgs(const ArgTuple& tp, const Args&... args) { static_assert(sizeof...(Args) == std::tuple_size::value-1, "inconsistent number of arguments"); - static Func f; + static BlockBinaryOp f; return f(std::get<0>(tp).get(), args...); } @@ -405,7 +400,7 @@ namespace MultiArrayHelper const std::tuple& ops, std::shared_ptr idxPtr) { - auto& subvec = std::get<0>(ops).block(idxPtr); + auto subvec = std::move( std::get<0>(ops).block(idxPtr) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); }