sc/inc/scmatrix.hxx | 4 + sc/source/core/tool/scmatrix.cxx | 156 +++++++++++++++++++++++++++------------ 2 files changed, 113 insertions(+), 47 deletions(-)
New commits: commit 9f162251c6ef672a2c7178af1463c2b13dd136de Author: Åukasz Hryniuk <lukasz.hryn...@wp.pl> Date: Sat Aug 8 15:47:19 2015 +0200 Add WalkElementBlocksMultipleValues and remove Ops WalkElementBlocksMultipleValues class is able to collect a few values at once. scmatrix.cxx were moved to matrixoperators.cxx Change-Id: Id069f89a58cce046fb3d4ddf6f49db0452bdfb36 Reviewed-on: https://gerrit.libreoffice.org/17593 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrh...@googlemail.com> diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index bd28944..db863cc 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -21,12 +21,16 @@ #define INCLUDED_SC_INC_SCMATRIX_HXX #include "global.hxx" +#include "matrixoperators.hxx" #include "types.hxx" #include <formula/errorcodes.hxx> #include "scdllapi.h" #include <rtl/ustring.hxx> #include <svl/sharedstring.hxx> +#include <functional> +#include <utility> +#include <vector> #include <boost/intrusive_ptr.hpp> #include <boost/interprocess/smart_ptr/unique_ptr.hpp> diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 5ef8378..207e451 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -24,6 +24,7 @@ #include "interpre.hxx" #include "mtvelements.hxx" #include "compare.hxx" +#include "matrixoperators.hxx" #include "math.hxx" #include <boost/noncopyable.hpp> @@ -999,47 +1000,10 @@ double ScMatrixImpl::Xor() const namespace { -struct SumOp -{ - static const double InitVal; - - void operator() (double& rAccum, double fVal) - { - rAccum += fVal; - } -}; - -const double SumOp::InitVal = 0.0; - -struct SumSquareOp -{ - static const double InitVal; - - void operator() (double& rAccum, double fVal) - { - rAccum += fVal*fVal; - } -}; - -const double SumSquareOp::InitVal = 0.0; - -struct ProductOp -{ - static const double InitVal; - - void operator() (double& rAccum, double fVal) - { - rAccum *= fVal; - } -}; - -const double ProductOp::InitVal = 1.0; - template<typename _Op> -class WalkElementBlocks : std::unary_function<MatrixImplType::element_block_node_type, void> +class WalkElementBlocks { _Op maOp; - ScMatrix::IterateResult maRes; bool mbFirst:1; bool mbTextAsZero:1; @@ -1066,7 +1030,9 @@ public: mbFirst = false; } else + { maOp(maRes.mfRest, *it); + } } maRes.mnCount += node.size; } @@ -1085,7 +1051,9 @@ public: mbFirst = false; } else + { maOp(maRes.mfRest, *it); + } } maRes.mnCount += node.size; } @@ -1101,6 +1069,95 @@ public: } }; +template<typename _Op> +class WalkElementBlocksMultipleValues +{ + const std::vector<std::unique_ptr<_Op>>& maOp; + std::vector<ScMatrix::IterateResult> maRes; + bool mbFirst:1; + bool mbTextAsZero:1; +public: + WalkElementBlocksMultipleValues(bool bTextAsZero, const std::vector<std::unique_ptr<_Op>>& aOp) : + maOp(aOp), mbFirst(true), mbTextAsZero(bTextAsZero) + { + for (const auto& pOp : maOp) + { + maRes.emplace_back(pOp->mInitVal, pOp->mInitVal, 0); + } + maRes.emplace_back(0.0, 0.0, 0); // count + } + + const std::vector<ScMatrix::IterateResult>& getResult() const { return maRes; } + + void operator() (const MatrixImplType::element_block_node_type& node) + { + switch (node.type) + { + case mdds::mtm::element_numeric: + { + typedef MatrixImplType::numeric_block_type block_type; + + block_type::const_iterator it = block_type::begin(*node.data); + block_type::const_iterator itEnd = block_type::end(*node.data); + for (; it != itEnd; ++it) + { + if (mbFirst) + { + for (auto i = 0u; i < maOp.size(); ++i) + { + (*maOp[i])(maRes[i].mfFirst, *it); + } + mbFirst = false; + } + else + { + for (auto i = 0u; i < maOp.size(); ++i) + { + (*maOp[i])(maRes[i].mfRest, *it); + } + } + } + maRes.back().mnCount += node.size; + } + break; + case mdds::mtm::element_boolean: + { + typedef MatrixImplType::boolean_block_type block_type; + + block_type::const_iterator it = block_type::begin(*node.data); + block_type::const_iterator itEnd = block_type::end(*node.data); + for (; it != itEnd; ++it) + { + if (mbFirst) + { + for (auto i = 0u; i < maOp.size(); ++i) + { + (*maOp[i])(maRes[i].mfFirst, *it); + } + mbFirst = false; + } + else + { + for (auto i = 0u; i < maOp.size(); ++i) + { + (*maOp[i])(maRes[i].mfRest, *it); + } + } + } + maRes.back().mnCount += node.size; + } + break; + case mdds::mtm::element_string: + if (mbTextAsZero) + maRes.back().mnCount += node.size; + break; + case mdds::mtm::element_empty: + default: + ; + } + } +}; + class CountElements : std::unary_function<MatrixImplType::element_block_node_type, void> { size_t mnCount; @@ -1697,26 +1754,31 @@ public: } -ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const +namespace { + +template<typename TOp> +ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) { - WalkElementBlocks<SumOp> aFunc(bTextAsZero); + WalkElementBlocks<TOp> aFunc(bTextAsZero); maMat.walk(aFunc); return aFunc.getResult(); } +} + +ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const +{ + return GetValueWithCount<sc::op::Sum>(bTextAsZero, maMat); +} + ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const { - WalkElementBlocks<SumSquareOp> aFunc(bTextAsZero); - maMat.walk(aFunc); - return aFunc.getResult(); + return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, maMat); } ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const { - WalkElementBlocks<ProductOp> aFunc(bTextAsZero); - maMat.walk(aFunc); - ScMatrix::IterateResult aRes = aFunc.getResult(); - return aRes; + return GetValueWithCount<sc::op::Product>(bTextAsZero, maMat); } size_t ScMatrixImpl::Count(bool bCountStrings) const
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits