33#include <rtl/math.hxx>
35#include <osl/diagnose.h>
43#include <mdds/multi_type_matrix.hpp>
44#include <mdds/multi_type_vector/types.hpp>
67struct matrix_flag_traits
70 typedef mdds::mtv::uint8_element_block integer_element_block;
80double convertStringToValue(
ScInterpreter* pErrorInterpreter,
const OUString& rStr )
82 if (pErrorInterpreter)
87 if (nError != FormulaError::NONE)
89 pErrorInterpreter->
SetError( nError);
99 double operator() (
double val)
const
101 if (!std::isfinite(val))
103 return val == 0.0 ? 1.0 : 0.0;
107struct ElemNotEqualZero
109 double operator() (
double val)
const
111 if (!std::isfinite(val))
113 return val != 0.0 ? 1.0 : 0.0;
117struct ElemGreaterZero
119 double operator() (
double val)
const
121 if (!std::isfinite(val))
123 return val > 0.0 ? 1.0 : 0.0;
129 double operator() (
double val)
const
131 if (!std::isfinite(val))
133 return val < 0.0 ? 1.0 : 0.0;
137struct ElemGreaterEqualZero
139 double operator() (
double val)
const
141 if (!std::isfinite(val))
143 return val >= 0.0 ? 1.0 : 0.0;
147struct ElemLessEqualZero
149 double operator() (
double val)
const
151 if (!std::isfinite(val))
153 return val <= 0.0 ? 1.0 : 0.0;
157template<
typename Comp>
158class CompareMatrixElemFunc
162 std::vector<double> maNewMatValues;
166 CompareMatrixElemFunc(
size_t nRow,
size_t nCol ) :
mnRow(nRow),
mnCol(nCol)
168 maNewMatValues.reserve(nRow*nCol);
171 CompareMatrixElemFunc(
const CompareMatrixElemFunc& ) =
delete;
172 CompareMatrixElemFunc& operator= (
const CompareMatrixElemFunc& ) =
delete;
174 CompareMatrixElemFunc( CompareMatrixElemFunc&& ) =
default;
175 CompareMatrixElemFunc& operator= ( CompareMatrixElemFunc&& ) =
default;
177 void operator() (
const MatrixImplType::element_block_node_type& node)
181 case mdds::mtm::element_numeric:
183 typedef MatrixImplType::numeric_block_type block_type;
185 block_type::const_iterator it = block_type::begin(*node.data);
186 block_type::const_iterator itEnd = block_type::end(*node.data);
187 for (; it != itEnd; ++it)
190 maNewMatValues.push_back(maComp(fVal));
194 case mdds::mtm::element_boolean:
196 typedef MatrixImplType::boolean_block_type block_type;
198 block_type::const_iterator it = block_type::begin(*node.data);
199 block_type::const_iterator itEnd = block_type::end(*node.data);
200 for (; it != itEnd; ++it)
202 double fVal = *it ? 1.0 : 0.0;
203 maNewMatValues.push_back(maComp(fVal));
207 case mdds::mtm::element_string:
208 case mdds::mtm::element_empty:
211 maNewMatValues.resize(maNewMatValues.size() + node.size, 0.0);
222template<
typename Comp>
223Comp CompareMatrixElemFunc<Comp>::maComp;
244 ScMatrixImpl(
size_t nC,
size_t nR,
const std::vector<double>& rInitVals );
314 size_t Count(
bool bCountStrings,
bool bCountErrors,
bool bIgnoreEmptyStrings)
const;
318 double GetMaxValue(
bool bTextAsZero,
bool bIgnoreErrorValues )
const;
319 double GetMinValue(
bool bTextAsZero,
bool bIgnoreErrorValues )
const;
325 void GetDoubleArray( std::vector<double>& rArray,
bool bEmptyAsZero )
const;
336 template<
typename T,
typename tRes>
344 bool IsValueOrEmpty(
const MatrixImplType::const_position_type & rPos )
const;
345 double GetDouble(
const MatrixImplType::const_position_type & rPos)
const;
347 bool IsValue(
const MatrixImplType::const_position_type & rPos )
const;
349 bool IsStringOrEmpty(
const MatrixImplType::const_position_type & rPos)
const;
376 constexpr size_t nPerElem = 12;
378 return nMemory / nPerElem;
381 constexpr size_t nMemMax = 0x40000000;
383 constexpr size_t nElemMax = nMemMax / nPerElem;
385 constexpr size_t nArbitraryLimit = size_t(
MAXROWCOUNT) * 128;
387 return std::min(nElemMax, nArbitraryLimit);
391 maMat(nR, nC), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
397 maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
403 maMat(nR, nC, rInitVals.
begin(), rInitVals.
end()), maMatFlag(nR, nC), pErrorInterpreter(nullptr)
425 maMat.resize(nR, nC);
442 maMat.resize(nR, nC, fVal);
461 MatrixImplType::size_pair_type aSize =
maMat.size();
468 MatrixImplType::size_pair_type aSize =
maMat.size();
469 return aSize.row * aSize.column;
474 MatrixImplType::size_pair_type aSize =
maMat.size();
475 return nR < aSize.row && nC < aSize.column;
480 MatrixImplType::size_pair_type aSize =
maMat.size();
481 if (aSize.column == 1 && aSize.row == 1)
487 else if (aSize.column == 1 && rR < aSize.row)
493 else if (aSize.row == 1 && rC < aSize.column)
516 maMat.set(nR, nC, fVal);
519 OSL_FAIL(
"ScMatrixImpl::PutDouble: dimension error");
526 maMat.set(nR, nC, pArray, pArray + nLen);
529 OSL_FAIL(
"ScMatrixImpl::PutDouble: dimension error");
543 maMat.set(nR, nC, rStr);
546 OSL_FAIL(
"ScMatrixImpl::PutString: dimension error");
553 maMat.set(nR, nC, pArray, pArray + nLen);
556 OSL_FAIL(
"ScMatrixImpl::PutString: dimension error");
571 maMat.set_empty(nR, nC);
576 OSL_FAIL(
"ScMatrixImpl::PutEmpty: dimension error");
584 maMat.set_empty(nR, nC);
589 OSL_FAIL(
"ScMatrixImpl::PutEmptyPath: dimension error");
601 maMat.set(nR, nC, bVal);
604 OSL_FAIL(
"ScMatrixImpl::PutBoolean: dimension error");
612 double fVal =
maMat.get_numeric(nR, nC);
617 OSL_FAIL(
"ScMatrixImpl::GetError: dimension error");
618 return FormulaError::NoValue;
626 double fVal =
maMat.get_numeric(nR, nC);
630 if ( nError != FormulaError::NONE )
637 OSL_FAIL(
"ScMatrixImpl::GetDouble: dimension error");
665 OSL_FAIL(
"ScMatrixImpl::GetString: dimension error");
673 switch (
maMat.get_type(rPos))
675 case mdds::mtm::element_string:
676 return maMat.get_string(rPos);
677 case mdds::mtm::element_empty:
679 case mdds::mtm::element_numeric:
680 case mdds::mtm::element_boolean:
681 fErr =
maMat.get_numeric(rPos);
684 OSL_FAIL(
"ScMatrixImpl::GetString: access error, no string");
701 OSL_FAIL(
"ScMatrixImpl::GetString: dimension error");
706 MatrixImplType::const_position_type aPos =
maMat.position(nR, nC);
707 switch (
maMat.get_type(aPos))
709 case mdds::mtm::element_string:
710 return maMat.get_string(aPos);
711 case mdds::mtm::element_empty:
721 const Color* pColor =
nullptr;
725 case mdds::mtm::element_numeric:
726 case mdds::mtm::element_boolean:
727 fVal =
maMat.get_numeric(aPos);
734 if (nError != FormulaError::NONE)
752 MatrixImplType::const_position_type aPos =
maMat.position(nR, nC);
753 mdds::mtm::element_t
eType =
maMat.get_type(aPos);
756 case mdds::mtm::element_boolean:
758 aVal.
fVal = double(
maMat.get_boolean(aPos));
760 case mdds::mtm::element_numeric:
764 case mdds::mtm::element_string:
768 case mdds::mtm::element_empty:
773 case mdds::mtm::element_empty:
776 case mdds::mtm::element_integer:
791 OSL_FAIL(
"ScMatrixImpl::Get: dimension error");
806 switch (
maMat.get_type(nR, nC))
808 case mdds::mtm::element_empty:
809 case mdds::mtm::element_string:
822 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
831 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
832 maMatFlag.get_type(nR, nC) == mdds::mtm::element_empty;
840 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
848 return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
864 switch (
maMat.get_type(nR, nC))
866 case mdds::mtm::element_boolean:
867 case mdds::mtm::element_numeric:
878 switch (
maMat.get_type(nR, nC))
880 case mdds::mtm::element_boolean:
881 case mdds::mtm::element_numeric:
882 case mdds::mtm::element_empty:
893 return maMat.get_type(nR, nC) == mdds::mtm::element_boolean;
898 return maMat.numeric();
906 OSL_FAIL(
"ScMatrixImpl::MatCopy: dimension error");
916 mRes.
maMat.transpose();
923 for (
SCSIZE j = nC1; j <= nC2; ++j)
926 std::vector<double> aVals(nR2-nR1+1, fVal);
927 maMat.set(nR1, j, aVals.begin(), aVals.end());
932 OSL_FAIL(
"ScMatrixImpl::FillDouble: dimension error");
940 maMat.set(nR, nC, rVec.begin(), rVec.end());
944 OSL_FAIL(
"ScMatrixImpl::PutDoubleVector: dimension error");
952 maMat.set(nR, nC, rVec.begin(), rVec.end());
956 OSL_FAIL(
"ScMatrixImpl::PutStringVector: dimension error");
970 OSL_FAIL(
"ScMatrixImpl::PutEmptyVector: dimension error");
981 maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
985 OSL_FAIL(
"ScMatrixImpl::PutEmptyResultVector: dimension error");
996 maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
1000 OSL_FAIL(
"ScMatrixImpl::PutEmptyPathVector: dimension error");
1006 MatrixImplType::size_pair_type aSize =
maMat.size();
1007 CompareMatrixElemFunc<ElemEqualZero> aFunc(aSize.row, aSize.column);
1008 aFunc =
maMat.walk(std::move(aFunc));
1014 MatrixImplType::size_pair_type aSize =
maMat.size();
1015 CompareMatrixElemFunc<ElemNotEqualZero> aFunc(aSize.row, aSize.column);
1016 aFunc =
maMat.walk(std::move(aFunc));
1022 MatrixImplType::size_pair_type aSize =
maMat.size();
1023 CompareMatrixElemFunc<ElemLessZero> aFunc(aSize.row, aSize.column);
1024 aFunc =
maMat.walk(std::move(aFunc));
1030 MatrixImplType::size_pair_type aSize =
maMat.size();
1031 CompareMatrixElemFunc<ElemGreaterZero> aFunc(aSize.row, aSize.column);
1032 aFunc =
maMat.walk(std::move(aFunc));
1038 MatrixImplType::size_pair_type aSize =
maMat.size();
1039 CompareMatrixElemFunc<ElemLessEqualZero> aFunc(aSize.row, aSize.column);
1040 aFunc =
maMat.walk(std::move(aFunc));
1046 MatrixImplType::size_pair_type aSize =
maMat.size();
1047 CompareMatrixElemFunc<ElemGreaterEqualZero> aFunc(aSize.row, aSize.column);
1048 aFunc =
maMat.walk(std::move(aFunc));
1057 void operate(
double fVal) { mbResult &= (fVal != 0.0); }
1058 bool result()
const {
return mbResult; }
1059 AndEvaluator() : mbResult(true) {}
1065 void operate(
double fVal) { mbResult |= (fVal != 0.0); }
1066 bool result()
const {
return mbResult; }
1067 OrEvaluator() : mbResult(false) {}
1073 void operate(
double fVal) { mbResult ^= (fVal != 0.0); }
1074 bool result()
const {
return mbResult; }
1075 XorEvaluator() : mbResult(false) {}
1080template <
typename Evaluator>
1084 size_t nRows = rMat.size().row, nCols = rMat.size().column;
1085 for (
size_t i = 0;
i < nRows; ++
i)
1087 for (
size_t j = 0; j < nCols; ++j)
1089 MatrixImplType::const_position_type aPos = rMat.position(i, j);
1090 mdds::mtm::element_t
eType = rMat.get_type(aPos);
1091 if (eType != mdds::mtm::element_numeric && eType != mdds::mtm::element_boolean)
1095 double fVal = rMat.get_numeric(aPos);
1096 if (!std::isfinite(fVal))
1100 aEval.operate(fVal);
1103 return aEval.result();
1112 return EvalMatrix<AndEvaluator>(
maMat);
1119 return EvalMatrix<OrEvaluator>(
maMat);
1126 return EvalMatrix<XorEvaluator>(
maMat);
1131template<
typename Op,
typename tRes>
1132class WalkElementBlocks
1136 bool mbTextAsZero:1;
1137 bool mbIgnoreErrorValues:1;
1139 WalkElementBlocks(
bool bTextAsZero,
bool bIgnoreErrorValues) :
1140 maRes(
Op::InitVal, 0),
1141 mbTextAsZero(bTextAsZero), mbIgnoreErrorValues(bIgnoreErrorValues)
1146 void operator() (
const MatrixImplType::element_block_node_type& node)
1150 case mdds::mtm::element_numeric:
1152 typedef MatrixImplType::numeric_block_type block_type;
1154 size_t nIgnored = 0;
1155 block_type::const_iterator it = block_type::begin(*node.data);
1156 block_type::const_iterator itEnd = block_type::end(*node.data);
1157 for (; it != itEnd; ++it)
1159 if (mbIgnoreErrorValues && !std::isfinite(*it))
1166 maRes.
mnCount += node.size - nIgnored;
1169 case mdds::mtm::element_boolean:
1171 typedef MatrixImplType::boolean_block_type block_type;
1173 block_type::const_iterator it = block_type::begin(*node.data);
1174 block_type::const_iterator itEnd = block_type::end(*node.data);
1175 for (; it != itEnd; ++it)
1182 case mdds::mtm::element_string:
1186 case mdds::mtm::element_empty:
1193template<
typename Op,
typename tRes>
1194class WalkElementBlocksMultipleValues
1196 const std::vector<Op>* mpOp;
1199 WalkElementBlocksMultipleValues(
const std::vector<Op>& aOp) :
1200 mpOp(&aOp), maRes(0)
1202 for (
const auto& rpOp : *mpOp)
1206 WalkElementBlocksMultipleValues(
const WalkElementBlocksMultipleValues& ) =
delete;
1207 WalkElementBlocksMultipleValues& operator= (
const WalkElementBlocksMultipleValues& ) =
delete;
1209 WalkElementBlocksMultipleValues(WalkElementBlocksMultipleValues&& r) noexcept
1210 : mpOp(r.mpOp), maRes(r.maRes.mnCount)
1215 WalkElementBlocksMultipleValues& operator=(WalkElementBlocksMultipleValues&& r)
noexcept
1219 maRes.
mnCount = r.maRes.mnCount;
1225 void operator() (
const MatrixImplType::element_block_node_type& node)
1229 case mdds::mtm::element_numeric:
1231 typedef MatrixImplType::numeric_block_type block_type;
1233 block_type::const_iterator it = block_type::begin(*node.data);
1234 block_type::const_iterator itEnd = block_type::end(*node.data);
1235 for (; it != itEnd; ++it)
1237 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1243 case mdds::mtm::element_boolean:
1245 typedef MatrixImplType::boolean_block_type block_type;
1247 block_type::const_iterator it = block_type::begin(*node.data);
1248 block_type::const_iterator itEnd = block_type::end(*node.data);
1249 for (; it != itEnd; ++it)
1251 for (
size_t i = 0u;
i < mpOp->size(); ++
i)
1257 case mdds::mtm::element_string:
1258 case mdds::mtm::element_empty:
1270 bool mbIgnoreEmptyStrings;
1272 explicit CountElements(
bool bCountString,
bool bCountErrors,
bool bIgnoreEmptyStrings) :
1273 mnCount(0), mbCountString(bCountString), mbCountErrors(bCountErrors),
1274 mbIgnoreEmptyStrings(bIgnoreEmptyStrings) {}
1276 size_t getCount()
const {
return mnCount; }
1278 void operator() (
const MatrixImplType::element_block_node_type& node)
1282 case mdds::mtm::element_numeric:
1286 typedef MatrixImplType::numeric_block_type block_type;
1288 block_type::const_iterator it = block_type::begin(*node.data);
1289 block_type::const_iterator itEnd = block_type::end(*node.data);
1290 for (; it != itEnd; ++it)
1292 if (!std::isfinite(*it))
1297 case mdds::mtm::element_boolean:
1300 case mdds::mtm::element_string:
1304 if (mbIgnoreEmptyStrings)
1306 typedef MatrixImplType::string_block_type block_type;
1308 block_type::const_iterator it = block_type::begin(*node.data);
1309 block_type::const_iterator itEnd = block_type::end(*node.data);
1310 for (; it != itEnd; ++it)
1318 case mdds::mtm::element_empty:
1325const size_t ResultNotSet = std::numeric_limits<size_t>::max();
1327template<
typename Type>
1328class WalkAndMatchElements
1337 WalkAndMatchElements(
Type aMatchValue,
const MatrixImplType::size_pair_type& aSize,
size_t nCol1,
size_t nCol2) :
1338 maMatchValue(
std::move(aMatchValue)),
1340 mnStopIndex( (nCol2 + 1) * aSize.row ),
1341 mnResult(ResultNotSet),
1344 assert( nCol1 < aSize.column && nCol2 < aSize.column);
1347 size_t getMatching()
const {
return mnResult; }
1349 size_t getRemainingCount()
const
1354 size_t compare(
const MatrixImplType::element_block_node_type& node)
const;
1356 void operator() (
const MatrixImplType::element_block_node_type& node)
1359 if (mnResult != ResultNotSet)
1363 if (mnStartIndex <= mnIndex && getRemainingCount() > 0)
1373size_t WalkAndMatchElements<double>::compare(
const MatrixImplType::element_block_node_type& node)
const
1378 case mdds::mtm::element_numeric:
1380 typedef MatrixImplType::numeric_block_type block_type;
1382 block_type::const_iterator it = block_type::begin(*node.data);
1383 block_type::const_iterator itEnd = block_type::end(*node.data);
1384 const size_t nRemaining = getRemainingCount();
1385 for (; it != itEnd &&
nCount < nRemaining; ++it, ++
nCount)
1387 if (*it == maMatchValue)
1394 case mdds::mtm::element_boolean:
1396 typedef MatrixImplType::boolean_block_type block_type;
1398 block_type::const_iterator it = block_type::begin(*node.data);
1399 block_type::const_iterator itEnd = block_type::end(*node.data);
1400 const size_t nRemaining = getRemainingCount();
1401 for (; it != itEnd &&
nCount < nRemaining; ++it, ++
nCount)
1403 if (
int(*it) == maMatchValue)
1411 case mdds::mtm::element_string:
1412 case mdds::mtm::element_empty:
1416 return ResultNotSet;
1420size_t WalkAndMatchElements<svl::SharedString>::compare(
const MatrixImplType::element_block_node_type& node)
const
1424 case mdds::mtm::element_string:
1427 typedef MatrixImplType::string_block_type block_type;
1429 block_type::const_iterator it = block_type::begin(*node.data);
1430 block_type::const_iterator itEnd = block_type::end(*node.data);
1431 const size_t nRemaining = getRemainingCount();
1432 for (; it != itEnd &&
nCount < nRemaining; ++it, ++
nCount)
1434 if (it->getDataIgnoreCase() == maMatchValue.getDataIgnoreCase())
1441 case mdds::mtm::element_boolean:
1442 case mdds::mtm::element_numeric:
1443 case mdds::mtm::element_empty:
1447 return ResultNotSet;
1452 static double init() {
return -std::numeric_limits<double>::max(); }
1453 static double compare(
double left,
double right)
1455 if (!std::isfinite(left))
1457 if (!std::isfinite(right))
1459 return std::max(left, right);
1462 static double boolValue(
1463 MatrixImplType::boolean_block_type::const_iterator it,
1464 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1467 it = std::find(it, itEnd,
true);
1468 return it == itEnd ? 0.0 : 1.0;
1474 static double init() {
return std::numeric_limits<double>::max(); }
1475 static double compare(
double left,
double right)
1477 if (!std::isfinite(left))
1479 if (!std::isfinite(right))
1481 return std::min(left, right);
1484 static double boolValue(
1485 MatrixImplType::boolean_block_type::const_iterator it,
1486 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1489 it = std::find(it, itEnd,
false);
1490 return it == itEnd ? 1.0 : 0.0;
1496 static double init() {
return 1.0; }
1497 static double calculate(
double fx,
double fy)
1502 static double boolValue(
1503 MatrixImplType::boolean_block_type::const_iterator it,
1504 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1507 it = std::find(it, itEnd,
false);
1508 return it == itEnd ? 1.0 : 0.0;
1514 static double init() {
return 0.0; }
1515 static double calculate(
double fx,
double fy)
1520 static double boolValue(
1521 MatrixImplType::boolean_block_type::const_iterator it,
1522 const MatrixImplType::boolean_block_type::const_iterator& itEnd)
1525 it = std::find(it, itEnd,
true);
1526 return it == itEnd ? 0.0 : 1.0;
1530template<
typename Op>
1531class CalcMaxMinValue
1535 bool mbIgnoreErrorValues;
1538 CalcMaxMinValue(
bool bTextAsZero,
bool bIgnoreErrorValues ) :
1540 mbTextAsZero(bTextAsZero),
1541 mbIgnoreErrorValues(bIgnoreErrorValues),
1542 mbHasValue(false) {}
1544 double getValue()
const {
return mbHasValue ?
mfVal : 0.0; }
1546 void operator() (
const MatrixImplType::element_block_node_type& node)
1551 case mdds::mtm::element_numeric:
1553 typedef MatrixImplType::numeric_block_type block_type;
1555 block_type::const_iterator it = block_type::begin(*node.data);
1556 block_type::const_iterator itEnd = block_type::end(*node.data);
1557 if (mbIgnoreErrorValues)
1559 for (; it != itEnd; ++it)
1561 if (std::isfinite(*it))
1567 for (; it != itEnd; ++it)
1574 case mdds::mtm::element_boolean:
1576 typedef MatrixImplType::boolean_block_type block_type;
1578 block_type::const_iterator it = block_type::begin(*node.data);
1579 block_type::const_iterator itEnd = block_type::end(*node.data);
1580 double fVal = Op::boolValue(it, itEnd);
1585 case mdds::mtm::element_string:
1586 case mdds::mtm::element_empty:
1602template<
typename Op>
1608 CalcGcdLcm() : mfval(
Op::
init()) {}
1610 double getResult()
const {
return mfval; }
1612 void operator() (
const MatrixImplType::element_block_node_type& node )
1616 case mdds::mtm::element_numeric:
1618 typedef MatrixImplType::numeric_block_type block_type;
1619 block_type::const_iterator it = block_type::begin(*node.data);
1620 block_type::const_iterator itEnd = block_type::end(*node.data);
1622 for ( ; it != itEnd; ++it)
1627 mfval = ::rtl::math::approxFloor( Op::calculate(*it,mfval));
1631 case mdds::mtm::element_boolean:
1633 typedef MatrixImplType::boolean_block_type block_type;
1634 block_type::const_iterator it = block_type::begin(*node.data);
1635 block_type::const_iterator itEnd = block_type::end(*node.data);
1637 mfval = Op::boolValue(it, itEnd);
1640 case mdds::mtm::element_empty:
1641 case mdds::mtm::element_string:
1652double evaluate(
double fVal,
ScQueryOp eOp )
1654 if (!std::isfinite(fVal))
1660 return fVal == 0.0 ? 1.0 : 0.0;
1662 return fVal < 0.0 ? 1.0 : 0.0;
1664 return fVal > 0.0 ? 1.0 : 0.0;
1666 return fVal <= 0.0 ? 1.0 : 0.0;
1668 return fVal >= 0.0 ? 1.0 : 0.0;
1670 return fVal != 0.0 ? 1.0 : 0.0;
1675 SAL_WARN(
"sc.core",
"evaluate: unhandled comparison operator: " <<
static_cast<int>(eOp));
1679class CompareMatrixFunc
1684 std::vector<double> maResValues;
1689 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1694 mrComp(rComp), mnMatPos(nMatPos), mpOptions(pOptions)
1696 maResValues.reserve(nResSize);
1699 CompareMatrixFunc(
const CompareMatrixFunc& ) =
delete;
1700 CompareMatrixFunc& operator= (
const CompareMatrixFunc& ) =
delete;
1702 CompareMatrixFunc(CompareMatrixFunc&& r) noexcept :
1704 mnMatPos(r.mnMatPos),
1705 mpOptions(r.mpOptions),
1706 maResValues(std::move(r.maResValues)) {}
1708 CompareMatrixFunc& operator=(CompareMatrixFunc&& r)
noexcept
1711 mnMatPos = r.mnMatPos;
1712 mpOptions = r.mpOptions;
1713 maResValues = std::move(r.maResValues);
1717 void operator() (
const MatrixImplType::element_block_node_type& node)
1723 case mdds::mtm::element_numeric:
1725 typedef MatrixImplType::numeric_block_type block_type;
1727 block_type::const_iterator it = block_type::begin(*node.data);
1728 block_type::const_iterator itEnd = block_type::end(*node.data);
1729 for (; it != itEnd; ++it)
1738 case mdds::mtm::element_boolean:
1740 typedef MatrixImplType::boolean_block_type block_type;
1742 block_type::const_iterator it = block_type::begin(*node.data);
1743 block_type::const_iterator itEnd = block_type::end(*node.data);
1744 for (; it != itEnd; ++it)
1753 case mdds::mtm::element_string:
1755 typedef MatrixImplType::string_block_type block_type;
1757 block_type::const_iterator it = block_type::begin(*node.data);
1758 block_type::const_iterator itEnd = block_type::end(*node.data);
1759 for (; it != itEnd; ++it)
1769 case mdds::mtm::element_empty:
1774 for (
size_t i = 0;
i < node.size; ++
i)
1783 const std::vector<double>& getValues()
const
1792class CompareMatrixToNumericFunc
1795 double mfRightValue;
1797 std::vector<double> maResValues;
1802 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1805 void compareLeftNumeric(
double fLeftVal )
1808 maResValues.push_back(evaluate(fVal, mrComp.
meOp));
1811 void compareLeftEmpty(
size_t nSize )
1814 bool bRes = evaluate(fVal, mrComp.
meOp);
1815 maResValues.resize(maResValues.size() + nSize, bRes ? 1.0 : 0.0);
1820 mrComp(rComp), mfRightValue(fRightValue), mpOptions(pOptions)
1822 maResValues.reserve(nResSize);
1825 CompareMatrixToNumericFunc(
const CompareMatrixToNumericFunc& ) =
delete;
1826 CompareMatrixToNumericFunc& operator= (
const CompareMatrixToNumericFunc& ) =
delete;
1828 CompareMatrixToNumericFunc(CompareMatrixToNumericFunc&& r) noexcept :
1830 mfRightValue(r.mfRightValue),
1831 mpOptions(r.mpOptions),
1832 maResValues(std::move(r.maResValues)) {}
1834 CompareMatrixToNumericFunc& operator=(CompareMatrixToNumericFunc&& r)
noexcept
1837 mfRightValue = r.mfRightValue;
1838 mpOptions = r.mpOptions;
1839 maResValues = std::move(r.maResValues);
1843 void operator() (
const MatrixImplType::element_block_node_type& node)
1847 case mdds::mtm::element_numeric:
1849 typedef MatrixImplType::numeric_block_type block_type;
1851 block_type::const_iterator it = block_type::begin(*node.data);
1852 block_type::const_iterator itEnd = block_type::end(*node.data);
1853 for (; it != itEnd; ++it)
1854 compareLeftNumeric(*it);
1857 case mdds::mtm::element_boolean:
1859 typedef MatrixImplType::boolean_block_type block_type;
1861 block_type::const_iterator it = block_type::begin(*node.data);
1862 block_type::const_iterator itEnd = block_type::end(*node.data);
1863 for (; it != itEnd; ++it)
1864 compareLeftNumeric(
double(*it));
1867 case mdds::mtm::element_string:
1869 typedef MatrixImplType::string_block_type block_type;
1871 block_type::const_iterator it = block_type::begin(*node.data);
1872 block_type::const_iterator itEnd = block_type::end(*node.data);
1873 for (; it != itEnd; ++it)
1884 case mdds::mtm::element_empty:
1885 compareLeftEmpty(node.size);
1892 const std::vector<double>& getValues()
const
1900 std::vector<double> maArray;
1901 std::vector<double>::iterator miPos;
1905 void moveArray( ToDoubleArray& r )
1910 size_t n = std::distance(r.maArray.begin(), r.miPos);
1911 maArray = std::move(r.maArray);
1912 miPos = maArray.begin();
1913 std::advance(miPos, n);
1917 ToDoubleArray(
size_t nSize,
bool bEmptyAsZero ) :
1918 maArray(nSize, 0.0), miPos(maArray.
begin()), mbEmptyAsZero(bEmptyAsZero)
1923 ToDoubleArray(
const ToDoubleArray& ) =
delete;
1924 ToDoubleArray& operator= (
const ToDoubleArray& ) =
delete;
1926 ToDoubleArray(ToDoubleArray&& r) noexcept :
1927 mfNaN(r.mfNaN), mbEmptyAsZero(r.mbEmptyAsZero)
1932 ToDoubleArray& operator=(ToDoubleArray&& r)
noexcept
1935 mbEmptyAsZero = r.mbEmptyAsZero;
1940 void operator() (
const MatrixImplType::element_block_node_type& node)
1942 using namespace mdds::mtv;
1946 case mdds::mtm::element_numeric:
1948 double_element_block::const_iterator it = double_element_block::begin(*node.data);
1949 double_element_block::const_iterator itEnd = double_element_block::end(*node.data);
1950 for (; it != itEnd; ++it, ++miPos)
1954 case mdds::mtm::element_boolean:
1956 boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
1957 boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
1958 for (; it != itEnd; ++it, ++miPos)
1959 *miPos = *it ? 1.0 : 0.0;
1962 case mdds::mtm::element_string:
1964 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
1968 case mdds::mtm::element_empty:
1972 std::advance(miPos, node.size);
1976 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
1985 void swap(std::vector<double>& rOther)
1987 maArray.swap(rOther);
1993 double operator() (
const double& lhs,
const double& rhs)
const
1999template<
typename Op>
2000class MergeDoubleArrayFunc
2002 std::vector<double>::iterator miPos;
2005 MergeDoubleArrayFunc(std::vector<double>& rArray) : miPos(rArray.
begin())
2010 MergeDoubleArrayFunc(
const MergeDoubleArrayFunc& ) =
delete;
2011 MergeDoubleArrayFunc& operator= (
const MergeDoubleArrayFunc& ) =
delete;
2013 MergeDoubleArrayFunc( MergeDoubleArrayFunc&& ) =
default;
2014 MergeDoubleArrayFunc& operator= ( MergeDoubleArrayFunc&& ) =
default;
2016 void operator() (
const MatrixImplType::element_block_node_type& node)
2018 using namespace mdds::mtv;
2023 case mdds::mtm::element_numeric:
2025 double_element_block::const_iterator it = double_element_block::begin(*node.data);
2026 double_element_block::const_iterator itEnd = double_element_block::end(*node.data);
2027 for (; it != itEnd; ++it, ++miPos)
2032 *miPos = op(*miPos, *it);
2036 case mdds::mtm::element_boolean:
2038 boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
2039 boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
2040 for (; it != itEnd; ++it, ++miPos)
2045 *miPos = op(*miPos, *it ? 1.0 : 0.0);
2049 case mdds::mtm::element_string:
2051 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
2055 case mdds::mtm::element_empty:
2058 for (
size_t i = 0;
i < node.size; ++
i, ++miPos)
2063 *miPos = op(*miPos, 0.0);
2077template<
typename TOp,
typename tRes>
2080 WalkElementBlocks<TOp, tRes> aFunc(bTextAsZero, bIgnoreErrorValues);
2081 aFunc = maMat.walk(aFunc);
2082 return aFunc.getResult();
2089 return GetValueWithCount<sc::op::Sum, KahanSum>(bTextAsZero, bIgnoreErrorValues,
maMat);
2094 return GetValueWithCount<sc::op::SumSquare, KahanSum>(bTextAsZero, bIgnoreErrorValues,
maMat);
2099 return GetValueWithCount<sc::op::Product, double>(bTextAsZero, bIgnoreErrorValues,
maMat);
2104 CountElements aFunc(bCountStrings, bCountErrors, bIgnoreEmptyStrings);
2105 aFunc =
maMat.walk(aFunc);
2106 return aFunc.getCount();
2111 WalkAndMatchElements<double> aFunc(fValue,
maMat.size(), nCol1, nCol2);
2112 aFunc =
maMat.walk(aFunc);
2113 return aFunc.getMatching();
2118 WalkAndMatchElements<svl::SharedString> aFunc(rStr,
maMat.size(), nCol1, nCol2);
2119 aFunc =
maMat.walk(aFunc);
2120 return aFunc.getMatching();
2125 CalcMaxMinValue<MaxOp> aFunc(bTextAsZero, bIgnoreErrorValues);
2126 aFunc =
maMat.walk(aFunc);
2127 return aFunc.getValue();
2132 CalcMaxMinValue<MinOp> aFunc(bTextAsZero, bIgnoreErrorValues);
2133 aFunc =
maMat.walk(aFunc);
2134 return aFunc.getValue();
2139 CalcGcdLcm<Gcd> aFunc;
2140 aFunc =
maMat.walk(aFunc);
2141 return aFunc.getResult();
2146 CalcGcdLcm<Lcm> aFunc;
2147 aFunc =
maMat.walk(aFunc);
2148 return aFunc.getResult();
2154 MatrixImplType::size_pair_type aSize =
maMat.size();
2155 size_t nSize = aSize.column * aSize.row;
2163 CompareMatrixToNumericFunc aFunc(nSize, rComp, rComp.
maCells[1].
mfValue, pOptions);
2164 aFunc =
maMat.walk(std::move(aFunc));
2167 const std::vector<double>& rResVal = aFunc.getValues();
2168 assert (nSize == rResVal.size());
2169 if (nSize != rResVal.size())
2176 CompareMatrixFunc aFunc(nSize, rComp, nMatPos, pOptions);
2177 aFunc =
maMat.walk(std::move(aFunc));
2180 const std::vector<double>& rResVal = aFunc.getValues();
2181 assert (nSize == rResVal.size());
2182 if (nSize != rResVal.size())
2190 MatrixImplType::size_pair_type aSize =
maMat.size();
2191 ToDoubleArray aFunc(aSize.row*aSize.column, bEmptyAsZero);
2192 aFunc =
maMat.walk(std::move(aFunc));
2198 MatrixImplType::size_pair_type aSize =
maMat.size();
2199 size_t nSize = aSize.row*aSize.column;
2200 if (nSize != rArray.size())
2203 MergeDoubleArrayFunc<ArrayMul> aFunc(rArray);
2204 maMat.walk(std::move(aFunc));
2209template<
typename T,
typename U,
typename return_type>
2210struct wrapped_iterator
2212 typedef ::std::bidirectional_iterator_tag iterator_category;
2213 typedef typename T::const_iterator::value_type old_value_type;
2214 typedef return_type value_type;
2215 typedef value_type* pointer;
2216 typedef value_type& reference;
2217 typedef typename T::const_iterator::difference_type difference_type;
2219 typename T::const_iterator it;
2220 mutable value_type val;
2225 value_type calcVal()
const
2232 wrapped_iterator(
typename T::const_iterator it_, U
const & aOp):
2239 wrapped_iterator(
const wrapped_iterator& r):
2246 wrapped_iterator& operator=(
const wrapped_iterator& r)
2252 bool operator==(
const wrapped_iterator& r)
const
2257 bool operator!=(
const wrapped_iterator& r)
const
2269 wrapped_iterator& operator--()
2282 pointer operator->()
const
2289template<
typename T,
typename U,
typename return_type>
2290struct MatrixIteratorWrapper
2293 typename T::const_iterator m_itBegin;
2294 typename T::const_iterator m_itEnd;
2297 MatrixIteratorWrapper(
typename T::const_iterator itBegin,
typename T::const_iterator itEnd, U
const & aOp):
2298 m_itBegin(
std::move(itBegin)),
2299 m_itEnd(
std::move(itEnd)),
2304 wrapped_iterator<T, U, return_type>
begin()
2306 return wrapped_iterator<T, U, return_type>(m_itBegin,
maOp);
2309 wrapped_iterator<T, U, return_type>
end()
2311 return wrapped_iterator<T, U, return_type>(m_itEnd,
maOp);
2315MatrixImplType::position_type increment_position(
const MatrixImplType::position_type& pos,
size_t n)
2317 MatrixImplType::position_type ret =
pos;
2320 if (ret.second + n < ret.first->size)
2327 n -= (ret.first->size - ret.second);
2337struct MatrixOpWrapper
2341 MatrixImplType::position_type
pos;
2352 MatrixOpWrapper(
const MatrixOpWrapper& r ) : mrMat(r.mrMat),
pos(r.
pos), mpOp(r.mpOp) {}
2354 MatrixOpWrapper& operator= (
const MatrixOpWrapper& r ) =
default;
2356 void operator()(
const MatrixImplType::element_block_node_type& node)
2360 case mdds::mtm::element_numeric:
2362 typedef MatrixImplType::numeric_block_type block_type;
2364 block_type::const_iterator it = block_type::begin(*node.data);
2365 block_type::const_iterator itEnd = block_type::end(*node.data);
2366 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2367 pos = mrMat.set(pos,aFunc.begin(), aFunc.end());
2370 case mdds::mtm::element_boolean:
2372 typedef MatrixImplType::boolean_block_type block_type;
2374 block_type::const_iterator it = block_type::begin(*node.data);
2375 block_type::const_iterator itEnd = block_type::end(*node.data);
2377 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2378 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2381 case mdds::mtm::element_string:
2383 typedef MatrixImplType::string_block_type block_type;
2385 block_type::const_iterator it = block_type::begin(*node.data);
2386 block_type::const_iterator itEnd = block_type::end(*node.data);
2388 MatrixIteratorWrapper<block_type, T, typename T::number_value_type> aFunc(it, itEnd, *mpOp);
2389 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2392 case mdds::mtm::element_empty:
2394 if (mpOp->useFunctionForEmpty())
2396 std::vector<char> aVec(node.size);
2397 MatrixIteratorWrapper<std::vector<char>, T,
typename T::number_value_type>
2398 aFunc(aVec.begin(), aVec.end(), *mpOp);
2399 pos = mrMat.set(pos, aFunc.begin(), aFunc.end());
2406 pos = increment_position(pos, node.size);
2415 MatrixOpWrapper<T> aFunc(rMat.
maMat, aOp);
2419template<
typename T,
typename tRes>
2422 WalkElementBlocksMultipleValues<T, tRes> aFunc(aOp);
2423 aFunc =
maMat.walk(std::move(aFunc));
2424 return aFunc.getResult();
2431 ElementBlock(
size_t nRowSize,
2436 mnRowSize(nRowSize),
2439 maDoubleFunc(
std::move(aDoubleFunc)),
2440 maBoolFunc(
std::move(aBoolFunc)),
2441 maStringFunc(
std::move(aStringFunc)),
2442 maEmptyFunc(
std::move(aEmptyFunc))
2456class WalkElementBlockOperation
2460 WalkElementBlockOperation(ElementBlock& rElementBlock)
2461 : mrElementBlock(rElementBlock)
2465 void operator()(
const MatrixImplType::element_block_node_type& node)
2469 case mdds::mtm::element_numeric:
2471 typedef MatrixImplType::numeric_block_type block_type;
2473 block_type::const_iterator it = block_type::begin(*node.data);
2474 std::advance(it, node.offset);
2475 block_type::const_iterator itEnd = it;
2476 std::advance(itEnd, node.size);
2477 for (
auto itr = it; itr != itEnd; ++itr)
2479 mrElementBlock.maDoubleFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2480 ++mrElementBlock.mnRowPos;
2481 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2483 mrElementBlock.mnRowPos = 0;
2484 ++mrElementBlock.mnColPos;
2489 case mdds::mtm::element_string:
2491 typedef MatrixImplType::string_block_type block_type;
2493 block_type::const_iterator it = block_type::begin(*node.data);
2494 std::advance(it, node.offset);
2495 block_type::const_iterator itEnd = it;
2496 std::advance(itEnd, node.size);
2497 for (
auto itr = it; itr != itEnd; ++itr)
2499 mrElementBlock.maStringFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2500 ++mrElementBlock.mnRowPos;
2501 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2503 mrElementBlock.mnRowPos = 0;
2504 ++mrElementBlock.mnColPos;
2509 case mdds::mtm::element_boolean:
2511 typedef MatrixImplType::boolean_block_type block_type;
2513 block_type::const_iterator it = block_type::begin(*node.data);
2514 std::advance(it, node.offset);
2515 block_type::const_iterator itEnd = it;
2516 std::advance(itEnd, node.size);
2517 for (
auto itr = it; itr != itEnd; ++itr)
2519 mrElementBlock.maBoolFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos, *itr);
2520 ++mrElementBlock.mnRowPos;
2521 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2523 mrElementBlock.mnRowPos = 0;
2524 ++mrElementBlock.mnColPos;
2529 case mdds::mtm::element_empty:
2531 for (
size_t i=0;
i < node.size; ++
i)
2533 mrElementBlock.maEmptyFunc(mrElementBlock.mnRowPos, mrElementBlock.mnColPos);
2534 ++mrElementBlock.mnRowPos;
2535 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2537 mrElementBlock.mnRowPos = 0;
2538 ++mrElementBlock.mnColPos;
2543 case mdds::mtm::element_integer:
2545 SAL_WARN(
"sc.core",
"WalkElementBlockOperation - unhandled element_integer");
2547 mrElementBlock.mnColPos += node.size / mrElementBlock.mnRowSize;
2548 mrElementBlock.mnRowPos += node.size % mrElementBlock.mnRowSize;
2549 if (mrElementBlock.mnRowPos >= mrElementBlock.mnRowSize)
2551 mrElementBlock.mnRowPos = 0;
2552 ++mrElementBlock.mnColPos;
2561 ElementBlock& mrElementBlock;
2571 ElementBlock aPayload(
maMat.size().row, aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
2572 WalkElementBlockOperation aFunc(aPayload);
2575 MatrixImplType::size_pair_type(rStartPos.first, rStartPos.second),
2576 MatrixImplType::size_pair_type(rEndPos.first, rEndPos.second));
2581void ScMatrixImpl::Dump()
const
2583 cout <<
"-- matrix content" <<
endl;
2586 for (
SCSIZE nRow = 0; nRow < nRows; ++nRow)
2588 for (
SCSIZE nCol = 0; nCol < nCols; ++nCol)
2590 cout <<
" row=" << nRow <<
", col=" << nCol <<
" : ";
2591 switch (
maMat.get_type(nRow, nCol))
2593 case mdds::mtm::element_string:
2594 cout <<
"string (" <<
maMat.get_string(nRow, nCol).getString() <<
")";
2596 case mdds::mtm::element_numeric:
2597 cout <<
"numeric (" <<
maMat.get_numeric(nRow, nCol) <<
")";
2599 case mdds::mtm::element_boolean:
2600 cout <<
"boolean (" <<
maMat.get_boolean(nRow, nCol) <<
")";
2602 case mdds::mtm::element_empty:
2618 SAL_WARN_IF( !nRowSize,
"sc.core",
"ScMatrixImpl::CalcPosition: 0 rows!");
2620 rR =
nIndex - rC*nRowSize;
2625size_t get_index(
SCSIZE nMaxRow,
size_t nRow,
size_t nCol,
size_t nRowOffset,
size_t nColOffset)
2627 return nMaxRow * (nCol + nColOffset) + nRow + nRowOffset;
2637 xMat1->GetDimensions(nC1, nR1);
2638 xMat2->GetDimensions(nC2, nR2);
2643 std::vector<OUString> aString(nMaxCol * nMaxRow);
2644 std::vector<bool> aValid(nMaxCol * nMaxRow,
true);
2645 std::vector<FormulaError> nErrors(nMaxCol * nMaxRow,FormulaError::NONE);
2647 size_t nRowOffset = 0;
2648 size_t nColOffset = 0;
2649 std::function<void(
size_t,
size_t,
double)> aDoubleFunc =
2650 [&](
size_t nRow,
size_t nCol,
double nVal)
2653 if (nErr != FormulaError::NONE)
2655 aValid[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
false;
2656 nErrors[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = nErr;
2661 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr;
2664 std::function<void(
size_t,
size_t,
bool)> aBoolFunc =
2665 [&](
size_t nRow,
size_t nCol,
bool nVal)
2669 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr;
2675 aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr.getString();
2678 std::function<void(
size_t,
size_t)> aEmptyFunc =
2679 [](
size_t ,
size_t )
2685 if (nC1 == 1 || nR1 == 1)
2687 size_t nRowRep = nR1 == 1 ? nMaxRow : 1;
2688 size_t nColRep = nC1 == 1 ? nMaxCol : 1;
2690 for (
size_t i = 0;
i < nRowRep; ++
i)
2693 for (
size_t j = 0; j < nColRep; ++j)
2696 xMat1->ExecuteOperation(
2697 std::pair<size_t, size_t>(0, 0),
2698 std::pair<size_t, size_t>(std::min(nR1, nMaxRow) - 1, std::min(nC1, nMaxCol) - 1),
2699 aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
2704 xMat1->ExecuteOperation(
2705 std::pair<size_t, size_t>(0, 0),
2706 std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1),
2707 std::move(aDoubleFunc), std::move(aBoolFunc), std::move(aStringFunc), std::move(aEmptyFunc));
2709 std::vector<svl::SharedString> aSharedString(nMaxCol*nMaxRow);
2711 std::function<void(
size_t,
size_t,
double)> aDoubleFunc2 =
2712 [&](
size_t nRow,
size_t nCol,
double nVal)
2715 if (nErr != FormulaError::NONE)
2717 aValid[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
false;
2718 nErrors[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = nErr;
2723 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr);
2726 std::function<void(
size_t,
size_t,
bool)> aBoolFunc2 =
2727 [&](
size_t nRow,
size_t nCol,
bool nVal)
2731 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] = rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr);
2737 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
2738 rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] +
aStr.getString());
2741 std::function<void(
size_t,
size_t)> aEmptyFunc2 =
2742 [&](
size_t nRow,
size_t nCol)
2744 aSharedString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)] =
2745 rStringPool.
intern(aString[get_index(nMaxRow, nRow, nCol, nRowOffset, nColOffset)]);
2750 if (nC2 == 1 || nR2 == 1)
2752 size_t nRowRep = nR2 == 1 ? nMaxRow : 1;
2753 size_t nColRep = nC2 == 1 ? nMaxCol : 1;
2755 for (
size_t i = 0;
i < nRowRep; ++
i)
2758 for (
size_t j = 0; j < nColRep; ++j)
2761 xMat2->ExecuteOperation(
2762 std::pair<size_t, size_t>(0, 0),
2763 std::pair<size_t, size_t>(std::min(nR2, nMaxRow) - 1, std::min(nC2, nMaxCol) - 1),
2764 aDoubleFunc2, aBoolFunc2, aStringFunc2, aEmptyFunc2);
2769 xMat2->ExecuteOperation(
2770 std::pair<size_t, size_t>(0, 0),
2771 std::pair<size_t, size_t>(nMaxRow - 1, nMaxCol - 1),
2772 std::move(aDoubleFunc2), std::move(aBoolFunc2), std::move(aStringFunc2), std::move(aEmptyFunc2));
2776 MatrixImplType::position_type
pos =
maMat.position(0, 0);
2779 for (
SCSIZE j = 0; j < nMaxRow &&
i < nMaxCol; ++j)
2781 if (aValid[nMaxRow *
i + j])
2783 auto itr = aValid.begin();
2784 std::advance(itr, nMaxRow *
i + j);
2785 auto itrEnd = std::find(itr, aValid.end(),
false);
2786 size_t nSteps = std::distance(itr, itrEnd);
2787 auto itrStr = aSharedString.begin();
2788 std::advance(itrStr, nMaxRow *
i + j);
2789 auto itrEndStr = itrStr;
2790 std::advance(itrEndStr, nSteps);
2792 size_t nColSteps = nSteps / nMaxRow;
2794 j += nSteps % nMaxRow;
2805 pos = MatrixImplType::next_position(
pos);
2812 switch (
maMat.get_type(rPos))
2814 case mdds::mtm::element_boolean:
2815 case mdds::mtm::element_numeric:
2816 case mdds::mtm::element_empty:
2826 double fVal =
maMat.get_numeric(rPos);
2830 if ( nError != FormulaError::NONE )
2841 switch (
maMat.get_type(rPos))
2843 case mdds::mtm::element_boolean:
2844 case mdds::mtm::element_numeric:
2854 double fVal =
maMat.get_numeric(rPos);
2860 switch (
maMat.get_type(rPos))
2862 case mdds::mtm::element_empty:
2863 case mdds::mtm::element_string:
2875 assert(
maMat.size().row == nMaxRow &&
maMat.size().column == nMaxCol
2876 &&
"the caller code should have sized the output matrix to the passed dimensions");
2877 auto & rMatImpl1 = *rInputMat1.
pImpl;
2878 auto & rMatImpl2 = *rInputMat2.
pImpl;
2880 if (rMatImpl1.maMat.size() == rMatImpl2.maMat.size()
2881 && rMatImpl1.maMat.size() ==
maMat.size())
2883 MatrixImplType::position_type aOutPos =
maMat.position(0, 0);
2884 MatrixImplType::const_position_type aPos1 = rMatImpl1.maMat.position(0, 0);
2885 MatrixImplType::const_position_type aPos2 = rMatImpl2.maMat.position(0, 0);
2888 for (
SCSIZE j = 0; j < nMaxRow; j++)
2890 bool bVal1 = rMatImpl1.IsValueOrEmpty(aPos1);
2891 bool bVal2 = rMatImpl2.IsValueOrEmpty(aPos2);
2895 double d =
Op(rMatImpl1.GetDouble(aPos1), rMatImpl2.GetDouble(aPos2));
2896 aOutPos =
maMat.set(aOutPos,
d);
2898 else if (((nErr = rMatImpl1.GetErrorIfNotString(aPos1)) != FormulaError::NONE) ||
2899 ((nErr = rMatImpl2.GetErrorIfNotString(aPos2)) != FormulaError::NONE))
2903 else if ((!bVal1 && rMatImpl1.IsStringOrEmpty(aPos1)) ||
2904 (!bVal2 && rMatImpl2.IsStringOrEmpty(aPos2)))
2908 double fVal1 = (bVal1 ? rMatImpl1.GetDouble(aPos1) :
2913 double fVal2 = (bVal2 ? rMatImpl2.GetDouble(aPos2) :
2916 if (nError1 != FormulaError::NONE)
2918 else if (nError2 != FormulaError::NONE)
2922 double d =
Op( fVal1, fVal2);
2923 aOutPos =
maMat.set(aOutPos,
d);
2928 aPos1 = MatrixImplType::next_position(aPos1);
2929 aPos2 = MatrixImplType::next_position(aPos2);
2930 aOutPos = MatrixImplType::next_position(aOutPos);
2941 MatrixImplType::position_type aOutPos =
maMat.position(0, 0);
2944 for (
SCSIZE j = 0; j < nMaxRow; j++)
2952 aOutPos =
maMat.set(aOutPos,
d);
2963 double fVal1 = (bVal1 ? rInputMat1.
GetDouble(
i,j) :
2968 double fVal2 = (bVal2 ? rInputMat2.
GetDouble(
i,j) :
2971 if (nError1 != FormulaError::NONE)
2973 else if (nError2 != FormulaError::NONE)
2977 double d =
Op( fVal1, fVal2);
2978 aOutPos =
maMat.set(aOutPos,
d);
2983 aOutPos = MatrixImplType::next_position(aOutPos);
3003 SAL_WARN_IF( !nC,
"sc.core",
"ScMatrix with 0 columns!");
3004 SAL_WARN_IF( !nR,
"sc.core",
"ScMatrix with 0 rows!");
3006 if ((nC && !nR) || (!nC && nR))
3008 SAL_WARN(
"sc.core",
"ScMatrix one-dimensional zero: " << nC <<
" columns * " << nR <<
" rows");
3017 const char* pEnv = std::getenv(
"SC_MAX_MATRIX_ELEMENTS");
3028#if SAL_TYPES_SIZEOFPOINTER < 8
3030 constexpr size_t nMemMax = 0x40000000;
3033 constexpr size_t nMemMax = 0x180000000;
3041 SAL_WARN(
"sc.core",
"ScMatrix overflow: " << nC <<
" columns * " << nR <<
" rows");
3048 nRefCnt(0), mbCloneIfConst(true)
3058 nRefCnt(0), mbCloneIfConst(true)
3068 nRefCnt(0), mbCloneIfConst(true)
3084 pImpl->GetDimensions(nC, nR);
3108 pImpl->Resize(nC, nR);
3113 pImpl->Resize(nC, nR, fVal);
3126 pImpl->SetErrorInterpreter(
p);
3131 pImpl->GetDimensions(rC, rR);
3136 return pImpl->GetElementCount();
3141 return pImpl->ValidColRow(nC, nR);
3146 return pImpl->ValidColRowReplicated(rC, rR);
3156 pImpl->PutDouble(fVal, nC, nR);
3166 pImpl->PutDouble(pArray, nLen, nC, nR);
3171 pImpl->PutString(rStr, nC, nR);
3181 pImpl->PutString(pArray, nLen, nC, nR);
3186 pImpl->PutEmpty(nC, nR);
3191 pImpl->PutEmptyPath(nC, nR);
3196 pImpl->PutError(nErrorCode, nC, nR);
3201 pImpl->PutBoolean(bVal, nC, nR);
3206 return pImpl->GetError(nC, nR);
3211 return pImpl->GetDouble(nC, nR);
3221 return pImpl->GetDoubleWithStringConversion(nC, nR);
3226 return pImpl->GetString(nC, nR);
3236 return pImpl->GetString(rFormatter, nC, nR);
3241 return pImpl->Get(nC, nR);
3251 return pImpl->IsStringOrEmpty(nC, nR);
3256 return pImpl->IsEmpty(nC, nR);
3261 return pImpl->IsEmptyCell(nC, nR);
3266 return pImpl->IsEmptyResult(nC, nR);
3271 return pImpl->IsEmptyPath(nC, nR);
3281 return pImpl->IsValue(nC, nR);
3286 return pImpl->IsValueOrEmpty(nC, nR);
3291 return pImpl->IsBoolean(nC, nR);
3296 return pImpl->IsNumeric();
3311 pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2);
3316 pImpl->PutDoubleVector(rVec, nC, nR);
3321 pImpl->PutStringVector(rVec, nC, nR);
3341 pImpl->CompareEqual();
3346 pImpl->CompareNotEqual();
3351 pImpl->CompareLess();
3356 pImpl->CompareGreater();
3361 pImpl->CompareLessEqual();
3366 pImpl->CompareGreaterEqual();
3371 return pImpl->And();
3381 return pImpl->Xor();
3386 return pImpl->Sum(bTextAsZero, bIgnoreErrorValues);
3391 return pImpl->SumSquare(bTextAsZero, bIgnoreErrorValues);
3396 return pImpl->Product(bTextAsZero, bIgnoreErrorValues);
3399size_t ScMatrix::Count(
bool bCountStrings,
bool bCountErrors,
bool bIgnoreEmptyStrings)
const
3401 return pImpl->Count(bCountStrings, bCountErrors, bIgnoreEmptyStrings);
3406 return pImpl->MatchDoubleInColumns(fValue, nCol1, nCol2);
3411 return pImpl->MatchStringInColumns(rStr, nCol1, nCol2);
3416 return pImpl->GetMaxValue(bTextAsZero, bIgnoreErrorValues);
3421 return pImpl->GetMinValue(bTextAsZero, bIgnoreErrorValues);
3426 return pImpl->GetGcd();
3431 return pImpl->GetLcm();
3438 return pImpl->CompareMatrix(rComp, nMatPos, pOptions);
3443 pImpl->GetDoubleArray(rArray, bEmptyAsZero);
3448 pImpl->MergeDoubleArrayMultiply(rArray);
3462template<
typename TOp>
3471 typedef double number_value_type;
3474 double fVal = 0.0 ):
3482 if (nErr != FormulaError::NONE)
3487 double operator()(
double fVal)
const
3492 double operator()(
bool bVal)
const
3494 return maOp(
static_cast<double>(bVal),
mfVal);
3503 double operator()(
char)
const
3508 static bool useFunctionForEmpty()
3520 auto not_ = [](
double a, double){
return double(
a == 0.0);};
3521 matop::MatOp<
decltype(not_)> aOp(not_,
pImpl->GetErrorInterpreter());
3527 auto neg_ = [](
double a, double){
return -
a;};
3528 matop::MatOp<
decltype(neg_)> aOp(neg_,
pImpl->GetErrorInterpreter());
3534 auto add_ = [](
double a,
double b){
return a + b;};
3535 matop::MatOp<
decltype(add_)> aOp(add_,
pImpl->GetErrorInterpreter(), fVal);
3543 auto sub_ = [](
double a,
double b){
return b -
a;};
3544 matop::MatOp<
decltype(sub_)> aOp(sub_,
pImpl->GetErrorInterpreter(), fVal);
3549 auto sub_ = [](
double a,
double b){
return a - b;};
3550 matop::MatOp<
decltype(sub_)> aOp(sub_,
pImpl->GetErrorInterpreter(), fVal);
3557 auto mul_ = [](
double a,
double b){
return a * b;};
3558 matop::MatOp<
decltype(mul_)> aOp(mul_,
pImpl->GetErrorInterpreter(), fVal);
3566 auto div_ = [](
double a,
double b){
return sc::div(b,
a);};
3567 matop::MatOp<
decltype(div_)> aOp(div_,
pImpl->GetErrorInterpreter(), fVal);
3572 auto div_ = [](
double a,
double b){
return sc::div(
a, b);};
3573 matop::MatOp<
decltype(div_)> aOp(div_,
pImpl->GetErrorInterpreter(), fVal);
3582 auto pow_ = [](
double a,
double b){
return sc::power(b,
a);};
3583 matop::MatOp<
decltype(pow_)> aOp(pow_,
pImpl->GetErrorInterpreter(), fVal);
3588 auto pow_ = [](
double a,
double b){
return sc::power(
a, b);};
3589 matop::MatOp<
decltype(pow_)> aOp(pow_,
pImpl->GetErrorInterpreter(), fVal);
3598 pImpl->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc, aEmptyFunc);
3607void ScMatrix::Dump()
const
3616 pImpl->MatConcat(nMaxCol, nMaxRow, xMat1, xMat2, rFormatter, rPool);
3622 pImpl->ExecuteBinaryOp(nMaxCol, nMaxRow, rInputMat1, rInputMat2, pInterpreter, op);
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 ...
FILE * init(int, char **)
This class provides LO with Kahan summation algorithm About this algorithm: https://en....
static SC_DLLPUBLIC LanguageType eLnge
static OUString GetErrorString(FormulaError nErrNumber)
void SetError(FormulaError nError)
double ConvertStringToValue(const OUString &)
FormulaError GetError() const
static double ScGetGCD(double fx, double fy)
void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
bool IsStringOrEmpty(SCSIZE nIndex) const
void PutError(FormulaError nErrorCode, SCSIZE nC, SCSIZE nR)
bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const
double GetMinValue(bool bTextAsZero, bool bIgnoreErrorValues) const
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
double GetMaxValue(bool bTextAsZero, bool bIgnoreErrorValues) const
FormulaError GetError(SCSIZE nC, SCSIZE nR) const
ScMatrix::IterateResultMultiple< tRes > ApplyCollectOperation(const std::vector< T > &aOp)
void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2)
ScMatrix::KahanIterateResult SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const
void GetDoubleArray(std::vector< double > &rArray, bool bEmptyAsZero) const
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
void CompareGreaterEqual()
bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const
ScInterpreter * pErrorInterpreter
void MatCopy(ScMatrixImpl &mRes) const
void SetErrorInterpreter(ScInterpreter *p)
ScMatrix::KahanIterateResult Sum(bool bTextAsZero, bool bIgnoreErrorValues) const
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
ScMatrix::DoubleIterateResult Product(bool bTextAsZero, bool bIgnoreErrorValues) const
double GetDoubleWithStringConversion(SCSIZE nC, SCSIZE nR) const
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
void CalcPosition(SCSIZE nIndex, SCSIZE &rC, SCSIZE &rR) const
size_t MatchStringInColumns(const svl::SharedString &rStr, size_t nCol1, size_t nCol2) const
void PutStringVector(const ::std::vector< svl::SharedString > &rVec, SCSIZE nC, SCSIZE nR)
void ExecuteBinaryOp(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrix &rInputMat1, const ScMatrix &rInputMat2, ScInterpreter *pInterpreter, ScMatrix::CalculateOpFunction op)
FormulaError GetErrorIfNotString(const MatrixImplType::const_position_type &rPos) const
void PutEmpty(SCSIZE nC, SCSIZE nR)
ScMatrixRef CompareMatrix(sc::Compare &rComp, size_t nMatPos, sc::CompareOptions *pOptions) const
MatrixFlagImplType maMatFlag
void PutDoubleVector(const ::std::vector< double > &rVec, SCSIZE nC, SCSIZE nR)
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
bool ValidColRowReplicated(SCSIZE &rC, SCSIZE &rR) const
bool IsValue(SCSIZE nIndex) const
bool ValidColRowOrReplicated(SCSIZE &rC, SCSIZE &rR) const
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const
void PutString(const svl::SharedString &rStr, SCSIZE nC, SCSIZE nR)
void MatTrans(ScMatrixImpl &mRes) const
void ApplyOperation(T aOp, ScMatrixImpl &rMat)
ScInterpreter * GetErrorInterpreter() const
void MergeDoubleArrayMultiply(std::vector< double > &rArray) const
void PutEmptyPath(SCSIZE nC, SCSIZE nR)
double GetDouble(SCSIZE nC, SCSIZE nR) const
void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef &xMat1, const ScMatrixRef &xMat2, SvNumberFormatter &rFormatter, svl::SharedStringPool &rPool)
void SetErrorAtInterpreter(FormulaError nError) const
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
const ScMatrixImpl & operator=(const ScMatrixImpl &)=delete
void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
void Resize(SCSIZE nC, SCSIZE nR)
SCSIZE GetElementCount() const
size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) const
ScMatrixImpl(const ScMatrixImpl &)=delete
bool ValidColRow(SCSIZE nC, SCSIZE nR) const
Matrix data type that can store values of mixed types.
void PutBoolean(bool bVal, SCSIZE nC, SCSIZE nR)
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
@ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string!
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
void NotOp(const ScMatrix &rMat)
bool IsStringOrEmpty(SCSIZE nIndex) const
FormulaError GetErrorIfNotString(SCSIZE nC, SCSIZE nR) const
Use in ScInterpreter to obtain the error code, if any.
std::function< double(double, double)> CalculateOpFunction
void MatCopy(const ScMatrix &mRes) const
bool IsEmpty(SCSIZE nC, SCSIZE nR) 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.
std::function< void(size_t, size_t)> EmptyOpFunction
void NegOp(const ScMatrix &rMat)
void PutString(const svl::SharedString &rStr, SCSIZE nC, SCSIZE nR)
KahanIterateResult SumSquare(bool bTextAsZero, bool bIgnoreErrorValues=false) const
std::function< void(size_t, size_t, svl::SharedString)> StringOpFunction
void FillDouble(double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2)
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
void SetErrorInterpreter(ScInterpreter *p)
ScMatrix * Clone() const
Clone the matrix.
size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const
void SubOp(bool bFlag, double fVal, const ScMatrix &rMat)
double GetDouble(SCSIZE nC, SCSIZE nR) const
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
SCSIZE GetElementCount() const
void PutEmptyResultVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empty results, starting at row nR, must fit into dimensions.
KahanIterateResult Sum(bool bTextAsZero, bool bIgnoreErrorValues=false) const
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
void SetMutable()
Set the matrix to mutable for CloneIfConst(), only the interpreter should do this and know the conseq...
std::function< void(size_t, size_t, double)> DoubleOpFunction
void PutEmptyPath(SCSIZE nC, SCSIZE nR)
Jump sal_False without path.
void AddOp(double fVal, const ScMatrix &rMat)
void MatConcat(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrixRef &xMat1, const ScMatrixRef &xMat2, SvNumberFormatter &rFormatter, svl::SharedStringPool &rPool)
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 PutEmpty(SCSIZE nC, SCSIZE nR)
void PutEmptyPathVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empty paths, starting at row nR, must fit into dimensions.
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...
DoubleIterateResult Product(bool bTextAsZero, bool bIgnoreErrorValues=false) const
void MatTrans(const ScMatrix &mRes) const
void MergeDoubleArrayMultiply(std::vector< double > &rArray) const
ScMatrix(const ScMatrix &)=delete
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.
bool IsEmptyCell(SCSIZE nC, SCSIZE nR) const
void DivOp(bool bFlag, double fVal, const ScMatrix &rMat)
void PowOp(bool bFlag, double fVal, const ScMatrix &rMat)
double GetDoubleWithStringConversion(SCSIZE nC, SCSIZE nR) const
KahanIterateResultMultiple CollectKahan(const std::vector< sc::op::kOp > &aOp)
void Resize(SCSIZE nC, SCSIZE nR)
Resize the matrix to specified new dimension.
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...
std::function< void(size_t, size_t, bool)> BoolOpFunction
friend class ScMatrixImpl
size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings=false) const
std::unique_ptr< ScMatrixImpl > pImpl
bool IsEmptyResult(SCSIZE nC, SCSIZE nR) const
bool ValidColRow(SCSIZE nC, SCSIZE nR) const
bool ValidColRowOrReplicated(SCSIZE &rC, SCSIZE &rR) const
Checks if the matrix position is within the matrix.
ScMatrixRef CompareMatrix(sc::Compare &rComp, size_t nMatPos, sc::CompareOptions *pOptions) const
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
void SetImmutable() const
Set the matrix to immutable for CloneIfConst(), only the interpreter should do this and know the cons...
bool IsEmptyPath(SCSIZE nC, SCSIZE nR) const
double GetMinValue(bool bTextAsZero, bool bIgnoreErrorValues=false) const
void ExecuteBinaryOp(SCSIZE nMaxCol, SCSIZE nMaxRow, const ScMatrix &rInputMat1, const ScMatrix &rInputMat2, ScInterpreter *pInterpreter, CalculateOpFunction op)
Apply binary operation to values from two input matrices, storing result into this matrix.
void GetDoubleArray(std::vector< double > &rArray, bool bEmptyAsZero=true) const
Convert the content of matrix into a linear array of numeric values.
void PutEmptyVector(SCSIZE nCount, SCSIZE nC, SCSIZE nR)
Put a column vector of empties, starting at row nR, must fit into dimensions.
void CompareGreaterEqual()
void MulOp(double fVal, const ScMatrix &rMat)
void PutError(FormulaError nErrorCode, SCSIZE nC, SCSIZE nR)
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
size_t MatchStringInColumns(const svl::SharedString &rStr, size_t nCol1, size_t nCol2) const
ScMatrix * CloneAndExtend(SCSIZE nNewCols, SCSIZE nNewRows) const
Clone the matrix and extend it to the new size.
ScMatrix * CloneIfConst()
Clone the matrix if mbCloneIfConst (immutable) is set, otherwise return this matrix,...
bool IsValue(SCSIZE nIndex) const
double GetMaxValue(bool bTextAsZero, bool bIgnoreErrorValues=false) const
SharedString intern(const OUString &rStr)
const OUString & getString() const
static const SharedString & getEmptyString()
#define suppress_fun_call_w_exception(expr)
double CreateDoubleError(FormulaError nErr)
FormulaError GetDoubleErrorValue(double fVal)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
enumrange< T >::Iterator begin(enumrange< T >)
Op_< std::function< void(KahanSum &, double)>, KahanSum > kOp
Op_< std::function< void(double &, double)>, double > Op
mdds::mtv::uint16_element_block uint16_block
double power(const double &fVal1, const double &fVal2)
Return pow(fVal1,fVal2) with error handling.
double CompareFunc(const Compare &rComp, CompareOptions *pOptions)
double div(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded into double.
mdds::mtv::default_element_block< element_type_string, svl::SharedString > string_block
double CompareEmptyToNumericFunc(double fCell2)
Left cell is empty while the right cell is numeric.
HSLColor operator*(double nFactor, const HSLColor &rRHS)
mdds::multi_type_matrix< matrix_traits > MatrixImplType
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)
static size_t GetElementsMax(size_t nMemory)
The maximum number of elements a matrix or the pool may have at runtime.
mdds::multi_type_matrix< matrix_flag_traits > MatrixFlagImplType
mdds::multi_type_matrix< matrix_traits > MatrixImplType
static std::once_flag bElementsMaxFetched
ScInterpreter * mpErrorInterpreter
static std::atomic< size_t > nElementsMax
const TMatFlag SC_MATFLAG_EMPTYPATH
const TMatFlag SC_MATFLAG_EMPTYRESULT
TOOLS_DLLPUBLIC SvStream & endl(SvStream &rStr)
Try NOT to use this struct.
When adding all numerical matrix elements for a scalar result such as summation, the interpreter want...
std::vector< tRes > maAccumulator
Iterator for executing one operation with the matrix data.
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)