32 #include <rtl/math.hxx>
34 #include <osl/diagnose.h>
40 #include <mdds/multi_type_matrix.hpp>
41 #include <mdds/multi_type_vector_types.hpp>
63 typedef mdds::mtv::custom_block_func1<sc::string_block> element_block_func;
72 double convertStringToValue(
ScInterpreter* pErrorInterpreter,
const OUString& rStr )
74 if (pErrorInterpreter)
79 if (nError != FormulaError::NONE)
81 pErrorInterpreter->
SetError( nError);
91 double operator() (
double val)
const
93 if (!std::isfinite(val))
95 return val == 0.0 ? 1.0 : 0.0;
99 struct ElemNotEqualZero
101 double operator() (
double val)
const
103 if (!std::isfinite(val))
105 return val != 0.0 ? 1.0 : 0.0;
109 struct ElemGreaterZero
111 double operator() (
double val)
const
113 if (!std::isfinite(val))
115 return val > 0.0 ? 1.0 : 0.0;
121 double operator() (
double val)
const
123 if (!std::isfinite(val))
125 return val < 0.0 ? 1.0 : 0.0;
129 struct ElemGreaterEqualZero
131 double operator() (
double val)
const
133 if (!std::isfinite(val))
135 return val >= 0.0 ? 1.0 : 0.0;
139 struct ElemLessEqualZero
141 double operator() (
double val)
const
143 if (!std::isfinite(val))
145 return val <= 0.0 ? 1.0 : 0.0;
149 template<
typename Comp>
150 class CompareMatrixElemFunc
154 std::vector<double> maNewMatValues;
158 CompareMatrixElemFunc(
size_t nRow,
size_t nCol ) :
mnRow(nRow),
mnCol(nCol)
160 maNewMatValues.reserve(nRow*nCol);
163 CompareMatrixElemFunc(
const CompareMatrixElemFunc& ) =
delete;
164 CompareMatrixElemFunc& operator= (
const CompareMatrixElemFunc& ) =
delete;
166 CompareMatrixElemFunc( CompareMatrixElemFunc&& ) =
default;
167 CompareMatrixElemFunc& operator= ( CompareMatrixElemFunc&& ) =
default;
169 void operator() (
const MatrixImplType::element_block_node_type& node)
173 case mdds::mtm::element_numeric:
175 typedef MatrixImplType::numeric_block_type block_type;
177 block_type::const_iterator it = block_type::begin(*node.data);
178 block_type::const_iterator itEnd = block_type::end(*node.data);
179 for (; it != itEnd; ++it)
182 maNewMatValues.push_back(maComp(fVal));
186 case mdds::mtm::element_boolean:
188 typedef MatrixImplType::boolean_block_type block_type;
190 block_type::const_iterator it = block_type::begin(*node.data);
191 block_type::const_iterator itEnd = block_type::end(*node.data);
192 for (; it != itEnd; ++it)
194 double fVal = *it ? 1.0 : 0.0;
195 maNewMatValues.push_back(maComp(fVal));
199 case mdds::mtm::element_string:
200 case mdds::mtm::element_empty:
203 maNewMatValues.resize(maNewMatValues.size() + node.size, 0.0);
209 MatrixImplType aNewMat(mnRow, mnCol, maNewMatValues.begin(), maNewMatValues.end());
214 template<
typename Comp>
215 Comp CompareMatrixElemFunc<Comp>::maComp;
238 ScMatrixImpl(
size_t nC,
size_t nR,
const std::vector<double>& rInitVals );
308 size_t Count(
bool bCountStrings,
bool bCountErrors,
bool bIgnoreEmptyStrings)
const;
312 double GetMaxValue(
bool bTextAsZero,
bool bIgnoreErrorValues )
const;
313 double GetMinValue(
bool bTextAsZero,
bool bIgnoreErrorValues )
const;
319 void GetDoubleArray( std::vector<double>& rArray,
bool bEmptyAsZero )
const;
360 constexpr
size_t nPerElem = 12;
362 return nMemory / nPerElem;
365 constexpr
size_t nMemMax = 0x40000000;
367 constexpr
size_t nElemMax = nMemMax / nPerElem;
369 constexpr
size_t nArbitraryLimit = size_t(
MAXROWCOUNT) * 128;
371 return std::min(nElemMax, nArbitraryLimit);
375 maMat(nR, nC), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
381 maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
387 maMat(nR, nC, rInitVals.
begin(), rInitVals.
end()), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
409 maMat.resize(nR, nC);
426 maMat.resize(nR, nC, fVal);
445 MatrixImplType::size_pair_type aSize =
maMat.size();
452 MatrixImplType::size_pair_type aSize =
maMat.size();
453 return aSize.row * aSize.column;
458 MatrixImplType::size_pair_type aSize =
maMat.size();
459 return nR < aSize.row && nC < aSize.column;
464 MatrixImplType::size_pair_type aSize =
maMat.size();
465 if (aSize.column == 1 && aSize.row == 1)
471 else if (aSize.column == 1 && rR < aSize.row)
477 else if (aSize.row == 1 && rC < aSize.column)
500 maMat.set(nR, nC, fVal);
503 OSL_FAIL(
"ScMatrixImpl::PutDouble: dimension error");
510 maMat.set(nR, nC, pArray, pArray + nLen);
513 OSL_FAIL(
"ScMatrixImpl::PutDouble: dimension error");
527 maMat.set(nR, nC, rStr);
530 OSL_FAIL(
"ScMatrixImpl::PutString: dimension error");
537 maMat.set(nR, nC, pArray, pArray + nLen);
540 OSL_FAIL(
"ScMatrixImpl::PutString: dimension error");
555 maMat.set_empty(nR, nC);
560 OSL_FAIL(
"ScMatrixImpl::PutEmpty: dimension error");
568 maMat.set_empty(nR, nC);
573 OSL_FAIL(
"ScMatrixImpl::PutEmptyPath: dimension error");
585 maMat.set(nR, nC, bVal);
588 OSL_FAIL(
"ScMatrixImpl::PutBoolean: dimension error");
596 double fVal =
maMat.get_numeric(nR, nC);
601 OSL_FAIL(
"ScMatrixImpl::GetError: dimension error");
602 return FormulaError::NoValue;
610 double fVal =
maMat.get_numeric(nR, nC);
614 if ( nError != FormulaError::NONE )
621 OSL_FAIL(
"ScMatrixImpl::GetDouble: dimension error");
646 MatrixImplType::const_position_type aPos =
maMat.position(nR, nC);
647 switch (
maMat.get_type(aPos))
649 case mdds::mtm::element_string:
650 return maMat.get_string(aPos);
651 case mdds::mtm::element_empty:
653 case mdds::mtm::element_numeric:
654 case mdds::mtm::element_boolean:
655 fErr =
maMat.get_numeric(aPos);
658 OSL_FAIL(
"ScMatrixImpl::GetString: access error, no string");
664 OSL_FAIL(
"ScMatrixImpl::GetString: dimension error");
680 OSL_FAIL(
"ScMatrixImpl::GetString: dimension error");
685 MatrixImplType::const_position_type aPos =
maMat.position(nR, nC);
686 switch (
maMat.get_type(aPos))
688 case mdds::mtm::element_string:
689 return maMat.get_string(aPos);
690 case mdds::mtm::element_empty:
700 const Color* pColor =
nullptr;
704 case mdds::mtm::element_numeric:
705 case mdds::mtm::element_boolean:
706 fVal =
maMat.get_numeric(aPos);
713 if (nError != FormulaError::NONE)
731 MatrixImplType::const_position_type aPos =
maMat.position(nR, nC);
732 mdds::mtm::element_t
eType =
maMat.get_type(aPos);
735 case mdds::mtm::element_boolean:
737 aVal.
fVal = double(
maMat.get_boolean(aPos));
739 case mdds::mtm::element_numeric:
743 case mdds::mtm::element_string:
747 case mdds::mtm::element_empty:
752 case mdds::mtm::element_empty:
755 case mdds::mtm::element_numeric:
770 OSL_FAIL(
"ScMatrixImpl::Get: dimension error");
785 switch (
maMat.get_type(nR, nC))
787 case mdds::mtm::element_empty:
788 case mdds::mtm::element_string:
801 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
810 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
811 maMatFlag.get_type(nR, nC) == mdds::mtm::element_empty;
819 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
827 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
843 switch (
maMat.get_type(nR, nC))
845 case mdds::mtm::element_boolean:
846 case mdds::mtm::element_numeric:
857 switch (
maMat.get_type(nR, nC))
859 case mdds::mtm::element_boolean:
860 case mdds::mtm::element_numeric:
861 case mdds::mtm::element_empty:
872 return maMat.get_type(nR, nC) == mdds::mtm::element_boolean;
877 return maMat.numeric();
885 OSL_FAIL(
"ScMatrixImpl::MatCopy: dimension error");
895 mRes.
maMat.transpose();
902 for (
SCSIZE j = nC1; j <= nC2; ++j)
905 std::vector<double> aVals(nR2-nR1+1, fVal);
906 maMat.set(nR1, j, aVals.begin(), aVals.end());
911 OSL_FAIL(
"ScMatrixImpl::FillDouble: dimension error");
919 maMat.set(nR, nC, rVec.begin(), rVec.end());
923 OSL_FAIL(
"ScMatrixImpl::PutDoubleVector: dimension error");
931 maMat.set(nR, nC, rVec.begin(), rVec.end());
935 OSL_FAIL(
"ScMatrixImpl::PutStringVector: dimension error");
943 maMat.set_empty(nR, nC, nCount);
949 OSL_FAIL(
"ScMatrixImpl::PutEmptyVector: dimension error");
957 maMat.set_empty(nR, nC, nCount);
960 maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
964 OSL_FAIL(
"ScMatrixImpl::PutEmptyResultVector: dimension error");
972 maMat.set_empty(nR, nC, nCount);
975 maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
979 OSL_FAIL(
"ScMatrixImpl::PutEmptyPathVector: dimension error");
985 MatrixImplType::size_pair_type aSize =
maMat.size();
986 CompareMatrixElemFunc<ElemEqualZero> aFunc(aSize.row, aSize.column);
987 aFunc =
maMat.walk(std::move(aFunc));
993 MatrixImplType::size_pair_type aSize =
maMat.size();
994 CompareMatrixElemFunc<ElemNotEqualZero> aFunc(aSize.row, aSize.column);
995 aFunc =
maMat.walk(std::move(aFunc));
1001 MatrixImplType::size_pair_type aSize =
maMat.size();
1002 CompareMatrixElemFunc<ElemLessZero> aFunc(aSize.row, aSize.column);
1003 aFunc =
maMat.walk(std::move(aFunc));
1009 MatrixImplType::size_pair_type aSize =
maMat.size();
1010 CompareMatrixElemFunc<ElemGreaterZero> aFunc(aSize.row, aSize.column);
1011 aFunc =
maMat.walk(std::move(aFunc));
1017 MatrixImplType::size_pair_type aSize =
maMat.size();
1018 CompareMatrixElemFunc<ElemLessEqualZero> aFunc(aSize.row, aSize.column);
1019 aFunc =
maMat.walk(std::move(aFunc));
1025 MatrixImplType::size_pair_type aSize =
maMat.size();
1026 CompareMatrixElemFunc<ElemGreaterEqualZero> aFunc(aSize.row, aSize.column);
1027 aFunc =
maMat.walk(std::move(aFunc));
1036 void operate(
double fVal) { mbResult &= (fVal != 0.0); }
1037 bool result()
const {
return mbResult; }
1038 AndEvaluator() : mbResult(true) {}
1044 void operate(
double fVal) { mbResult |= (fVal != 0.0); }
1045 bool result()
const {
return mbResult; }
1046 OrEvaluator() : mbResult(false) {}
1052 void operate(
double fVal) { mbResult ^= (fVal != 0.0); }
1053 bool result()
const {
return mbResult; }
1054 XorEvaluator() : mbResult(false) {}
1059 template <
typename Evaluator>
1063 size_t nRows = rMat.size().row, nCols = rMat.size().column;
1064 for (
size_t i = 0;
i < nRows; ++
i)
1066 for (
size_t j = 0; j < nCols; ++j)
1068 MatrixImplType::const_position_type aPos = rMat.position(i, j);
1069 mdds::mtm::element_t
eType = rMat.get_type(aPos);
1070 if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
1074 double fVal = rMat.get_numeric(aPos);
1075 if (!std::isfinite(fVal))
1079 aEval.operate(fVal);
1082 return aEval.result();
1091 return EvalMatrix<AndEvaluator>(
maMat);
1098 return EvalMatrix<OrEvaluator>(
maMat);
1105 return EvalMatrix<XorEvaluator>(
maMat);
1110 template<
typename Op>
1111 class WalkElementBlocks
1116 bool mbTextAsZero:1;
1117 bool mbIgnoreErrorValues:1;
1119 WalkElementBlocks(
bool bTextAsZero,
bool bIgnoreErrorValues) :
1120 maRes(
Op::InitVal,
Op::InitVal, 0), mbFirst(true),
1121 mbTextAsZero(bTextAsZero), mbIgnoreErrorValues(bIgnoreErrorValues)
1126 void operator() (
const MatrixImplType::element_block_node_type& node)
1130 case mdds::mtm::element_numeric:
1132 typedef MatrixImplType::numeric_block_type block_type;
1134 size_t nIgnored = 0;
1135 block_type::const_iterator it = block_type::begin(*node.data);
1136 block_type::const_iterator itEnd = block_type::end(*node.data);
1137 for (; it != itEnd; ++it)
1139 if (mbIgnoreErrorValues && !std::isfinite(*it))
1155 maRes.
mnCount += node.size - nIgnored;
1158 case mdds::mtm::element_boolean:
1160 typedef MatrixImplType::boolean_block_type block_type;
1162 block_type::const_iterator it = block_type::begin(*node.data);
1163 block_type::const_iterator itEnd = block_type::end(*node.data);
1164 for (; it != itEnd; ++it)
1179 case mdds::mtm::element_string:
1183 case mdds::mtm::element_empty:
1190 template<
typename Op>
1191 class WalkElementBlocksMultipleValues
1193 const std::vector<Op>* mpOp;
1194 std::vector<ScMatrix::IterateResult> maRes;
1197 WalkElementBlocksMultipleValues(
const std::vector<Op>& aOp) :
1198 mpOp(&aOp), mbFirst(true)
1200 for (
const auto& rpOp : *mpOp)
1202 maRes.emplace_back(rpOp.mInitVal, rpOp.mInitVal, 0);
1204 maRes.emplace_back(0.0, 0.0, 0);
1207 WalkElementBlocksMultipleValues(
const WalkElementBlocksMultipleValues& ) =
delete;
1208 WalkElementBlocksMultipleValues& operator= (
const WalkElementBlocksMultipleValues& ) =
delete;
1210 WalkElementBlocksMultipleValues(WalkElementBlocksMultipleValues&& r) noexcept :
1211 mpOp(r.mpOp), maRes(
std::move(r.maRes)), mbFirst(r.mbFirst) {}
1213 WalkElementBlocksMultipleValues& operator=(WalkElementBlocksMultipleValues&& r) noexcept
1216 maRes = std::move(r.maRes);
1217 mbFirst = r.mbFirst;
1221 const std::vector<ScMatrix::IterateResult>& getResult()
const {
return maRes; }
1223 void operator() (
const MatrixImplType::element_block_node_type& node)
1227 case mdds::mtm::element_numeric:
1229 typedef MatrixImplType::numeric_block_type block_type;
1231 block_type::const_iterator it = block_type::begin(*node.data);
1232 block_type::const_iterator itEnd = block_type::end(*node.data);
1233 for (; it != itEnd; ++it)
1237 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1239 (*mpOp)[
i](maRes[
i].mfFirst, *it);
1245 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1247 (*mpOp)[
i](maRes[
i].mfRest, *it);
1251 maRes.back().mnCount += node.size;
1254 case mdds::mtm::element_boolean:
1256 typedef MatrixImplType::boolean_block_type block_type;
1258 block_type::const_iterator it = block_type::begin(*node.data);
1259 block_type::const_iterator itEnd = block_type::end(*node.data);
1260 for (; it != itEnd; ++it)
1264 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1266 (*mpOp)[
i](maRes[
i].mfFirst, *it);
1272 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1274 (*mpOp)[
i](maRes[
i].mfRest, *it);
1278 maRes.back().mnCount += node.size;
1281 case mdds::mtm::element_string:
1282 case mdds::mtm::element_empty:
1294 bool mbIgnoreEmptyStrings;
1296 explicit CountElements(
bool bCountString,
bool bCountErrors,
bool bIgnoreEmptyStrings) :
1297 mnCount(0), mbCountString(bCountString), mbCountErrors(bCountErrors),
1298 mbIgnoreEmptyStrings(bIgnoreEmptyStrings) {}
1300 size_t getCount()
const {
return mnCount; }
1302 void operator() (
const MatrixImplType::element_block_node_type& node)
1306 case mdds::mtm::element_numeric:
1307 mnCount += node.size;
1310 typedef MatrixImplType::numeric_block_type block_type;
1312 block_type::const_iterator it = block_type::begin(*node.data);
1313 block_type::const_iterator itEnd = block_type::end(*node.data);
1314 for (; it != itEnd; ++it)
1316 if (!std::isfinite(*it))
1321 case mdds::mtm::element_boolean:
1322 mnCount += node.size;
1324 case mdds::mtm::element_string:
1327 mnCount += node.size;
1328 if (mbIgnoreEmptyStrings)
1330 typedef MatrixImplType::string_block_type block_type;
1332 block_type::const_iterator it = block_type::begin(*node.data);
1333 block_type::const_iterator itEnd = block_type::end(*node.data);
1334 for (; it != itEnd; ++it)
1342 case mdds::mtm::element_empty:
1349 const size_t ResultNotSet = std::numeric_limits<size_t>::max();
1351 template<
typename Type>
1352 class WalkAndMatchElements
1361 WalkAndMatchElements(
Type aMatchValue,
const MatrixImplType::size_pair_type& aSize,
size_t nCol1,
size_t nCol2) :
1362 maMatchValue(aMatchValue),
1363 mnStartIndex( nCol1 * aSize.row ),
1364 mnStopIndex( (nCol2 + 1) * aSize.row ),
1365 mnResult(ResultNotSet),
1368 assert( nCol1 < aSize.column && nCol2 < aSize.column);
1371 size_t getMatching()
const {
return mnResult; }
1373 size_t getRemainingCount()
const
1375 return mnIndex < mnStopIndex ? mnStopIndex - mnIndex : 0;
1378 size_t compare(
const MatrixImplType::element_block_node_type& node)
const;
1380 void operator() (
const MatrixImplType::element_block_node_type& node)
1383 if (mnResult != ResultNotSet)
1387 if (mnStartIndex <= mnIndex && getRemainingCount() > 0)
1392 mnIndex += node.size;
1397 size_t WalkAndMatchElements<double>::compare(
const MatrixImplType::element_block_node_type& node)
const
1402 case mdds::mtm::element_numeric:
1404 typedef MatrixImplType::numeric_block_type block_type;
1406 block_type::const_iterator it = block_type::begin(*node.data);
1407 block_type::const_iterator itEnd = block_type::end(*node.data);
1408 const size_t nRemaining = getRemainingCount();
1409 for (; it != itEnd && nCount < nRemaining; ++it, ++nCount)
1411 if (*it == maMatchValue)
1413 return mnIndex + nCount;
1418 case mdds::mtm::element_boolean:
1420 typedef MatrixImplType::boolean_block_type block_type;
1422 block_type::const_iterator it = block_type::begin(*node.data);
1423 block_type::const_iterator itEnd = block_type::end(*node.data);
1424 const size_t nRemaining = getRemainingCount();
1425 for (; it != itEnd && nCount < nRemaining; ++it, ++nCount)
1427 if (
int(*it) == maMatchValue)
1429 return mnIndex + nCount;
1435 case mdds::mtm::element_string:
1436 case mdds::mtm::element_empty:
1440 return ResultNotSet;
1444 size_t WalkAndMatchElements<svl::SharedString>::compare(
const MatrixImplType::element_block_node_type& node)
const
1448 case mdds::mtm::element_string:
1451 typedef MatrixImplType::string_block_type block_type;
1453 block_type::const_iterator it = block_type::begin(*node.data);
1454 block_type::const_iterator itEnd = block_type::end(*node.data);
1455 const size_t nRemaining = getRemainingCount();
1456 for (; it != itEnd && nCount < nRemaining; ++it, ++nCount)
1458 if (it->getDataIgnoreCase() == maMatchValue.getDataIgnoreCase())
1460 return mnIndex + nCount;
1465 case mdds::mtm::element_boolean:
1466 case mdds::mtm::element_numeric:
1467 case mdds::mtm::element_empty:
1471 return ResultNotSet;
1476 static double init() {
return -std::numeric_limits<double>::max(); }
1477 static double compare(
double left,
double right)
1479 if (!std::isfinite(left))
1481 if (!std::isfinite(right))
1483 return std::max(left, right);
1486 static double boolValue(
1487 MatrixImplType::boolean_block_type::const_iterator it,
1488 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1491 it = std::find(it, itEnd,
true);
1492 return it == itEnd ? 0.0 : 1.0;
1498 static double init() {
return std::numeric_limits<double>::max(); }
1499 static double compare(
double left,
double right)
1501 if (!std::isfinite(left))
1503 if (!std::isfinite(right))
1505 return std::min(left, right);
1508 static double boolValue(
1509 MatrixImplType::boolean_block_type::const_iterator it,
1510 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1513 it = std::find(it, itEnd,
false);
1514 return it == itEnd ? 1.0 : 0.0;
1520 static double init() {
return 1.0; }
1521 static double calculate(
double fx,
double fy)
1526 static double boolValue(
1527 MatrixImplType::boolean_block_type::const_iterator it,
1528 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1531 it = std::find(it, itEnd,
false);
1532 return it == itEnd ? 1.0 : 0.0;
1538 static double init() {
return 0.0; }
1539 static double calculate(
double fx,
double fy)
1544 static double boolValue(
1545 MatrixImplType::boolean_block_type::const_iterator it,
1546 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1549 it = std::find(it, itEnd,
true);
1550 return it == itEnd ? 0.0 : 1.0;
1554 template<
typename Op>
1555 class CalcMaxMinValue
1559 bool mbIgnoreErrorValues;
1562 CalcMaxMinValue(
bool bTextAsZero,
bool bIgnoreErrorValues ) :
1564 mbTextAsZero(bTextAsZero),
1565 mbIgnoreErrorValues(bIgnoreErrorValues),
1566 mbHasValue(false) {}
1568 double getValue()
const {
return mbHasValue ? mfVal : 0.0; }
1570 void operator() (
const MatrixImplType::element_block_node_type& node)
1575 case mdds::mtm::element_numeric:
1577 typedef MatrixImplType::numeric_block_type block_type;
1579 block_type::const_iterator it = block_type::begin(*node.data);
1580 block_type::const_iterator itEnd = block_type::end(*node.data);
1581 if (mbIgnoreErrorValues)
1583 for (; it != itEnd; ++it)
1585 if (std::isfinite(*it))
1586 mfVal = Op::compare(mfVal, *it);
1591 for (; it != itEnd; ++it)
1592 mfVal = Op::compare(mfVal, *it);
1598 case mdds::mtm::element_boolean:
1600 typedef MatrixImplType::boolean_block_type block_type;
1602 block_type::const_iterator it = block_type::begin(*node.data);
1603 block_type::const_iterator itEnd = block_type::end(*node.data);
1604 double fVal = Op::boolValue(it, itEnd);
1605 mfVal = Op::compare(mfVal, fVal);
1609 case mdds::mtm::element_string:
1610 case mdds::mtm::element_empty:
1615 mfVal = Op::compare(mfVal, 0.0);
1626 template<
typename Op>
1632 CalcGcdLcm() : mfval(
Op::
init()) {}
1634 double getResult()
const {
return mfval; }
1636 void operator() (
const MatrixImplType::element_block_node_type& node )
1640 case mdds::mtm::element_numeric:
1642 typedef MatrixImplType::numeric_block_type block_type;
1643 block_type::const_iterator it = block_type::begin(*node.data);
1644 block_type::const_iterator itEnd = block_type::end(*node.data);
1646 for ( ; it != itEnd; ++it)
1651 mfval = ::rtl::math::approxFloor( Op::calculate(*it,mfval));
1655 case mdds::mtm::element_boolean:
1657 typedef MatrixImplType::boolean_block_type block_type;
1658 block_type::const_iterator it = block_type::begin(*node.data);
1659 block_type::const_iterator itEnd = block_type::end(*node.data);
1661 mfval = Op::boolValue(it, itEnd);
1664 case mdds::mtm::element_empty:
1665 case mdds::mtm::element_string:
1676 double evaluate(
double fVal,
ScQueryOp eOp )
1678 if (!std::isfinite(fVal))
1684 return fVal == 0.0 ? 1.0 : 0.0;
1686 return fVal < 0.0 ? 1.0 : 0.0;
1688 return fVal > 0.0 ? 1.0 : 0.0;
1691 return fVal <= 0.0 ? 1.0 : 0.0;
1694 return fVal >= 0.0 ? 1.0 : 0.0;
1697 return fVal != 0.0 ? 1.0 : 0.0;
1703 SAL_WARN(
"sc.core",
"evaluate: unhandled comparison operator: " << static_cast<int>(eOp));
1707 class CompareMatrixFunc
1712 std::vector<double> maResValues;
1717 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1722 mrComp(rComp), mnMatPos(nMatPos), mpOptions(pOptions)
1724 maResValues.reserve(nResSize);
1727 CompareMatrixFunc(
const CompareMatrixFunc& ) =
delete;
1728 CompareMatrixFunc& operator= (
const CompareMatrixFunc& ) =
delete;
1730 CompareMatrixFunc(CompareMatrixFunc&& r) noexcept :
1732 mnMatPos(r.mnMatPos),
1733 mpOptions(r.mpOptions),
1734 maResValues(
std::move(r.maResValues)) {}
1736 CompareMatrixFunc& operator=(CompareMatrixFunc&& r) noexcept
1739 mnMatPos = r.mnMatPos;
1740 mpOptions = r.mpOptions;
1741 maResValues = std::move(r.maResValues);
1745 void operator() (
const MatrixImplType::element_block_node_type& node)
1751 case mdds::mtm::element_numeric:
1753 typedef MatrixImplType::numeric_block_type block_type;
1755 block_type::const_iterator it = block_type::begin(*node.data);
1756 block_type::const_iterator itEnd = block_type::end(*node.data);
1757 for (; it != itEnd; ++it)
1766 case mdds::mtm::element_boolean:
1768 typedef MatrixImplType::boolean_block_type block_type;
1770 block_type::const_iterator it = block_type::begin(*node.data);
1771 block_type::const_iterator itEnd = block_type::end(*node.data);
1772 for (; it != itEnd; ++it)
1781 case mdds::mtm::element_string:
1783 typedef MatrixImplType::string_block_type block_type;
1785 block_type::const_iterator it = block_type::begin(*node.data);
1786 block_type::const_iterator itEnd = block_type::end(*node.data);
1787 for (; it != itEnd; ++it)
1797 case mdds::mtm::element_empty:
1802 for (
size_t i = 0;
i < node.size; ++
i)
1811 const std::vector<double>& getValues()
const
1820 class CompareMatrixToNumericFunc
1823 double mfRightValue;
1825 std::vector<double> maResValues;
1830 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1833 void compareLeftNumeric(
double fLeftVal )
1836 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1839 void compareLeftEmpty(
size_t nSize )
1842 bool bRes = evaluate(fVal, mrComp.
meOp);
1843 maResValues.resize(maResValues.size() + nSize, bRes ? 1.0 : 0.0);
1848 mrComp(rComp), mfRightValue(fRightValue), mpOptions(pOptions)
1850 maResValues.reserve(nResSize);
1853 CompareMatrixToNumericFunc(
const CompareMatrixToNumericFunc& ) =
delete;
1854 CompareMatrixToNumericFunc& operator= (
const CompareMatrixToNumericFunc& ) =
delete;
1856 CompareMatrixToNumericFunc(CompareMatrixToNumericFunc&& r) noexcept :
1858 mfRightValue(r.mfRightValue),
1859 mpOptions(r.mpOptions),
1860 maResValues(
std::move(r.maResValues)) {}
1862 CompareMatrixToNumericFunc& operator=(CompareMatrixToNumericFunc&& r) noexcept
1865 mfRightValue = r.mfRightValue;
1866 mpOptions = r.mpOptions;
1867 maResValues = std::move(r.maResValues);
1871 void operator() (
const MatrixImplType::element_block_node_type& node)
1875 case mdds::mtm::element_numeric:
1877 typedef MatrixImplType::numeric_block_type block_type;
1879 block_type::const_iterator it = block_type::begin(*node.data);
1880 block_type::const_iterator itEnd = block_type::end(*node.data);
1881 for (; it != itEnd; ++it)
1882 compareLeftNumeric(*it);
1885 case mdds::mtm::element_boolean:
1887 typedef MatrixImplType::boolean_block_type block_type;
1889 block_type::const_iterator it = block_type::begin(*node.data);
1890 block_type::const_iterator itEnd = block_type::end(*node.data);
1891 for (; it != itEnd; ++it)
1892 compareLeftNumeric(
double(*it));
1895 case mdds::mtm::element_string:
1897 typedef MatrixImplType::string_block_type block_type;
1899 block_type::const_iterator it = block_type::begin(*node.data);
1900 block_type::const_iterator itEnd = block_type::end(*node.data);
1901 for (; it != itEnd; ++it)
1912 case mdds::mtm::element_empty:
1913 compareLeftEmpty(node.size);
1920 const std::vector<double>& getValues()
const
1928 std::vector<double> maArray;
1929 std::vector<double>::iterator miPos;
1933 void moveArray( ToDoubleArray& r )
1938 size_t n = std::distance(r.maArray.begin(), r.miPos);
1939 maArray = std::move(r.maArray);
1940 miPos = maArray.begin();
1941 std::advance(miPos, n);
1945 ToDoubleArray(
size_t nSize,
bool bEmptyAsZero ) :
1946 maArray(nSize, 0.0), miPos(maArray.
begin()), mbEmptyAsZero(bEmptyAsZero)
1951 ToDoubleArray(
const ToDoubleArray& ) =
delete;
1952 ToDoubleArray& operator= (
const ToDoubleArray& ) =
delete;
1954 ToDoubleArray(ToDoubleArray&& r) noexcept :
1955 mfNaN(r.mfNaN), mbEmptyAsZero(r.mbEmptyAsZero)
1960 ToDoubleArray& operator=(ToDoubleArray&& r) noexcept
1963 mbEmptyAsZero = r.mbEmptyAsZero;
1968 void operator() (
const MatrixImplType::element_block_node_type& node)
1970 using namespace mdds::mtv;
1974 case mdds::mtm::element_numeric:
1976 double_element_block::const_iterator it = double_element_block::begin(*node.data);
1977 double_element_block::const_iterator itEnd = double_element_block::end(*node.data);
1978 for (; it != itEnd; ++it, ++miPos)
1982 case mdds::mtm::element_boolean:
1984 boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
1985 boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
1986 for (; it != itEnd; ++it, ++miPos)
1987 *miPos = *it ? 1.0 : 0.0;
1990 case mdds::mtm::element_string:
1992 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
1996 case mdds::mtm::element_empty:
2000 std::advance(miPos, node.size);
2004 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
2013 void swap(std::vector<double>& rOther)
2015 maArray.swap(rOther);
2021 double operator() (
const double& lhs,
const double& rhs)
const
2027 template<
typename Op>
2028 class MergeDoubleArrayFunc
2030 std::vector<double>::iterator miPos;
2033 MergeDoubleArrayFunc(std::vector<double>& rArray) : miPos(rArray.
begin())
2038 MergeDoubleArrayFunc(
const MergeDoubleArrayFunc& ) =
delete;
2039 MergeDoubleArrayFunc& operator= (
const MergeDoubleArrayFunc& ) =
delete;
2041 MergeDoubleArrayFunc( MergeDoubleArrayFunc&& ) =
default;
2042 MergeDoubleArrayFunc& operator= ( MergeDoubleArrayFunc&& ) =
default;
2044 void operator() (
const MatrixImplType::element_block_node_type& node)
2046 using namespace mdds::mtv;
2051 case mdds::mtm::element_numeric:
2053 double_element_block::const_iterator it = double_element_block::begin(*node.data);
2054 double_element_block::const_iterator itEnd = double_element_block::end(*node.data);
2055 for (; it != itEnd; ++it, ++miPos)
2060 *miPos = op(*miPos, *it);
2064 case mdds::mtm::element_boolean:
2066 boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
2067 boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
2068 for (; it != itEnd; ++it, ++miPos)
2073 *miPos = op(*miPos, *it ? 1.0 : 0.0);
2077 case mdds::mtm::element_string:
2079 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
2083 case mdds::mtm::element_empty:
2086 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
2091 *miPos = op(*miPos, 0.0);
2105 template<
typename TOp>
2108 WalkElementBlocks<TOp> aFunc(bTextAsZero, bIgnoreErrorValues);
2109 aFunc = maMat.walk(aFunc);
2110 return aFunc.getResult();
2117 return GetValueWithCount<sc::op::Sum>(bTextAsZero, bIgnoreErrorValues, maMat);
2122 return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, bIgnoreErrorValues, maMat);
2127 return GetValueWithCount<sc::op::Product>(bTextAsZero, bIgnoreErrorValues, maMat);
2132 CountElements aFunc(bCountStrings, bCountErrors, bIgnoreEmptyStrings);
2133 aFunc = maMat.walk(aFunc);
2134 return aFunc.getCount();
2139 WalkAndMatchElements<double> aFunc(fValue, maMat.size(), nCol1, nCol2);
2140 aFunc = maMat.walk(aFunc);
2141 return aFunc.getMatching();
2146 WalkAndMatchElements<svl::SharedString> aFunc(rStr, maMat.size(), nCol1, nCol2);
2147 aFunc = maMat.walk(aFunc);
2148 return aFunc.getMatching();
2153 CalcMaxMinValue<MaxOp> aFunc(bTextAsZero, bIgnoreErrorValues);
2154 aFunc = maMat.walk(aFunc);
2155 return aFunc.getValue();
2160 CalcMaxMinValue<MinOp> aFunc(bTextAsZero, bIgnoreErrorValues);
2161 aFunc = maMat.walk(aFunc);
2162 return aFunc.getValue();
2167 CalcGcdLcm<Gcd> aFunc;
2168 aFunc = maMat.walk(aFunc);
2169 return aFunc.getResult();
2174 CalcGcdLcm<Lcm> aFunc;
2175 aFunc = maMat.walk(aFunc);
2176 return aFunc.getResult();
2182 MatrixImplType::size_pair_type aSize = maMat.size();
2183 size_t nSize = aSize.column * aSize.row;
2191 CompareMatrixToNumericFunc aFunc(nSize, rComp, rComp.
maCells[1].
mfValue, pOptions);
2192 aFunc = maMat.walk(std::move(aFunc));
2195 const std::vector<double>& rResVal = aFunc.getValues();
2196 assert (nSize == rResVal.size());
2197 if (nSize != rResVal.size())
2204 CompareMatrixFunc aFunc(nSize, rComp, nMatPos, pOptions);
2205 aFunc = maMat.walk(std::move(aFunc));
2208 const std::vector<double>& rResVal = aFunc.getValues();
2209 assert (nSize == rResVal.size());
2210 if (nSize != rResVal.size())
2218 MatrixImplType::size_pair_type aSize = maMat.size();
2219 ToDoubleArray aFunc(aSize.row*aSize.column, bEmptyAsZero);
2220 aFunc = maMat.walk(std::move(aFunc));
2226 MatrixImplType::size_pair_type aSize = maMat.size();
2227 size_t nSize = aSize.row*aSize.column;
2228 if (nSize != rArray.size())
2231 MergeDoubleArrayFunc<ArrayMul> aFunc(rArray);
2232 maMat.walk(std::move(aFunc));
2237 template<
typename T,
typename U,
typename return_type>
2238 struct wrapped_iterator
2240 typedef ::std::bidirectional_iterator_tag iterator_category;
2241 typedef typename T::const_iterator::value_type old_value_type;
2242 typedef return_type value_type;
2243 typedef value_type* pointer;
2244 typedef value_type& reference;
2245 typedef typename T::const_iterator::difference_type difference_type;
2247 typename T::const_iterator it;
2248 mutable value_type val;
2253 value_type calcVal()
const
2260 wrapped_iterator(
typename T::const_iterator
const & it_, U
const & aOp):
2267 wrapped_iterator(
const wrapped_iterator& r):
2274 wrapped_iterator& operator=(
const wrapped_iterator& r)
2280 bool operator==(
const wrapped_iterator& r)
const
2285 bool operator!=(
const wrapped_iterator& r)
const
2297 wrapped_iterator& operator--()
2310 pointer operator->()
const
2317 template<
typename T,
typename U,
typename return_type>
2318 struct MatrixIteratorWrapper
2321 typename T::const_iterator m_itBegin;
2322 typename T::const_iterator m_itEnd;
2325 MatrixIteratorWrapper(
typename T::const_iterator
const & itBegin,
typename T::const_iterator
const & itEnd, U
const & aOp):
2332 wrapped_iterator<T, U, return_type>
begin()
2334 return wrapped_iterator<T, U, return_type>(m_itBegin,
maOp);
2337 wrapped_iterator<T, U, return_type>
end()
2339 return wrapped_iterator<T, U, return_type>(m_itEnd,
maOp);
2343 MatrixImplType::position_type increment_position(
const MatrixImplType::position_type& pos,
size_t n)
2345 MatrixImplType::position_type ret = pos;
2348 if (ret.second + n < ret.first->size)
2355 n -= (ret.first->size - ret.second);
2364 template<
typename T>
2365 struct MatrixOpWrapper
2369 MatrixImplType::position_type pos;
2380 MatrixOpWrapper(
const MatrixOpWrapper& r ) : mrMat(r.mrMat), pos(r.pos), mpOp(r.mpOp) {}
2382 MatrixOpWrapper& operator= (
const MatrixOpWrapper& r ) =
default;
2384 void operator()(
const MatrixImplType::element_block_node_type& node)
2388 case mdds::mtm::element_numeric:
2390 typedef MatrixImplType::numeric_block_type block_type;
2392 block_type::const_iterator it = block_type::begin(*node.data);
2393 block_type::const_iterator itEnd = block_type::end(*node.data);
2394 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2395 pos = mrMat.set(pos,aFunc.begin(), aFunc.end());
2398 case mdds::mtm::element_boolean:
2400 typedef MatrixImplType::boolean_block_type block_type;
2402 block_type::const_iterator it = block_type::begin(*node.data);
2403 block_type::const_iterator itEnd = block_type::end(*node.data);
2405 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2406 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2409 case mdds::mtm::element_string:
2411 typedef MatrixImplType::string_block_type block_type;
2413 block_type::const_iterator it = block_type::begin(*node.data);
2414 block_type::const_iterator itEnd = block_type::end(*node.data);
2416 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2417 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2420 case mdds::mtm::element_empty:
2422 if (mpOp->useFunctionForEmpty())
2424 std::vector<char> aVec(node.size);
2425 MatrixIteratorWrapper<std::vector<char>, T,
typename T::number_value_type>
2426 aFunc(aVec.begin(), aVec.end(), *mpOp);
2427 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2434 pos = increment_position(pos, node.size);
2440 template<
typename T>
2443 MatrixOpWrapper<T> aFunc(rMat.
maMat, aOp);
2447 template<
typename T>
2450 WalkElementBlocksMultipleValues<T> aFunc(aOp);
2451 aFunc = maMat.walk(std::move(aFunc));
2452 return aFunc.getResult();
2459 ElementBlock(
size_t nRowSize,
2464 mnRowSize(nRowSize),
2467 maDoubleFunc(aDoubleFunc),
2468 maBoolFunc(aBoolFunc),
2469 maStringFunc(aStringFunc),
2470 maEmptyFunc(aEmptyFunc)
2484 class WalkElementBlockOperation
2488 WalkElementBlockOperation(ElementBlock& rElementBlock)
2489 : mrElementBlock(rElementBlock)
2493 void operator()(
const MatrixImplType::element_block_node_type& node)
2497 case mdds::mtm::element_numeric:
2499 typedef MatrixImplType::numeric_block_type block_type;
2501 block_type::const_iterator it = block_type::begin(*node.data);
2502 std::advance(it, node.offset);
2503 block_type::const_iterator itEnd = it;
2504 std::advance(itEnd, node.size);
2505 for (
auto itr = it; itr != itEnd; ++itr)
2507 mrElementBlock.maDoubleFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2508 ++mrElementBlock.mnRowPos;
2509 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2511 mrElementBlock.mnRowPos = 0;
2512 ++mrElementBlock.mnColPos;
2517 case mdds::mtm::element_string:
2519 typedef MatrixImplType::string_block_type block_type;
2521 block_type::const_iterator it = block_type::begin(*node.data);
2522 std::advance(it, node.offset);
2523 block_type::const_iterator itEnd = it;
2524 std::advance(itEnd, node.size);
2525 for (
auto itr = it; itr != itEnd; ++itr)
2527 mrElementBlock.maStringFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2528 ++mrElementBlock.mnRowPos;
2529 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2531 mrElementBlock.mnRowPos = 0;
2532 ++mrElementBlock.mnColPos;
2537 case mdds::mtm::element_boolean:
2539 typedef MatrixImplType::boolean_block_type block_type;
2541 block_type::const_iterator it = block_type::begin(*node.data);
2542 std::advance(it, node.offset);
2543 block_type::const_iterator itEnd = it;
2544 std::advance(itEnd, node.size);
2545 for (
auto itr = it; itr != itEnd; ++itr)
2547 mrElementBlock.maBoolFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2548 ++mrElementBlock.mnRowPos;
2549 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2551 mrElementBlock.mnRowPos = 0;
2552 ++mrElementBlock.mnColPos;
2557 case mdds::mtm::element_empty:
2559 for (
size_t i=0;
i < node.size; ++
i)
2561 mrElementBlock.maEmptyFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos);
2562 ++mrElementBlock.mnRowPos;
2563 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2565 mrElementBlock.mnRowPos = 0;
2566 ++mrElementBlock.mnColPos;
2571 case mdds::mtm::element_integer:
2573 SAL_WARN(
"sc.core",
"WalkElementBlockOperation - unhandled element_integer");
2575 mrElementBlock.mnColPos += node.size / mrElementBlock.mnRowSize;
2576 mrElementBlock.mnRowPos += node.size % mrElementBlock.mnRowSize;
2577 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2579 mrElementBlock.mnRowPos = 0;
2580 ++mrElementBlock.mnColPos;
2589 ElementBlock& mrElementBlock;
2599 ElementBlock aPayload(maMat.size().row, aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
2600 WalkElementBlockOperation aFunc(aPayload);
2603 MatrixImplType::size_pair_type(rStartPos.first, rStartPos.second),
2604 MatrixImplType::size_pair_type(rEndPos.first, rEndPos.second));
2609 void ScMatrixImpl::Dump()
const
2611 cout <<
"-- matrix content" <<
endl;
2613 GetDimensions(nCols, nRows);
2614 for (
SCSIZE nRow = 0; nRow < nRows; ++nRow)
2616 for (
SCSIZE nCol = 0; nCol < nCols; ++nCol)
2618 cout <<
" row=" << nRow <<
", col=" << nCol <<
" : ";
2619 switch (maMat.get_type(nRow, nCol))
2621 case mdds::mtm::element_string:
2622 cout <<
"string (" << maMat.get_string(nRow, nCol).getString() <<
")";
2624 case mdds::mtm::element_numeric:
2625 cout <<
"numeric (" << maMat.get_numeric(nRow, nCol) <<
")";
2627 case mdds::mtm::element_boolean:
2628 cout <<
"boolean (" << maMat.get_boolean(nRow, nCol) <<
")";
2630 case mdds::mtm::element_empty:
2645 SCSIZE nRowSize = maMat.size().row;
2646 SAL_WARN_IF( !nRowSize,
"sc.core",
"ScMatrixImpl::CalcPosition: 0 rows!");
2647 rC = nRowSize > 1 ? nIndex / nRowSize : nIndex;
2648 rR = nIndex - rC*nRowSize;
2653 size_t get_index(
SCSIZE nMaxRow,
size_t nRow,
size_t nCol,
size_t nRowOffset,
size_t nColOffset)
2655 return nMaxRow * (nCol + nColOffset) + nRow + nRowOffset;
2665 xMat1->GetDimensions(nC1, nR1);
2666 xMat2->GetDimensions(nC2, nR2);
2671 std::vector<OUString> aString(nMaxCol * nMaxRow);
2672 std::vector<bool> aValid(nMaxCol * nMaxRow,
true);
2673 std::vector<FormulaError> nErrors(nMaxCol * nMaxRow,FormulaError::NONE);
2675 size_t nRowOffset = 0;
2676 size_t nColOffset = 0;
2677 std::function<void(size_t, size_t, double)> aDoubleFunc =
2678 [&](
size_t nRow,
size_t nCol,
double nVal)
2681 if (nErr != FormulaError::NONE)
2683 aValid[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
false;
2684 nErrors[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = nErr;
2689 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] + aStr;
2692 std::function<void(size_t, size_t, bool)> aBoolFunc =
2693 [&](
size_t nRow,
size_t nCol,
bool nVal)
2697 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] + aStr;
2700 std::function<void(size_t, size_t, const svl::SharedString&)> aStringFunc =
2703 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr.getString();
2706 std::function<void(size_t, size_t)> aEmptyFunc =
2707 [&](
size_t ,
size_t )
2713 if (nC1 == 1 || nR1 == 1)
2715 size_t nRowRep = nR1 == 1 ? nMaxRow : 1;
2716 size_t nColRep = nC1 == 1 ? nMaxCol : 1;
2718 for (
size_t i = 0;
i < nRowRep; ++
i)
2721 for (
size_t j = 0; j < nColRep; ++j)
2724 xMat1->ExecuteOperation(
2725 std::pair<size_t, size_t>(0, 0),
2726 std::pair<size_t, size_t>(std::min(nR1, nMaxRow) - 1, std::min(nC1, nMaxCol) - 1),
2727 aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
2732 xMat1->ExecuteOperation(
2733 std::pair<size_t, size_t>(0, 0),
2734 std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1),
2735 aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
2737 std::vector<svl::SharedString> aSharedString(nMaxCol*nMaxRow);
2739 std::function<void(size_t, size_t, double)> aDoubleFunc2 =
2740 [&](
size_t nRow,
size_t nCol,
double nVal)
2743 if (nErr != FormulaError::NONE)
2745 aValid[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
false;
2746 nErrors[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = nErr;
2751 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] + aStr);
2754 std::function<void(size_t, size_t, bool)> aBoolFunc2 =
2755 [&](
size_t nRow,
size_t nCol,
bool nVal)
2759 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] + aStr);
2762 std::function<void(size_t, size_t, const svl::SharedString&)> aStringFunc2 =
2765 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
2766 rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr.getString());
2769 std::function<void(size_t, size_t)> aEmptyFunc2 =
2770 [&](
size_t nRow,
size_t nCol)
2772 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
2773 rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)]);
2778 if (nC2 == 1 || nR2 == 1)
2780 size_t nRowRep = nR2 == 1 ? nMaxRow : 1;
2781 size_t nColRep = nC2 == 1 ? nMaxCol : 1;
2783 for (
size_t i = 0;
i < nRowRep; ++
i)
2786 for (
size_t j = 0; j < nColRep; ++j)
2789 xMat2->ExecuteOperation(
2790 std::pair<size_t, size_t>(0, 0),
2791 std::pair<size_t, size_t>(std::min(nR2, nMaxRow) - 1, std::min(nC2, nMaxCol) - 1),
2792 aDoubleFunc2, aBoolFunc2, aStringFunc2, aEmptyFunc2);
2797 xMat2->ExecuteOperation(
2798 std::pair<size_t, size_t>(0, 0),
2799 std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1),
2800 aDoubleFunc2, aBoolFunc2, aStringFunc2, aEmptyFunc2);
2804 MatrixImplType::position_type pos = maMat.position(0, 0);
2807 for (
SCSIZE j = 0; j < nMaxRow &&
i < nMaxCol; ++j)
2809 if (aValid[nMaxRow *
i + j])
2811 auto itr = aValid.begin();
2812 std::advance(itr, nMaxRow *
i + j);
2813 auto itrEnd = std::find(itr, aValid.end(),
false);
2814 size_t nSteps = std::distance(itr, itrEnd);
2815 auto itrStr = aSharedString.begin();
2816 std::advance(itrStr, nMaxRow *
i + j);
2817 auto itrEndStr = itrStr;
2818 std::advance(itrEndStr, nSteps);
2819 pos = maMat.set(pos, itrStr, itrEndStr);
2820 size_t nColSteps = nSteps / nMaxRow;
2822 j += nSteps % nMaxRow;
2833 pos = MatrixImplType::next_position(pos);
2852 SAL_WARN_IF( !nC,
"sc.core",
"ScMatrix with 0 columns!");
2853 SAL_WARN_IF( !nR,
"sc.core",
"ScMatrix with 0 rows!");
2855 if ((nC && !nR) || (!nC && nR))
2857 SAL_WARN(
"sc.core",
"ScMatrix one-dimensional zero: " << nC <<
" columns * " << nR <<
" rows");
2865 const char* pEnv = std::getenv(
"SC_MAX_MATRIX_ELEMENTS");
2876 #if SAL_TYPES_SIZEOFPOINTER < 8
2878 constexpr
size_t nMemMax = 0x40000000;
2881 constexpr
size_t nMemMax = 0x180000000;
2890 SAL_WARN(
"sc.core",
"ScMatrix overflow: " << nC <<
" columns * " << nR <<
" rows");
2897 nRefCnt(0), mbCloneIfConst(true)
2907 nRefCnt(0), mbCloneIfConst(true)
2917 nRefCnt(0), mbCloneIfConst(true)
2933 pImpl->GetDimensions(nC, nR);
2957 pImpl->Resize(nC, nR);
2962 pImpl->Resize(nC, nR, fVal);
2975 pImpl->SetErrorInterpreter(p);
2980 pImpl->GetDimensions(rC, rR);
2985 return pImpl->GetElementCount();
2990 return pImpl->ValidColRow(nC, nR);
2995 return pImpl->ValidColRowReplicated(rC, rR);
3005 pImpl->PutDouble(fVal, nC, nR);
3010 pImpl->PutDouble(fVal, nIndex);
3015 pImpl->PutDouble(pArray, nLen, nC, nR);
3020 pImpl->PutString(rStr, nC, nR);
3025 pImpl->PutString(rStr, nIndex);
3030 pImpl->PutString(pArray, nLen, nC, nR);
3035 pImpl->PutEmpty(nC, nR);
3040 pImpl->PutEmptyPath(nC, nR);
3045 pImpl->PutError(nErrorCode, nC, nR);
3050 pImpl->PutBoolean(bVal, nC, nR);
3055 return pImpl->GetError(nC, nR);
3060 return pImpl->GetDouble(nC, nR);
3065 return pImpl->GetDouble(nIndex);
3070 return pImpl->GetDoubleWithStringConversion(nC, nR);
3075 return pImpl->GetString(nC, nR);
3080 return pImpl->GetString(nIndex);
3085 return pImpl->GetString(rFormatter, nC, nR);
3090 return pImpl->Get(nC, nR);
3095 return pImpl->IsStringOrEmpty(nIndex);
3100 return pImpl->IsStringOrEmpty(nC, nR);
3105 return pImpl->IsEmpty(nC, nR);
3110 return pImpl->IsEmptyCell(nC, nR);
3115 return pImpl->IsEmptyResult(nC, nR);
3120 return pImpl->IsEmptyPath(nC, nR);
3125 return pImpl->IsValue(nIndex);
3130 return pImpl->IsValue(nC, nR);
3135 return pImpl->IsValueOrEmpty(nC, nR);
3140 return pImpl->IsBoolean(nC, nR);
3145 return pImpl->IsNumeric();
3160 pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2);
3165 pImpl->PutDoubleVector(rVec, nC, nR);
3170 pImpl->PutStringVector(rVec, nC, nR);
3175 pImpl->PutEmptyVector(nCount, nC, nR);
3180 pImpl->PutEmptyResultVector(nCount, nC, nR);
3185 pImpl->PutEmptyPathVector(nCount, nC, nR);
3190 pImpl->CompareEqual();
3195 pImpl->CompareNotEqual();
3200 pImpl->CompareLess();
3205 pImpl->CompareGreater();
3210 pImpl->CompareLessEqual();
3215 pImpl->CompareGreaterEqual();
3220 return pImpl->And();
3230 return pImpl->Xor();
3235 return pImpl->Sum(bTextAsZero, bIgnoreErrorValues);
3240 return pImpl->SumSquare(bTextAsZero, bIgnoreErrorValues);
3245 return pImpl->Product(bTextAsZero, bIgnoreErrorValues);
3248 size_t ScMatrix::Count(
bool bCountStrings,
bool bCountErrors,
bool bIgnoreEmptyStrings)
const
3250 return pImpl->Count(bCountStrings, bCountErrors, bIgnoreEmptyStrings);
3255 return pImpl->MatchDoubleInColumns(fValue, nCol1, nCol2);
3260 return pImpl->MatchStringInColumns(rStr, nCol1, nCol2);
3265 return pImpl->GetMaxValue(bTextAsZero, bIgnoreErrorValues);
3270 return pImpl->GetMinValue(bTextAsZero, bIgnoreErrorValues);
3275 return pImpl->GetGcd();
3280 return pImpl->GetLcm();
3287 return pImpl->CompareMatrix(rComp, nMatPos, pOptions);
3292 pImpl->GetDoubleArray(rArray, bEmptyAsZero);
3297 pImpl->MergeDoubleArrayMultiply(rArray);
3308 template <
typename T,
typename S>
3313 template <
typename T>
3314 struct COp<T,
svl::SharedString>
3322 template <
typename T>
3323 struct COp<T, double>
3342 template<
typename TOp,
typename TEmptyRes=
double,
typename TRet=
double>
3353 typedef TRet number_value_type;
3358 mpErrorInterpreter(pErrorInterpreter),
3362 if (mpErrorInterpreter)
3365 if (nErr != FormulaError::NONE)
3370 TRet operator()(
double fVal)
const
3372 return maOp(fVal, mfVal);
3375 TRet operator()(
bool bVal)
const
3377 return maOp(static_cast<double>(bVal), mfVal);
3382 return maOp( convertStringToValue( mpErrorInterpreter, rStr.
getString()), mfVal);
3385 TEmptyRes operator()(
char)
const
3390 static bool useFunctionForEmpty()
3402 auto not_ = [](
double a, double){
return double(a == 0.0);};
3403 matop::MatOp<decltype(not_), double> aOp(not_,
pImpl->GetErrorInterpreter());
3409 auto neg_ = [](
double a, double){
return -a;};
3410 matop::MatOp<decltype(neg_), double> aOp(neg_,
pImpl->GetErrorInterpreter());
3416 auto add_ = [](
double a,
double b){
return a + b;};
3417 matop::MatOp<decltype(add_)> aOp(add_,
pImpl->GetErrorInterpreter(), fVal);
3425 auto sub_ = [](
double a,
double b){
return b - a;};
3426 matop::MatOp<decltype(sub_)> aOp(sub_,
pImpl->GetErrorInterpreter(), fVal);
3431 auto sub_ = [](
double a,
double b){
return a - b;};
3432 matop::MatOp<decltype(sub_)> aOp(sub_,
pImpl->GetErrorInterpreter(), fVal);
3439 auto mul_ = [](
double a,
double b){
return a * b;};
3440 matop::MatOp<decltype(mul_)> aOp(mul_,
pImpl->GetErrorInterpreter(), fVal);
3448 auto div_ = [](
double a,
double b){
return sc::div(b, a);};
3449 matop::MatOp<decltype(div_)> aOp(div_,
pImpl->GetErrorInterpreter(), fVal);
3454 auto div_ = [](
double a,
double b){
return sc::div(a, b);};
3455 matop::MatOp<decltype(div_)> aOp(div_,
pImpl->GetErrorInterpreter(), fVal);
3464 auto pow_ = [](
double a,
double b){
return sc::power(b, a);};
3465 matop::MatOp<decltype(pow_)> aOp(pow_,
pImpl->GetErrorInterpreter(), fVal);
3470 auto pow_ = [](
double a,
double b){
return sc::power(a, b);};
3471 matop::MatOp<decltype(pow_)> aOp(pow_,
pImpl->GetErrorInterpreter(), fVal);
3480 pImpl->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
3485 return pImpl->ApplyCollectOperation(aOp);
3489 void ScMatrix::Dump()
const
3498 pImpl->MatConcat(nMaxCol, nMaxRow, xMat1, xMat2, rFormatter, rPool);
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
Matrix data type that can store values of mixed types.
bool ValidColRowOrReplicated(SCSIZE &rC, SCSIZE &rR) const
Checks if the matrix position is within the matrix.
bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const
ScMatrixRef CompareMatrix(sc::Compare &rComp, size_t nMatPos, sc::CompareOptions *pOptions) const
void SetErrorAtInterpreter(FormulaError nError) const
COp< TOp, TEmptyRes > maCOp
static bool bElementsMaxFetched
void PutStringVector(const ::std::vector< svl::SharedString > &rVec, SCSIZE nC, SCSIZE nR)
void MatTrans(ScMatrixImpl &mRes) const
OUString getString() const
bool ValidColRow(SCSIZE nC, SCSIZE nR) const
SharedString intern(const OUString &rStr)
~ScMatrixImpl() COVERITY_NOEXCEPT_FALSE
std::vector< ScMatrix::IterateResult > ApplyCollectOperation(const std::vector< T > &aOp)
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
static SharedString getEmptyString()
FormulaError GetError() const
ScInterpreter * pErrorInterpreter
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
void CompareGreaterEqual()
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string! ...
svl::SharedString maString
const TMatFlag SC_MATFLAG_EMPTYPATH
mdds::mtv::default_element_block< element_type_string, svl::SharedString > string_block
SCSIZE GetElementCount() const
const TMatFlag SC_MATFLAG_EMPTYRESULT
void GetDoubleArray(std::vector< double > &rArray, bool bEmptyAsZero) const
void SubOp(bool bFlag, double fVal, const ScMatrix &rMat)
friend class ScMatrixImpl
size_t MatchStringInColumns(const svl::SharedString &rStr, size_t nCol1, size_t nCol2) const
void MatCopy(const ScMatrix &mRes) const
ScMatrix(const ScMatrix &)=delete
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
void PutEmptyPath(SCSIZE nC, SCSIZE nR)
Jump sal_False without path.
IterateResult Sum(bool bTextAsZero, bool bIgnoreErrorValues=false) const
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
const ScMatrixImpl & operator=(const ScMatrixImpl &)=delete
void PutString(const svl::SharedString &rStr, SCSIZE nC, SCSIZE nR)
void AddOp(double fVal, const ScMatrix &rMat)
Try NOT to use this struct.
size_t MatchStringInColumns(const svl::SharedString &rStr, size_t nCol1, size_t nCol2) const
const svl::SharedString & operator()(char, T, double, double, const svl::SharedString &rString) const
double CompareEmptyToNumericFunc(double fCell2)
Left cell is empty while the right cell is numeric.
void PutEmpty(SCSIZE nC, SCSIZE nR)
void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2)
void DivOp(bool bFlag, double fVal, const ScMatrix &rMat)
double GetDouble(SCSIZE nC, SCSIZE nR) const
double CompareFunc(const Compare &rComp, CompareOptions *pOptions)
Op_< std::function< void(double &, double)>> Op
void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2)
double GetMaxValue(bool bTextAsZero, bool bIgnoreErrorValues=false) const
enumrange< T >::Iterator begin(enumrange< T >)
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void ExecuteOperation(const std::pair< size_t, size_t > &rStartPos, const std::pair< size_t, size_t > &rEndPos, DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc, EmptyOpFunction aEmptyFunc) const
std::unique_ptr< ScMatrixImpl > pImpl
void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empty paths, starting at row nR, must fit into dimensions. ...
mdds::multi_type_matrix< matrix_trait > MatrixImplType
void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empties, starting at row nR, must fit into dimensions.
static size_t GetElementsMax(size_t nMemory)
The maximum number of elements a matrix or the pool may have at runtime.
size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
void MatCopy(ScMatrixImpl &mRes) const
bool ValidColRow(SCSIZE nC, SCSIZE nR) const
bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
ScMatrix::IterateResult SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const
bool IsStringOrEmpty(SCSIZE nIndex) const
FormulaError GetDoubleErrorValue(double fVal)
bool IsValue(SCSIZE nIndex) const
ScInterpreter * GetErrorInterpreter() const
mdds::mtv::uint16_element_block uint16_block
std::function< void(size_t, size_t)> EmptyOpFunction
ScMatrix::IterateResult Sum(bool bTextAsZero, bool bIgnoreErrorValues) const
void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empty results, starting at row nR, must fit into dimensions.
void PowOp(bool bFlag, double fVal, const ScMatrix &rMat)
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
void MergeDoubleArrayMultiply(std::vector< double > &rArray) const
void Resize(SCSIZE nC, SCSIZE nR)
Resize the matrix to specified new dimension.
double GetMaxValue(bool bTextAsZero, bool bIgnoreErrorValues) const
void PutDoubleVector(const ::std::vector< double > &rVec, SCSIZE nC, SCSIZE nR)
Put a column vector of doubles, starting at row nR, must fit into dimensions.
void PutString(const svl::SharedString &rStr, SCSIZE nC, SCSIZE nR)
double ConvertStringToValue(const OUString &)
void NotOp(const ScMatrix &rMat)
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
ScMatrix * CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const
Clone the matrix and extend it to the new size.
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
double GetDoubleWithStringConversion(SCSIZE nC, SCSIZE nR) const
FormulaError GetError(SCSIZE nC, SCSIZE nR) const
May be used before obtaining the double value of an element to avoid passing its NAN around...
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
ScMatrixRef CompareMatrix(sc::Compare &rComp, size_t nMatPos, sc::CompareOptions *pOptions) const
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
void CompareGreaterEqual()
mdds::multi_type_matrix< matrix_trait > MatrixImplType
double operator()(char, T aOp, double a, double b, const svl::SharedString &) const
void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
static SC_DLLPUBLIC LanguageType eLnge
bool ValidColRowReplicated(SCSIZE &rC, SCSIZE &rR) const
For a row vector or column vector, if the position does not point into the vector but is a valid colu...
void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef &xMat1, const ScMatrixRef &xMat2, SvNumberFormatter &rFormatter, svl::SharedStringPool &rPool)
ScMatrix * CloneIfConst()
Clone the matrix if mbCloneIfConst (immutable) is set, otherwise return this matrix, to be assigned to a ScMatrixRef.
double GetDouble(SCSIZE nC, SCSIZE nR) const
enumrange< T >::Iterator end(enumrange< T >)
FormulaError GetError(SCSIZE nC, SCSIZE nR) const
static size_t nElementsMax
void MatTrans(const ScMatrix &mRes) const
double power(const double &fVal1, const double &fVal2)
Return pow(fVal1,fVal2) with error handling.
IterateResult Product(bool bTextAsZero, bool bIgnoreErrorValues=false) const
void PutDoubleVector(const ::std::vector< double > &rVec, SCSIZE nC, SCSIZE nR)
std::vector< ScMatrix::IterateResult > Collect(const std::vector< sc::op::Op > &aOp)
void PutError(FormulaError nErrorCode, SCSIZE nC, SCSIZE nR)
double CreateDoubleError(FormulaError nErr)
void SetErrorInterpreter(ScInterpreter *p)
ScInterpreter * mpErrorInterpreter
bool ValidColRowOrReplicated(SCSIZE &rC, SCSIZE &rR) const
std::function< void(size_t, size_t, double)> DoubleOpFunction
#define SAL_WARN_IF(condition, area, stream)
void ExecuteOperation(const std::pair< size_t, size_t > &rStartPos, const std::pair< size_t, size_t > &rEndPos, const ScMatrix::DoubleOpFunction &aDoubleFunc, const ScMatrix::BoolOpFunction &aBoolFunc, const ScMatrix::StringOpFunction &aStringFunc, const ScMatrix::EmptyOpFunction &aEmptyFunc) const
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
void Resize(SCSIZE nC, SCSIZE nR)
SvStream & endl(SvStream &rStr)
bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const
std::function< void(size_t, size_t, svl::SharedString)> StringOpFunction
size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings=false) const
void SetMutable()
Set the matrix to mutable for CloneIfConst(), only the interpreter should do this and know the conseq...
void GetDoubleArray(std::vector< double > &rArray, bool bEmptyAsZero=true) const
Convert the content of matrix into a linear array of numeric values.
bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const
void SetErrorInterpreter(ScInterpreter *p)
These need to be in global namespace just like their respective types are.
void CalcPosition(SCSIZE nIndex, SCSIZE &rC, SCSIZE &rR) const
When adding all numerical matrix elements for a scalar result such as summation, the interpreter want...
HSLColor operator*(double nFactor, const HSLColor &rRHS)
ScMatrix * Clone() const
Clone the matrix.
double GetDoubleWithStringConversion(SCSIZE nC, SCSIZE nR) const
FILE * init(int, char **)
ScMatrix::IterateResult Product(bool bTextAsZero, bool bIgnoreErrorValues) const
void PutEmpty(SCSIZE nC, SCSIZE nR)
void PutError(FormulaError nErrorCode, SCSIZE nC, SCSIZE nR)
double GetMinValue(bool bTextAsZero, bool bIgnoreErrorValues=false) const
void PutEmptyPath(SCSIZE nC, SCSIZE nR)
#define SAL_WARN(area, stream)
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
bool IsValue(SCSIZE nIndex) const
SCSIZE GetElementCount() const
IterateResult SumSquare(bool bTextAsZero, bool bIgnoreErrorValues=false) const
void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const
void SetImmutable() const
Set the matrix to immutable for CloneIfConst(), only the interpreter should do this and know the cons...
void PutStringVector(const ::std::vector< svl::SharedString > &rVec, SCSIZE nC, SCSIZE nR)
Put a column vector of strings, starting at row nR, must fit into dimensions.
void MulOp(double fVal, const ScMatrix &rMat)
void ApplyOperation(T aOp, ScMatrixImpl &rMat)
bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const
double GetMinValue(bool bTextAsZero, bool bIgnoreErrorValues) const
void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
void NegOp(const ScMatrix &rMat)
bool IsStringOrEmpty(SCSIZE nIndex) const
void MergeDoubleArrayMultiply(std::vector< double > &rArray) const
void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
void SetError(FormulaError nError)
std::function< void(size_t, size_t, bool)> BoolOpFunction
static OUString GetErrorString(FormulaError nErrNumber)
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
double div(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded into double.
static double ScGetGCD(double fx, double fy)
ScMatrixImpl(const ScMatrixImpl &)=delete
static bool IsSizeAllocatable(SCSIZE nC, SCSIZE nR)
Checks nC or nR for zero and uses GetElementsMax() whether a matrix of the size of nC*nR could be all...
void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef &xMat1, const ScMatrixRef &xMat2, SvNumberFormatter &rFormatter, svl::SharedStringPool &rPool)
bool ValidColRowReplicated(SCSIZE &rC, SCSIZE &rR) const
size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) const